diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index d20afd7103..bc417e9070 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -340,6 +340,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private let recordingActivityPromise = ValuePromise(.none, ignoreRepeated: true) private var recordingActivityDisposable: Disposable? private var acquiredRecordingActivityDisposable: Disposable? + private let choosingStickerActivityPromise = Promise(false) + private var choosingStickerActivityDisposable: Disposable? private var searchDisposable: MetaDisposable? @@ -3821,6 +3823,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) + self.choosingStickerActivityDisposable = (self.choosingStickerActivityPromise.get() + |> deliverOnMainQueue).start(next: { [weak self] value in + if let strongSelf = self { + strongSelf.context.account.updateLocalInputActivity(peerId: activitySpace, activity: .choosingSticker, isPresent: value) + } + }) + self.recordingActivityDisposable = (self.recordingActivityPromise.get() |> deliverOnMainQueue).start(next: { [weak self] value in if let strongSelf = self { @@ -4400,6 +4409,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.chatDisplayNode.historyNode.voicePlaylistItemChanged(nil, currentItem) } + self.choosingStickerActivityPromise.set(self.chatDisplayNode.choosingSticker) + self.chatDisplayNode.historyNode.didScrollWithOffset = { [weak self] offset, transition, itemNode in guard let strongSelf = self else { return diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index ee97ed130c..7362cdc100 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -121,6 +121,11 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { private(set) var textInputPanelNode: ChatTextInputPanelNode? private var inputMediaNode: ChatMediaInputNode? + private let choosingStickerPromise = Promise(false) + var choosingSticker: Signal { + return self.choosingStickerPromise.get() + } + let navigateButtons: ChatHistoryNavigationButtons private var ignoreUpdateHeight = false @@ -832,6 +837,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } if let inputMediaNode = inputNode as? ChatMediaInputNode, self.inputMediaNode == nil { self.inputMediaNode = inputMediaNode + self.choosingStickerPromise.set(inputMediaNode.choosingSticker) inputMediaNode.requestDisableStickerAnimations = { [weak self] disabled in self?.controller?.disableStickerAnimations = disabled } @@ -1923,6 +1929,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self?.controller?.disableStickerAnimations = disabled } self.inputMediaNode = inputNode + self.choosingStickerPromise.set(inputNode.choosingSticker) if let (validLayout, _) = self.validLayout { let _ = inputNode.updateLayout(width: validLayout.size.width, leftInset: validLayout.safeInsets.left, rightInset: validLayout.safeInsets.right, bottomInset: validLayout.intrinsicInsets.bottom, standardInputHeight: validLayout.standardInputHeight, inputHeight: validLayout.inputHeight ?? 0.0, maximumHeight: validLayout.standardInputHeight, inputPanelHeight: 44.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, deviceMetrics: validLayout.deviceMetrics, isVisible: false) } diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index fea4e9e675..7d4ad1744b 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -492,6 +492,21 @@ final class ChatMediaInputNode: ChatInputNode { private var currentView: ItemCollectionsView? private let dismissedPeerSpecificStickerPack = Promise() + private var scrollingStickerPacksListPromise = ValuePromise(false) + private var scrollingStickersGridPromise = ValuePromise(false) + private var previewingStickersPromise = ValuePromise(false) + var choosingSticker: Signal { + return combineLatest(self.scrollingStickerPacksListPromise.get(), self.scrollingStickersGridPromise.get(), self.previewingStickersPromise.get()) + |> mapToSignal { scrollingStickerPacksList, scrollingStickersGrid, previewingStickers -> Signal in + if scrollingStickerPacksList || scrollingStickersGrid || previewingStickers { + return .single(true) + } else { + return .single(false) |> delay(2.0, queue: Queue.mainQueue()) + } + } + |> distinctUntilChanged + } + private var panelFocusScrollToIndex: Int? private var panelFocusInitialPosition: CGPoint? private let panelIsFocusedPromise = ValuePromise(false) @@ -584,6 +599,13 @@ final class ChatMediaInputNode: ChatInputNode { super.init() + self.stickerPane.beganScrolling = { [weak self] in + self?.scrollingStickersGridPromise.set(true) + } + self.stickerPane.endedScrolling = { [weak self] in + self?.scrollingStickersGridPromise.set(false) + } + let temporaryPackOrder = Promise<[ItemCollectionId]?>(nil) self.listView.willBeginReorder = { [weak self] point in @@ -902,7 +924,7 @@ final class ChatMediaInputNode: ChatInputNode { self.panesBackgroundNode.backgroundColor = theme.chat.inputMediaPanel.stickersBackgroundColor.withAlphaComponent(1.0) self.addSubnode(self.paneClippingContainer) - self.paneClippingContainer.addSubnode(panesBackgroundNode) + self.paneClippingContainer.addSubnode(self.panesBackgroundNode) self.collectionListPanel.addSubnode(self.listView) self.collectionListPanel.addSubnode(self.gifListView) self.gifListView.isHidden = true @@ -1217,6 +1239,8 @@ final class ChatMediaInputNode: ChatInputNode { self.listView.beganInteractiveDragging = { [weak self] position in if let strongSelf = self { strongSelf.stopCollapseTimer() + + strongSelf.scrollingStickerPacksListPromise.set(true) var position = position var index = strongSelf.listView.itemIndexAtPoint(CGPoint(x: 0.0, y: position.y)) @@ -1251,6 +1275,8 @@ final class ChatMediaInputNode: ChatInputNode { strongSelf.panelFocusInitialPosition = nil } strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 1.5) + + strongSelf.scrollingStickerPacksListPromise.set(false) } } @@ -1682,6 +1708,7 @@ final class ChatMediaInputNode: ChatInputNode { return sourceNode }) controller.visibilityUpdated = { [weak self] visible in + self?.previewingStickersPromise.set(visible) self?.requestDisableStickerAnimations?(visible) self?.simulateUpdateLayout(isVisible: !visible) } diff --git a/submodules/TelegramUI/Sources/ChatMediaInputStickerPane.swift b/submodules/TelegramUI/Sources/ChatMediaInputStickerPane.swift index fcc255d156..202583e97d 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputStickerPane.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputStickerPane.swift @@ -69,6 +69,9 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane { private var didScrollPreviousOffset: CGFloat? private var didScrollPreviousState: ChatMediaInputPaneScrollState? + var beganScrolling: (() -> Void)? + var endedScrolling: (() -> Void)? + init(theme: PresentationTheme, strings: PresentationStrings, paneDidScroll: @escaping (ChatMediaInputPane, ChatMediaInputPaneScrollState, ContainedViewLayoutTransition) -> Void, fixPaneScroll: @escaping (ChatMediaInputPane, ChatMediaInputPaneScrollState) -> Void) { self.gridNode = GridNode() self.paneDidScroll = paneDidScroll @@ -98,12 +101,16 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane { } } } + self.gridNode.scrollingInitiated = { [weak self] in + self?.beganScrolling?() + } self.gridNode.scrollingCompleted = { [weak self] in if let strongSelf = self { if let didScrollPreviousState = strongSelf.didScrollPreviousState { strongSelf.fixPaneScroll(strongSelf, didScrollPreviousState) } fixGridScrolling(strongSelf.gridNode) + strongSelf.endedScrolling?() } } self.gridNode.setupNode = { [weak self] itemNode in