diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index e8446f3402..049a52efc1 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -10272,7 +10272,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } strongSelf.presentAttachmentPremiumGift() - let _ = ApplicationSpecificNotice.incrementDismissedPremiumGiftSuggestion(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId).start() + Queue.mainQueue().after(0.5) { + let _ = ApplicationSpecificNotice.incrementDismissedPremiumGiftSuggestion(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId).start() + } }, requestLayout: { [weak self] transition in if let strongSelf = self, let layout = strongSelf.validLayout { strongSelf.containerLayoutUpdated(layout, transition: transition) diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 953eaae337..0afc2f043e 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -15,6 +15,7 @@ func chatHistoryEntriesForView( includeSearchEntry: Bool, reverse: Bool, groupMessages: Bool, + reverseGroupedMessages: Bool, selectedMessages: Set?, presentationData: ChatPresentationData, historyAppearsCleared: Bool, @@ -154,9 +155,18 @@ func chatHistoryEntriesForView( } } - if groupMessages { + if groupMessages || reverseGroupedMessages { if !groupBucket.isEmpty && message.groupInfo != groupBucket[0].0.groupInfo { - entries.append(.MessageGroupEntry(groupBucket[0].0.groupInfo!, groupBucket, presentationData)) + if reverseGroupedMessages { + groupBucket.reverse() + } + if groupMessages { + entries.append(.MessageGroupEntry(groupBucket[0].0.groupInfo!, groupBucket, presentationData)) + } else { + for (message, isRead, selection, attributes, location) in groupBucket { + entries.append(.MessageEntry(message, presentationData, isRead, location, selection, attributes)) + } + } groupBucket.removeAll() } if let _ = message.groupInfo { @@ -188,8 +198,17 @@ func chatHistoryEntriesForView( } if !groupBucket.isEmpty { - assert(groupMessages) - entries.append(.MessageGroupEntry(groupBucket[0].0.groupInfo!, groupBucket, presentationData)) + assert(groupMessages || reverseGroupedMessages) + if reverseGroupedMessages { + groupBucket.reverse() + } + if groupMessages { + entries.append(.MessageGroupEntry(groupBucket[0].0.groupInfo!, groupBucket, presentationData)) + } else { + for (message, isRead, selection, attributes, location) in groupBucket { + entries.append(.MessageEntry(message, presentationData, isRead, location, selection, attributes)) + } + } } if let maybeJoinMessage = joinMessage, !view.holeLater { diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 43db38fa4d..31ec565a7b 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -47,7 +47,7 @@ public enum ChatHistoryListDisplayHeaders { public enum ChatHistoryListMode: Equatable { case bubbles - case list(search: Bool, reversed: Bool, displayHeaders: ChatHistoryListDisplayHeaders, hintLinks: Bool, isGlobalSearch: Bool) + case list(search: Bool, reversed: Bool, reverseGroups: Bool, displayHeaders: ChatHistoryListDisplayHeaders, hintLinks: Bool, isGlobalSearch: Bool) } enum ChatHistoryViewScrollPosition { @@ -224,7 +224,7 @@ private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLoca switch mode { case .bubbles: item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location)) - case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch): + case let .list(_, _, _, displayHeaders, hintLinks, isGlobalSearch): let displayHeader: Bool switch displayHeaders { case .none: @@ -269,7 +269,7 @@ private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLoca switch mode { case .bubbles: item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location)) - case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch): + case let .list(_, _, _, displayHeaders, hintLinks, isGlobalSearch): let displayHeader: Bool switch displayHeaders { case .none: @@ -1216,10 +1216,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var updatedScrollPosition = scrollPosition var reverse = false + var reverseGroups = false var includeSearchEntry = false - if case let .list(search, reverseValue, _, _, _) = mode { + if case let .list(search, reverseValue, reverseGroupsValue, _, _, _) = mode { includeSearchEntry = search reverse = reverseValue + reverseGroups = reverseGroupsValue } var isCopyProtectionEnabled: Bool = data.initialData?.peer?.isCopyProtectionEnabled ?? false @@ -1265,6 +1267,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { includeSearchEntry: includeSearchEntry && tagMask != nil, reverse: reverse, groupMessages: mode == .bubbles, + reverseGroupedMessages: reverseGroups, selectedMessages: selectedMessages, presentationData: chatPresentationData, historyAppearsCleared: historyAppearsCleared, @@ -3465,7 +3468,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { switch self.mode { case .bubbles: item = ChatMessageItem(presentationData: presentationData, context: self.context, chatLocation: self.chatLocation, associatedData: associatedData, controllerInteraction: self.controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location)) - case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch): + case let .list(_, _, _, displayHeaders, hintLinks, isGlobalSearch): let displayHeader: Bool switch displayHeaders { case .none: @@ -3521,7 +3524,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { switch self.mode { case .bubbles: item = ChatMessageItem(presentationData: presentationData, context: self.context, chatLocation: self.chatLocation, associatedData: associatedData, controllerInteraction: self.controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location)) - case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch): + case let .list(_, _, _, displayHeaders, hintLinks, isGlobalSearch): let displayHeader: Bool switch displayHeaders { case .none: diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index cd49d9a72c..fe1088f646 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -208,7 +208,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu self.isGlobalSearch = false } - self.historyNode = ChatHistoryListNode(context: context, updatedPresentationData: (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, source: source, subject: .message(id: .id(initialMessageId), highlight: true, timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) + self.historyNode = ChatHistoryListNode(context: context, updatedPresentationData: (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, source: source, subject: .message(id: .id(initialMessageId), highlight: true, timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: true, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) self.historyNode.clipsToBounds = true super.init() @@ -550,7 +550,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu } let chatLocationContextHolder = Atomic(value: nil) - let historyNode = ChatHistoryListNode(context: self.context, updatedPresentationData: (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData), chatLocation: self.chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: .message(id: .id(messageId), highlight: true, timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) + let historyNode = ChatHistoryListNode(context: self.context, updatedPresentationData: (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData), chatLocation: self.chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: .message(id: .id(messageId), highlight: true, timecode: nil), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: true, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch)) historyNode.clipsToBounds = true historyNode.preloadPages = true historyNode.stackFromBottom = true diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift index f785e9da7d..a6575ab42b 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoListPaneNode.swift @@ -76,7 +76,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode { self.selectedMessages = chatControllerInteraction.selectionState.flatMap { $0.selectedIds } self.selectedMessagesPromise.set(.single(self.selectedMessages)) - self.listNode = ChatHistoryListNode(context: context, updatedPresentationData: updatedPresentationData ?? (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: nil, controllerInteraction: chatControllerInteraction, selectedMessages: self.selectedMessagesPromise.get(), mode: .list(search: false, reversed: false, displayHeaders: .allButLast, hintLinks: tagMask == .webPage, isGlobalSearch: false)) + self.listNode = ChatHistoryListNode(context: context, updatedPresentationData: updatedPresentationData ?? (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: tagMask, subject: nil, controllerInteraction: chatControllerInteraction, selectedMessages: self.selectedMessagesPromise.get(), mode: .list(search: false, reversed: false, reverseGroups: false, displayHeaders: .allButLast, hintLinks: tagMask == .webPage, isGlobalSearch: false)) self.listNode.clipsToBounds = true self.listNode.defaultToSynchronousTransactionWhileScrolling = true self.listNode.scroller.bounces = false diff --git a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift index a61a51613c..55d9f0ee29 100644 --- a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift +++ b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift @@ -264,10 +264,23 @@ private func navigatedMessageFromView(_ view: MessageHistoryView, anchorIndex: M let message = view.entries[index + 1].message return (message, aroundMessagesFromView(view: view, centralIndex: view.entries[index + 1].index), true) } else { + var nextGroupingKey: Int64? for i in (0 ..< index).reversed() { - if view.entries[i].message.groupingKey != currentGroupKey { - let message = view.entries[i].message - return (message, aroundMessagesFromView(view: view, centralIndex: view.entries[i].index), true) + if let nextGroupingKey { + if view.entries[i].message.groupingKey != nextGroupingKey { + let message = view.entries[i + 1].message + return (message, aroundMessagesFromView(view: view, centralIndex: view.entries[i + 1].index), true) + } else if i == 0 { + let message = view.entries[i].message + return (message, aroundMessagesFromView(view: view, centralIndex: view.entries[i].index), true) + } + } else if view.entries[i].message.groupingKey != currentGroupKey { + if let groupingKey = view.entries[i].message.groupingKey { + nextGroupingKey = groupingKey + } else { + let message = view.entries[i].message + return (message, aroundMessagesFromView(view: view, centralIndex: view.entries[i].index), true) + } } } }