From c1c2db4777714743eee0cacc79048d557192e727 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sat, 24 Jun 2023 18:45:52 +0200 Subject: [PATCH] Various fixes --- .../Telegram-iOS/en.lproj/Localizable.strings | 1 + submodules/DrawingUI/BUILD | 1 + .../Sources/StickerPickerScreen.swift | 77 ++++++++++++------- .../Sources/ChatMediaInputTrendingPane.swift | 28 ++++++- .../Sources/StickerPackScreen.swift | 15 +++- .../Sources/PaneSearchContainerNode.swift | 4 +- .../StickerPaneSearchContentNode.swift | 5 +- .../EntitySearchContentComponent.swift | 4 +- .../StoryItemSetContainerComponent.swift | 4 + 9 files changed, 99 insertions(+), 40 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index e6bb311d7b..8974dd8a44 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -2061,6 +2061,7 @@ "StickerPack.Share" = "Share"; "StickerPack.Send" = "Send Sticker"; +"StickerPack.Select" = "Select Sticker"; "StickerPack.RemoveStickerCount_1" = "Remove 1 Sticker"; "StickerPack.RemoveStickerCount_2" = "Remove 2 Stickers"; diff --git a/submodules/DrawingUI/BUILD b/submodules/DrawingUI/BUILD index c4e0a40cf7..0e40dd4048 100644 --- a/submodules/DrawingUI/BUILD +++ b/submodules/DrawingUI/BUILD @@ -95,6 +95,7 @@ swift_library( "//submodules/FastBlur:FastBlur", "//submodules/TelegramUI/Components/MediaEditor", "//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState", + "//submodules/StickerPackPreviewUI:StickerPackPreviewUI", ], visibility = [ "//visibility:public", diff --git a/submodules/DrawingUI/Sources/StickerPickerScreen.swift b/submodules/DrawingUI/Sources/StickerPickerScreen.swift index 68d74d0034..5ec41118d3 100644 --- a/submodules/DrawingUI/Sources/StickerPickerScreen.swift +++ b/submodules/DrawingUI/Sources/StickerPickerScreen.swift @@ -17,6 +17,7 @@ import ChatEntityKeyboardInputNode import ContextUI import ChatPresentationInterfaceState import MediaEditor +import StickerPackPreviewUI public struct StickerPickerInputData: Equatable { var emoji: EmojiPagerContentComponent @@ -45,6 +46,7 @@ private final class StickerSelectionComponent: Component { let content: StickerPickerInputData let backgroundColor: UIColor let separatorColor: UIColor + let getController: () -> StickerPickerScreen? init( context: AccountContext, @@ -54,7 +56,8 @@ private final class StickerSelectionComponent: Component { bottomInset: CGFloat, content: StickerPickerInputData, backgroundColor: UIColor, - separatorColor: UIColor + separatorColor: UIColor, + getController: @escaping () -> StickerPickerScreen? ) { self.context = context self.theme = theme @@ -64,6 +67,7 @@ private final class StickerSelectionComponent: Component { self.content = content self.backgroundColor = backgroundColor self.separatorColor = separatorColor + self.getController = getController } public static func ==(lhs: StickerSelectionComponent, rhs: StickerSelectionComponent) -> Bool { @@ -105,6 +109,7 @@ private final class StickerSelectionComponent: Component { private var inputNodeInteraction: ChatMediaInputNodeInteraction? private let trendingGifsPromise = Promise(nil) + private var searchVisible = false private var forceUpdate = false override init(frame: CGRect) { @@ -122,16 +127,22 @@ private final class StickerSelectionComponent: Component { self.addSubview(self.panelHostView) self.interaction = ChatEntityKeyboardInputNode.Interaction( - sendSticker: { file, silent, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, _ in - let _ = file - let _ = silent - let _ = schedule - let _ = query - let _ = clearInput - let _ = sourceView - let _ = sourceRect - let _ = sourceLayer - + sendSticker: { [weak self] file, silent, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, _ in + if let self, let controller = self.component?.getController() { + controller.completion(.file(file.media)) + controller.forEachController { c in + if let c = c as? StickerPackScreenImpl { + c.dismiss(animated: true) + } + return true + } + controller.window?.forEachController({ c in + if let c = c as? StickerPackScreenImpl { + c.dismiss(animated: true) + } + }) + controller.dismiss(animated: true) + } return false }, sendEmoji: { _, _, _ in @@ -148,20 +159,23 @@ private final class StickerSelectionComponent: Component { insertText: { _ in }, backwardsDeleteText: {}, - presentController: { c, a in - let _ = c - let _ = a + presentController: { [weak self] c, a in + if let self, let controller = self.component?.getController() { + controller.present(c, in: .window(.root), with: a) + } }, - presentGlobalOverlayController: { c, a in - let _ = c - let _ = a + presentGlobalOverlayController: { [weak self] c, a in + if let self, let controller = self.component?.getController() { + controller.presentInGlobalOverlay(c, with: a) + } }, getNavigationController: { return nil }, requestLayout: { transition in let _ = transition - }) + } + ) self.inputNodeInteraction = ChatMediaInputNodeInteraction( navigateToCollectionId: { _ in @@ -237,14 +251,17 @@ private final class StickerSelectionComponent: Component { externalBottomPanelContainer: nil, displayTopPanelBackground: .blur, topPanelExtensionUpdated: { _, _ in }, - hideInputUpdated: { [weak self] _, _, transition in + hideInputUpdated: { [weak self] _, searchVisible, transition in guard let self else { return } self.forceUpdate = true + self.searchVisible = searchVisible self.state?.updated(transition: transition) }, - hideTopPanelUpdated: { _, _ in }, + hideTopPanelUpdated: { _, _ in + print() + }, switchToTextInput: {}, switchToGifSubject: { _ in }, reorderItems: { _, _ in }, @@ -269,17 +286,12 @@ private final class StickerSelectionComponent: Component { interaction: interaction, inputNodeInteraction: inputNodeInteraction, mode: mappedMode, + stickerActionTitle: presentationData.strings.StickerPack_Select, trendingGifsPromise: trendingGifsPromise, cancel: { }, peekBehavior: stickerPeekBehavior ) -// searchContainerNode.openGifContextMenu = { [weak self] item, sourceNode, sourceRect, gesture, isSaved in -// guard let self else { -// return -// } -// self.openGifContextMenu(file: item.file, contextResult: item.contextResult, sourceView: sourceNode.view, sourceRect: sourceRect, gesture: gesture, isSaved: isSaved) -// } return searchContainerNode }, @@ -315,8 +327,10 @@ private final class StickerSelectionComponent: Component { transition.setFrame(view: self.panelBackgroundView, frame: CGRect(origin: CGPoint(), size: CGSize(width: keyboardSize.width, height: topPanelHeight))) self.panelBackgroundView.update(size: self.panelBackgroundView.bounds.size, transition: transition.containedViewLayoutTransition) + transition.setAlpha(view: self.panelBackgroundView, alpha: self.searchVisible ? 0.0 : 1.0) + transition.setAlpha(view: self.panelSeparatorView, alpha: self.searchVisible ? 0.0 : 1.0) + transition.setFrame(view: self.panelSeparatorView, frame: CGRect(origin: CGPoint(x: 0.0, y: topPanelHeight), size: CGSize(width: keyboardSize.width, height: UIScreenPixel))) - transition.setAlpha(view: self.panelSeparatorView, alpha: 1.0) } return availableSize @@ -1316,7 +1330,14 @@ public class StickerPickerScreen: ViewController { bottomInset: bottomInset, content: content, backgroundColor: self.theme.list.itemBlocksBackgroundColor, - separatorColor: self.theme.list.blocksBackgroundColor + separatorColor: self.theme.list.blocksBackgroundColor, + getController: { [weak self] in + if let self { + return self.controller + } else { + return nil + } + } ) ), environment: {}, diff --git a/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift b/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift index 6e253b32c8..047eb744f5 100644 --- a/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift +++ b/submodules/FeaturedStickersScreen/Sources/ChatMediaInputTrendingPane.swift @@ -208,6 +208,7 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane { } private let context: AccountContext + private let forceTheme: PresentationTheme? private let interaction: ChatMediaInputTrendingPane.Interaction private let getItemIsPreviewed: (StickerPackItem) -> Bool private let isPane: Bool @@ -228,10 +229,13 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane { public var scrollingInitiated: (() -> Void)? + public var stickerActionTitle: String? + private let installDisposable = MetaDisposable() - public init(context: AccountContext, interaction: ChatMediaInputTrendingPane.Interaction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool, isPane: Bool) { + public init(context: AccountContext, forceTheme: PresentationTheme?, interaction: ChatMediaInputTrendingPane.Interaction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool, isPane: Bool) { self.context = context + self.forceTheme = forceTheme self.interaction = interaction self.getItemIsPreviewed = getItemIsPreviewed self.isPane = isPane @@ -290,7 +294,10 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane { var cancelImpl: (() -> Void)? let progressSignal = Signal { subscriber in - let presentationData = context.sharedContext.currentPresentationData.with { $0 } + var presentationData = context.sharedContext.currentPresentationData.with { $0 } + if let forceTheme = self?.forceTheme { + presentationData = presentationData.withUpdated(theme: forceTheme) + } let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: { cancelImpl?() })) @@ -330,7 +337,10 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane { } } - let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } + var presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } + if let forceTheme = strongSelf.forceTheme { + presentationData = presentationData.withUpdated(theme: forceTheme) + } strongSelf.interaction.getNavigationController()?.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: presentationData.strings.StickerPackActionInfo_AddedTitle, text: presentationData.strings.StickerPackActionInfo_AddedText(info.title).string, undo: false, info: info, topItem: items.first, context: strongSelf.context), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return true })) @@ -340,7 +350,12 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane { if let strongSelf = self, let info = info as? StickerPackCollectionInfo { strongSelf.view.window?.endEditing(true) let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash) - let controller = StickerPackScreen(context: strongSelf.context, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: strongSelf.interaction.getNavigationController(), sendSticker: { fileReference, sourceNode, sourceRect in + var updatedPresentationData: (PresentationData, Signal)? + if let forceTheme = strongSelf.forceTheme { + let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: forceTheme) + updatedPresentationData = (presentationData, .single(presentationData)) + } + let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], actionTitle: strongSelf.stickerActionTitle, parentNavigationController: strongSelf.interaction.getNavigationController(), sendSticker: { fileReference, sourceNode, sourceRect in if let strongSelf = self { return strongSelf.interaction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, []) } else { @@ -358,8 +373,13 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane { let isPane = self.isPane let previousEntries = Atomic<[TrendingPaneEntry]?>(value: nil) let context = self.context + let forceTheme = self.forceTheme self.disposable = (combineLatest(context.account.viewTracker.featuredStickerPacks(), context.account.postbox.combinedView(keys: [.itemCollectionInfos(namespaces: [Namespaces.ItemCollection.CloudStickerPacks])]), context.sharedContext.presentationData) |> map { trendingEntries, view, presentationData -> TrendingPaneTransition in + var presentationData = presentationData + if let forceTheme { + presentationData = presentationData.withUpdated(theme: forceTheme) + } var installedPacks = Set() if let stickerPacksView = view.views[.itemCollectionInfos(namespaces: [Namespaces.ItemCollection.CloudStickerPacks])] as? ItemCollectionInfosView { if let packsEntries = stickerPacksView.entriesByNamespace[Namespaces.ItemCollection.CloudStickerPacks] { diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift index a3f35c5eae..e5357adea0 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift @@ -464,7 +464,13 @@ private final class StickerPackContainer: ASDisplayNode { var menuItems: [ContextMenuItem] = [] if let (info, _, _) = strongSelf.currentStickerPack, info.id.namespace == Namespaces.ItemCollection.CloudStickerPacks { if strongSelf.sendSticker != nil { - menuItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.StickerPack_Send, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { _, f in + let actionTitle: String + if let title = strongSelf.controller?.actionTitle { + actionTitle = title + } else { + actionTitle = strongSelf.presentationData.strings.StickerPack_Send + } + menuItems.append(.action(ContextMenuActionItem(text: actionTitle, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { _, f in if let strongSelf = self, let peekController = strongSelf.peekController { if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode { let _ = strongSelf.sendSticker?(.standalone(media: item.file), animationNode.view, animationNode.bounds) @@ -1901,12 +1907,15 @@ public final class StickerPackScreenImpl: ViewController { let animationCache: AnimationCache let animationRenderer: MultiAnimationRenderer + let actionTitle: String? + public init( context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack], selectedStickerPackIndex: Int = 0, + actionTitle: String? = nil, parentNavigationController: NavigationController? = nil, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)? = nil, sendEmoji: ((String, ChatTextInputTextCustomEmojiAttribute) -> Void)?, @@ -1918,6 +1927,7 @@ public final class StickerPackScreenImpl: ViewController { self.stickerPacks = stickerPacks self.loadedStickerPacks = loadedStickerPacks self.initialSelectedStickerPackIndex = selectedStickerPackIndex + self.actionTitle = actionTitle self.parentNavigationController = parentNavigationController self.sendSticker = sendSticker self.sendEmoji = sendEmoji @@ -2142,6 +2152,7 @@ public func StickerPackScreen( mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack] = [], + actionTitle: String? = nil, parentNavigationController: NavigationController? = nil, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)? = nil, sendEmoji: ((String, ChatTextInputTextCustomEmojiAttribute) -> Void)? = nil, @@ -2151,9 +2162,11 @@ public func StickerPackScreen( ) -> ViewController { let controller = StickerPackScreenImpl( context: context, + updatedPresentationData: updatedPresentationData, stickerPacks: stickerPacks, loadedStickerPacks: loadedStickerPacks, selectedStickerPackIndex: stickerPacks.firstIndex(of: mainStickerPack) ?? 0, + actionTitle: actionTitle, parentNavigationController: parentNavigationController, sendSticker: sendSticker, sendEmoji: sendEmoji, diff --git a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/PaneSearchContainerNode.swift b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/PaneSearchContainerNode.swift index 7ee75218f0..0c749591e7 100644 --- a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/PaneSearchContainerNode.swift +++ b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/PaneSearchContainerNode.swift @@ -55,7 +55,7 @@ public final class PaneSearchContainerNode: ASDisplayNode, EntitySearchContainer return self.contentNode.ready } - public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, interaction: ChatEntityKeyboardInputNode.Interaction, inputNodeInteraction: ChatMediaInputNodeInteraction, mode: ChatMediaInputSearchMode, trendingGifsPromise: Promise, cancel: @escaping () -> Void, peekBehavior: EmojiContentPeekBehavior?) { + public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, interaction: ChatEntityKeyboardInputNode.Interaction, inputNodeInteraction: ChatMediaInputNodeInteraction, mode: ChatMediaInputSearchMode, stickerActionTitle: String? = nil, trendingGifsPromise: Promise, cancel: @escaping () -> Void, peekBehavior: EmojiContentPeekBehavior?) { self.context = context self.mode = mode self.interaction = interaction @@ -65,7 +65,7 @@ public final class PaneSearchContainerNode: ASDisplayNode, EntitySearchContainer case .gif: self.contentNode = GifPaneSearchContentNode(context: context, theme: theme, strings: strings, interaction: interaction, inputNodeInteraction: inputNodeInteraction, trendingPromise: trendingGifsPromise) case .sticker, .trending: - self.contentNode = StickerPaneSearchContentNode(context: context, theme: theme, strings: strings, interaction: interaction, inputNodeInteraction: inputNodeInteraction) + self.contentNode = StickerPaneSearchContentNode(context: context, theme: theme, strings: strings, interaction: interaction, inputNodeInteraction: inputNodeInteraction, stickerActionTitle: stickerActionTitle) } self.backgroundNode = ASDisplayNode() diff --git a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift index 035fabdbc2..532d562ba5 100644 --- a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift +++ b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/StickerPaneSearchContentNode.swift @@ -167,7 +167,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode { private let installDisposable = MetaDisposable() - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, interaction: ChatEntityKeyboardInputNode.Interaction, inputNodeInteraction: ChatMediaInputNodeInteraction) { + init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, interaction: ChatEntityKeyboardInputNode.Interaction, inputNodeInteraction: ChatMediaInputNodeInteraction, stickerActionTitle: String?) { self.context = context self.interaction = interaction self.inputNodeInteraction = inputNodeInteraction @@ -181,9 +181,10 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode { getNavigationController: interaction.getNavigationController ) - self.trendingPane = ChatMediaInputTrendingPane(context: context, interaction: trendingPaneInteraction, getItemIsPreviewed: { [weak inputNodeInteraction] item in + self.trendingPane = ChatMediaInputTrendingPane(context: context, forceTheme: theme, interaction: trendingPaneInteraction, getItemIsPreviewed: { [weak inputNodeInteraction] item in return inputNodeInteraction?.previewedStickerPackItemFile?.id == item.file.id }, isPane: false) + self.trendingPane.stickerActionTitle = stickerActionTitle self.gridNode = GridNode() diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntitySearchContentComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntitySearchContentComponent.swift index 87d4072f6c..d009b49f0a 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntitySearchContentComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EntitySearchContentComponent.swift @@ -97,8 +97,7 @@ final class EntitySearchContentComponent: Component { } if let containerNode = containerNode { - - let environmentValue = environment[EntitySearchContentEnvironment.self].value + let environmentValue = environment[EntitySearchContentEnvironment.self].value transition.setFrame(view: containerNode.view, frame: CGRect(origin: CGPoint(), size: availableSize)) containerNode.updateLayout( size: availableSize, @@ -109,7 +108,6 @@ final class EntitySearchContentComponent: Component { deviceMetrics: environmentValue.deviceMetrics, transition: transition.containedViewLayoutTransition ) - containerNode.onCancel = { component.dismissSearch() } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index de4029bc51..797752ef4b 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -2440,6 +2440,8 @@ public final class StoryItemSetContainerComponent: Component { if let mediaResult { switch mediaResult { case let .image(image, dimensions): + updateProgressImpl?(0.0) + if let imageData = compressImageToJPEG(image, quality: 0.7) { let _ = (context.engine.messages.editStory(media: .image(dimensions: dimensions, data: imageData), id: id, text: updatedText, entities: updatedEntities, privacy: updatedPrivacy) |> deliverOnMainQueue).start(next: { [weak self] result in @@ -2462,6 +2464,8 @@ public final class StoryItemSetContainerComponent: Component { }) } case let .video(content, firstFrameImage, values, duration, dimensions): + updateProgressImpl?(0.0) + if let valuesData = try? JSONEncoder().encode(values) { let data = MemoryBuffer(data: valuesData) let digest = MemoryBuffer(data: data.md5Digest())