diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 6e32852eaf..0c3d34a763 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -7891,3 +7891,5 @@ Sorry for the inconvenience."; "Conversation.VoiceMessagesRestricted" = "%@ doesn't accept voice and video messages"; "Emoji.ClearRecent" = "Clear Recent Emoji"; + +"Premium.AnimatedEmoji.Proceed" = "Unlock Animated Emoji"; diff --git a/submodules/AppLock/Sources/AppLock.swift b/submodules/AppLock/Sources/AppLock.swift index 2f8d668b27..49ec60fb5d 100644 --- a/submodules/AppLock/Sources/AppLock.swift +++ b/submodules/AppLock/Sources/AppLock.swift @@ -44,19 +44,23 @@ private func getCoveringViewSnaphot(window: Window1) -> UIImage? { context.clear(CGRect(origin: CGPoint(), size: size)) context.scaleBy(x: scale, y: scale) UIGraphicsPushContext(context) + + window.badgeView.alpha = 0.0 window.forEachViewController({ controller in if let controller = controller as? PasscodeEntryController { controller.displayNode.alpha = 0.0 } return true }) - window.hostView.containerView.drawHierarchy(in: CGRect(origin: CGPoint(), size: unscaledSize), afterScreenUpdates: false) + window.hostView.containerView.drawHierarchy(in: CGRect(origin: CGPoint(), size: unscaledSize), afterScreenUpdates: true) window.forEachViewController({ controller in if let controller = controller as? PasscodeEntryController { controller.displayNode.alpha = 1.0 } return true }) + window.badgeView.alpha = 1.0 + UIGraphicsPopContext() }).flatMap(applyScreenshotEffectToImage) } diff --git a/submodules/ContextUI/Sources/ContextActionsContainerNode.swift b/submodules/ContextUI/Sources/ContextActionsContainerNode.swift index 0045400c43..c7507f66c9 100644 --- a/submodules/ContextUI/Sources/ContextActionsContainerNode.swift +++ b/submodules/ContextUI/Sources/ContextActionsContainerNode.swift @@ -357,7 +357,7 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode { private let targetSelectionIndex: Int? private var action: (() -> Void)? - var requestDismiss: () -> Void = {} + var requestDismiss: (@escaping () -> Void) -> Void = { _ in } init(presentationData: PresentationData, tip: ContextController.Tip) { self.presentationData = presentationData @@ -369,8 +369,8 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode { self.buttonNode = HighlightTrackingButtonNode() self.textNode = TextNodeWithEntities() + self.textNode.textNode.displaysAsynchronously = false self.textNode.textNode.isUserInteractionEnabled = false - self.textNode.textNode.displaysAsynchronously = true var isUserInteractionEnabled = false var icon: UIImage? @@ -400,7 +400,7 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode { self.arguments = arguments self.file = file self.targetSelectionIndex = nil - icon = nil //UIImage(bundleImageName: "Chat/Context Menu/Arrow") + icon = nil isUserInteractionEnabled = text != nil } @@ -467,8 +467,9 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode { } @objc func pressed() { - self.requestDismiss() - self.action?() + self.requestDismiss({ + self.action?() + }) } func updateLayout(widthClass: ContainerViewLayoutSizeClass, width: CGFloat, transition: ContainedViewLayoutTransition) -> CGSize { @@ -652,8 +653,8 @@ final class ContextActionsContainerNode: ASDisplayNode { self.actionsNode = InnerActionsContainerNode(presentationData: presentationData, items: itemList, getController: getController, actionSelected: actionSelected, requestLayout: requestLayout, feedbackTap: feedbackTap, blurBackground: blurBackground) if let tip = items.tip { let textSelectionTipNode = InnerTextSelectionTipContainerNode(presentationData: presentationData, tip: tip) - textSelectionTipNode.requestDismiss = { - getController()?.dismiss(completion: nil) + textSelectionTipNode.requestDismiss = { completion in + getController()?.dismiss(completion: completion) } self.textSelectionTipNode = textSelectionTipNode } else { diff --git a/submodules/ContextUI/Sources/ContextController.swift b/submodules/ContextUI/Sources/ContextController.swift index 398eea1cfb..5e655079d0 100644 --- a/submodules/ContextUI/Sources/ContextController.swift +++ b/submodules/ContextUI/Sources/ContextController.swift @@ -2396,6 +2396,7 @@ public final class ContextController: ViewController, StandalonePresentableContr public func setItems(_ items: Signal, minHeight: ContextController.ActionsHeight?) { self.items = items if self.isNodeLoaded { + self.immediateItemsTransitionAnimation = false self.controllerNode.setItemsSignal(items: items, minHeight: minHeight, previousActionsTransition: .scale) } } diff --git a/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift b/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift index 4b7e5ac84a..e4e72f488a 100644 --- a/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift +++ b/submodules/ContextUI/Sources/ContextControllerActionsStackNode.swift @@ -887,8 +887,8 @@ final class ContextControllerActionsStackNode: ASDisplayNode { if self.tipNode == nil { updatedTransition = .immediate let tipNode = InnerTextSelectionTipContainerNode(presentationData: presentationData, tip: tip) - tipNode.requestDismiss = { [weak self] in - self?.getController()?.dismiss(completion: nil) + tipNode.requestDismiss = { [weak self] completion in + self?.getController()?.dismiss(completion: completion) } self.tipNode = tipNode } @@ -997,6 +997,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode { if animated { self.dismissingItemContainers.append((itemContainer, false)) } else { + itemContainer.tipNode?.removeFromSupernode() itemContainer.removeFromSupernode() } } @@ -1198,6 +1199,7 @@ final class ContextControllerActionsStackNode: ASDisplayNode { itemContainer?.removeFromSupernode() }) if let tipNode = itemContainer.tipNode { + transition.updateFrame(node: tipNode, frame: CGRect(origin: CGPoint(x: navigationContainerFrame.minX, y: navigationContainerFrame.maxY + tipSpacing), size: tipNode.frame.size), beginWithCurrentState: true) transition.updateAlpha(node: tipNode, alpha: 0.0, completion: { [weak tipNode] _ in tipNode?.removeFromSupernode() }) diff --git a/submodules/Display/Source/Navigation/NavigationController.swift b/submodules/Display/Source/Navigation/NavigationController.swift index 3cbd98634f..7de91ddaf2 100644 --- a/submodules/Display/Source/Navigation/NavigationController.swift +++ b/submodules/Display/Source/Navigation/NavigationController.swift @@ -357,41 +357,10 @@ open class NavigationController: UINavigationController, ContainableController, self.updateContainers(layout: layout, transition: transition) } } - - private var forceBadgeHidden = false - public func setForceBadgeHidden(_ hidden: Bool) { - guard hidden != self.forceBadgeHidden else { - return - } - self.forceBadgeHidden = hidden - if let layout = self.validLayout { - self.updateBadgeVisibility(layout: layout) - } - } - - private func updateBadgeVisibility(layout: ContainerViewLayout) { - guard let badgeNode = self.badgeNode else { - return - } - let badgeIsHidden = !layout.deviceMetrics.hasTopNotch || self.forceBadgeHidden || layout.size.width > layout.size.height - if badgeIsHidden != badgeNode.isHidden && !badgeIsHidden { - Queue.mainQueue().after(0.3) { - badgeNode.isHidden = badgeIsHidden - } - } else { - badgeNode.isHidden = badgeIsHidden - } - } - private func updateContainers(layout rawLayout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { self.isUpdatingContainers = true - - if let badgeNode = self.badgeNode, let image = badgeNode.image { - self.updateBadgeVisibility(layout: rawLayout) - badgeNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((rawLayout.size.width - image.size.width) / 2.0), y: 6.0), size: image.size) - } - + var layout = rawLayout if self.ignoreInputHeight { @@ -1268,16 +1237,8 @@ open class NavigationController: UINavigationController, ContainableController, self.displayNode.addSubnode(inCallStatusBar) } } - - let badgeNode = ASImageNode() - badgeNode.displaysAsynchronously = false - badgeNode.image = UIImage(bundleImageName: "Components/AppBadge") - self.badgeNode = badgeNode - self.displayNode.addSubnode(badgeNode) } - - private var badgeNode: ASImageNode? - + public func pushViewController(_ controller: ViewController) { self.pushViewController(controller, completion: {}) } diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift index 82b0b44a1c..e66677cd42 100644 --- a/submodules/Display/Source/WindowContent.swift +++ b/submodules/Display/Source/WindowContent.swift @@ -240,6 +240,7 @@ public final class WindowKeyboardGestureRecognizerDelegate: NSObject, UIGestureR public class Window1 { public let hostView: WindowHostView + public let badgeView: UIImageView private var deviceMetrics: DeviceMetrics @@ -328,6 +329,9 @@ public class Window1 { public init(hostView: WindowHostView, statusBarHost: StatusBarHost?) { self.hostView = hostView + self.badgeView = UIImageView() + self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge") + self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle let boundsSize = self.hostView.eventView.bounds.size @@ -626,8 +630,9 @@ public class Window1 { } self.windowPanRecognizer = recognizer self.hostView.containerView.addGestureRecognizer(recognizer) + self.hostView.containerView.addSubview(self.badgeView) } - + public required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -650,6 +655,26 @@ public class Window1 { } } + private var forceBadgeHidden = false + public func setForceBadgeHidden(_ hidden: Bool) { + guard hidden != self.forceBadgeHidden else { + return + } + self.forceBadgeHidden = hidden + self.updateBadgeVisibility(layout: self.windowLayout) + } + + private func updateBadgeVisibility(layout: WindowLayout) { + let badgeIsHidden = !self.deviceMetrics.hasTopNotch || self.forceBadgeHidden || layout.size.width > layout.size.height + if badgeIsHidden != self.badgeView.isHidden && !badgeIsHidden { + Queue.mainQueue().after(0.3) { + self.badgeView.isHidden = badgeIsHidden + } + } else { + self.badgeView.isHidden = badgeIsHidden + } + } + public func setForceInCallStatusBar(_ forceInCallStatusBarText: String?, transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)) { if self.forceInCallStatusBarText != forceInCallStatusBarText { self.forceInCallStatusBarText = forceInCallStatusBarText @@ -828,7 +853,7 @@ public class Window1 { if let coveringView = self.coveringView { self.hostView.containerView.insertSubview(controller.view, belowSubview: coveringView) } else { - self.hostView.containerView.addSubview(controller.view) + self.hostView.containerView.insertSubview(controller.view, belowSubview: self.badgeView) } if let controller = controller as? ViewController { @@ -868,7 +893,7 @@ public class Window1 { if let controller = self.topPresentationContext.controllers.first { self.hostView.containerView.insertSubview(coveringView, belowSubview: controller.0.displayNode.view) } else { - self.hostView.containerView.addSubview(coveringView) + self.hostView.containerView.insertSubview(coveringView, belowSubview: self.badgeView) } if !self.windowLayout.size.width.isZero { coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size) @@ -1087,6 +1112,11 @@ public class Window1 { coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size) coveringView.updateLayout(self.windowLayout.size) } + + if let image = self.badgeView.image { + self.updateBadgeVisibility(layout: self.windowLayout) + self.badgeView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((self.windowLayout.size.width - image.size.width) / 2.0), y: 6.0), size: image.size) + } } } } diff --git a/submodules/LegacyComponents/Sources/PGVideoMovie.m b/submodules/LegacyComponents/Sources/PGVideoMovie.m index 274ec0605c..ceb10a7b57 100755 --- a/submodules/LegacyComponents/Sources/PGVideoMovie.m +++ b/submodules/LegacyComponents/Sources/PGVideoMovie.m @@ -16,8 +16,8 @@ GLfloat kColorConversion601FullRangeDefault[] = { GLfloat kColorConversion709Default[] = { 1, 1, 1, - 0, -.21482, 2.12798, - 1.28033, -.38059, 0, + 0, -0.1873, 1.8556, + 1.5748, -0.4681, 0, }; GLfloat *kColorConversion601 = kColorConversion601Default; diff --git a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift index 2c80a1cb54..0095bff066 100644 --- a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift @@ -485,7 +485,7 @@ private final class DemoSheetContent: CombinedComponent { self.context = context self.subject = subject self.source = source - self.order = order ?? [.moreUpload, .fasterDownload, .voiceToText, .noAds, .uniqueReactions, .premiumStickers, .advancedChatManagement, .profileBadge, .animatedUserpics, .appIcons] + self.order = order ?? [.moreUpload, .fasterDownload, .voiceToText, .noAds, .uniqueReactions, .premiumStickers, .animatedEmoji, .advancedChatManagement, .profileBadge, .animatedUserpics, .appIcons] self.action = action self.dismiss = dismiss } @@ -994,6 +994,9 @@ private final class DemoSheetContent: CombinedComponent { buttonAnimationName = "premium_unlock" case .noAds: buttonText = strings.Premium_NoAds_Proceed + case .animatedEmoji: + buttonText = strings.Premium_AnimatedEmoji_Proceed + buttonAnimationName = "premium_unlock" default: buttonText = strings.Common_OK } diff --git a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift index 19d1249bcd..2dc3ae0916 100644 --- a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift @@ -1223,7 +1223,7 @@ public final class PremiumGiftScreen: ViewControllerComponentContainer { public weak var containerView: UIView? public var animationColor: UIColor? - public init(context: AccountContext, peerId: PeerId) { + public init(context: AccountContext, peerId: PeerId, options: [CachedPremiumGiftOption]) { self.context = context var updateInProgressImpl: ((Bool) -> Void)? diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 823359e6bd..b0305e0722 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -36,6 +36,7 @@ public enum PremiumSource: Equatable { case accounts case about case appIcons + case animatedEmoji case deeplink(String?) case profile(PeerId) case gift(from: PeerId, to: PeerId, duration: Int32) @@ -73,6 +74,8 @@ public enum PremiumSource: Equatable { return "double_limits__accounts" case .about: return "double_limits__about" + case .animatedEmoji: + return "animated_emoji" case let .profile(id): return "profile__\(id.id._internalGetInt64Value())" case .gift, .giftTerms: diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift index 09f3a97eec..a20f4fe1d8 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift @@ -769,6 +769,9 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting }), true) } } else { + let hapticFeedback = HapticFeedback() + hapticFeedback.impact() + presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Privacy_VoiceMessages_Tooltip), elevatedLayout: false, animateInAsReplacement: false, action: { action in if action == .info { let controller = PremiumIntroScreen(context: context, source: .settings) diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackEmojisItem.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackEmojisItem.swift index 0b12336a11..2b5a4c4404 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackEmojisItem.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackEmojisItem.swift @@ -172,13 +172,19 @@ final class StickerPackEmojisItemNode: GridItemNode { super.didLoad() let shimmerHostView = PortalSourceView() + shimmerHostView.alpha = 0.0 + shimmerHostView.frame = CGRect(origin: CGPoint(), size: self.frame.size) + self.view.addSubview(shimmerHostView) self.shimmerHostView = shimmerHostView let standaloneShimmerEffect = StandaloneShimmerEffect() self.standaloneShimmerEffect = standaloneShimmerEffect - - shimmerHostView.alpha = 0.0 - self.view.addSubview(shimmerHostView) + if let item = self.item { + let shimmerBackgroundColor = item.theme.chat.inputPanel.primaryTextColor.withMultipliedAlpha(0.08) + let shimmerForegroundColor = item.theme.list.itemBlocksBackgroundColor.withMultipliedAlpha(0.15) + standaloneShimmerEffect.update(background: shimmerBackgroundColor, foreground: shimmerForegroundColor) + self.updateShimmerIfNeeded() + } let boundsChangeTrackerLayer = SimpleLayer() boundsChangeTrackerLayer.opacity = 0.0 @@ -261,7 +267,7 @@ final class StickerPackEmojisItemNode: GridItemNode { placeholderColor: theme.chat.inputPanel.primaryTextColor.withMultipliedAlpha(0.1), blurredBadgeColor: theme.chat.inputPanel.panelBackgroundColor.withMultipliedAlpha(0.5), pointSize: itemNativeFitSize, - onUpdateDisplayPlaceholder: { [weak self] displayPlaceholder, _ in + onUpdateDisplayPlaceholder: { [weak self] displayPlaceholder, duration in guard let strongSelf = self else { return } @@ -275,7 +281,7 @@ final class StickerPackEmojisItemNode: GridItemNode { context: context, file: item.file, shimmerView: strongSelf.shimmerHostView, - color: nil, + color: theme.chat.inputPanel.primaryTextColor.withMultipliedAlpha(0.08), size: itemNativeFitSize ) strongSelf.visibleItemPlaceholderViews[itemId] = placeholderView @@ -289,9 +295,20 @@ final class StickerPackEmojisItemNode: GridItemNode { } else { if let placeholderView = strongSelf.visibleItemPlaceholderViews[itemId] { strongSelf.visibleItemPlaceholderViews.removeValue(forKey: itemId) - placeholderView.removeFromSuperview() - strongSelf.updateShimmerIfNeeded() + if duration > 0.0 { + placeholderView.layer.opacity = 0.0 + placeholderView.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, completion: { [weak self, weak placeholderView] _ in + guard let strongSelf = self else { + return + } + placeholderView?.removeFromSuperview() + strongSelf.updateShimmerIfNeeded() + }) + } else { + placeholderView.removeFromSuperview() + strongSelf.updateShimmerIfNeeded() + } } } } @@ -324,6 +341,13 @@ final class StickerPackEmojisItemNode: GridItemNode { itemLayer.isVisibleForAnimations = true } + + for id in self.visibleItemLayers.keys { + if !validIds.contains(id) { + self.visibleItemLayers[id]?.removeFromSuperlayer() + self.visibleItemLayers[id] = nil + } + } } private func updateShimmerIfNeeded() { diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift index 576b23290f..1401791f68 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift @@ -715,7 +715,7 @@ private final class StickerPackContainer: ASDisplayNode { } else if loadedCount == contents.count { self.onReady() - if !contents.isEmpty && self.currentStickerPack == nil { + if !contents.isEmpty && self.currentStickerPacks.isEmpty { if let _ = self.validLayout, abs(self.expandScrollProgress - 1.0) < .ulpOfOne { scrollToItem = GridNodeScrollToItem(index: 0, position: .top(0.0), transition: .immediate, directionHint: .up, adjustForSection: false) } diff --git a/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift b/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift index 092277a4e0..9f3b56b741 100644 --- a/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift +++ b/submodules/TelegramUI/Components/TextNodeWithEntities/Sources/TextNodeWithEntities.swift @@ -78,7 +78,7 @@ public final class TextNodeWithEntities { context: self.context, cache: self.cache, renderer: self.renderer, - placeholderColor: self.placeholderColor, + placeholderColor: color, attemptSynchronous: self.attemptSynchronous ) } diff --git a/submodules/TelegramUI/Images.xcassets/Components/AppBadge.imageset/AppBadge@3x.png b/submodules/TelegramUI/Images.xcassets/Components/AppBadge.imageset/AppBadge@3x.png index d647852ab0..f9746877fd 100644 Binary files a/submodules/TelegramUI/Images.xcassets/Components/AppBadge.imageset/AppBadge@3x.png and b/submodules/TelegramUI/Images.xcassets/Components/AppBadge.imageset/AppBadge@3x.png differ diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 66e2d188bc..ab34e8964d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -3702,6 +3702,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }, cancelInteractiveKeyboardGestures: { [weak self] in (self?.view.window as? WindowHost)?.cancelInteractiveKeyboardGestures() self?.chatDisplayNode.cancelInteractiveKeyboardGestures() + }, dismissTextInput: { [weak self] in + self?.chatDisplayNode.dismissTextInput() }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: self.stickerSettings, presentationContext: ChatPresentationContext(context: context, backgroundNode: self.chatBackgroundNode)) self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift index 36261570fc..95c6a9da12 100644 --- a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift @@ -141,6 +141,7 @@ public final class ChatControllerInteraction { let requestMessageUpdate: (MessageId) -> Void let cancelInteractiveKeyboardGestures: () -> Void + let dismissTextInput: () -> Void var canPlayMedia: Bool = false var hiddenMedia: [MessageId: [Media]] = [:] @@ -243,6 +244,7 @@ public final class ChatControllerInteraction { openWebView: @escaping (String, String, Bool, Bool) -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, + dismissTextInput: @escaping () -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState, stickerSettings: ChatInterfaceStickerSettings, @@ -330,6 +332,7 @@ public final class ChatControllerInteraction { self.openWebView = openWebView self.requestMessageUpdate = requestMessageUpdate self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures + self.dismissTextInput = dismissTextInput self.automaticMediaDownloadSettings = automaticMediaDownloadSettings diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 230b858fc1..6d26a9f3ce 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -2317,6 +2317,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.view.window?.endEditing(true) } + func dismissTextInput() { + self.view.window?.endEditing(true) + } + func collapseInput() { if self.inputPanelContainerNode.expansionFraction != 0.0 { self.inputPanelContainerNode.collapse() @@ -2866,10 +2870,11 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { guard let strongSelf = self else { return } + strongSelf.dismissTextInput() var replaceImpl: ((ViewController) -> Void)? - let controller = PremiumDemoScreen(context: strongSelf.context, subject: .premiumStickers, action: { - let controller = PremiumIntroScreen(context: strongSelf.context, source: .stickers) + let controller = PremiumDemoScreen(context: strongSelf.context, subject: .animatedEmoji, action: { + let controller = PremiumIntroScreen(context: strongSelf.context, source: .animatedEmoji) replaceImpl?(controller) }) replaceImpl = { [weak controller] c in diff --git a/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift b/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift index ad7920f3ef..03f950533a 100644 --- a/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift @@ -314,7 +314,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode { if file.isPremiumEmoji && !hasPremium { //TODO:localize - + let presentationData = context.sharedContext.currentPresentationData.with { $0 } controllerInteraction.presentController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Subscribe to Telegram Premium to unlock this emoji.", undoText: "More", customAction: { [weak controllerInteraction] in guard let controllerInteraction = controllerInteraction else { @@ -322,8 +322,8 @@ final class ChatEntityKeyboardInputNode: ChatInputNode { } var replaceImpl: ((ViewController) -> Void)? - let controller = PremiumDemoScreen(context: context, subject: .premiumStickers, action: { - let controller = PremiumIntroScreen(context: context, source: .stickers) + let controller = PremiumDemoScreen(context: context, subject: .animatedEmoji, action: { + let controller = PremiumIntroScreen(context: context, source: .animatedEmoji) replaceImpl?(controller) }) replaceImpl = { [weak controller] c in @@ -1765,8 +1765,8 @@ final class EntityInputView: UIView, AttachmentTextInputPanelInputView, UIInputV } var replaceImpl: ((ViewController) -> Void)? - let controller = PremiumDemoScreen(context: strongSelf.context, subject: .premiumStickers, action: { - let controller = PremiumIntroScreen(context: strongSelf.context, source: .stickers) + let controller = PremiumDemoScreen(context: strongSelf.context, subject: .animatedEmoji, action: { + let controller = PremiumIntroScreen(context: strongSelf.context, source: .animatedEmoji) replaceImpl?(controller) }) replaceImpl = { [weak controller] c in diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index 17e7d41d94..5fa9774f2f 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -537,6 +537,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { }, openWebView: { _, _, _, _ in }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { + }, dismissTextInput: { }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false), presentationContext: ChatPresentationContext(context: context, backgroundNode: self.backgroundNode)) self.controllerInteraction = controllerInteraction diff --git a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift index 0e8743ef92..97ea2d7c5e 100644 --- a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift +++ b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift @@ -163,6 +163,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode { }, openWebView: { _, _, _, _ in }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { + }, dismissTextInput: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: true), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil)) diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index 7918d25600..928371d929 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -155,6 +155,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu }, openWebView: { _, _, _, _ in }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { + }, dismissTextInput: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil)) self.dimNode = ASDisplayNode() diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 641416b426..0653983289 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -2356,6 +2356,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate }, openWebView: { _, _, _, _ in }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { + }, dismissTextInput: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil)) self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in @@ -4064,7 +4065,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Gift"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in f(.dismissWithoutContent) - self?.giftPremium() + + if let strongSelf = self { + let controller = PremiumGiftScreen(context: strongSelf.context, peerId: strongSelf.peerId, options: cachedData.premiumGiftOptions) + strongSelf.controller?.push(controller) + } }))) } @@ -6426,12 +6431,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate } })) } - - private func giftPremium() { - let controller = PremiumGiftScreen(context: self.context, peerId: self.peerId) - self.controller?.push(controller) - } - + fileprivate func switchToAccount(id: AccountRecordId) { self.accountsAndPeers.set(.never()) self.context.sharedContext.switchToAccount(id: id, fromSettingsController: nil, withChatListController: nil) diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 260943c25f..00ae018e33 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1334,6 +1334,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { }, openWebView: { _, _, _, _ in }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { + }, dismissTextInput: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false), presentationContext: ChatPresentationContext(context: context, backgroundNode: backgroundNode as? WallpaperBackgroundNode)) diff --git a/submodules/TelegramUI/Sources/TelegramRootController.swift b/submodules/TelegramUI/Sources/TelegramRootController.swift index 73927f1538..6957009e80 100644 --- a/submodules/TelegramUI/Sources/TelegramRootController.swift +++ b/submodules/TelegramUI/Sources/TelegramRootController.swift @@ -76,11 +76,8 @@ public final class TelegramRootController: NavigationController { self.applicationInFocusDisposable = (context.sharedContext.applicationBindings.applicationIsActive |> distinctUntilChanged - |> deliverOn(Queue.mainQueue())).start(next: { [weak self] value in - guard let strongSelf = self else { - return - } - strongSelf.setForceBadgeHidden(!value) + |> deliverOn(Queue.mainQueue())).start(next: { value in + context.sharedContext.mainWindow?.setForceBadgeHidden(!value) }) } diff --git a/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift b/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift index e962e26fb7..9915f8fae4 100644 --- a/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift +++ b/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift @@ -974,6 +974,8 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode { case let .sticker(_, _, _, _, _, customAction): if let customAction = customAction { customAction() + } else { + let _ = self.action(.undo) } default: let _ = self.action(.undo)