mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-01 12:17:53 +00:00
Update non-premium tags
This commit is contained in:
parent
27c5ca7474
commit
4b91f1fc29
@ -17,21 +17,24 @@ import SavedTagNameAlertController
|
|||||||
import PremiumUI
|
import PremiumUI
|
||||||
|
|
||||||
extension ChatControllerImpl {
|
extension ChatControllerImpl {
|
||||||
|
func presentTagPremiumPaywall() {
|
||||||
|
//TODO:localize
|
||||||
|
let context = self.context
|
||||||
|
var replaceImpl: ((ViewController) -> Void)?
|
||||||
|
let controller = PremiumDemoScreen(context: context, subject: .uniqueReactions, action: {
|
||||||
|
let controller = PremiumIntroScreen(context: context, source: .reactions)
|
||||||
|
replaceImpl?(controller)
|
||||||
|
})
|
||||||
|
replaceImpl = { [weak controller] c in
|
||||||
|
controller?.replace(with: c)
|
||||||
|
}
|
||||||
|
self.push(controller)
|
||||||
|
}
|
||||||
|
|
||||||
func openMessageReactionContextMenu(message: Message, sourceView: ContextExtractedContentContainingView, gesture: ContextGesture?, value: MessageReaction.Reaction) {
|
func openMessageReactionContextMenu(message: Message, sourceView: ContextExtractedContentContainingView, gesture: ContextGesture?, value: MessageReaction.Reaction) {
|
||||||
if message.areReactionsTags(accountPeerId: self.context.account.peerId) {
|
if message.areReactionsTags(accountPeerId: self.context.account.peerId) {
|
||||||
if !self.presentationInterfaceState.isPremium {
|
if !self.presentationInterfaceState.isPremium {
|
||||||
//TODO:localize
|
self.presentTagPremiumPaywall()
|
||||||
let context = self.context
|
|
||||||
var replaceImpl: ((ViewController) -> Void)?
|
|
||||||
let controller = PremiumDemoScreen(context: context, subject: .uniqueReactions, action: {
|
|
||||||
let controller = PremiumIntroScreen(context: context, source: .reactions)
|
|
||||||
replaceImpl?(controller)
|
|
||||||
})
|
|
||||||
replaceImpl = { [weak controller] c in
|
|
||||||
controller?.replace(with: c)
|
|
||||||
}
|
|
||||||
self.push(controller)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,11 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if case .standard(.embedded) = chatPresentationInterfaceState.mode {
|
||||||
|
if !chatPresentationInterfaceState.isPremium {
|
||||||
|
matches = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if matches {
|
if matches {
|
||||||
if let currentPanel = currentPanel as? ChatSearchTitleAccessoryPanelNode {
|
if let currentPanel = currentPanel as? ChatSearchTitleAccessoryPanelNode {
|
||||||
|
|||||||
@ -119,7 +119,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
self.action()
|
self.action()
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(theme: PresentationTheme, strings: PresentationStrings, height: CGFloat, transition: Transition) -> CGSize {
|
func update(theme: PresentationTheme, strings: PresentationStrings, height: CGFloat, isUnlock: Bool, transition: Transition) -> CGSize {
|
||||||
let titleIconSpacing: CGFloat = 0.0
|
let titleIconSpacing: CGFloat = 0.0
|
||||||
|
|
||||||
let titleIconSize = self.titleIcon.update(
|
let titleIconSize = self.titleIcon.update(
|
||||||
@ -137,7 +137,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
let titleSize = self.title.update(
|
let titleSize = self.title.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(MultilineTextComponent(
|
component: AnyComponent(MultilineTextComponent(
|
||||||
text: .plain(NSAttributedString(string: "Add tags", font: Font.medium(14.0), textColor: theme.rootController.navigationBar.accentTextColor))
|
text: .plain(NSAttributedString(string: isUnlock ? "Unlock" : "Add tags", font: Font.medium(14.0), textColor: theme.rootController.navigationBar.accentTextColor))
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 200.0, height: 100.0)
|
containerSize: CGSize(width: 200.0, height: 100.0)
|
||||||
@ -201,6 +201,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
self.containerButton.addSubview(textView)
|
self.containerButton.addSubview(textView)
|
||||||
}
|
}
|
||||||
textView.frame = textFrame
|
textView.frame = textFrame
|
||||||
|
transition.setAlpha(view: textView, alpha: isUnlock ? 0.0 : 1.0)
|
||||||
}
|
}
|
||||||
totalSize.width += textSize.width
|
totalSize.width += textSize.width
|
||||||
totalSize.width += arrowSpacing
|
totalSize.width += arrowSpacing
|
||||||
@ -212,12 +213,13 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
self.containerButton.addSubview(arrowIconView)
|
self.containerButton.addSubview(arrowIconView)
|
||||||
}
|
}
|
||||||
arrowIconView.frame = arrowFrame
|
arrowIconView.frame = arrowFrame
|
||||||
|
transition.setAlpha(view: arrowIconView, alpha: isUnlock ? 0.0 : 1.0)
|
||||||
}
|
}
|
||||||
totalSize.width += arrowSize.width
|
totalSize.width += arrowSize.width
|
||||||
|
|
||||||
transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: totalSize))
|
transition.setFrame(view: self.containerButton, frame: CGRect(origin: CGPoint(), size: totalSize))
|
||||||
|
|
||||||
return totalSize
|
return isUnlock ? size : totalSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,9 +309,11 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
return super.hitTest(mappedPoint, with: event)
|
return super.hitTest(mappedPoint, with: event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(item: Item, isSelected: Bool, theme: PresentationTheme, height: CGFloat, transition: Transition) -> CGSize {
|
func update(item: Item, isSelected: Bool, isLocked: Bool, theme: PresentationTheme, height: CGFloat, transition: Transition) -> CGSize {
|
||||||
let spacing: CGFloat = 3.0
|
let spacing: CGFloat = 3.0
|
||||||
|
|
||||||
|
let contentsAlpha: CGFloat = isLocked ? 0.6 : 1.0
|
||||||
|
|
||||||
let reactionSize = CGSize(width: 20.0, height: 20.0)
|
let reactionSize = CGSize(width: 20.0, height: 20.0)
|
||||||
var reactionDisplaySize = reactionSize
|
var reactionDisplaySize = reactionSize
|
||||||
if case .builtin = item.reaction {
|
if case .builtin = item.reaction {
|
||||||
@ -379,6 +383,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
self.containerButton.addSubview(iconView)
|
self.containerButton.addSubview(iconView)
|
||||||
}
|
}
|
||||||
iconView.frame = reactionDisplaySize.centered(around: iconFrame.center)
|
iconView.frame = reactionDisplaySize.centered(around: iconFrame.center)
|
||||||
|
transition.setAlpha(view: iconView, alpha: contentsAlpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let titleView = self.title.view {
|
if let titleView = self.title.view {
|
||||||
@ -387,6 +392,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
self.containerButton.addSubview(titleView)
|
self.containerButton.addSubview(titleView)
|
||||||
}
|
}
|
||||||
titleView.frame = titleFrame
|
titleView.frame = titleFrame
|
||||||
|
transition.setAlpha(view: titleView, alpha: contentsAlpha)
|
||||||
}
|
}
|
||||||
if let counterView = self.counter.view {
|
if let counterView = self.counter.view {
|
||||||
if counterView.superview == nil {
|
if counterView.superview == nil {
|
||||||
@ -394,6 +400,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
self.containerButton.addSubview(counterView)
|
self.containerButton.addSubview(counterView)
|
||||||
}
|
}
|
||||||
counterView.frame = counterFrame
|
counterView.frame = counterFrame
|
||||||
|
transition.setAlpha(view: counterView, alpha: contentsAlpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
if theme.overallDarkAppearance {
|
if theme.overallDarkAppearance {
|
||||||
@ -570,6 +577,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
var validIds: [MessageReaction.Reaction] = []
|
var validIds: [MessageReaction.Reaction] = []
|
||||||
|
|
||||||
let hadItemViews = !self.itemViews.isEmpty
|
let hadItemViews = !self.itemViews.isEmpty
|
||||||
|
var isFirst = true
|
||||||
|
|
||||||
if !params.interfaceState.isPremium {
|
if !params.interfaceState.isPremium {
|
||||||
let promoView: PromoView
|
let promoView: PromoView
|
||||||
@ -601,108 +609,121 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
self.scrollView.addSubview(promoView)
|
self.scrollView.addSubview(promoView)
|
||||||
}
|
}
|
||||||
|
|
||||||
let itemSize = promoView.update(theme: params.interfaceState.theme, strings: params.interfaceState.strings, height: panelHeight, transition: .immediate)
|
let itemSize = promoView.update(theme: params.interfaceState.theme, strings: params.interfaceState.strings, height: panelHeight, isUnlock: !self.items.isEmpty, transition: .immediate)
|
||||||
let itemFrame = CGRect(origin: CGPoint(x: contentSize.width, y: -5.0), size: itemSize)
|
let itemFrame = CGRect(origin: CGPoint(x: contentSize.width, y: -5.0), size: itemSize)
|
||||||
|
|
||||||
itemTransition.updatePosition(layer: promoView.layer, position: itemFrame.center)
|
itemTransition.updatePosition(layer: promoView.layer, position: itemFrame.center)
|
||||||
promoView.bounds = CGRect(origin: CGPoint(), size: itemFrame.size)
|
promoView.bounds = CGRect(origin: CGPoint(), size: itemFrame.size)
|
||||||
|
|
||||||
contentSize.width += itemSize.width
|
contentSize.width += itemSize.width
|
||||||
|
|
||||||
|
isFirst = false
|
||||||
} else {
|
} else {
|
||||||
if let promoView = self.promoView {
|
if let promoView = self.promoView {
|
||||||
self.promoView = nil
|
self.promoView = nil
|
||||||
promoView.removeFromSuperview()
|
promoView.removeFromSuperview()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var isFirst = true
|
for item in self.items {
|
||||||
for item in self.items {
|
if isFirst {
|
||||||
if isFirst {
|
isFirst = false
|
||||||
isFirst = false
|
} else {
|
||||||
} else {
|
contentSize.width += itemSpacing
|
||||||
contentSize.width += itemSpacing
|
}
|
||||||
}
|
let itemId = item.reaction
|
||||||
let itemId = item.reaction
|
validIds.append(itemId)
|
||||||
validIds.append(itemId)
|
|
||||||
|
var itemTransition = transition
|
||||||
var itemTransition = transition
|
var animateIn = false
|
||||||
var animateIn = false
|
let itemView: ItemView
|
||||||
let itemView: ItemView
|
if let current = self.itemViews[itemId] {
|
||||||
if let current = self.itemViews[itemId] {
|
itemView = current
|
||||||
itemView = current
|
} else {
|
||||||
} else {
|
itemTransition = .immediate
|
||||||
itemTransition = .immediate
|
animateIn = true
|
||||||
animateIn = true
|
let reaction = item.reaction
|
||||||
let reaction = item.reaction
|
itemView = ItemView(context: self.context, action: { [weak self] in
|
||||||
itemView = ItemView(context: self.context, action: { [weak self] in
|
guard let self, let params = self.params else {
|
||||||
guard let self, let params = self.params else {
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !params.interfaceState.isPremium {
|
||||||
|
if let chatController = self.interfaceInteraction?.chatController() {
|
||||||
|
(chatController as? ChatControllerImpl)?.presentTagPremiumPaywall()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let tag = ReactionsMessageAttribute.messageTag(reaction: reaction)
|
||||||
|
|
||||||
|
var updatedFilter: ChatPresentationInterfaceState.HistoryFilter?
|
||||||
|
let currentTag = params.interfaceState.historyFilter?.customTag
|
||||||
|
if currentTag == tag {
|
||||||
|
updatedFilter = nil
|
||||||
|
} else {
|
||||||
|
updatedFilter = ChatPresentationInterfaceState.HistoryFilter(customTag: tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.interfaceInteraction?.updateHistoryFilter({ filter in
|
||||||
|
return updatedFilter
|
||||||
|
})
|
||||||
|
}, contextGesture: { [weak self] gesture, sourceNode in
|
||||||
|
guard let self, let params = self.params, let interfaceInteraction = self.interfaceInteraction, let chatController = interfaceInteraction.chatController() else {
|
||||||
|
gesture.cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !params.interfaceState.isPremium {
|
||||||
|
(chatController as? ChatControllerImpl)?.presentTagPremiumPaywall()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var items: [ContextMenuItem] = []
|
||||||
|
|
||||||
|
let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
|
//TODO:localize
|
||||||
|
items.append(.action(ContextMenuActionItem(text: "Edit Title", icon: { theme in
|
||||||
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/TagEditName"), color: theme.contextMenu.primaryColor)
|
||||||
|
}, action: { [weak self] c, a in
|
||||||
|
guard let self else {
|
||||||
|
a(.default)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let tag = ReactionsMessageAttribute.messageTag(reaction: reaction)
|
c.dismiss(completion: { [weak self] in
|
||||||
|
guard let self, let item = self.items.first(where: { $0.reaction == reaction }) else {
|
||||||
var updatedFilter: ChatPresentationInterfaceState.HistoryFilter?
|
|
||||||
let currentTag = params.interfaceState.historyFilter?.customTag
|
|
||||||
if currentTag == tag {
|
|
||||||
updatedFilter = nil
|
|
||||||
} else {
|
|
||||||
updatedFilter = ChatPresentationInterfaceState.HistoryFilter(customTag: tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.interfaceInteraction?.updateHistoryFilter({ filter in
|
|
||||||
return updatedFilter
|
|
||||||
})
|
|
||||||
}, contextGesture: { [weak self] gesture, sourceNode in
|
|
||||||
guard let self, let interfaceInteraction = self.interfaceInteraction, let chatController = interfaceInteraction.chatController() else {
|
|
||||||
gesture.cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var items: [ContextMenuItem] = []
|
|
||||||
|
|
||||||
let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 })
|
|
||||||
//TODO:localize
|
|
||||||
items.append(.action(ContextMenuActionItem(text: "Edit Title", icon: { theme in
|
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/TagEditName"), color: theme.contextMenu.primaryColor)
|
|
||||||
}, action: { [weak self] c, a in
|
|
||||||
guard let self else {
|
|
||||||
a(.default)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
self.openEditTagTitle(reaction: reaction, hasTitle: item.title != nil)
|
||||||
c.dismiss(completion: { [weak self] in
|
})
|
||||||
guard let self, let item = self.items.first(where: { $0.reaction == reaction }) else {
|
})))
|
||||||
return
|
|
||||||
}
|
let controller = ContextController(presentationData: presentationData, source: .extracted(TagContextExtractedContentSource(controller: chatController, sourceNode: sourceNode, keepInPlace: false)), items: .single(ContextController.Items(content: .list(items))), recognizer: nil, gesture: gesture)
|
||||||
self.openEditTagTitle(reaction: reaction, hasTitle: item.title != nil)
|
interfaceInteraction.presentGlobalOverlayController(controller, nil)
|
||||||
})
|
})
|
||||||
})))
|
self.itemViews[itemId] = itemView
|
||||||
|
self.scrollView.addSubview(itemView)
|
||||||
let controller = ContextController(presentationData: presentationData, source: .extracted(TagContextExtractedContentSource(controller: chatController, sourceNode: sourceNode, keepInPlace: false)), items: .single(ContextController.Items(content: .list(items))), recognizer: nil, gesture: gesture)
|
|
||||||
interfaceInteraction.presentGlobalOverlayController(controller, nil)
|
|
||||||
})
|
|
||||||
self.itemViews[itemId] = itemView
|
|
||||||
self.scrollView.addSubview(itemView)
|
|
||||||
}
|
|
||||||
|
|
||||||
var isSelected = false
|
|
||||||
if let historyFilter = params.interfaceState.historyFilter {
|
|
||||||
if historyFilter.customTag == ReactionsMessageAttribute.messageTag(reaction: item.reaction) {
|
|
||||||
isSelected = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let itemSize = itemView.update(item: item, isSelected: isSelected, theme: params.interfaceState.theme, height: panelHeight, transition: .immediate)
|
|
||||||
let itemFrame = CGRect(origin: CGPoint(x: contentSize.width, y: -5.0), size: itemSize)
|
|
||||||
|
|
||||||
itemTransition.updatePosition(layer: itemView.layer, position: itemFrame.center)
|
|
||||||
itemTransition.updateBounds(layer: itemView.layer, bounds: CGRect(origin: CGPoint(), size: itemFrame.size))
|
|
||||||
|
|
||||||
if animateIn && transition.isAnimated {
|
|
||||||
itemView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15)
|
|
||||||
transition.animateTransformScale(view: itemView, from: 0.001)
|
|
||||||
}
|
|
||||||
|
|
||||||
contentSize.width += itemSize.width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isSelected = false
|
||||||
|
if let historyFilter = params.interfaceState.historyFilter {
|
||||||
|
if historyFilter.customTag == ReactionsMessageAttribute.messageTag(reaction: item.reaction) {
|
||||||
|
isSelected = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let itemSize = itemView.update(item: item, isSelected: isSelected, isLocked: !params.interfaceState.isPremium, theme: params.interfaceState.theme, height: panelHeight, transition: .immediate)
|
||||||
|
let itemFrame = CGRect(origin: CGPoint(x: contentSize.width, y: -5.0), size: itemSize)
|
||||||
|
|
||||||
|
itemTransition.updatePosition(layer: itemView.layer, position: itemFrame.center)
|
||||||
|
itemTransition.updateBounds(layer: itemView.layer, bounds: CGRect(origin: CGPoint(), size: itemFrame.size))
|
||||||
|
|
||||||
|
if animateIn && transition.isAnimated {
|
||||||
|
itemView.layer.animateAlpha(from: 0.0, to: itemView.alpha, duration: 0.15)
|
||||||
|
transition.animateTransformScale(view: itemView, from: 0.001)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentSize.width += itemSize.width
|
||||||
}
|
}
|
||||||
var removedIds: [MessageReaction.Reaction] = []
|
var removedIds: [MessageReaction.Reaction] = []
|
||||||
for (id, itemView) in self.itemViews {
|
for (id, itemView) in self.itemViews {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user