From 554cd0e6fe380441c03750a8ba86648dcd48d6d7 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sat, 29 Oct 2022 00:26:57 +0400 Subject: [PATCH 1/9] Topic improvements + interval ads --- .../Telegram-iOS/en.lproj/Localizable.strings | 14 +- .../ChatListUI/Sources/ChatContextMenus.swift | 12 ++ .../Sources/ChatListController.swift | 156 +++++++++++---- .../Sources/ChatListControllerNode.swift | 3 +- .../Sources/ChatListSearchListPaneNode.swift | 15 +- .../Sources/Node/ChatListItemStrings.swift | 4 +- .../Sources/Node/ChatListNode.swift | 93 +++++++-- .../Sources/Node/ChatListNodeEntries.swift | 31 ++- ...ChatSendMessageActionSheetController.swift | 2 +- .../Sources/InstantPageControllerNode.swift | 2 +- .../Sources/MediaPickerSelectedListNode.swift | 4 +- submodules/Postbox/Sources/ChatListView.swift | 2 +- .../Postbox/Sources/ChatListViewState.swift | 2 +- .../Sources/GlobalMessageTagsView.swift | 2 +- submodules/Postbox/Sources/Message.swift | 52 ++++- .../Postbox/Sources/MessageHistoryTable.swift | 18 +- .../Postbox/Sources/MessageHistoryView.swift | 4 +- .../Sources/MessageHistoryViewState.swift | 6 +- submodules/Postbox/Sources/Postbox.swift | 4 +- .../Postbox/Sources/SeedConfiguration.swift | 5 +- .../BubbleSettingsController.swift | 10 +- .../ForwardPrivacyChatPreviewItem.swift | 2 +- .../Reactions/ReactionChatPreviewItem.swift | 2 +- .../TextSizeSelectionController.swift | 13 +- .../ThemeAccentColorControllerNode.swift | 19 +- .../Themes/ThemePreviewControllerNode.swift | 19 +- .../Themes/ThemeSettingsChatPreviewItem.swift | 4 +- .../Sources/Themes/WallpaperGalleryItem.swift | 4 +- ...yncCore_StandaloneAccountTransaction.swift | 6 + .../TelegramEngine/Messages/AdMessages.swift | 3 +- .../ApplyMaxReadIndexInteractively.swift | 29 +++ .../TelegramEngine/Messages/Message.swift | 16 +- .../Messages/SparseMessageList.swift | 13 +- .../Messages/TelegramEngineMessages.swift | 11 +- .../Sources/Utils/MessageUtils.swift | 2 +- .../Sources/MessageContentKind.swift | 2 +- .../Sources/ServiceMessageStrings.swift | 86 ++++++-- .../Sources/EmojiStatusComponent.swift | 63 +----- .../Sources/EmojiTextAttachmentView.swift | 86 +++++++- .../TelegramUI/Sources/ChatController.swift | 58 +++++- .../Sources/ChatEntityKeyboardInputNode.swift | 2 +- .../Sources/ChatHistoryEntriesForView.swift | 19 +- .../Sources/ChatHistoryListNode.swift | 188 ++++++++++++++++-- .../Sources/ChatMediaInputNode.swift | 2 +- .../Sources/ChatMessageActionItemNode.swift | 11 +- .../ChatMessageAnimatedStickerItemNode.swift | 2 + .../Sources/ChatMessageBubbleItemNode.swift | 1 + .../Sources/ChatMessageGiftItemNode.swift | 2 +- .../Sources/ChatMessageStickerItemNode.swift | 2 + .../ChatRecentActionsHistoryTransition.swift | 106 +++++----- .../Sources/NavigateToChatController.swift | 12 +- .../Panes/PeerInfoVisualMediaPaneNode.swift | 8 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 4 +- .../Sources/ChatTextInputAttributes.swift | 4 +- 54 files changed, 884 insertions(+), 358 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 8b99cb3b93..bf1da82240 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8189,14 +8189,16 @@ Sorry for the inconvenience."; "Notification.TopicCreated" = "Topic created"; "Notification.TopicClosed" = "Topic closed"; "Notification.TopicReopened" = "Topic reopened"; -"Notification.TopicClosedAuthor" = "%1$@ closed the topic"; -"Notification.TopicReopenedAuthor" = "%1$@ reopened the topic"; +"Notification.TopicClosedAuthor" = "%1$@ closed topic"; +"Notification.TopicReopenedAuthor" = "%1$@ reopened topic"; "Notification.TopicRenamed" = "Topic renamed to \"%1$@\""; -"Notification.TopicRenamedAuthor" = "%1$@ changed the topic name to \"%2$@\""; +"Notification.TopicRenamedAuthor" = "%1$@ changed the topic title to \"%2$@\""; "Notification.TopicIconChanged" = "Topic icon changed to %1$@"; -"Notification.TopicIconRemoved" = "Topic icon changed"; "Notification.TopicIconChangedAuthor" = "%1$@ changed the topic icon to %2$@"; -"Notification.TopicIconRemovedAuthor" = "%1$@ changed the topic icon"; +"Notification.TopicRenamedIconChangedAuthor" = "%1$@ changed the topic title and icon to %2$@ %3$@"; +"Notification.OverviewTopicCreated" = "%1$@ %2$@ was created"; +"Notification.OverviewTopicClosed" = "%1$@ closed %2$@ %3$@"; +"Notification.OverviewTopicReopened" = "%1$@ reopened %2$@ %3$@"; "Chat.EmptyTopicPlaceholder.Title" = "Almost done!"; "Chat.EmptyTopicPlaceholder.Text" = "Send the first message to\nstart this topic."; @@ -8237,3 +8239,5 @@ Sorry for the inconvenience."; "Attachment.Pasteboard" = "Clipboard"; "Attachment.DiscardPasteboardAlertText" = "Discard pasted items?"; + +"Undo.DeletedTopic" = "Topic Deleted"; diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index 6626825e5a..f53523f584 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -523,6 +523,18 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: }))) } + var isUnread = false + if threadData.incomingUnreadCount != 0 { + isUnread = true + } + + if isUnread { + items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_MarkAsRead, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MarkAsRead"), color: theme.contextMenu.primaryColor) }, action: { _, f in + let _ = context.engine.messages.markForumThreadAsRead(peerId: peerId, threadId: threadId).start() + f(.default) + }))) + } + var isMuted = false if case .muted = threadData.notificationSettings.muteState { isMuted = true diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index dd7de0e20c..89aa2c0196 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -450,6 +450,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController (self.navigationController as? NavigationController)?.pushViewController(controller) }) } + self.chatTitleView?.longPressed = { [weak self] in + guard let self else { + return + } + self.activateSearch() + } let peerView = Promise() peerView.set(context.account.viewTracker.peerView(peerId)) @@ -516,7 +522,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController case .member: strongSelf.setToolbar(nil, transition: .animated(duration: 0.4, curve: .spring)) default: - strongSelf.setToolbar(Toolbar(leftAction: nil, rightAction: nil, middleAction: ToolbarAction(title: strongSelf.presentationData.strings.Channel_JoinChannel, isEnabled: true)), transition: .animated(duration: 0.4, curve: .spring)) + let actionTitle: String + if channel.flags.contains(.requestToJoin) { + actionTitle = strongSelf.presentationData.strings.Channel_JoinChannel + } else { + actionTitle = strongSelf.presentationData.strings.Group_ApplyToJoin + } + strongSelf.setToolbar(Toolbar(leftAction: nil, rightAction: nil, middleAction: ToolbarAction(title: actionTitle, isEnabled: true)), transition: .animated(duration: 0.4, curve: .spring)) } } }) @@ -1244,7 +1256,17 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController self.navigationItem.backBarButtonItem = backBarButtonItem } - self.searchContentNode?.updateThemeAndPlaceholder(theme: self.presentationData.theme, placeholder: self.presentationData.strings.DialogList_SearchLabel, compactPlaceholder: self.presentationData.strings.DialogList_SearchLabelCompact) + let placeholder: String + let compactPlaceholder: String + if case .forum = location { + placeholder = self.presentationData.strings.Common_Search + compactPlaceholder = self.presentationData.strings.Common_Search + } else { + placeholder = self.presentationData.strings.DialogList_SearchLabel + compactPlaceholder = self.presentationData.strings.DialogList_SearchLabelCompact + } + self.searchContentNode?.updateThemeAndPlaceholder(theme: self.presentationData.theme, placeholder: placeholder, compactPlaceholder: compactPlaceholder) + let editing = self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing let editItem: UIBarButtonItem if editing { @@ -1444,12 +1466,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController if group { strongSelf.archiveChats(peerIds: [peerId]) } else { - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerId) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) let _ = strongSelf.context.engine.peers.updatePeersGroupIdInteractively(peerIds: [peerId], groupId: group ? .archive : .root).start(completed: { guard let strongSelf = self else { return } - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) }) } } @@ -2923,12 +2945,25 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController public private(set) var isSearchActive: Bool = false public func activateSearch(filter: ChatListSearchFilter = .chats, query: String? = nil) { + self.activateSearch(filter: filter, query: query, skipScrolling: false) + } + + private func activateSearch(filter: ChatListSearchFilter = .chats, query: String? = nil, skipScrolling: Bool = false) { if self.displayNavigationBar { + if !skipScrolling, let searchContentNode = self.searchContentNode, searchContentNode.expansionProgress != 1.0 { + self.scrollToTop?() + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2, execute: { [weak self] in + self?.activateSearch(filter: filter, query: query, skipScrolling: true) + }) + return + } + let _ = (combineLatest(self.chatListDisplayNode.containerNode.currentItemNode.contentsReady |> take(1), self.context.account.postbox.tailChatListView(groupId: .root, count: 16, summaryComponents: ChatListEntrySummaryComponents(components: [:])) |> take(1)) |> deliverOnMainQueue).start(next: { [weak self] _, chatListView in guard let strongSelf = self else { return } + if let scrollToTop = strongSelf.scrollToTop { scrollToTop() } @@ -3165,9 +3200,9 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController let signal: Signal var completion: (() -> Void)? if !peerIds.isEmpty { - self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerIds.first!) + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds.first!, threadId: nil)) completion = { [weak self] in - self?.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + self?.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) } signal = self.context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: Array(peerIds), setToValue: false) } else if case let .chatList(groupId) = self.location { @@ -3206,7 +3241,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController strongSelf.chatListDisplayNode.containerNode.updateState(onlyCurrent: false, { state in var state = state for peerId in peerIds { - state.pendingRemovalPeerIds.insert(peerId) + state.pendingRemovalItemIds.insert(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) } return state }) @@ -3251,15 +3286,15 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return true } else if value == .undo { - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerIds.first!) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds.first!, threadId: nil)) strongSelf.chatListDisplayNode.containerNode.updateState(onlyCurrent: false, { state in var state = state for peerId in peerIds { - state.pendingRemovalPeerIds.remove(peerId) + state.pendingRemovalItemIds.remove(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) } return state }) - self?.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerIds.first!) + self?.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds.first!, threadId: nil)) return true } return false @@ -3286,13 +3321,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController self.archiveChats(peerIds: Array(peerIds)) } else { if !peerIds.isEmpty { - self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerIds.first!) + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds.first!, threadId: nil)) let _ = (self.context.engine.peers.updatePeersGroupIdInteractively(peerIds: Array(peerIds), groupId: .root) |> deliverOnMainQueue).start(completed: { [weak self] in guard let strongSelf = self else { return } - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) strongSelf.donePressed() }) } @@ -3532,7 +3567,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } strongSelf.chatListDisplayNode.containerNode.updateState({ state in var state = state - state.pendingClearHistoryPeerIds.insert(peer.peerId) + state.pendingClearHistoryPeerIds.insert(ChatListNodeState.ItemId(peerId: peer.peerId, threadId: nil)) return state }) strongSelf.forEachController({ controller in @@ -3553,7 +3588,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } strongSelf.chatListDisplayNode.containerNode.updateState({ state in var state = state - state.pendingClearHistoryPeerIds.remove(peer.peerId) + state.pendingClearHistoryPeerIds.remove(ChatListNodeState.ItemId(peerId: peer.peerId, threadId: nil)) return state }) }) @@ -3561,7 +3596,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } else if value == .undo { strongSelf.chatListDisplayNode.containerNode.updateState({ state in var state = state - state.pendingClearHistoryPeerIds.remove(peer.peerId) + state.pendingClearHistoryPeerIds.remove(ChatListNodeState.ItemId(peerId: peer.peerId, threadId: nil)) return state }) return true @@ -3741,7 +3776,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController items.append(ActionSheetTextItem(title: self.presentationData.strings.ChatList_DeleteTopicConfirmationText, parseMarkdown: true)) items.append(ActionSheetButtonItem(title: self.presentationData.strings.ChatList_DeleteTopicConfirmationAction, color: .destructive, action: { [weak self, weak actionSheet] in actionSheet?.dismissAnimated() - self?.commitDeletePeerThread(peerId: peerId, threadId: threadId) + self?.commitDeletePeerThread(peerId: peerId, threadId: threadId, completion: {}) })) actionSheet.setItemGroups([ActionSheetItemGroup(items: items), @@ -3754,18 +3789,61 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController self.present(actionSheet, in: .window(.root)) } - private func commitDeletePeerThread(peerId: EnginePeer.Id, threadId: Int64) { - let _ = self.context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).start(completed: { [weak self] in - guard let strongSelf = self else { - return + private func commitDeletePeerThread(peerId: EnginePeer.Id, threadId: Int64, completion: @escaping () -> Void) { + self.forEachController({ controller in + if let controller = controller as? UndoOverlayController { + controller.dismissWithCommitActionAndReplacementAnimation() } - strongSelf.chatListDisplayNode.containerNode.updateState({ state in - var state = state - state.pendingRemovalPeerIds.remove(peerId) - return state - }) - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + return true }) + + self.chatListDisplayNode.containerNode.updateState({ state in + var state = state + state.pendingRemovalItemIds.insert(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) + return state + }) + + let statusText = self.presentationData.strings.Undo_DeletedTopic + + self.present(UndoOverlayController(presentationData: self.context.sharedContext.currentPresentationData.with { $0 }, content: .removedChat(text: statusText), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in + guard let self else { + return false + } + if value == .commit { + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) + + let _ = self.context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).start(completed: { [weak self] in + guard let self else { + return + } + self.chatListDisplayNode.containerNode.updateState({ state in + var state = state + state.pendingRemovalItemIds.remove(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) + return state + }) + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) + }) + + self.chatListDisplayNode.containerNode.updateState({ state in + var state = state + state.selectedThreadIds.remove(threadId) + return state + }) + + completion() + return true + } else if value == .undo { + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) + self.chatListDisplayNode.containerNode.updateState({ state in + var state = state + state.pendingRemovalItemIds.remove(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) + return state + }) + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) + return true + } + return false + }), in: .current) } private func setPeerThreadStopped(peerId: EnginePeer.Id, threadId: Int64, isStopped: Bool) { @@ -3870,7 +3948,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return } let engine = self.context.engine - self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerIds[0]) + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds[0], threadId: nil)) let _ = (ApplicationSpecificNotice.incrementArchiveChatTips(accountManager: self.context.sharedContext.accountManager, count: 1) |> deliverOnMainQueue).start(next: { [weak self] previousHintCount in let _ = (engine.peers.updatePeersGroupIdInteractively(peerIds: peerIds, groupId: .archive) @@ -3878,7 +3956,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController guard let strongSelf = self else { return } - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) for peerId in peerIds { deleteSendMessageIntents(peerId: peerId) @@ -3889,13 +3967,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return false } if value == .undo { - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerIds[0]) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerIds[0], threadId: nil)) let _ = (engine.peers.updatePeersGroupIdInteractively(peerIds: peerIds, groupId: .root) |> deliverOnMainQueue).start(completed: { guard let strongSelf = self else { return } - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) }) return true } else { @@ -3941,13 +4019,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } let peerId = peer.peerId - self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerId) + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) self.chatListDisplayNode.containerNode.updateState({ state in var state = state - state.pendingRemovalPeerIds.insert(peer.peerId) + state.pendingRemovalItemIds.insert(ChatListNodeState.ItemId(peerId: peer.peerId, threadId: nil)) return state }) - self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + self.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) let statusText: String if case let .channel(channel) = chatPeer { if deleteGloballyIfPossible { @@ -3991,7 +4069,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return false } if value == .commit { - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerId) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) if case let .channel(channel) = chatPeer { strongSelf.context.peerChannelMemberCategoriesContextsManager.externallyRemoved(peerId: channel.id, memberId: strongSelf.context.account.peerId) } @@ -4001,10 +4079,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } strongSelf.chatListDisplayNode.containerNode.updateState({ state in var state = state - state.pendingRemovalPeerIds.remove(peer.peerId) + state.pendingRemovalItemIds.remove(ChatListNodeState.ItemId(peerId: peer.peerId, threadId: nil)) return state }) - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) deleteSendMessageIntents(peerId: peerId) }) @@ -4018,13 +4096,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController completion() return true } else if value == .undo { - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerId) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) strongSelf.chatListDisplayNode.containerNode.updateState({ state in var state = state - state.pendingRemovalPeerIds.remove(peer.peerId) + state.pendingRemovalItemIds.remove(ChatListNodeState.ItemId(peerId: peer.peerId, threadId: nil)) return state }) - strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil) + strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingItemId(nil) return true } return false diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index 84a57a1c38..7d359f0160 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -209,7 +209,8 @@ private final class ChatListShimmerNode: ASDisplayNode { peers: peers, associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) let readState = EnginePeerReadCounters() diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index a6de16afe8..f3caf18460 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -3082,7 +3082,8 @@ private final class ChatListSearchShimmerNode: ASDisplayNode { peers: peers, associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) let readState = EnginePeerReadCounters() return ChatListItem(presentationData: chatListPresentationData, context: context, chatListLocation: .chatList(groupId: .root), filterData: nil, index: .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: 0, messageIndex: EngineMessage.Index(id: EngineMessage.Id(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1))), content: .peer(messages: [message], peer: EngineRenderedPeer(peer: peer1), threadInfo: nil, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, hasUnseenMentions: false, hasUnseenReactions: false, draftState: nil, inputActivities: nil, promoInfo: nil, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false, forumTopicData: nil), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction) @@ -3112,7 +3113,8 @@ private final class ChatListSearchShimmerNode: ASDisplayNode { peers: peers, associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: true, isGlobalSearchResult: true) @@ -3140,7 +3142,8 @@ private final class ChatListSearchShimmerNode: ASDisplayNode { peers: peers, associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true) @@ -3168,7 +3171,8 @@ private final class ChatListSearchShimmerNode: ASDisplayNode { peers: peers, associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true) @@ -3196,7 +3200,8 @@ private final class ChatListSearchShimmerNode: ASDisplayNode { peers: peers, associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true) diff --git a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift index 61e8fa1ba9..1048701c8a 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift @@ -276,14 +276,14 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder: default: hideAuthor = true } - if let (text, textSpoilers, customEmojiRangesValue) = plainServiceMessageString(strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: message, accountPeerId: accountPeerId, forChatList: true) { + if let (text, textSpoilers, customEmojiRangesValue) = plainServiceMessageString(strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: message, accountPeerId: accountPeerId, forChatList: true, forForumOverview: false) { messageText = text spoilers = textSpoilers customEmojiRanges = customEmojiRangesValue } } case _ as TelegramMediaExpiredContent: - if let (text, _, _) = plainServiceMessageString(strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: message, accountPeerId: accountPeerId, forChatList: true) { + if let (text, _, _) = plainServiceMessageString(strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: message, accountPeerId: accountPeerId, forChatList: true, forForumOverview: false) { messageText = text } case let poll as TelegramMediaPoll: diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index ff162d10df..1438dcf409 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -175,13 +175,23 @@ private func areFoundPeerArraysEqual(_ lhs: [(EnginePeer, EnginePeer?)], _ rhs: } public struct ChatListNodeState: Equatable { + public struct ItemId: Hashable { + public var peerId: EnginePeer.Id + public var threadId: Int64? + + public init(peerId: EnginePeer.Id, threadId: Int64?) { + self.peerId = peerId + self.threadId = threadId + } + } + public var presentationData: ChatListPresentationData public var editing: Bool - public var peerIdWithRevealedOptions: EnginePeer.Id? + public var peerIdWithRevealedOptions: ItemId? public var selectedPeerIds: Set public var peerInputActivities: ChatListNodePeerInputActivities? - public var pendingRemovalPeerIds: Set - public var pendingClearHistoryPeerIds: Set + public var pendingRemovalItemIds: Set + public var pendingClearHistoryPeerIds: Set public var archiveShouldBeTemporaryRevealed: Bool public var selectedAdditionalCategoryIds: Set public var hiddenPsaPeerId: EnginePeer.Id? @@ -189,7 +199,21 @@ public struct ChatListNodeState: Equatable { public var selectedPeerMap: [EnginePeer.Id: EnginePeer] public var selectedThreadIds: Set - public init(presentationData: ChatListPresentationData, editing: Bool, peerIdWithRevealedOptions: EnginePeer.Id?, selectedPeerIds: Set, foundPeers: [(EnginePeer, EnginePeer?)], selectedPeerMap: [EnginePeer.Id: EnginePeer], selectedAdditionalCategoryIds: Set, peerInputActivities: ChatListNodePeerInputActivities?, pendingRemovalPeerIds: Set, pendingClearHistoryPeerIds: Set, archiveShouldBeTemporaryRevealed: Bool, hiddenPsaPeerId: EnginePeer.Id?, selectedThreadIds: Set) { + public init( + presentationData: ChatListPresentationData, + editing: Bool, + peerIdWithRevealedOptions: ItemId?, + selectedPeerIds: Set, + foundPeers: [(EnginePeer, EnginePeer?)], + selectedPeerMap: [EnginePeer.Id: EnginePeer], + selectedAdditionalCategoryIds: Set, + peerInputActivities: ChatListNodePeerInputActivities?, + pendingRemovalItemIds: Set, + pendingClearHistoryPeerIds: Set, + archiveShouldBeTemporaryRevealed: Bool, + hiddenPsaPeerId: EnginePeer.Id?, + selectedThreadIds: Set + ) { self.presentationData = presentationData self.editing = editing self.peerIdWithRevealedOptions = peerIdWithRevealedOptions @@ -198,7 +222,7 @@ public struct ChatListNodeState: Equatable { self.foundPeers = foundPeers self.selectedPeerMap = selectedPeerMap self.peerInputActivities = peerInputActivities - self.pendingRemovalPeerIds = pendingRemovalPeerIds + self.pendingRemovalItemIds = pendingRemovalItemIds self.pendingClearHistoryPeerIds = pendingClearHistoryPeerIds self.archiveShouldBeTemporaryRevealed = archiveShouldBeTemporaryRevealed self.hiddenPsaPeerId = hiddenPsaPeerId @@ -230,7 +254,7 @@ public struct ChatListNodeState: Equatable { if lhs.peerInputActivities !== rhs.peerInputActivities { return false } - if lhs.pendingRemovalPeerIds != rhs.pendingRemovalPeerIds { + if lhs.pendingRemovalItemIds != rhs.pendingRemovalItemIds { return false } if lhs.pendingClearHistoryPeerIds != rhs.pendingClearHistoryPeerIds { @@ -321,6 +345,13 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL } else { enabled = false } + + if let threadInfo, threadInfo.isClosed, case let .channel(channel) = itemPeer { + if threadInfo.isOwnedByMe || channel.hasPermission(.manageTopics) { + } else { + enabled = false + } + } } if filter.contains(.onlyPrivateChats) { if let peer = peer.peers[peer.peerId] { @@ -535,6 +566,13 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL } else { enabled = false } + + if let threadInfo, threadInfo.isClosed, case let .channel(channel) = itemPeer { + if threadInfo.isOwnedByMe || channel.hasPermission(.manageTopics) { + } else { + enabled = false + } + } } if filter.contains(.excludeChannels) { if case let .channel(peer) = peer.chatMainPeer, case .broadcast = peer.info { @@ -811,9 +849,9 @@ public final class ChatListNode: ListView { public var addedVisibleChatsWithPeerIds: (([EnginePeer.Id]) -> Void)? - private let currentRemovingPeerId = Atomic(value: nil) - public func setCurrentRemovingPeerId(_ peerId: EnginePeer.Id?) { - let _ = self.currentRemovingPeerId.swap(peerId) + private let currentRemovingItemId = Atomic(value: nil) + public func setCurrentRemovingItemId(_ itemId: ChatListNodeState.ItemId?) { + let _ = self.currentRemovingItemId.swap(itemId) } private var hapticFeedback: HapticFeedback? @@ -843,7 +881,7 @@ public final class ChatListNode: ListView { isSelecting = true } - self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), foundPeers: [], selectedPeerMap: [:], selectedAdditionalCategoryIds: Set(), peerInputActivities: nil, pendingRemovalPeerIds: Set(), pendingClearHistoryPeerIds: Set(), archiveShouldBeTemporaryRevealed: false, hiddenPsaPeerId: nil, selectedThreadIds: Set()) + self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), foundPeers: [], selectedPeerMap: [:], selectedAdditionalCategoryIds: Set(), peerInputActivities: nil, pendingRemovalItemIds: Set(), pendingClearHistoryPeerIds: Set(), archiveShouldBeTemporaryRevealed: false, hiddenPsaPeerId: nil, selectedThreadIds: Set()) self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true) self.theme = theme @@ -948,9 +986,13 @@ public final class ChatListNode: ListView { }, setPeerIdWithRevealedOptions: { [weak self] peerId, fromPeerId in if let strongSelf = self { strongSelf.updateState { state in - if (peerId == nil && fromPeerId == state.peerIdWithRevealedOptions) || (peerId != nil && fromPeerId == nil) || (peerId == nil && fromPeerId == nil) { + if (peerId == nil && fromPeerId == state.peerIdWithRevealedOptions?.peerId) || (peerId != nil && fromPeerId == nil) || (peerId == nil && fromPeerId == nil) { var state = state - state.peerIdWithRevealedOptions = peerId + if let peerId = peerId { + state.peerIdWithRevealedOptions = ChatListNodeState.ItemId(peerId: peerId, threadId: nil) + } else { + state.peerIdWithRevealedOptions = nil + } return state } else { return state @@ -1020,7 +1062,7 @@ public final class ChatListNode: ListView { guard let strongSelf = self else { return } - strongSelf.setCurrentRemovingPeerId(peerId) + strongSelf.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) let _ = (context.engine.peers.togglePeerMuted(peerId: peerId, threadId: nil) |> deliverOnMainQueue).start(completed: { self?.updateState { state in @@ -1028,10 +1070,10 @@ public final class ChatListNode: ListView { state.peerIdWithRevealedOptions = nil return state } - self?.setCurrentRemovingPeerId(nil) + self?.setCurrentRemovingItemId(nil) }) }, setPeerThreadMuted: { [weak self] peerId, threadId, value in - //self?.setCurrentRemovingPeerId(peerId) + self?.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) let _ = (context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value ? Int32.max : 0) |> deliverOnMainQueue).start(completed: { self?.updateState { state in @@ -1039,7 +1081,7 @@ public final class ChatListNode: ListView { state.peerIdWithRevealedOptions = nil return state } - //self?.setCurrentRemovingPeerId(nil) + self?.setCurrentRemovingItemId(nil) }) }, deletePeer: { [weak self] peerId, joined in self?.deletePeerChat?(peerId, joined) @@ -1055,7 +1097,7 @@ public final class ChatListNode: ListView { guard let context = context else { return } - self?.setCurrentRemovingPeerId(peerId) + self?.setCurrentRemovingItemId(ChatListNodeState.ItemId(peerId: peerId, threadId: nil)) let _ = (context.engine.messages.togglePeersUnreadMarkInteractively(peerIds: [peerId], setToValue: nil) |> deliverOnMainQueue).start(completed: { self?.updateState { state in @@ -1063,7 +1105,7 @@ public final class ChatListNode: ListView { state.peerIdWithRevealedOptions = nil return state } - self?.setCurrentRemovingPeerId(nil) + self?.setCurrentRemovingItemId(nil) }) }, toggleArchivedFolderHiddenByDefault: { [weak self] in self?.toggleArchivedFolderHiddenByDefault?() @@ -1113,7 +1155,7 @@ public final class ChatListNode: ListView { let previousState = Atomic(value: self.currentState) let previousView = Atomic(value: nil) let previousHideArchivedFolderByDefault = Atomic(value: nil) - let currentRemovingPeerId = self.currentRemovingPeerId + let currentRemovingItemId = self.currentRemovingItemId let savedMessagesPeer: Signal if case let .peers(filter, _, _, _) = mode, filter.contains(.onlyWriteable), case .chatList = location { @@ -1327,7 +1369,7 @@ public final class ChatListNode: ListView { } } - let removingPeerId = currentRemovingPeerId.with { $0 } + let removingItemId = currentRemovingItemId.with { $0 } var disableAnimations = true if previousState.editing != state.editing { @@ -1347,13 +1389,16 @@ public final class ChatListNode: ListView { if chatListIndex.pinningIndex != nil { previousPinnedChats.append(chatListIndex.messageIndex.id.peerId) } - if chatListIndex.messageIndex.id.peerId == removingPeerId { + if ChatListNodeState.ItemId(peerId: chatListIndex.messageIndex.id.peerId, threadId: nil) == removingItemId { didIncludeRemovingPeerId = true } } else if case let .forum(pinnedIndex, _, threadId, _, _) = index { if case .index = pinnedIndex { previousPinnedThreads.append(threadId) } + if case let .forum(peerId) = location, ChatListNodeState.ItemId(peerId: peerId, threadId: threadId) == removingItemId { + didIncludeRemovingPeerId = true + } } } else if case let .GroupReferenceEntry(_, _, _, _, _, _, _, _, hiddenByDefault) = entry { didIncludeHiddenByDefaultArchive = hiddenByDefault @@ -1373,8 +1418,12 @@ public final class ChatListNode: ListView { } } - if case let .chatList(index) = index, index.messageIndex.id.peerId == removingPeerId { + if case let .chatList(index) = index, ChatListNodeState.ItemId(peerId: index.messageIndex.id.peerId, threadId: nil) == removingItemId { doesIncludeRemovingPeerId = true + } else if case let .forum(_, _, threadId, _, _) = index { + if case let .forum(peerId) = location, ChatListNodeState.ItemId(peerId: peerId, threadId: threadId) == removingItemId { + doesIncludeRemovingPeerId = true + } } } else if case let .GroupReferenceEntry(_, _, _, _, _, _, _, _, hiddenByDefault) = entry { doesIncludeArchive = true diff --git a/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift b/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift index 048e9acf7c..98bb0792ba 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift @@ -343,24 +343,26 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState } loop: for entry in view.items { var peerId: EnginePeer.Id? + var threadId: Int64? var activityItemId: ChatListNodePeerInputActivities.ItemId? if case let .chatList(index) = entry.index { peerId = index.messageIndex.id.peerId activityItemId = ChatListNodePeerInputActivities.ItemId(peerId: index.messageIndex.id.peerId, threadId: nil) - } else if case let .forum(_, _, threadId, _, _) = entry.index, case let .forum(peerIdValue) = chatListLocation { + } else if case let .forum(_, _, threadIdValue, _, _) = entry.index, case let .forum(peerIdValue) = chatListLocation { peerId = peerIdValue - activityItemId = ChatListNodePeerInputActivities.ItemId(peerId: peerIdValue, threadId: threadId) + activityItemId = ChatListNodePeerInputActivities.ItemId(peerId: peerIdValue, threadId: threadIdValue) + threadId = threadIdValue } if let savedMessagesPeer = savedMessagesPeer, let peerId = peerId, savedMessagesPeer.id == peerId || foundPeerIds.contains(peerId) { continue loop } - if let peerId = peerId, state.pendingRemovalPeerIds.contains(peerId) { + if let peerId = peerId, state.pendingRemovalItemIds.contains(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) { continue loop } var updatedMessages = entry.messages var updatedCombinedReadState = entry.readCounters - if let peerId = peerId, state.pendingClearHistoryPeerIds.contains(peerId) { + if let peerId = peerId, state.pendingClearHistoryPeerIds.contains(ChatListNodeState.ItemId(peerId: peerId, threadId: threadId)) { updatedMessages = [] updatedCombinedReadState = nil } @@ -372,29 +374,26 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState var hasActiveRevealControls = false if let peerId { - hasActiveRevealControls = peerId == state.peerIdWithRevealedOptions + hasActiveRevealControls = ChatListNodeState.ItemId(peerId: peerId, threadId: threadId) == state.peerIdWithRevealedOptions } var inputActivities: [(EnginePeer, PeerInputActivity)]? if let activityItemId { inputActivities = state.peerInputActivities?.activities[activityItemId] } - var threadId: Int64 = 0 - switch entry.index { - case let .forum(_, _, threadIdValue, _, _): - threadId = threadIdValue - default: - break - } - var isSelected = false - if threadId != 0 { + if let threadId, threadId != 0 { isSelected = state.selectedThreadIds.contains(threadId) } else if let peerId { isSelected = state.selectedPeerIds.contains(peerId) } + + var threadInfo: ChatListItemContent.ThreadInfo? + if let threadData = entry.threadData, let threadId = threadId { + threadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadData.info, isOwnedByMe: threadData.isOwnedByMe, isClosed: threadData.isClosed) + } - result.append(.PeerEntry(index: offsetPinnedIndex(entry.index, offset: pinnedIndexOffset), presentationData: state.presentationData, messages: updatedMessages, readState: updatedCombinedReadState, isRemovedFromTotalUnreadCount: entry.isMuted, draftState: draftState, peer: entry.renderedPeer, threadInfo: entry.threadData.flatMap { ChatListItemContent.ThreadInfo(id: threadId, info: $0.info, isOwnedByMe: $0.isOwnedByMe, isClosed: $0.isClosed) }, presence: entry.presence, hasUnseenMentions: entry.hasUnseenMentions, hasUnseenReactions: entry.hasUnseenReactions, editing: state.editing, hasActiveRevealControls: hasActiveRevealControls, selected: isSelected, inputActivities: inputActivities, promoInfo: nil, hasFailedMessages: entry.hasFailed, isContact: entry.isContact, forumTopicData: entry.forumTopicData)) + result.append(.PeerEntry(index: offsetPinnedIndex(entry.index, offset: pinnedIndexOffset), presentationData: state.presentationData, messages: updatedMessages, readState: updatedCombinedReadState, isRemovedFromTotalUnreadCount: entry.isMuted, draftState: draftState, peer: entry.renderedPeer, threadInfo: threadInfo, presence: entry.presence, hasUnseenMentions: entry.hasUnseenMentions, hasUnseenReactions: entry.hasUnseenReactions, editing: state.editing, hasActiveRevealControls: hasActiveRevealControls, selected: isSelected, inputActivities: inputActivities, promoInfo: nil, hasFailedMessages: entry.hasFailed, isContact: entry.isContact, forumTopicData: entry.forumTopicData)) } if !view.hasLater { var pinningIndex: UInt16 = UInt16(pinnedIndexOffset == 0 ? 0 : (pinnedIndexOffset - 1)) @@ -477,7 +476,7 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState hasUnseenMentions: item.item.hasUnseenMentions, hasUnseenReactions: item.item.hasUnseenReactions, editing: state.editing, - hasActiveRevealControls: peerId == state.peerIdWithRevealedOptions, + hasActiveRevealControls: ChatListNodeState.ItemId(peerId: peerId, threadId: threadId) == state.peerIdWithRevealedOptions, selected: isSelected, inputActivities: state.peerInputActivities?.activities[ChatListNodePeerInputActivities.ItemId(peerId: peerId, threadId: nil)], promoInfo: promoInfo, diff --git a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift index 50a0b0858e..42c6046040 100644 --- a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift +++ b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetController.swift @@ -85,7 +85,7 @@ public final class ChatSendMessageActionSheetController: ViewController { var isSecret = false var canSchedule = false var hasEntityKeyboard = false - if case let .peer(peerId) = self.interfaceState.chatLocation { + if let peerId = self.interfaceState.chatLocation.peerId { reminders = peerId == context.account.peerId isSecret = peerId.namespace == Namespaces.Peer.SecretChat canSchedule = !isSecret diff --git a/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift b/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift index 61a4a38927..79addadc0c 100644 --- a/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift +++ b/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift @@ -1404,7 +1404,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate { }, showAll: false) let peer = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer, text: "", attributes: [], media: [map], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer, text: "", attributes: [], media: [map], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) let controller = LocationViewController(context: self.context, subject: message, params: controllerParams) self.pushController(controller) diff --git a/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift b/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift index d4c0feb291..5b2cc83554 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift @@ -757,10 +757,10 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI let previewText = groupLayouts.count > 1 ? presentationData.strings.Attachment_MessagesPreview : presentationData.strings.Attachment_MessagePreview - let previewMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [TelegramMediaAction(action: .customText(text: previewText, entities: []))], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let previewMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [TelegramMediaAction(action: .customText(text: previewText, entities: []))], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) let previewItem = self.context.sharedContext.makeChatMessagePreviewItem(context: context, messages: [previewMessage], theme: theme, strings: presentationData.strings, wallpaper: wallpaper, fontSize: presentationData.chatFontSize, chatBubbleCorners: bubbleCorners, dateTimeFormat: presentationData.dateTimeFormat, nameOrder: presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.wallpaperBackgroundNode, availableReactions: nil, isCentered: true) - let dragMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [TelegramMediaAction(action: .customText(text: presentationData.strings.Attachment_DragToReorder, entities: []))], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let dragMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [TelegramMediaAction(action: .customText(text: presentationData.strings.Attachment_DragToReorder, entities: []))], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) let dragItem = self.context.sharedContext.makeChatMessagePreviewItem(context: context, messages: [dragMessage], theme: theme, strings: presentationData.strings, wallpaper: wallpaper, fontSize: presentationData.chatFontSize, chatBubbleCorners: bubbleCorners, dateTimeFormat: presentationData.dateTimeFormat, nameOrder: presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.wallpaperBackgroundNode, availableReactions: nil, isCentered: true) let headerItems: [ListViewItem] = [previewItem, dragItem] diff --git a/submodules/Postbox/Sources/ChatListView.swift b/submodules/Postbox/Sources/ChatListView.swift index 340ac48c66..263b8a3b76 100644 --- a/submodules/Postbox/Sources/ChatListView.swift +++ b/submodules/Postbox/Sources/ChatListView.swift @@ -511,7 +511,7 @@ final class MutableChatListView { renderedPeers.append(ChatListGroupReferencePeer(peer: renderedPeer, isUnread: isUnread)) if foundIndices.count == 1 && message == nil { - message = postbox.messageHistoryTable.getMessage(messageIndex).flatMap({ postbox.messageHistoryTable.renderMessage($0, peerTable: postbox.peerTable) }) + message = postbox.messageHistoryTable.getMessage(messageIndex).flatMap({ postbox.messageHistoryTable.renderMessage($0, peerTable: postbox.peerTable, threadIndexTable: postbox.messageHistoryThreadIndexTable) }) } } } diff --git a/submodules/Postbox/Sources/ChatListViewState.swift b/submodules/Postbox/Sources/ChatListViewState.swift index 7b3d0eaae3..73a86ae8f0 100644 --- a/submodules/Postbox/Sources/ChatListViewState.swift +++ b/submodules/Postbox/Sources/ChatListViewState.swift @@ -102,7 +102,7 @@ private func updateMessagePeers(_ message: Message, updatedPeers: [PeerId: Peer] peers[peerId] = currentPeer } } - return Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: message.media, peers: peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia) + return Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: message.media, peers: peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia, associatedThreadInfo: message.associatedThreadInfo) } return nil } diff --git a/submodules/Postbox/Sources/GlobalMessageTagsView.swift b/submodules/Postbox/Sources/GlobalMessageTagsView.swift index 0466e20cbb..e6af1fa66a 100644 --- a/submodules/Postbox/Sources/GlobalMessageTagsView.swift +++ b/submodules/Postbox/Sources/GlobalMessageTagsView.swift @@ -167,7 +167,7 @@ final class MutableGlobalMessageTagsView: MutablePostboxView { hasChanges = true } case let .message(message): - if self.add(.message(Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: updatedTimestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: message.media, peers: message.peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia))) { + if self.add(.message(Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: updatedTimestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: message.media, peers: message.peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia, associatedThreadInfo: message.associatedThreadInfo))) { hasChanges = true } } diff --git a/submodules/Postbox/Sources/Message.swift b/submodules/Postbox/Sources/Message.swift index 20e1e20340..bed76188af 100644 --- a/submodules/Postbox/Sources/Message.swift +++ b/submodules/Postbox/Sources/Message.swift @@ -608,6 +608,34 @@ public struct MessageGroupInfo: Equatable { } public final class Message { + public final class AssociatedThreadInfo: Equatable { + public let title: String + public let icon: Int64? + public let iconColor: Int32 + + public init(title: String, icon: Int64?, iconColor: Int32) { + self.title = title + self.icon = icon + self.iconColor = iconColor + } + + public static func ==(lhs: AssociatedThreadInfo, rhs: AssociatedThreadInfo) -> Bool { + if lhs === rhs { + return true + } + if lhs.title != rhs.title { + return false + } + if lhs.icon != rhs.icon { + return false + } + if lhs.iconColor != rhs.iconColor { + return false + } + return true + } + } + public let stableId: UInt32 public let stableVersion: UInt32 @@ -630,12 +658,13 @@ public final class Message { public let associatedMessages: SimpleDictionary public let associatedMessageIds: [MessageId] public let associatedMedia: [MediaId: Media] + public let associatedThreadInfo: AssociatedThreadInfo? public var index: MessageIndex { return MessageIndex(id: self.id, timestamp: self.timestamp) } - public init(stableId: UInt32, stableVersion: UInt32, id: MessageId, globallyUniqueId: Int64?, groupingKey: Int64?, groupInfo: MessageGroupInfo?, threadId: Int64?, timestamp: Int32, flags: MessageFlags, tags: MessageTags, globalTags: GlobalMessageTags, localTags: LocalMessageTags, forwardInfo: MessageForwardInfo?, author: Peer?, text: String, attributes: [MessageAttribute], media: [Media], peers: SimpleDictionary, associatedMessages: SimpleDictionary, associatedMessageIds: [MessageId], associatedMedia: [MediaId: Media]) { + public init(stableId: UInt32, stableVersion: UInt32, id: MessageId, globallyUniqueId: Int64?, groupingKey: Int64?, groupInfo: MessageGroupInfo?, threadId: Int64?, timestamp: Int32, flags: MessageFlags, tags: MessageTags, globalTags: GlobalMessageTags, localTags: LocalMessageTags, forwardInfo: MessageForwardInfo?, author: Peer?, text: String, attributes: [MessageAttribute], media: [Media], peers: SimpleDictionary, associatedMessages: SimpleDictionary, associatedMessageIds: [MessageId], associatedMedia: [MediaId: Media], associatedThreadInfo: AssociatedThreadInfo?) { self.stableId = stableId self.stableVersion = stableVersion self.id = id @@ -657,46 +686,47 @@ public final class Message { self.associatedMessages = associatedMessages self.associatedMessageIds = associatedMessageIds self.associatedMedia = associatedMedia + self.associatedThreadInfo = associatedThreadInfo } public func withUpdatedText(_ text: String) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } public func withUpdatedTimestamp(_ timestamp: Int32) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } public func withUpdatedMedia(_ media: [Media]) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } public func withUpdatedPeers(_ peers: SimpleDictionary) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } public func withUpdatedFlags(_ flags: MessageFlags) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } func withUpdatedGroupInfo(_ groupInfo: MessageGroupInfo?) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } public func withUpdatedAttributes(_ attributes: [MessageAttribute]) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } func withUpdatedAssociatedMessages(_ associatedMessages: SimpleDictionary) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } public func withUpdatedForwardInfo(_ forwardInfo: MessageForwardInfo?) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } public func withUpdatedAuthor(_ author: Peer?) -> Message { - return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia) + return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } } diff --git a/submodules/Postbox/Sources/MessageHistoryTable.swift b/submodules/Postbox/Sources/MessageHistoryTable.swift index 75dfb842a7..4dea1bb185 100644 --- a/submodules/Postbox/Sources/MessageHistoryTable.swift +++ b/submodules/Postbox/Sources/MessageHistoryTable.swift @@ -2498,7 +2498,7 @@ final class MessageHistoryTable: Table { return parsedMedia } - func renderMessage(_ message: IntermediateMessage, peerTable: PeerTable, addAssociatedMessages: Bool = true) -> Message { + func renderMessage(_ message: IntermediateMessage, peerTable: PeerTable, threadIndexTable: MessageHistoryThreadIndexTable, addAssociatedMessages: Bool = true) -> Message { var parsedAttributes: [MessageAttribute] = [] var parsedMedia: [Media] = [] @@ -2584,9 +2584,6 @@ final class MessageHistoryTable: Table { } for mediaId in attribute.associatedMediaIds { if associatedMedia[mediaId] == nil { - if mediaId.id == 5364107552168613887 { - assert(true) - } if let media = self.getMedia(mediaId) { associatedMedia[mediaId] = media } @@ -2597,14 +2594,19 @@ final class MessageHistoryTable: Table { for messageId in attribute.associatedMessageIds { if let index = self.messageHistoryIndexTable.getIndex(messageId) { if let message = self.getMessage(index) { - associatedMessages[messageId] = self.renderMessage(message, peerTable: peerTable, addAssociatedMessages: false) + associatedMessages[messageId] = self.renderMessage(message, peerTable: peerTable, threadIndexTable: threadIndexTable, addAssociatedMessages: false) } } } } } - return Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: forwardInfo, author: author, text: message.text, attributes: parsedAttributes, media: parsedMedia, peers: peers, associatedMessages: associatedMessages, associatedMessageIds: associatedMessageIds, associatedMedia: associatedMedia) + var associatedThreadInfo: Message.AssociatedThreadInfo? + if let threadId = message.threadId, let data = threadIndexTable.get(peerId: message.id.peerId, threadId: threadId) { + associatedThreadInfo = self.seedConfiguration.decodeMessageThreadInfo(data.data) + } + + return Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: forwardInfo, author: author, text: message.text, attributes: parsedAttributes, media: parsedMedia, peers: peers, associatedMessages: associatedMessages, associatedMessageIds: associatedMessageIds, associatedMedia: associatedMedia, associatedThreadInfo: associatedThreadInfo) } func renderMessagePeers(_ message: Message, peerTable: PeerTable) -> Message { @@ -2647,12 +2649,12 @@ final class MessageHistoryTable: Table { return message.withUpdatedPeers(peers) } - func renderAssociatedMessages(associatedMessageIds: [MessageId], peerTable: PeerTable) -> SimpleDictionary { + func renderAssociatedMessages(associatedMessageIds: [MessageId], peerTable: PeerTable, threadIndexTable: MessageHistoryThreadIndexTable) -> SimpleDictionary { var associatedMessages = SimpleDictionary() for messageId in associatedMessageIds { if let index = self.messageHistoryIndexTable.getIndex(messageId) { if let message = self.getMessage(index) { - associatedMessages[messageId] = self.renderMessage(message, peerTable: peerTable, addAssociatedMessages: false) + associatedMessages[messageId] = self.renderMessage(message, peerTable: peerTable, threadIndexTable: threadIndexTable, addAssociatedMessages: false) } } } diff --git a/submodules/Postbox/Sources/MessageHistoryView.swift b/submodules/Postbox/Sources/MessageHistoryView.swift index 3f43211ee1..8f6549342d 100644 --- a/submodules/Postbox/Sources/MessageHistoryView.swift +++ b/submodules/Postbox/Sources/MessageHistoryView.swift @@ -137,7 +137,7 @@ enum MutableMessageHistoryEntry { return .IntermediateMessageEntry(updatedMessage, location, monthLocation) case let .MessageEntry(value, reloadAssociatedMessages, reloadPeers): let message = value.message - let updatedMessage = Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: message.media, peers: message.peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia) + let updatedMessage = Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: message.media, peers: message.peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia, associatedThreadInfo: message.associatedThreadInfo) return .MessageEntry(MessageHistoryMessageEntry(message: updatedMessage, location: value.location, monthLocation: value.monthLocation, attributes: value.attributes), reloadAssociatedMessages: reloadAssociatedMessages, reloadPeers: reloadPeers) } } @@ -901,7 +901,7 @@ final class MutableMessageHistoryView { private func render(postbox: PostboxImpl) { for namespace in self.topTaggedMessages.keys { if let entry = self.topTaggedMessages[namespace]!, case let .intermediate(message) = entry { - let item: MessageHistoryTopTaggedMessage? = .message(postbox.messageHistoryTable.renderMessage(message, peerTable: postbox.peerTable)) + let item: MessageHistoryTopTaggedMessage? = .message(postbox.messageHistoryTable.renderMessage(message, peerTable: postbox.peerTable, threadIndexTable: postbox.messageHistoryThreadIndexTable)) self.topTaggedMessages[namespace] = item } } diff --git a/submodules/Postbox/Sources/MessageHistoryViewState.swift b/submodules/Postbox/Sources/MessageHistoryViewState.swift index ea0dcc41f5..de3eaeb89f 100644 --- a/submodules/Postbox/Sources/MessageHistoryViewState.swift +++ b/submodules/Postbox/Sources/MessageHistoryViewState.swift @@ -1248,7 +1248,7 @@ final class HistoryViewLoadedState { messageMedia.append(media) } } - let updatedMessage = Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: messageMedia, peers: message.peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia) + let updatedMessage = Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, threadId: message.threadId, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: messageMedia, peers: message.peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, associatedMedia: message.associatedMedia, associatedThreadInfo: message.associatedThreadInfo) return .MessageEntry(MessageHistoryMessageEntry(message: updatedMessage, location: value.location, monthLocation: value.monthLocation, attributes: value.attributes), reloadAssociatedMessages: reloadAssociatedMessages, reloadPeers: reloadPeers) } case .IntermediateMessageEntry: @@ -1449,7 +1449,7 @@ final class HistoryViewLoadedState { case let .MessageEntry(value, reloadAssociatedMessages, reloadPeers): var updatedMessage = value.message if reloadAssociatedMessages { - let associatedMessages = postbox.messageHistoryTable.renderAssociatedMessages(associatedMessageIds: value.message.associatedMessageIds, peerTable: postbox.peerTable) + let associatedMessages = postbox.messageHistoryTable.renderAssociatedMessages(associatedMessageIds: value.message.associatedMessageIds, peerTable: postbox.peerTable, threadIndexTable: postbox.messageHistoryThreadIndexTable) updatedMessage = value.message.withUpdatedAssociatedMessages(associatedMessages) } if reloadPeers { @@ -1468,7 +1468,7 @@ final class HistoryViewLoadedState { result.append(value) } case let .IntermediateMessageEntry(message, location, monthLocation): - let renderedMessage = postbox.messageHistoryTable.renderMessage(message, peerTable: postbox.peerTable) + let renderedMessage = postbox.messageHistoryTable.renderMessage(message, peerTable: postbox.peerTable, threadIndexTable: postbox.messageHistoryThreadIndexTable) var authorIsContact = false if let author = renderedMessage.author { authorIsContact = postbox.contactsTable.isContact(peerId: author.id) diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index 746236fb64..601f085004 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -2012,7 +2012,7 @@ final class PostboxImpl { } func renderIntermediateMessage(_ message: IntermediateMessage) -> Message { - let renderedMessage = self.messageHistoryTable.renderMessage(message, peerTable: self.peerTable) + let renderedMessage = self.messageHistoryTable.renderMessage(message, peerTable: self.peerTable, threadIndexTable: self.messageHistoryThreadIndexTable) return renderedMessage } @@ -2545,7 +2545,7 @@ final class PostboxImpl { var result: [Message] = [] for messageId in self.textIndexTable.search(peerId: peerId, text: query, tags: tags) { if let index = self.messageHistoryIndexTable.getIndex(messageId), let message = self.messageHistoryTable.getMessage(index) { - result.append(self.messageHistoryTable.renderMessage(message, peerTable: self.peerTable)) + result.append(self.messageHistoryTable.renderMessage(message, peerTable: self.peerTable, threadIndexTable: self.messageHistoryThreadIndexTable)) } else { assertionFailure() } diff --git a/submodules/Postbox/Sources/SeedConfiguration.swift b/submodules/Postbox/Sources/SeedConfiguration.swift index 4467004572..a189187b97 100644 --- a/submodules/Postbox/Sources/SeedConfiguration.swift +++ b/submodules/Postbox/Sources/SeedConfiguration.swift @@ -74,6 +74,7 @@ public final class SeedConfiguration { public let getGlobalNotificationSettings: (Transaction) -> PostboxGlobalNotificationSettings? public let defaultGlobalNotificationSettings: PostboxGlobalNotificationSettings public let mergeMessageAttributes: ([MessageAttribute], inout [MessageAttribute]) -> Void + public let decodeMessageThreadInfo: (CodableEntry) -> Message.AssociatedThreadInfo? public init( globalMessageIdsPeerIdNamespaces: Set, @@ -97,7 +98,8 @@ public final class SeedConfiguration { chatMessagesNamespaces: Set, getGlobalNotificationSettings: @escaping (Transaction) -> PostboxGlobalNotificationSettings?, defaultGlobalNotificationSettings: PostboxGlobalNotificationSettings, - mergeMessageAttributes: @escaping ([MessageAttribute], inout [MessageAttribute]) -> Void + mergeMessageAttributes: @escaping ([MessageAttribute], inout [MessageAttribute]) -> Void, + decodeMessageThreadInfo: @escaping (CodableEntry) -> Message.AssociatedThreadInfo? ) { self.globalMessageIdsPeerIdNamespaces = globalMessageIdsPeerIdNamespaces self.initializeChatListWithHole = initializeChatListWithHole @@ -117,5 +119,6 @@ public final class SeedConfiguration { self.getGlobalNotificationSettings = getGlobalNotificationSettings self.defaultGlobalNotificationSettings = defaultGlobalNotificationSettings self.mergeMessageAttributes = mergeMessageAttributes + self.decodeMessageThreadInfo = decodeMessageThreadInfo } } diff --git a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift index c94c8c1b81..1745f599e7 100644 --- a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift +++ b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift @@ -167,22 +167,22 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, UIScrollViewDel peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) - messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) - let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) - let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA=" let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 23, title: nil, performer: nil, waveform: Data(base64Encoded: waveformBase64)!)] let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: 0, attributes: voiceAttributes) - let message3 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message3 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message3], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: FileMediaResourceStatus(mediaStatus: .playbackStatus(.paused), fetchStatus: .Local), tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) - let message4 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message4 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message4], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) let width: CGFloat diff --git a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift index bc6b2838c6..be9f265359 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift @@ -149,7 +149,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { let forwardInfo = MessageForwardInfo(author: item.linkEnabled ? peers[peerId] : nil, source: nil, sourceMessageId: nil, date: 0, authorSignature: item.linkEnabled ? nil : item.peerName, psaType: nil, flags: []) - let messageItem = item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: forwardInfo, author: nil, text: item.strings.Privacy_Forwards_PreviewMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:])], theme: item.theme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false) + let messageItem = item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: forwardInfo, author: nil, text: item.strings.Privacy_Forwards_PreviewMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil)], theme: item.theme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false) var node: ListViewItemNode? if let current = currentNode { diff --git a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift index eb238e4687..eab5fdc9fc 100644 --- a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift @@ -283,7 +283,7 @@ class ReactionChatPreviewItemNode: ListViewItemNode { attributes.append(ReactionsMessageAttribute(canViewList: false, reactions: [MessageReaction(value: reaction, count: 1, chosenOrder: 0)], recentPeers: [])) } - let messageItem = item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: chatPeerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[userPeerId], text: messageText, attributes: attributes, media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:])], theme: item.theme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: item.availableReactions, isCentered: true) + let messageItem = item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: chatPeerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[userPeerId], text: messageText, attributes: attributes, media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil)], theme: item.theme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: item.availableReactions, isCentered: true) var node: ListViewItemNode? if let current = currentNode { diff --git a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift index df4324f164..e9497fb24f 100644 --- a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift +++ b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift @@ -265,7 +265,8 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView peers: [:], associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) ], peer: EngineRenderedPeer(peer: peer), @@ -422,22 +423,22 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) - messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) - let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message1 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) - let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message2 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) let waveformBase64 = "DAAOAAkACQAGAAwADwAMABAADQAPABsAGAALAA0AGAAfABoAHgATABgAGQAYABQADAAVABEAHwANAA0ACQAWABkACQAOAAwACQAfAAAAGQAVAAAAEwATAAAACAAfAAAAHAAAABwAHwAAABcAGQAAABQADgAAABQAHwAAAB8AHwAAAAwADwAAAB8AEwAAABoAFwAAAB8AFAAAAAAAHwAAAAAAHgAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAHwAAAAAAAAA=" let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 23, title: nil, performer: nil, waveform: Data(base64Encoded: waveformBase64)!)] let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: 0, attributes: voiceAttributes) - let message3 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message3 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message3], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: FileMediaResourceStatus(mediaStatus: .playbackStatus(.paused), fetchStatus: .Local), tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) - let message4 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message4 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message4], theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: self.presentationData.chatWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.chatBackgroundNode, availableReactions: nil, isCentered: false)) let width: CGFloat diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index 8012376327..b975380659 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -885,7 +885,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate peers: [:], associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) ], peer: EngineRenderedPeer(peer: peer), @@ -1013,20 +1014,20 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate var sampleMessages: [Message] = [] - let message1 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message1 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message1) - let message2 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message2 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message2) - let message3 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message3 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message3) - let message4 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_7_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message4 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_7_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) messages[message4.id] = message4 sampleMessages.append(message4) - let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) messages[message5.id] = message5 sampleMessages.append(message5) @@ -1034,13 +1035,13 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 23, title: nil, performer: nil, waveform: Data(base64Encoded: waveformBase64)!)] let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: 0, attributes: voiceAttributes) - let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message6) - let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message7) - let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message8) items = sampleMessages.reversed().map { message in diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index 547ac2726b..86f0e1b911 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -408,7 +408,8 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { peers: [:], associatedMessages: [:], associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) ], peer: EngineRenderedPeer(peer: peer), @@ -574,20 +575,20 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { var sampleMessages: [Message] = [] - let message1 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message1 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message1) - let message2 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message2 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message2) - let message3 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message3 = Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message3) - let message4 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_7_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message4 = Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_7_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) messages[message4.id] = message4 sampleMessages.append(message4) - let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message5 = Message(stableId: 5, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 5), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66004, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: message4.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) messages[message5.id] = message5 sampleMessages.append(message5) @@ -595,13 +596,13 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 23, title: nil, performer: nil, waveform: Data(base64Encoded: waveformBase64)!)] let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: 0, attributes: voiceAttributes) - let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message6 = Message(stableId: 6, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 6), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66005, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message6) - let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message7 = Message(stableId: 7, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 7), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66006, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [ReplyMessageAttribute(messageId: message5.id, threadMessageId: nil)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message7) - let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message8 = Message(stableId: 8, stableVersion: 0, id: MessageId(peerId: otherPeerId, namespace: 0, id: 8), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66007, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) sampleMessages.append(message8) items = sampleMessages.reversed().map { message in diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift index 31082bf2d9..0991a31855 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift @@ -156,10 +156,10 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) if let (author, text) = messageItem.reply { peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: author, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) - messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) } - let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false)) } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 5625a33427..342f3f8d08 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -1102,10 +1102,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode { let theme = self.presentationData.theme.withUpdated(preview: true) - let message1 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message1 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: theme, strings: self.presentationData.strings, wallpaper: currentWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.nativeNode, availableReactions: nil, isCentered: false)) - let message2 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: topMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) + let message2 = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: topMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message2], theme: theme, strings: self.presentationData.strings, wallpaper: currentWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.nativeNode, availableReactions: nil, isCentered: false)) let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, availableHeight: layout.size.height) diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift index 437c5a9f06..5f4885c97c 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_StandaloneAccountTransaction.swift @@ -127,6 +127,12 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = { updated.append(audioTranscription) } } + }, + decodeMessageThreadInfo: { entry in + guard let data = entry.get(MessageHistoryThreadData.self) else { + return nil + } + return Message.AssociatedThreadInfo(title: data.info.title, icon: data.info.icon, iconColor: data.info.iconColor) } ) }() diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift index e81997b2ab..e0fba0edc0 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift @@ -256,7 +256,8 @@ private class AdMessagesHistoryContextImpl { peers: messagePeers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift index 5f5f2c4020..32ddd48b9c 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ApplyMaxReadIndexInteractively.swift @@ -115,6 +115,35 @@ func _internal_togglePeerUnreadMarkInteractively(postbox: Postbox, network: Netw } } +func _internal_markForumThreadAsReadInteractively(transaction: Transaction, network: Network, viewTracker: AccountViewTracker, peerId: PeerId, threadId: Int64) { + guard let peer = transaction.getPeer(peerId) else { + return + } + guard let channel = peer as? TelegramChannel, channel.flags.contains(.isForum) else { + return + } + guard var data = transaction.getMessageHistoryThreadInfo(peerId: peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) else { + return + } + guard let messageIndex = transaction.getMessageHistoryThreadTopMessage(peerId: peerId, threadId: threadId, namespaces: Set([Namespaces.Message.Cloud])) else { + return + } + if data.incomingUnreadCount != 0 { + data.incomingUnreadCount = 0 + data.maxIncomingReadId = max(messageIndex.id.id, data.maxIncomingReadId) + data.maxKnownMessageId = max(data.maxKnownMessageId, messageIndex.id.id) + + if let entry = StoredMessageHistoryThreadInfo(data) { + transaction.setMessageHistoryThreadInfo(peerId: peerId, threadId: threadId, info: entry) + } + + if let inputPeer = apiInputPeer(channel) { + //TODO:loc + let _ = network.request(Api.functions.messages.readDiscussion(peer: inputPeer, msgId: Int32(clamping: threadId), readMaxId: messageIndex.id.id)).start() + } + } +} + func _internal_togglePeerUnreadMarkInteractively(transaction: Transaction, network: Network, viewTracker: AccountViewTracker, peerId: PeerId, setToValue: Bool? = nil) { guard let peer = transaction.getPeer(peerId) else { return diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Message.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Message.swift index fa8be0fb1a..5c67dd3af7 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Message.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Message.swift @@ -10,9 +10,9 @@ public final class EngineMessage: Equatable { public typealias GlobalTags = GlobalMessageTags public typealias LocalTags = LocalMessageTags public typealias ForwardInfo = MessageForwardInfo - + private let impl: Message - + public var stableId: UInt32 { return self.impl.stableId } @@ -78,6 +78,9 @@ public final class EngineMessage: Equatable { public var associatedMedia: [MediaId: Media] { return self.impl.associatedMedia } + public var associatedThreadInfo: Message.AssociatedThreadInfo? { + return self.impl.associatedThreadInfo + } public var index: MessageIndex { return self.impl.index @@ -104,7 +107,8 @@ public final class EngineMessage: Equatable { peers: [EnginePeer.Id: EnginePeer], associatedMessages: [EngineMessage.Id: EngineMessage], associatedMessageIds: [EngineMessage.Id], - associatedMedia: [MediaId: Media] + associatedMedia: [MediaId: Media], + associatedThreadInfo: Message.AssociatedThreadInfo? ) { var mappedPeers: [PeerId: Peer] = [:] for (id, peer) in peers { @@ -137,7 +141,8 @@ public final class EngineMessage: Equatable { peers: SimpleDictionary(mappedPeers), associatedMessages: SimpleDictionary(mappedAssociatedMessages), associatedMessageIds: associatedMessageIds, - associatedMedia: associatedMedia + associatedMedia: associatedMedia, + associatedThreadInfo: associatedThreadInfo ) } @@ -192,6 +197,9 @@ public final class EngineMessage: Equatable { if !areMediaArraysEqual(lhs.media, rhs.media) { return false } + if lhs.associatedThreadInfo != rhs.associatedThreadInfo { + return false + } return true } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift index 2229234496..93814a4fc5 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SparseMessageList.swift @@ -828,6 +828,7 @@ public final class SparseMessageCalendar { private let queue: Queue private let account: Account private let peerId: PeerId + private let threadId: Int64? private let messageTag: MessageTags private var state: InternalState @@ -845,10 +846,11 @@ public final class SparseMessageCalendar { return self.isLoadingMorePromise.get() } - init(queue: Queue, account: Account, peerId: PeerId, messageTag: MessageTags) { + init(queue: Queue, account: Account, peerId: PeerId, threadId: Int64?, messageTag: MessageTags) { self.queue = queue self.account = account self.peerId = peerId + self.threadId = threadId self.messageTag = messageTag self.state = InternalState(nextRequestOffset: 0, minTimestamp: nil, messagesByDay: [:]) @@ -881,7 +883,7 @@ public final class SparseMessageCalendar { self.statePromise.set(.single(self.state)) - return _internal_clearHistoryInRangeInteractively(postbox: self.account.postbox, peerId: self.peerId, threadId: nil, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type).start(completed: { + return _internal_clearHistoryInRangeInteractively(postbox: self.account.postbox, peerId: self.peerId, threadId: self.threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type).start(completed: { completion() }) } @@ -890,6 +892,9 @@ public final class SparseMessageCalendar { guard let nextRequestOffset = self.state.nextRequestOffset else { return } + if self.threadId != nil { + return + } self.isLoadingMore = true @@ -1011,11 +1016,11 @@ public final class SparseMessageCalendar { public var minTimestamp: Int32? private var disposable: Disposable? - init(account: Account, peerId: PeerId, messageTag: MessageTags) { + init(account: Account, peerId: PeerId, threadId: Int64?, messageTag: MessageTags) { let queue = Queue() self.queue = queue self.impl = QueueLocalObject(queue: queue, generate: { - return Impl(queue: queue, account: account, peerId: peerId, messageTag: messageTag) + return Impl(queue: queue, account: account, peerId: peerId, threadId: threadId, messageTag: messageTag) }) self.disposable = self.state.start(next: { [weak self] state in diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index 579f917963..be02729d5a 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -289,8 +289,8 @@ public extension TelegramEngine { return SparseMessageList(account: self.account, peerId: peerId, threadId: threadId, messageTag: tag) } - public func sparseMessageCalendar(peerId: EnginePeer.Id, tag: EngineMessage.Tags) -> SparseMessageCalendar { - return SparseMessageCalendar(account: self.account, peerId: peerId, messageTag: tag) + public func sparseMessageCalendar(peerId: EnginePeer.Id, threadId: Int64?, tag: EngineMessage.Tags) -> SparseMessageCalendar { + return SparseMessageCalendar(account: self.account, peerId: peerId, threadId: threadId, messageTag: tag) } public func sparseMessageScrollingContext(peerId: EnginePeer.Id) -> SparseMessageScrollingContext { @@ -465,6 +465,13 @@ public extension TelegramEngine { |> ignoreValues } + public func markForumThreadAsRead(peerId: EnginePeer.Id, threadId: Int64) -> Signal { + return self.account.postbox.transaction { transaction -> Void in + _internal_markForumThreadAsReadInteractively(transaction: transaction, network: self.account.network, viewTracker: self.account.viewTracker, peerId: peerId, threadId: threadId) + } + |> ignoreValues + } + public func debugAddHoles() -> Signal { return self.account.postbox.transaction { transaction -> Void in transaction.addHolesEverywhere(peerNamespaces: [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel], holeNamespace: Namespaces.Message.Cloud) diff --git a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift index 8f9686b872..c19bd2855f 100644 --- a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift @@ -209,7 +209,7 @@ func locallyRenderedMessage(message: StoreMessage, peers: [PeerId: Peer]) -> Mes let second = UInt32(hashValue & 0xffffffff) let stableId = first &+ second - return Message(stableId: stableId, stableVersion: 0, id: id, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: message.timestamp, flags: MessageFlags(message.flags), tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: forwardInfo, author: author, text: message.text, attributes: message.attributes, media: message.media, peers: messagePeers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + return Message(stableId: stableId, stableVersion: 0, id: id, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: message.timestamp, flags: MessageFlags(message.flags), tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: forwardInfo, author: author, text: message.text, attributes: message.attributes, media: message.media, peers: messagePeers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) } public extension Message { diff --git a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift index 39a890a310..600caaad12 100644 --- a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift +++ b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift @@ -318,7 +318,7 @@ public func mediaContentKind(_ media: EngineMedia, message: EngineMessage? = nil } case .action: if let message = message, let strings = strings, let nameDisplayOrder = nameDisplayOrder, let accountPeerId = accountPeerId { - return .text(NSAttributedString(string: plainServiceMessageString(strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat ?? PresentationDateTimeFormat(timeFormat: .military, dateFormat: .dayFirst, dateSeparator: ".", dateSuffix: "", requiresFullYear: false, decimalSeparator: ".", groupingSeparator: ""), message: message, accountPeerId: accountPeerId, forChatList: false)?.0 ?? "")) + return .text(NSAttributedString(string: plainServiceMessageString(strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat ?? PresentationDateTimeFormat(timeFormat: .military, dateFormat: .dayFirst, dateSeparator: ".", dateSuffix: "", requiresFullYear: false, decimalSeparator: ".", groupingSeparator: ""), message: message, accountPeerId: accountPeerId, forChatList: false, forForumOverview: false)?.0 ?? "")) } else { return nil } diff --git a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift index 1018b472b9..7a547eea0b 100644 --- a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift +++ b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift @@ -34,8 +34,8 @@ private func peerMentionsAttributes(primaryTextColor: UIColor, peerIds: [(Int, E return result } -public func plainServiceMessageString(strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: EngineMessage, accountPeerId: EnginePeer.Id, forChatList: Bool) -> (text: String, spoilerRanges: [NSRange], customEmojiRanges: [(NSRange, ChatTextInputTextCustomEmojiAttribute)])? { - if let attributedString = universalServiceMessageString(presentationData: nil, strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: message, accountPeerId: accountPeerId, forChatList: forChatList) { +public func plainServiceMessageString(strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: EngineMessage, accountPeerId: EnginePeer.Id, forChatList: Bool, forForumOverview: Bool) -> (text: String, spoilerRanges: [NSRange], customEmojiRanges: [(NSRange, ChatTextInputTextCustomEmojiAttribute)])? { + if let attributedString = universalServiceMessageString(presentationData: nil, strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: message, accountPeerId: accountPeerId, forChatList: forChatList, forForumOverview: forForumOverview) { var ranges: [NSRange] = [] var customEmojiRanges: [(NSRange, ChatTextInputTextCustomEmojiAttribute)] = [] attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length), options: [], using: { attributes, range, _ in @@ -51,7 +51,7 @@ public func plainServiceMessageString(strings: PresentationStrings, nameDisplayO } } -public func universalServiceMessageString(presentationData: (PresentationTheme, TelegramWallpaper)?, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: EngineMessage, accountPeerId: EnginePeer.Id, forChatList: Bool) -> NSAttributedString? { +public func universalServiceMessageString(presentationData: (PresentationTheme, TelegramWallpaper)?, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: EngineMessage, accountPeerId: EnginePeer.Id, forChatList: Bool, forForumOverview: Bool) -> NSAttributedString? { var attributedString: NSAttributedString? let primaryTextColor: UIColor @@ -679,8 +679,13 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, attributes[1] = boldAttributes attributedString = addAttributesToStringWithRanges(strings.Notification_PremiumGift_Sent(authorName, price)._tuple, body: bodyAttributes, argumentAttributes: attributes) } - case .topicCreated: - attributedString = NSAttributedString(string: strings.Notification_TopicCreated, font: titleFont, textColor: primaryTextColor) + case let .topicCreated(title, iconColor, iconFileId): + if forForumOverview { + let maybeFileId = iconFileId ?? 0 + attributedString = addAttributesToStringWithRanges(strings.Notification_OverviewTopicCreated(".", title)._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) + } else { + attributedString = NSAttributedString(string: strings.Notification_TopicCreated, font: titleFont, textColor: primaryTextColor) + } case let .topicEdited(components): if let isClosed = components.compactMap({ item -> Bool? in switch item { @@ -691,10 +696,26 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, } }).first { if case let .user(user) = message.author { - if isClosed { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicClosedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) + if forForumOverview { + var title: String = "" + var iconColor: Int32 = 0 + var maybeFileId: Int64 = 0 + if let info = message.associatedThreadInfo { + iconColor = info.iconColor + title = info.title + maybeFileId = info.icon ?? 0 + } + if isClosed { + attributedString = addAttributesToStringWithRanges(strings.Notification_OverviewTopicClosed(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".", title)._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) + } else { + attributedString = addAttributesToStringWithRanges(strings.Notification_OverviewTopicReopened(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".", title)._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) + } } else { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicReopenedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) + if isClosed { + attributedString = addAttributesToStringWithRanges(strings.Notification_TopicClosedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) + } else { + attributedString = addAttributesToStringWithRanges(strings.Notification_TopicReopenedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) + } } } else { if isClosed { @@ -703,6 +724,33 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, attributedString = NSAttributedString(string: strings.Notification_TopicReopened, font: titleFont, textColor: primaryTextColor) } } + } else if let maybeFileId = components.compactMap({ item -> Int64? in + switch item { + case let .iconFileId(id): + return id ?? 0 + default: + return nil + } + }).first, let title = components.compactMap({ item -> String? in + switch item { + case let .title(title): + return title + default: + return nil + } + }).first { + if case let .user(user) = message.author { + var iconColor: Int32 = 0 + if let info = message.associatedThreadInfo { + iconColor = info.iconColor + } + attributedString = addAttributesToStringWithRanges(strings.Notification_TopicRenamedIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".", title)._tuple, body: bodyAttributes, argumentAttributes: [ + 0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), + 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)]) + ]) + } else { + attributedString = NSAttributedString(string: strings.Notification_TopicRenamed(title).string, font: titleFont, textColor: primaryTextColor) + } } else if let title = components.compactMap({ item -> String? in switch item { case let .title(title): @@ -724,20 +772,16 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, return nil } }).first { - if maybeFileId != 0 { - let bodyAttributes = MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [:]) - - if case let .user(user) = message.author { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".")._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil)])]) - } else { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChanged(".")._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil)])]) - } + var title: String = "" + var iconColor: Int32 = 0 + if let info = message.associatedThreadInfo { + iconColor = info.iconColor + title = info.title + } + if case let .user(user) = message.author { + attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".")._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) } else { - if case let .user(user) = message.author { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconRemovedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) - } else { - attributedString = NSAttributedString(string: strings.Notification_TopicIconRemoved, font: titleFont, textColor: primaryTextColor) - } + attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChanged(".")._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) } } case .unknown: diff --git a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift index aa6d315c0a..a1d8482277 100644 --- a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift +++ b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift @@ -224,67 +224,6 @@ public final class EmojiStatusComponent: Component { iconImage = nil } case let .topic(title, color, realSize): - func generateTopicIcon(backgroundColors: [UIColor], strokeColors: [UIColor]) -> UIImage? { - return generateImage(realSize, rotatedContext: { realSize, context in - context.clear(CGRect(origin: .zero, size: realSize)) - - context.saveGState() - - let size = CGSize(width: 32.0, height: 32.0) - - let scale: CGFloat = realSize.width / size.width - context.scaleBy(x: scale, y: scale) - - context.translateBy(x: size.width / 2.0, y: size.height / 2.0) - context.translateBy(x: -14.0 - UIScreenPixel, y: -14.0 - UIScreenPixel) - - let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") - context.closePath() - context.clip() - - let colorsArray = backgroundColors.map { $0.cgColor } as NSArray - var locations: [CGFloat] = [0.0, 1.0] - let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! - context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) - - context.resetClip() - - let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") - context.closePath() - if let path = context.path { - let strokePath = path.copy(strokingWithWidth: 1.0 + UIScreenPixel, lineCap: .round, lineJoin: .round, miterLimit: 0.0) - context.beginPath() - context.addPath(strokePath) - context.clip() - - let colorsArray = strokeColors.map { $0.cgColor } as NSArray - var locations: [CGFloat] = [0.0, 1.0] - let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! - context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) - } - - context.restoreGState() - - let fontSize = round(15.0 * scale) - - let attributedString = NSAttributedString(string: title, attributes: [NSAttributedString.Key.font: Font.with(size: fontSize, design: .round, weight: .bold), NSAttributedString.Key.foregroundColor: UIColor.white]) - - let line = CTLineCreateWithAttributedString(attributedString) - let lineBounds = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds) - - let lineOffset = CGPoint(x: title == "B" ? 1.0 : 0.0, y: floorToScreenPixels(realSize.height * 0.05)) - let lineOrigin = CGPoint(x: floorToScreenPixels(-lineBounds.origin.x + (realSize.width - lineBounds.size.width) / 2.0) + lineOffset.x, y: floorToScreenPixels(-lineBounds.origin.y + (realSize.height - lineBounds.size.height) / 2.0) + lineOffset.y) - - context.translateBy(x: realSize.width / 2.0, y: realSize.height / 2.0) - context.scaleBy(x: 1.0, y: -1.0) - context.translateBy(x: -realSize.width / 2.0, y: -realSize.height / 2.0) - - context.translateBy(x: lineOrigin.x, y: lineOrigin.y) - CTLineDraw(line, context) - context.translateBy(x: -lineOrigin.x, y: -lineOrigin.y) - }) - } - func generateTopicColors(_ color: Int32) -> ([UInt32], [UInt32]) { return ([0x6FB9F0, 0x0261E4], [0x026CB5, 0x064BB7]) } @@ -299,7 +238,7 @@ public final class EmojiStatusComponent: Component { ] let colors = topicColors[color] ?? generateTopicColors(color) - if let image = generateTopicIcon(backgroundColors: colors.0.map(UIColor.init(rgb:)), strokeColors: colors.1.map(UIColor.init(rgb:))) { + if let image = generateTopicIcon(title: title, backgroundColors: colors.0.map(UIColor.init(rgb:)), strokeColors: colors.1.map(UIColor.init(rgb:)), size: realSize) { iconImage = image } else { iconImage = nil diff --git a/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift b/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift index 5a3b255956..0dca01f208 100644 --- a/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift +++ b/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift @@ -16,6 +16,68 @@ import MultiAnimationRenderer import ShimmerEffect import TextFormat +public func generateTopicIcon(title: String, backgroundColors: [UIColor], strokeColors: [UIColor], size: CGSize) -> UIImage? { + let realSize = size + return generateImage(realSize, rotatedContext: { realSize, context in + context.clear(CGRect(origin: .zero, size: realSize)) + + context.saveGState() + + let size = CGSize(width: 32.0, height: 32.0) + + let scale: CGFloat = realSize.width / size.width + context.scaleBy(x: scale, y: scale) + + context.translateBy(x: size.width / 2.0, y: size.height / 2.0) + context.translateBy(x: -14.0 - UIScreenPixel, y: -14.0 - UIScreenPixel) + + let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") + context.closePath() + context.clip() + + let colorsArray = backgroundColors.map { $0.cgColor } as NSArray + var locations: [CGFloat] = [0.0, 1.0] + let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + + context.resetClip() + + let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") + context.closePath() + if let path = context.path { + let strokePath = path.copy(strokingWithWidth: 1.0 + UIScreenPixel, lineCap: .round, lineJoin: .round, miterLimit: 0.0) + context.beginPath() + context.addPath(strokePath) + context.clip() + + let colorsArray = strokeColors.map { $0.cgColor } as NSArray + var locations: [CGFloat] = [0.0, 1.0] + let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + } + + context.restoreGState() + + let fontSize = round(15.0 * scale) + + let attributedString = NSAttributedString(string: title, attributes: [NSAttributedString.Key.font: Font.with(size: fontSize, design: .round, weight: .bold), NSAttributedString.Key.foregroundColor: UIColor.white]) + + let line = CTLineCreateWithAttributedString(attributedString) + let lineBounds = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds) + + let lineOffset = CGPoint(x: title == "B" ? 1.0 : 0.0, y: floorToScreenPixels(realSize.height * 0.05)) + let lineOrigin = CGPoint(x: floorToScreenPixels(-lineBounds.origin.x + (realSize.width - lineBounds.size.width) / 2.0) + lineOffset.x, y: floorToScreenPixels(-lineBounds.origin.y + (realSize.height - lineBounds.size.height) / 2.0) + lineOffset.y) + + context.translateBy(x: realSize.width / 2.0, y: realSize.height / 2.0) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -realSize.width / 2.0, y: -realSize.height / 2.0) + + context.translateBy(x: lineOrigin.x, y: lineOrigin.y) + CTLineDraw(line, context) + context.translateBy(x: -lineOrigin.x, y: -lineOrigin.y) + }) +} + public enum AnimationCacheAnimationType { case still case lottie @@ -132,7 +194,9 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { super.init() - if let file = file { + if let topicInfo = emoji.topicInfo { + self.updateTopicInfo(topicInfo: topicInfo) + } else if let file = file { self.updateFile(file: file, attemptSynchronousLoad: attemptSynchronousLoad) } else { self.infoDisposable = (context.engine.stickers.resolveInlineStickers(fileIds: [emoji.fileId]) @@ -197,6 +261,26 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { } } + private func updateTopicInfo(topicInfo: EngineMessageHistoryThread.Info) { + func generateTopicColors(_ color: Int32) -> ([UInt32], [UInt32]) { + return ([0x6FB9F0, 0x0261E4], [0x026CB5, 0x064BB7]) + } + + let topicColors: [Int32: ([UInt32], [UInt32])] = [ + 0x6FB9F0: ([0x6FB9F0, 0x0261E4], [0x026CB5, 0x064BB7]), + 0xFFD67E: ([0xFFD67E, 0xFC8601], [0xDA9400, 0xFA5F00]), + 0xCB86DB: ([0xCB86DB, 0x9338AF], [0x812E98, 0x6F2B87]), + 0x8EEE98: ([0x8EEE98, 0x02B504], [0x02A01B, 0x009716]), + 0xFF93B2: ([0xFF93B2, 0xE23264], [0xFC447A, 0xC80C46]), + 0xFB6F5F: ([0xFB6F5F, 0xD72615], [0xDC1908, 0xB61506]) + ] + let colors = topicColors[topicInfo.iconColor] ?? generateTopicColors(topicInfo.iconColor) + + if let image = generateTopicIcon(title: String(topicInfo.title.prefix(1)), backgroundColors: colors.0.map(UIColor.init(rgb:)), strokeColors: colors.1.map(UIColor.init(rgb:)), size: CGSize(width: 32.0, height: 32.0)) { + self.contents = image.cgImage + } + } + private func updateFile(file: TelegramMediaFile, attemptSynchronousLoad: Bool) { if self.file?.fileId == file.fileId { return diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index cdb76f7a90..a94316ab21 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -4268,7 +4268,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G break } - if case .peer = chatLocation, !isScheduledOrPinnedMessages, peerId.namespace != Namespaces.Peer.SecretChat { + if chatLocation.peerId != nil, !isScheduledOrPinnedMessages, peerId.namespace != Namespaces.Peer.SecretChat { let chatLocationContextHolder = self.chatLocationContextHolder hasScheduledMessages = peerView.get() |> take(1) @@ -4801,6 +4801,31 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } + var isScheduledOrPinnedMessages = false + switch subject { + case .scheduledMessages, .pinnedMessages, .forwardedMessages: + isScheduledOrPinnedMessages = true + default: + break + } + + var hasScheduledMessages: Signal = .single(false) + if chatLocation.peerId != nil, !isScheduledOrPinnedMessages, peerId.namespace != Namespaces.Peer.SecretChat { + let chatLocationContextHolder = self.chatLocationContextHolder + hasScheduledMessages = peerView + |> take(1) + |> mapToSignal { view -> Signal in + if let peer = peerViewMainPeer(view) as? TelegramChannel, !peer.hasPermission(.sendMessages) { + return .single(false) + } else { + return context.account.viewTracker.scheduledMessagesViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder)) + |> map { view, _, _ in + return !view.entries.isEmpty + } + } + } + } + var onlineMemberCount: Signal = .single(nil) if peerId.namespace == Namespaces.Peer.CloudChannel { let recentOnlineSignal: Signal = peerView @@ -4838,10 +4863,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.peerDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView, messageAndTopic, - onlineMemberCount + onlineMemberCount, + hasScheduledMessages ) - |> deliverOnMainQueue).start(next: { [weak self] peerView, messageAndTopic, onlineMemberCount in + |> deliverOnMainQueue).start(next: { [weak self] peerView, messageAndTopic, onlineMemberCount, hasScheduledMessages in if let strongSelf = self { + strongSelf.hasScheduledMessages = hasScheduledMessages + let message = messageAndTopic.message var count = 0 @@ -5029,7 +5057,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.updateChatPresentationInterfaceState(animated: animated, interactive: false, { return $0.updatedPeer { _ in return renderedPeer - }.updatedIsNotAccessible(isNotAccessible).updatedContactStatus(contactStatus).updatedHasBots(hasBots).updatedIsArchived(isArchived).updatedPeerIsMuted(peerIsMuted).updatedPeerDiscussionId(peerDiscussionId).updatedPeerGeoLocation(peerGeoLocation).updatedExplicitelyCanPinMessages(explicitelyCanPinMessages).updatedHasScheduledMessages(false).updatedCurrentSendAsPeerId(currentSendAsPeerId) + }.updatedIsNotAccessible(isNotAccessible).updatedContactStatus(contactStatus).updatedHasBots(hasBots).updatedIsArchived(isArchived).updatedPeerIsMuted(peerIsMuted).updatedPeerDiscussionId(peerDiscussionId).updatedPeerGeoLocation(peerGeoLocation).updatedExplicitelyCanPinMessages(explicitelyCanPinMessages).updatedHasScheduledMessages(hasScheduledMessages).updatedCurrentSendAsPeerId(currentSendAsPeerId) .updatedCopyProtectionEnabled(copyProtectionEnabled) }) if !strongSelf.didSetChatLocationInfoReady { @@ -7420,7 +7448,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedForwardOptionsState(f($0.forwardOptionsState ?? ChatInterfaceForwardOptionsState(hideNames: false, hideCaptions: false, unhideNamesOnCaptionChange: false))) }) }) } }, presentForwardOptions: { [weak self] sourceNode in - if let strongSelf = self, case let .peer(peerId) = strongSelf.chatLocation { + if let strongSelf = self, let peerId = strongSelf.chatLocation.peerId { let presentationData = strongSelf.presentationData let forwardOptions: Signal @@ -14469,7 +14497,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } private func openCalendarSearch(timestamp: Int32) { - guard case let .peer(peerId) = self.chatLocation else { + guard let peerId = self.chatLocation.peerId else { return } self.chatDisplayNode.dismissInput() @@ -14484,7 +14512,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let calendarScreen = CalendarMessageScreen( context: self.context, peerId: peerId, - calendarSource: self.context.engine.messages.sparseMessageCalendar(peerId: peerId, tag: .photoOrVideo), + calendarSource: self.context.engine.messages.sparseMessageCalendar(peerId: peerId, threadId: self.chatLocation.threadId, tag: .photoOrVideo), initialTimestamp: initialTimestamp, enableMessageRangeDeletion: enableMessageRangeDeletion, canNavigateToEmptyDays: true, @@ -14784,13 +14812,21 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) } else if case let .peer(peerId) = self.chatLocation, let messageId = messageLocation.messageId, (messageId.peerId != peerId && !forceInCurrentChat) || (isScheduledMessages && messageId.id != 0 && !Namespaces.Message.allScheduled.contains(messageId.namespace)) { - let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in + let _ = (self.context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId), + TelegramEngine.EngineData.Item.Messages.Message(id: messageId) + ) + |> deliverOnMainQueue).start(next: { [weak self] peer, message in guard let self, let peer = peer else { return } if let navigationController = self.effectiveNavigationController { - self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always)) + var chatLocation: NavigateToChatControllerParams.Location = .peer(peer) + if let message = message, let threadId = message.threadId { + chatLocation = .replyThread(ChatReplyThreadMessage(messageId: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId)), channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) + } + + self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: chatLocation, subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always)) } }) } else if forceInCurrentChat { @@ -16994,7 +17030,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } private func presentScheduleTimePicker(style: ChatScheduleTimeControllerStyle = .default, selectedTime: Int32? = nil, dismissByTapOutside: Bool = true, completion: @escaping (Int32) -> Void) { - guard case let .peer(peerId) = self.chatLocation else { + guard let peerId = self.chatLocation.peerId else { return } let _ = (self.context.account.viewTracker.peerView(peerId) diff --git a/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift b/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift index 21dc5eb086..cd7df1e188 100644 --- a/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatEntityKeyboardInputNode.swift @@ -1779,7 +1779,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode { } let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) let gallery = GalleryController(context: strongSelf.context, source: .standaloneMessage(message), streamSingleVideo: true, replaceRootController: { _, _ in }, baseNavigationController: nil) diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 2df95d5687..74cba9b745 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -25,7 +25,8 @@ func chatHistoryEntriesForView( customChannelDiscussionReadState: MessageId?, customThreadOutgoingReadState: MessageId?, cachedData: CachedPeerData?, - adMessages: (interPostInterval: Int32?, messages: [Message]) + adMessages: (interPostInterval: Int32?, messages: [Message]), + dynamicAdMessages: [Message] ) -> [ChatHistoryEntry] { if historyAppearsCleared { return [] @@ -72,7 +73,8 @@ func chatHistoryEntriesForView( peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) } @@ -327,9 +329,17 @@ func chatHistoryEntriesForView( } } } + + if !dynamicAdMessages.isEmpty { + assert(entries.sorted() == entries) + for message in dynamicAdMessages { + entries.append(.MessageEntry(message, presentationData, false, nil, .none, ChatMessageEntryAttributes(rank: nil, isContact: false, contentTypeHint: .generic, updatingMedia: nil, isPlaying: false, isCentered: false))) + } + entries.sort() + } if view.laterId == nil && !view.isLoading { - if !entries.isEmpty, case let .MessageEntry(lastMessage, _, _, _, _, _) = entries[entries.count - 1], !adMessages.messages.isEmpty { + if !entries.isEmpty, case let .MessageEntry(lastMessage, _, _, _, _, _) = entries[entries.count - 1], !adMessages.messages.isEmpty, adMessages.interPostInterval == nil { var nextAdMessageId: Int32 = 1 if let message = adMessages.messages.first { let updatedMessage = Message( @@ -353,7 +363,8 @@ func chatHistoryEntriesForView( peers: message.peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds, - associatedMedia: message.associatedMedia + associatedMedia: message.associatedMedia, + associatedThreadInfo: message.associatedThreadInfo ) nextAdMessageId += 1 entries.append(.MessageEntry(updatedMessage, presentationData, false, nil, .none, ChatMessageEntryAttributes(rank: nil, isContact: false, contentTypeHint: .generic, updatingMedia: nil, isPlaying: false, isCentered: false))) diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 12d8ec9695..0ef1029782 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -506,7 +506,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let prefetchManager: InChatPrefetchManager private var currentEarlierPrefetchMessages: [(Message, Media)] = [] private var currentLaterPrefetchMessages: [(Message, Media)] = [] - private var currentPrefetchDirectionIsToLater: Bool = true + private var currentPrefetchDirectionIsToLater: Bool = false private var maxVisibleMessageIndexReported: MessageIndex? var maxVisibleMessageIndexUpdated: ((MessageIndex) -> Void)? @@ -608,6 +608,17 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { private let adMessagesContext: AdMessagesHistoryContext? private var preloadAdPeerId: PeerId? private let preloadAdPeerDisposable = MetaDisposable() + private var pendingDynamicAdMessages: [Message] = [] + private var pendingDynamicAdMessageInterval: Int? + private var remainingDynamicAdMessageInterval: Int? + private var nextPendingDynamicMessageId: Int32 = 1 + private var dynamicAdMessages: ([Message], Int) = ([], 0) { + didSet { + self.dynamicAdMessagesPromise.set(.single(self.dynamicAdMessages)) + } + } + private let dynamicAdMessagesPromise = Promise<([Message], Int)>(([], 0)) + private var seenMessageIds = Set() private var refreshDisplayedItemRangeTimer: SwiftSignalKit.Timer? @@ -681,18 +692,25 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { guard let strongSelf = self else { return } - var adPeerId: PeerId? - adPeerId = messages.first?.author?.id - - if strongSelf.preloadAdPeerId != adPeerId { - strongSelf.preloadAdPeerId = adPeerId - if let adPeerId = adPeerId { - let combinedDisposable = DisposableSet() - strongSelf.preloadAdPeerDisposable.set(combinedDisposable) - combinedDisposable.add(strongSelf.context.account.viewTracker.polledChannel(peerId: adPeerId).start()) - combinedDisposable.add(strongSelf.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId)) - } else { - strongSelf.preloadAdPeerDisposable.set(nil) + + if let interPostInterval = interPostInterval { + strongSelf.pendingDynamicAdMessages = messages + strongSelf.pendingDynamicAdMessageInterval = Int(interPostInterval) + strongSelf.remainingDynamicAdMessageInterval = Int(interPostInterval) + } else { + var adPeerId: PeerId? + adPeerId = messages.first?.author?.id + + if strongSelf.preloadAdPeerId != adPeerId { + strongSelf.preloadAdPeerId = adPeerId + if let adPeerId = adPeerId { + let combinedDisposable = DisposableSet() + strongSelf.preloadAdPeerDisposable.set(combinedDisposable) + combinedDisposable.add(strongSelf.context.account.viewTracker.polledChannel(peerId: adPeerId).start()) + combinedDisposable.add(strongSelf.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId)) + } else { + strongSelf.preloadAdPeerDisposable.set(nil) + } } } } @@ -882,7 +900,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } } - let previousView = Atomic<(ChatHistoryView, Int, Set?)?>(value: nil) + let previousView = Atomic<(ChatHistoryView, Int, Set?, Int)?>(value: nil) let automaticDownloadNetworkType = context.account.networkType |> map { type -> MediaAutoDownloadNetworkType in switch type { @@ -1084,8 +1102,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { accountPeer, audioTranscriptionSuggestion, promises, - topicAuthorId - ).start(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, adMessages, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId in + topicAuthorId, + self.dynamicAdMessagesPromise.get() + ).start(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, adMessages, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, dynamicAdMessages in let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId) = promises let currentlyPlayingMessageId = currentlyPlayingMessageIdAndType?.0 @@ -1246,11 +1265,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { customChannelDiscussionReadState: customChannelDiscussionReadState, customThreadOutgoingReadState: customThreadOutgoingReadState, cachedData: data.cachedData, - adMessages: adMessages + adMessages: adMessages, + dynamicAdMessages: dynamicAdMessages.0 ) let lastHeaderId = filteredEntries.last.flatMap { listMessageDateHeaderId(timestamp: $0.index.timestamp) } ?? 0 let processedView = ChatHistoryView(originalView: view, filteredEntries: filteredEntries, associatedData: associatedData, lastHeaderId: lastHeaderId, id: id, locationInput: update.2, ignoreMessagesInTimestampRange: update.3) - let previousValueAndVersion = previousView.swap((processedView, update.1, selectedMessages)) + let previousValueAndVersion = previousView.swap((processedView, update.1, selectedMessages, dynamicAdMessages.1)) let previous = previousValueAndVersion?.0 let previousSelectedMessages = previousValueAndVersion?.2 @@ -1274,7 +1294,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } } - let reason: ChatHistoryViewTransitionReason + var reason: ChatHistoryViewTransitionReason let previousHistoryAppearsClearedValue = previousHistoryAppearsCleared.swap(historyAppearsCleared) if previousHistoryAppearsClearedValue != nil && previousHistoryAppearsClearedValue != historyAppearsCleared && !historyAppearsCleared { @@ -1300,6 +1320,15 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } } + var disableAnimations = false + var forceSynchronous = false + + if let previousValueAndVersion = previousValueAndVersion, dynamicAdMessages.1 != previousValueAndVersion.3 { + reason = ChatHistoryViewTransitionReason.Reload + disableAnimations = true + forceSynchronous = true + } + var scrollAnimationCurve: ListViewAnimationCurve? = nil if let strongSelf = self, case .default = source { if strongSelf.appliedScrollToMessageId == nil, let scrollToMessageId = scrollToMessageId { @@ -1322,8 +1351,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { isFirstTime = false } - var disableAnimations = false - if let strongSelf = self, updatedScrollPosition == nil, case .InteractiveChanges = reason, case let .known(offset) = strongSelf.visibleContentOffset(), abs(offset) <= 0.9, let previous = previous { var fillsScreen = true switch strongSelf.visibleBottomContentOffset() { @@ -1378,6 +1405,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { mappedTransition.options.remove(.AnimateTopItemPosition) mappedTransition.options.remove(.RequestItemInsertionAnimations) } + if forceSynchronous { + mappedTransition.options.insert(.Synchronous) + } Queue.mainQueue().async { guard let strongSelf = self else { @@ -1808,6 +1838,95 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { }) } + private func maybeInsertPendingAdMessage(historyView: ChatHistoryView, toLaterRange: (Int, Int), toEarlierRange: (Int, Int)) { + if self.pendingDynamicAdMessages.isEmpty { + return + } + + let selectedRange: (Int, Int) + if self.currentPrefetchDirectionIsToLater { + selectedRange = (toLaterRange.0 + 1, toLaterRange.1) + } else { + selectedRange = (toEarlierRange.0, toEarlierRange.1 - 1) + } + + if selectedRange.0 <= selectedRange.1 { + var insertionTimestamp: Int32? + if self.currentPrefetchDirectionIsToLater { + outer: for i in selectedRange.0 ... selectedRange.1 { + switch historyView.filteredEntries[i] { + case let .MessageEntry(message, _, _, _, _, _): + if message.id.namespace == Namespaces.Message.Cloud { + insertionTimestamp = message.timestamp + break outer + } + case let .MessageGroupEntry(_, messages, _): + for (message, _, _, _, _) in messages { + if message.id.namespace == Namespaces.Message.Cloud { + insertionTimestamp = message.timestamp + break outer + } + } + default: + break + } + } + } else { + outer: for i in (selectedRange.0 ... selectedRange.1).reversed() { + switch historyView.filteredEntries[i] { + case let .MessageEntry(message, _, _, _, _, _): + if message.id.namespace == Namespaces.Message.Cloud { + insertionTimestamp = message.timestamp + break outer + } + case let .MessageGroupEntry(_, messages, _): + for (message, _, _, _, _) in messages { + if message.id.namespace == Namespaces.Message.Cloud { + insertionTimestamp = message.timestamp + break outer + } + } + default: + break + } + } + } + if let insertionTimestamp = insertionTimestamp { + let initialMessage = self.pendingDynamicAdMessages.removeFirst() + let message = Message( + stableId: UInt32.max - 1 - UInt32(self.nextPendingDynamicMessageId), + stableVersion: 1, + id: MessageId(peerId: initialMessage.id.peerId, namespace: initialMessage.id.namespace, id: self.nextPendingDynamicMessageId), + globallyUniqueId: nil, + groupingKey: nil, + groupInfo: nil, + threadId: nil, + timestamp: insertionTimestamp, + flags: initialMessage.flags, + tags: initialMessage.tags, + globalTags: initialMessage.globalTags, + localTags: initialMessage.localTags, + forwardInfo: initialMessage.forwardInfo, + author: initialMessage.author, + text: initialMessage.text, + attributes: initialMessage.attributes, + media: initialMessage.media, + peers: initialMessage.peers, + associatedMessages: initialMessage.associatedMessages, + associatedMessageIds: initialMessage.associatedMessageIds, + associatedMedia: initialMessage.associatedMedia, + associatedThreadInfo: initialMessage.associatedThreadInfo + ) + self.nextPendingDynamicMessageId += 1 + + var dynamicAdMessages = self.dynamicAdMessages + dynamicAdMessages.0.append(message) + dynamicAdMessages.1 += 1 + self.dynamicAdMessages = dynamicAdMessages + } + } + } + private func processDisplayedItemRangeChanged(displayedRange: ListViewDisplayedItemRange, transactionState: ChatHistoryTransactionOpaqueState) { let historyView = transactionState.historyView var isTopReplyThreadMessageShownValue = false @@ -1833,6 +1952,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var messageIdsWithUnseenReactions: [MessageId] = [] var messageIdsWithInactiveExtendedMedia = Set() var downloadableResourceIds: [(messageId: MessageId, resourceId: String)] = [] + var allVisibleAnchorMessageIds: [MessageId] = [] if indexRange.0 <= indexRange.1 { for i in (indexRange.0 ... indexRange.1) { @@ -1923,6 +2043,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } else { topVisibleMessageRange = ChatTopVisibleMessageRange(lowerBound: message.index, upperBound: message.index, isLast: i == historyView.filteredEntries.count - 1) } + if message.id.namespace == Namespaces.Message.Cloud, self.remainingDynamicAdMessageInterval != nil { + allVisibleAnchorMessageIds.append(message.id) + } case let .MessageGroupEntry(_, messages, _): for (message, _, _, _, _) in messages { var hasUnconsumedMention = false @@ -1974,6 +2097,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { topVisibleMessageRange = ChatTopVisibleMessageRange(lowerBound: message.index, upperBound: message.index, isLast: i == historyView.filteredEntries.count - 1) } } + if let message = messages.first { + if message.0.id.namespace == Namespaces.Message.Cloud, self.remainingDynamicAdMessageInterval != nil { + allVisibleAnchorMessageIds.append(message.0.id) + } + } default: break } @@ -2143,6 +2271,24 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { self.maxVisibleMessageIndexUpdated?(maxOverallIndex) } } + + if let visible = displayedRange.visibleRange { + let indexRange = (historyView.filteredEntries.count - 1 - visible.lastIndex, historyView.filteredEntries.count - 1 - visible.firstIndex) + if indexRange.0 <= indexRange.1 { + for messageId in allVisibleAnchorMessageIds { + //TODO:loc optimize eviction + if self.seenMessageIds.insert(messageId).inserted, let remainingDynamicAdMessageIntervalValue = self.remainingDynamicAdMessageInterval { + let pendingInterval = remainingDynamicAdMessageIntervalValue - 1 + if pendingInterval <= 0 { + self.remainingDynamicAdMessageInterval = self.pendingDynamicAdMessageInterval + self.maybeInsertPendingAdMessage(historyView: historyView, toLaterRange: toLaterRange, toEarlierRange: toEarlierRange) + } else { + self.remainingDynamicAdMessageInterval = pendingInterval + } + } + } + } + } } self.isTopReplyThreadMessageShown.set(isTopReplyThreadMessageShownValue) self.topVisibleMessageRange.set(topVisibleMessageRange) diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index cca0a9497a..9910024c28 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -1456,7 +1456,7 @@ final class ChatMediaInputNode: ChatInputNode { } let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) let gallery = GalleryController(context: strongSelf.context, source: .standaloneMessage(message), streamSingleVideo: true, replaceRootController: { _, _ in }, baseNavigationController: nil) diff --git a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift index 6e7737bed9..b542bbedfe 100644 --- a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift @@ -20,8 +20,8 @@ import WallpaperBackgroundNode import InvisibleInkDustNode import TextNodeWithEntities -private func attributedServiceMessageString(theme: ChatPresentationThemeData, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: Message, accountPeerId: PeerId) -> NSAttributedString? { - return universalServiceMessageString(presentationData: (theme.theme, theme.wallpaper), strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: EngineMessage(message), accountPeerId: accountPeerId, forChatList: false) +private func attributedServiceMessageString(theme: ChatPresentationThemeData, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: Message, accountPeerId: PeerId, forForumOverview: Bool) -> NSAttributedString? { + return universalServiceMessageString(presentationData: (theme.theme, theme.wallpaper), strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: EngineMessage(message), accountPeerId: accountPeerId, forChatList: false, forForumOverview: forForumOverview) } class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { @@ -159,7 +159,12 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { let backgroundImage = PresentationResourcesChat.chatActionPhotoBackgroundImage(item.presentationData.theme.theme, wallpaper: !item.presentationData.theme.wallpaper.isEmpty) return (contentProperties, nil, CGFloat.greatestFiniteMagnitude, { constrainedSize, position in - let attributedString = attributedServiceMessageString(theme: item.presentationData.theme, strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, dateTimeFormat: item.presentationData.dateTimeFormat, message: item.message, accountPeerId: item.context.account.peerId) + var forForumOverview = false + if item.chatLocation.threadId == nil { + forForumOverview = true + } + + let attributedString = attributedServiceMessageString(theme: item.presentationData.theme, strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, dateTimeFormat: item.presentationData.dateTimeFormat, message: item.message, accountPeerId: item.context.account.peerId, forForumOverview: forForumOverview) var image: TelegramMediaImage? for media in item.message.media { diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index ded4ba96e5..468b75054a 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -1161,8 +1161,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { viaBotApply = viaBotLayout(TextNodeLayoutArguments(attributedString: botString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(0, availableContentWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) } } + if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId { + } else if let threadId = item.message.threadId, Int64(replyAttribute.messageId.id) == threadId, let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum) { } else { replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( presentationData: item.presentationData, diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 0390c00975..41a063a254 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -1426,6 +1426,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } else if let attribute = attribute as? ReplyMessageAttribute { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == attribute.messageId { + } else if let threadId = firstMessage.threadId, Int64(attribute.messageId.id) == threadId, let channel = firstMessage.peers[firstMessage.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum) { } else { replyMessage = firstMessage.associatedMessages[attribute.messageId] } diff --git a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift index d64cc9e5b1..828b3a8e8d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift @@ -18,7 +18,7 @@ import AnimatedStickerNode import TelegramAnimatedStickerNode private func attributedServiceMessageString(theme: ChatPresentationThemeData, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, message: Message, accountPeerId: PeerId) -> NSAttributedString? { - return universalServiceMessageString(presentationData: (theme.theme, theme.wallpaper), strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: EngineMessage(message), accountPeerId: accountPeerId, forChatList: false) + return universalServiceMessageString(presentationData: (theme.theme, theme.wallpaper), strings: strings, nameDisplayOrder: nameDisplayOrder, dateTimeFormat: dateTimeFormat, message: EngineMessage(message), accountPeerId: accountPeerId, forChatList: false, forForumOverview: false) } class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 3f45d85c54..110178d951 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -605,8 +605,10 @@ class ChatMessageStickerItemNode: ChatMessageItemView { viaBotApply = viaBotLayout(TextNodeLayoutArguments(attributedString: botString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(0, availableWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) } } + if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId { + } else if let threadId = item.message.threadId, Int64(replyAttribute.messageId.id) == threadId, let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum) { } else { replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( presentationData: item.presentationData, diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift index 25e009fcfa..f93677edd6 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift @@ -113,7 +113,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { peers[peer.id] = peer let action = TelegramMediaActionType.titleUpdated(title: new) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .changeAbout(prev, new): var peers = SimpleDictionary() @@ -144,14 +144,14 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: let peers = SimpleDictionary() let attributes: [MessageAttribute] = [] - let prevMessage = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prev, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let prevMessage = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prev, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: new, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: new, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousDescription(prevMessage) : nil) } case let .changeUsername(prev, new): @@ -182,7 +182,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) } let action: TelegramMediaActionType = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: var previousAttributes: [MessageAttribute] = [] @@ -200,8 +200,8 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { attributes.append(TextEntitiesMessageAttribute(entities: [MessageTextEntity(range: 0 ..< text.count, type: .Italic)])) } - let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil) } case let .changeUsernames(prev, new): @@ -232,7 +232,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) } let action: TelegramMediaActionType = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: var previousAttributes: [MessageAttribute] = [] @@ -269,8 +269,8 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { attributes.append(TextEntitiesMessageAttribute(entities: [MessageTextEntity(range: 0 ..< text.count, type: .Italic)])) } - let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil) } case let .changePhoto(_, new): @@ -289,7 +289,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.photoUpdated(image: photo) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .toggleInvites(value): var peers = SimpleDictionary() @@ -316,7 +316,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .toggleSignatures(value): var peers = SimpleDictionary() @@ -343,7 +343,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .updatePinned(message): switch self.id.contentIndex { @@ -374,7 +374,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: if let message = message { @@ -392,7 +392,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) } else { var peers = SimpleDictionary() @@ -414,7 +414,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 0), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 0), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) } } @@ -459,7 +459,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: var peers = SimpleDictionary() @@ -476,7 +476,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil) } case let .deleteMessage(message): @@ -502,7 +502,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: var peers = SimpleDictionary() @@ -526,7 +526,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) } case .participantJoin, .participantLeave: @@ -544,7 +544,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } else { action = TelegramMediaActionType.removedMembers(peerIds: [self.entry.event.peerId]) } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .participantInvite(participant): var peers = SimpleDictionary() @@ -561,7 +561,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action: TelegramMediaActionType action = TelegramMediaActionType.addedMembers(peerIds: [participant.peer.id]) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .participantToggleBan(prev, new): var peers = SimpleDictionary() @@ -692,7 +692,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .participantToggleAdmin(prev, new): var peers = SimpleDictionary() @@ -926,7 +926,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .changeStickerPack(_, new): var peers = SimpleDictionary() @@ -955,7 +955,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .togglePreHistoryHidden(value): var peers = SimpleDictionary() @@ -985,7 +985,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .updateDefaultBannedRights(prev, new): var peers = SimpleDictionary() @@ -1044,7 +1044,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .pollStopped(message): switch self.id.contentIndex { @@ -1072,7 +1072,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: var peers = SimpleDictionary() @@ -1089,7 +1089,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: nil) } case let .linkedPeerUpdated(previous, updated): @@ -1145,7 +1145,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .changeGeoLocation(_, updated): var peers = SimpleDictionary() @@ -1167,12 +1167,12 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let mediaMap = TelegramMediaMap(latitude: updated.latitude, longitude: updated.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: [], media: [mediaMap], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: [], media: [mediaMap], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) } else { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) } case let .updateSlowmode(_, newValue): @@ -1203,7 +1203,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .startGroupCall, .endGroupCall: var peers = SimpleDictionary() @@ -1240,7 +1240,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .groupCallUpdateParticipantMuteStatus(participantId, isMuted): var peers = SimpleDictionary() @@ -1274,7 +1274,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .updateGroupCallSettings(joinMuted): var peers = SimpleDictionary() @@ -1303,7 +1303,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .groupCallUpdateParticipantVolume(participantId, volume): var peers = SimpleDictionary() @@ -1334,7 +1334,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .deleteExportedInvitation(invite): var peers = SimpleDictionary() @@ -1360,7 +1360,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .revokeExportedInvitation(invite): var peers = SimpleDictionary() @@ -1386,7 +1386,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .editExportedInvitation(_, updatedInvite): var peers = SimpleDictionary() @@ -1412,7 +1412,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .participantJoinedViaInvite(invite): var peers = SimpleDictionary() @@ -1438,7 +1438,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .changeHistoryTTL(_, updatedValue): var peers = SimpleDictionary() @@ -1469,7 +1469,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .changeAvailableReactions(_, updatedValue): var peers = SimpleDictionary() @@ -1511,7 +1511,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .changeTheme(_, updatedValue): var peers = SimpleDictionary() @@ -1542,7 +1542,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .participantJoinByRequest(invite, approvedBy): var peers = SimpleDictionary() @@ -1582,7 +1582,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .toggleCopyProtection(value): var peers = SimpleDictionary() @@ -1609,7 +1609,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .sendMessage(message): switch self.id.contentIndex { @@ -1634,7 +1634,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case .content: var peers = SimpleDictionary() @@ -1651,7 +1651,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } } } - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) } case let .createTopic(info): @@ -1671,7 +1671,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { return [] }, to: &text, entities: &entities) let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .deleteTopic(info): var peers = SimpleDictionary() @@ -1692,7 +1692,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .editTopic(prevInfo, newInfo): var peers = SimpleDictionary() @@ -1764,7 +1764,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .pinTopic(prevInfo, newInfo): var peers = SimpleDictionary() @@ -1802,7 +1802,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { } let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) case let .toggleForum(isForum): var peers = SimpleDictionary() @@ -1823,7 +1823,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) let action = TelegramMediaActionType.customText(text: text, entities: entities) - let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)) } } diff --git a/submodules/TelegramUI/Sources/NavigateToChatController.swift b/submodules/TelegramUI/Sources/NavigateToChatController.swift index 5c0dab0aa8..95a2486031 100644 --- a/submodules/TelegramUI/Sources/NavigateToChatController.swift +++ b/submodules/TelegramUI/Sources/NavigateToChatController.swift @@ -19,12 +19,22 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam for controller in params.navigationController.viewControllers.reversed() { if let controller = controller as? ChatListControllerImpl, case let .forum(peerId) = controller.location, peer.id == peerId { let _ = params.navigationController.popToViewController(controller, animated: params.animated) + if let activateMessageSearch = params.activateMessageSearch { + controller.activateSearch(query: activateMessageSearch.1) + } return } } let controller = ChatListControllerImpl(context: params.context, location: .forum(peerId: peer.id), controlsHistoryPreload: false, enableDebugActions: false) - params.navigationController.pushViewController(controller) + + let activateMessageSearch = params.activateMessageSearch + params.navigationController.pushViewController(controller, completion: { [weak controller] in + guard let controller, let activateMessageSearch else { + return + } + controller.activateSearch(query: activateMessageSearch.1) + }) return } diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift index 842c815df8..af86cf906e 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift @@ -1255,7 +1255,8 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding, ListShimme peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) let messageItem = ListMessageItem( presentationData: self.chatPresentationData, @@ -1733,7 +1734,7 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro if threadId == nil { switch contentType { case .photoOrVideo, .photo, .video: - self.calendarSource = self.context.engine.messages.sparseMessageCalendar(peerId: self.peerId, tag: tagMaskForType(self.contentType)) + self.calendarSource = self.context.engine.messages.sparseMessageCalendar(peerId: self.peerId, threadId: threadId, tag: tagMaskForType(self.contentType)) default: self.calendarSource = nil } @@ -2453,7 +2454,8 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], - associatedMedia: [:] + associatedMedia: [:], + associatedThreadInfo: nil ) let messageItem = ListMessageItem( presentationData: self.itemGridBinding.chatPresentationData, diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 8c0fd71bfd..b99bca27ad 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -3514,7 +3514,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate } } - if let channel = data.peer as? TelegramChannel, channel.flags.contains(.isForum) { + if let channel = data.peer as? TelegramChannel, channel.flags.contains(.isForum), self.chatLocation.threadId == nil { if self.forumTopicNotificationExceptionsDisposable == nil { self.forumTopicNotificationExceptionsDisposable = (self.context.engine.peers.forumChannelTopicNotificationExceptions(id: channel.id) |> deliverOnMainQueue).start(next: { [weak self] list in @@ -6180,7 +6180,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate }, openPeer: { _ in }, showAll: false) - let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer, text: "", attributes: [], media: [map], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer, text: "", attributes: [], media: [map], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) let controller = LocationViewController(context: context, updatedPresentationData: self.controller?.updatedPresentationData, subject: message, params: controllerParams) self.controller?.push(controller) diff --git a/submodules/TextFormat/Sources/ChatTextInputAttributes.swift b/submodules/TextFormat/Sources/ChatTextInputAttributes.swift index b940175bf7..6bca8ae0b1 100644 --- a/submodules/TextFormat/Sources/ChatTextInputAttributes.swift +++ b/submodules/TextFormat/Sources/ChatTextInputAttributes.swift @@ -195,12 +195,14 @@ public final class ChatTextInputTextUrlAttribute: NSObject { public final class ChatTextInputTextCustomEmojiAttribute: NSObject { public let interactivelySelectedFromPackId: ItemCollectionId? public let fileId: Int64 + public let topicInfo: EngineMessageHistoryThread.Info? public let file: TelegramMediaFile? - public init(interactivelySelectedFromPackId: ItemCollectionId?, fileId: Int64, file: TelegramMediaFile?) { + public init(interactivelySelectedFromPackId: ItemCollectionId?, fileId: Int64, file: TelegramMediaFile?, topicInfo: EngineMessageHistoryThread.Info? = nil) { self.interactivelySelectedFromPackId = interactivelySelectedFromPackId self.fileId = fileId self.file = file + self.topicInfo = topicInfo super.init() } From efe0566b797db8ba58e5146ce1d3d21f9b23003f Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 1 Nov 2022 15:17:08 +0400 Subject: [PATCH 2/9] Better history-ad integration --- submodules/Postbox/Sources/Message.swift | 4 + .../TelegramUI/Sources/ChatController.swift | 30 +++- .../Sources/ChatControllerInteraction.swift | 3 + .../Sources/ChatHistoryEntriesForView.swift | 60 ++++--- .../Sources/ChatHistoryListNode.swift | 153 +++++++++++------- .../Sources/ChatHistoryViewForLocation.swift | 10 +- .../Sources/ChatMessageDateHeader.swift | 22 ++- .../ChatMessageWebpageBubbleContentNode.swift | 24 +-- .../ChatRecentActionsControllerNode.swift | 1 + .../Sources/DrawingStickersScreen.swift | 1 + .../OverlayAudioPlayerControllerNode.swift | 1 + .../Sources/PeerInfo/PeerInfoScreen.swift | 1 + .../Sources/SharedAccountContext.swift | 1 + .../Sources/OngoingCallThreadLocalContext.mm | 4 +- submodules/TgVoipWebrtc/tgcalls | 2 +- 15 files changed, 186 insertions(+), 131 deletions(-) diff --git a/submodules/Postbox/Sources/Message.swift b/submodules/Postbox/Sources/Message.swift index bed76188af..90de067a6b 100644 --- a/submodules/Postbox/Sources/Message.swift +++ b/submodules/Postbox/Sources/Message.swift @@ -689,6 +689,10 @@ public final class Message { self.associatedThreadInfo = associatedThreadInfo } + public func withUpdatedStableVersion(stableVersion: UInt32) -> Message { + return Message(stableId: self.stableId, stableVersion: stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) + } + public func withUpdatedText(_ text: String) -> Message { return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, forwardInfo: self.forwardInfo, author: self.author, text: text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo) } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index a94316ab21..bb1d8f7c5a 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -4038,6 +4038,32 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G })], parseMarkdown: true), in: .window(.root), with: nil) } }) + }, activateAdAction: { [weak self] messageId in + guard let self, let message = self.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId), let adAttribute = message.adAttribute else { + return + } + + switch adAttribute.target { + case let .peer(id, messageId, startParam): + let navigationData: ChatControllerInteractionNavigateToPeer + if let bot = message.author as? TelegramUser, bot.botInfo != nil, let startParam = startParam { + navigationData = .withBotStartPayload(ChatControllerInitialBotStart(payload: startParam, behavior: .interactive)) + } else { + var subject: ChatControllerSubject? + if let messageId = messageId { + subject = .message(id: .id(messageId), highlight: true, timecode: nil) + } + navigationData = .chat(textInputState: nil, subject: subject, peekData: nil) + } + let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: id)) + |> deliverOnMainQueue).start(next: { [weak self] peer in + if let self, let peer = peer { + self.openPeer(peer: peer, navigation: navigationData, fromMessage: nil) + } + }) + case let .join(_, joinHash): + self.controllerInteraction?.openJoinLink(joinHash) + } }, requestMessageUpdate: { [weak self] id, scroll in if let strongSelf = self { strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id, andScrollToItem: scroll) @@ -6554,13 +6580,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G var minOffsetForNavigation: CGFloat = 40.0 strongSelf.chatDisplayNode.historyNode.enumerateItemNodes { itemNode in if let itemNode = itemNode as? ChatMessageBubbleItemNode { - if let message = itemNode.item?.content.firstMessage, message.adAttribute != nil { + if let message = itemNode.item?.content.firstMessage, let adAttribute = message.adAttribute { minOffsetForNavigation += itemNode.bounds.height switch offset { case let .known(offset): if offset <= 50.0 { - strongSelf.chatDisplayNode.historyNode.adSeenProcessingManager.add([message.id]) + strongSelf.chatDisplayNode.historyNode.markAdAsSeen(opaqueId: adAttribute.opaqueId) } default: break diff --git a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift index 09c0f070a1..26fed4917d 100644 --- a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift @@ -141,6 +141,7 @@ public final class ChatControllerInteraction { let openLargeEmojiInfo: (String, String?, TelegramMediaFile) -> Void let openJoinLink: (String) -> Void let openWebView: (String, String, Bool, Bool) -> Void + let activateAdAction: (EngineMessage.Id) -> Void let requestMessageUpdate: (MessageId, Bool) -> Void let cancelInteractiveKeyboardGestures: () -> Void @@ -248,6 +249,7 @@ public final class ChatControllerInteraction { openLargeEmojiInfo: @escaping (String, String?, TelegramMediaFile) -> Void, openJoinLink: @escaping (String) -> Void, openWebView: @escaping (String, String, Bool, Bool) -> Void, + activateAdAction: @escaping (EngineMessage.Id) -> Void, requestMessageUpdate: @escaping (MessageId, Bool) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, dismissTextInput: @escaping () -> Void, @@ -338,6 +340,7 @@ public final class ChatControllerInteraction { self.openLargeEmojiInfo = openLargeEmojiInfo self.openJoinLink = openJoinLink self.openWebView = openWebView + self.activateAdAction = activateAdAction self.requestMessageUpdate = requestMessageUpdate self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures self.dismissTextInput = dismissTextInput diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 74cba9b745..e8845b4aa9 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -25,7 +25,7 @@ func chatHistoryEntriesForView( customChannelDiscussionReadState: MessageId?, customThreadOutgoingReadState: MessageId?, cachedData: CachedPeerData?, - adMessages: (interPostInterval: Int32?, messages: [Message]), + adMessage: Message?, dynamicAdMessages: [Message] ) -> [ChatHistoryEntry] { if historyAppearsCleared { @@ -339,36 +339,34 @@ func chatHistoryEntriesForView( } if view.laterId == nil && !view.isLoading { - if !entries.isEmpty, case let .MessageEntry(lastMessage, _, _, _, _, _) = entries[entries.count - 1], !adMessages.messages.isEmpty, adMessages.interPostInterval == nil { - var nextAdMessageId: Int32 = 1 - if let message = adMessages.messages.first { - let updatedMessage = Message( - stableId: UInt32.max - 1 - UInt32(nextAdMessageId), - stableVersion: message.stableVersion, - id: MessageId(peerId: message.id.peerId, namespace: message.id.namespace, id: nextAdMessageId), - globallyUniqueId: nil, - groupingKey: nil, - groupInfo: nil, - threadId: nil, - timestamp: lastMessage.timestamp, - flags: message.flags, - tags: message.tags, - globalTags: message.globalTags, - localTags: message.localTags, - forwardInfo: message.forwardInfo, - author: message.author, - text: message.text, - attributes: message.attributes, - media: message.media, - peers: message.peers, - associatedMessages: message.associatedMessages, - associatedMessageIds: message.associatedMessageIds, - associatedMedia: message.associatedMedia, - associatedThreadInfo: message.associatedThreadInfo - ) - nextAdMessageId += 1 - entries.append(.MessageEntry(updatedMessage, presentationData, false, nil, .none, ChatMessageEntryAttributes(rank: nil, isContact: false, contentTypeHint: .generic, updatingMedia: nil, isPlaying: false, isCentered: false))) - } + if !entries.isEmpty, case let .MessageEntry(lastMessage, _, _, _, _, _) = entries[entries.count - 1], let message = adMessage { + var nextAdMessageId: Int32 = 10000 + let updatedMessage = Message( + stableId: ChatHistoryListNode.fixedAdMessageStableId, + stableVersion: message.stableVersion, + id: MessageId(peerId: message.id.peerId, namespace: message.id.namespace, id: nextAdMessageId), + globallyUniqueId: nil, + groupingKey: nil, + groupInfo: nil, + threadId: nil, + timestamp: lastMessage.timestamp, + flags: message.flags, + tags: message.tags, + globalTags: message.globalTags, + localTags: message.localTags, + forwardInfo: message.forwardInfo, + author: message.author, + text: /*"\(message.adAttribute!.opaqueId.hashValue)" + */message.text, + attributes: message.attributes, + media: message.media, + peers: message.peers, + associatedMessages: message.associatedMessages, + associatedMessageIds: message.associatedMessageIds, + associatedMedia: message.associatedMedia, + associatedThreadInfo: message.associatedThreadInfo + ) + nextAdMessageId += 1 + entries.append(.MessageEntry(updatedMessage, presentationData, false, nil, .none, ChatMessageEntryAttributes(rank: nil, isContact: false, contentTypeHint: .generic, updatingMedia: nil, isPlaying: false, isCentered: false))) } } } else if includeSearchEntry { diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 0ef1029782..be1dcf86e8 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -408,6 +408,8 @@ public enum ChatHistoryListSource { } public final class ChatHistoryListNode: ListView, ChatHistoryNode { + static let fixedAdMessageStableId: UInt32 = UInt32.max - 5000 + private let context: AccountContext private let chatLocation: ChatLocation private let chatLocationContextHolder: Atomic @@ -495,7 +497,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { private let messageProcessingManager = ChatMessageThrottledProcessingManager() private let messageWithReactionsProcessingManager = ChatMessageThrottledProcessingManager(submitInterval: 4.0) - let adSeenProcessingManager = ChatMessageThrottledProcessingManager() private let seenLiveLocationProcessingManager = ChatMessageThrottledProcessingManager() private let unsupportedMessageProcessingManager = ChatMessageThrottledProcessingManager() private let refreshMediaProcessingManager = ChatMessageThrottledProcessingManager() @@ -606,18 +607,20 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { private var contentInsetAnimator: DisplayLinkAnimator? private let adMessagesContext: AdMessagesHistoryContext? + private var adMessagesDisposable: Disposable? private var preloadAdPeerId: PeerId? private let preloadAdPeerDisposable = MetaDisposable() private var pendingDynamicAdMessages: [Message] = [] private var pendingDynamicAdMessageInterval: Int? private var remainingDynamicAdMessageInterval: Int? + private var remainingDynamicAdMessageDistance: CGFloat? private var nextPendingDynamicMessageId: Int32 = 1 - private var dynamicAdMessages: ([Message], Int) = ([], 0) { + private var allAdMessages: (fixed: Message?, opportunistic: [Message], version: Int) = (nil, [], 0) { didSet { - self.dynamicAdMessagesPromise.set(.single(self.dynamicAdMessages)) + self.allAdMessagesPromise.set(.single(self.allAdMessages)) } } - private let dynamicAdMessagesPromise = Promise<([Message], Int)>(([], 0)) + private let allAdMessagesPromise = Promise<(fixed: Message?, opportunistic: [Message], version: Int)>((nil, [], 0)) private var seenMessageIds = Set() private var refreshDisplayedItemRangeTimer: SwiftSignalKit.Timer? @@ -686,35 +689,43 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { super.init() - adMessages = adMessages - |> afterNext { [weak self] interPostInterval, messages in - Queue.mainQueue().async { - guard let strongSelf = self else { - return + self.adMessagesDisposable = (adMessages + |> deliverOnMainQueue).start(next: { [weak self] interPostInterval, messages in + guard let self else { + return + } + + if let interPostInterval = interPostInterval { + self.pendingDynamicAdMessages = messages + self.pendingDynamicAdMessageInterval = Int(interPostInterval) + + if self.remainingDynamicAdMessageInterval == nil { + self.remainingDynamicAdMessageInterval = Int(interPostInterval) + } + if self.remainingDynamicAdMessageDistance == nil { + self.remainingDynamicAdMessageDistance = self.bounds.height } - if let interPostInterval = interPostInterval { - strongSelf.pendingDynamicAdMessages = messages - strongSelf.pendingDynamicAdMessageInterval = Int(interPostInterval) - strongSelf.remainingDynamicAdMessageInterval = Int(interPostInterval) - } else { - var adPeerId: PeerId? - adPeerId = messages.first?.author?.id - - if strongSelf.preloadAdPeerId != adPeerId { - strongSelf.preloadAdPeerId = adPeerId - if let adPeerId = adPeerId { - let combinedDisposable = DisposableSet() - strongSelf.preloadAdPeerDisposable.set(combinedDisposable) - combinedDisposable.add(strongSelf.context.account.viewTracker.polledChannel(peerId: adPeerId).start()) - combinedDisposable.add(strongSelf.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId)) - } else { - strongSelf.preloadAdPeerDisposable.set(nil) - } + self.allAdMessages = (messages.first, [], 0) + } else { + var adPeerId: PeerId? + adPeerId = messages.first?.author?.id + + if self.preloadAdPeerId != adPeerId { + self.preloadAdPeerId = adPeerId + if let adPeerId = adPeerId { + let combinedDisposable = DisposableSet() + self.preloadAdPeerDisposable.set(combinedDisposable) + combinedDisposable.add(self.context.account.viewTracker.polledChannel(peerId: adPeerId).start()) + combinedDisposable.add(self.context.account.addAdditionalPreloadHistoryPeerId(peerId: adPeerId)) + } else { + self.preloadAdPeerDisposable.set(nil) } } + + self.allAdMessages = (messages.first, [], 0) } - } + }) self.clipsToBounds = false @@ -737,16 +748,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { self.messageWithReactionsProcessingManager.process = { [weak context] messageIds in context?.account.viewTracker.updateReactionsForMessageIds(messageIds: messageIds) } - self.adSeenProcessingManager.process = { [weak self] messageIds in - guard let strongSelf = self, let adMessagesContext = strongSelf.adMessagesContext else { - return - } - for id in messageIds { - if let message = strongSelf.messageInCurrentHistoryView(id), let adAttribute = message.adAttribute { - adMessagesContext.markAsSeen(opaqueId: adAttribute.opaqueId) - } - } - } self.seenLiveLocationProcessingManager.process = { [weak context] messageIds in context?.account.viewTracker.updateSeenLiveLocationForMessageIds(messageIds: messageIds) } @@ -1096,15 +1097,14 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, - adMessages, availableReactions, defaultReaction, accountPeer, audioTranscriptionSuggestion, promises, topicAuthorId, - self.dynamicAdMessagesPromise.get() - ).start(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, adMessages, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, dynamicAdMessages in + self.allAdMessagesPromise.get() + ).start(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, allAdMessages in let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId) = promises let currentlyPlayingMessageId = currentlyPlayingMessageIdAndType?.0 @@ -1265,12 +1265,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { customChannelDiscussionReadState: customChannelDiscussionReadState, customThreadOutgoingReadState: customThreadOutgoingReadState, cachedData: data.cachedData, - adMessages: adMessages, - dynamicAdMessages: dynamicAdMessages.0 + adMessage: allAdMessages.fixed, + dynamicAdMessages: allAdMessages.opportunistic ) let lastHeaderId = filteredEntries.last.flatMap { listMessageDateHeaderId(timestamp: $0.index.timestamp) } ?? 0 let processedView = ChatHistoryView(originalView: view, filteredEntries: filteredEntries, associatedData: associatedData, lastHeaderId: lastHeaderId, id: id, locationInput: update.2, ignoreMessagesInTimestampRange: update.3) - let previousValueAndVersion = previousView.swap((processedView, update.1, selectedMessages, dynamicAdMessages.1)) + let previousValueAndVersion = previousView.swap((processedView, update.1, selectedMessages, allAdMessages.version)) let previous = previousValueAndVersion?.0 let previousSelectedMessages = previousValueAndVersion?.2 @@ -1323,7 +1323,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var disableAnimations = false var forceSynchronous = false - if let previousValueAndVersion = previousValueAndVersion, dynamicAdMessages.1 != previousValueAndVersion.3 { + if let previousValueAndVersion = previousValueAndVersion, allAdMessages.version != previousValueAndVersion.3 { reason = ChatHistoryViewTransitionReason.Reload disableAnimations = true forceSynchronous = true @@ -1688,6 +1688,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { self.preloadAdPeerDisposable.dispose() self.refreshDisplayedItemRangeTimer?.invalidate() self.genericReactionEffectDisposable?.dispose() + self.adMessagesDisposable?.dispose() } private func attemptReadingReactions() { @@ -1895,7 +1896,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let initialMessage = self.pendingDynamicAdMessages.removeFirst() let message = Message( stableId: UInt32.max - 1 - UInt32(self.nextPendingDynamicMessageId), - stableVersion: 1, + stableVersion: initialMessage.stableVersion, id: MessageId(peerId: initialMessage.id.peerId, namespace: initialMessage.id.namespace, id: self.nextPendingDynamicMessageId), globallyUniqueId: nil, groupingKey: nil, @@ -1908,7 +1909,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { localTags: initialMessage.localTags, forwardInfo: initialMessage.forwardInfo, author: initialMessage.author, - text: initialMessage.text, + text: /*"\(initialMessage.adAttribute!.opaqueId.hashValue)" + */initialMessage.text, attributes: initialMessage.attributes, media: initialMessage.media, peers: initialMessage.peers, @@ -1919,12 +1920,26 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { ) self.nextPendingDynamicMessageId += 1 - var dynamicAdMessages = self.dynamicAdMessages - dynamicAdMessages.0.append(message) - dynamicAdMessages.1 += 1 - self.dynamicAdMessages = dynamicAdMessages + var allAdMessages = self.allAdMessages + if allAdMessages.fixed?.adAttribute?.opaqueId == message.adAttribute?.opaqueId { + allAdMessages.fixed = self.pendingDynamicAdMessages.first?.withUpdatedStableVersion(stableVersion: UInt32(self.nextPendingDynamicMessageId)) + } + allAdMessages.opportunistic.append(message) + allAdMessages.version += 1 + self.allAdMessages = allAdMessages } } + //TODO:loc mark all ads as seen + } + + func markAdAsSeen(opaqueId: Data) { + for i in 0 ..< self.pendingDynamicAdMessages.count { + if let pendingAttribute = self.pendingDynamicAdMessages[i].adAttribute, pendingAttribute.opaqueId == opaqueId { + self.pendingDynamicAdMessages.remove(at: i) + break + } + } + self.adMessagesContext?.markAsSeen(opaqueId: opaqueId) } private func processDisplayedItemRangeChanged(displayedRange: ListViewDisplayedItemRange, transactionState: ChatHistoryTransactionOpaqueState) { @@ -1952,10 +1967,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { var messageIdsWithUnseenReactions: [MessageId] = [] var messageIdsWithInactiveExtendedMedia = Set() var downloadableResourceIds: [(messageId: MessageId, resourceId: String)] = [] - var allVisibleAnchorMessageIds: [MessageId] = [] + var allVisibleAnchorMessageIds: [(MessageId, Int)] = [] + var visibleAdOpaqueIds: [Data] = [] if indexRange.0 <= indexRange.1 { for i in (indexRange.0 ... indexRange.1) { + let nodeIndex = historyView.filteredEntries.count - 1 - i + switch historyView.filteredEntries[i] { case let .MessageEntry(message, _, _, _, _, _): var hasUnconsumedMention = false @@ -1985,6 +2003,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { contentRequiredValidation = true } else if let attribute = attribute as? ReactionsMessageAttribute, attribute.hasUnseen { hasUnseenReactions = true + } else if let attribute = attribute as? AdMessageAttribute { + if message.stableId != ChatHistoryListNode.fixedAdMessageStableId { + visibleAdOpaqueIds.append(attribute.opaqueId) + } } } for media in message.media { @@ -2044,7 +2066,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { topVisibleMessageRange = ChatTopVisibleMessageRange(lowerBound: message.index, upperBound: message.index, isLast: i == historyView.filteredEntries.count - 1) } if message.id.namespace == Namespaces.Message.Cloud, self.remainingDynamicAdMessageInterval != nil { - allVisibleAnchorMessageIds.append(message.id) + allVisibleAnchorMessageIds.append((message.id, nodeIndex)) } case let .MessageGroupEntry(_, messages, _): for (message, _, _, _, _) in messages { @@ -2099,7 +2121,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } if let message = messages.first { if message.0.id.namespace == Namespaces.Message.Cloud, self.remainingDynamicAdMessageInterval != nil { - allVisibleAnchorMessageIds.append(message.0.id) + allVisibleAnchorMessageIds.append((message.0.id, nodeIndex)) } } default: @@ -2242,6 +2264,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if !messageIdsWithInactiveExtendedMedia.isEmpty { self.extendedMediaProcessingManager.update(messageIdsWithInactiveExtendedMedia) } + if !visibleAdOpaqueIds.isEmpty { + for opaqueId in visibleAdOpaqueIds { + self.markAdAsSeen(opaqueId: opaqueId) + } + } self.currentEarlierPrefetchMessages = toEarlierMediaMessages self.currentLaterPrefetchMessages = toLaterMediaMessages @@ -2275,15 +2302,23 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if let visible = displayedRange.visibleRange { let indexRange = (historyView.filteredEntries.count - 1 - visible.lastIndex, historyView.filteredEntries.count - 1 - visible.firstIndex) if indexRange.0 <= indexRange.1 { - for messageId in allVisibleAnchorMessageIds { + for (messageId, nodeIndex) in allVisibleAnchorMessageIds { + guard let itemNode = self.itemNodeAtIndex(nodeIndex) else { + continue + } //TODO:loc optimize eviction - if self.seenMessageIds.insert(messageId).inserted, let remainingDynamicAdMessageIntervalValue = self.remainingDynamicAdMessageInterval { - let pendingInterval = remainingDynamicAdMessageIntervalValue - 1 - if pendingInterval <= 0 { + if self.seenMessageIds.insert(messageId).inserted, let remainingDynamicAdMessageIntervalValue = self.remainingDynamicAdMessageInterval, let remainingDynamicAdMessageDistanceValue = self.remainingDynamicAdMessageDistance { + let itemHeight = itemNode.bounds.height + + let remainingDynamicAdMessageInterval = remainingDynamicAdMessageIntervalValue - 1 + let remainingDynamicAdMessageDistance = remainingDynamicAdMessageDistanceValue - itemHeight + if remainingDynamicAdMessageInterval <= 0 && remainingDynamicAdMessageDistance <= 0.0 { self.remainingDynamicAdMessageInterval = self.pendingDynamicAdMessageInterval + self.remainingDynamicAdMessageDistance = self.bounds.height self.maybeInsertPendingAdMessage(historyView: historyView, toLaterRange: toLaterRange, toEarlierRange: toEarlierRange) } else { - self.remainingDynamicAdMessageInterval = pendingInterval + self.remainingDynamicAdMessageInterval = remainingDynamicAdMessageInterval + self.remainingDynamicAdMessageDistance = remainingDynamicAdMessageDistance } } } diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift index c227ba7d60..2fbc11de14 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift @@ -93,11 +93,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, ignoreMess let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData) - if preloaded { - if tagMask == nil && view.entries.isEmpty { - print("") - } - + if preloaded { return .HistoryView(view: view, type: .Generic(type: updateType), scrollPosition: nil, flashIndicators: false, originalScrollPosition: nil, initialData: combinedInitialData, id: location.id) } else { if view.isLoading { @@ -168,10 +164,6 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, ignoreMess } } - if tagMask == nil && view.entries.isEmpty { - print("") - } - preloaded = true return .HistoryView(view: view, type: .Initial(fadeIn: fadeIn), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id) } diff --git a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift index 78b6e54388..f64cbc03a9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift @@ -373,6 +373,7 @@ final class ChatMessageAvatarHeader: ListViewItemHeader { let peerId: PeerId let peer: Peer? let messageReference: MessageReference? + let adMessageId: EngineMessage.Id? let effectiveTimestamp: Int32 let presentationData: ChatPresentationData let context: AccountContext @@ -382,6 +383,11 @@ final class ChatMessageAvatarHeader: ListViewItemHeader { self.peerId = peerId self.peer = peer self.messageReference = messageReference + if message.adAttribute != nil { + self.adMessageId = message.id + } else { + self.adMessageId = nil + } var effectiveTimestamp = message.timestamp if let forwardInfo = message.forwardInfo, forwardInfo.flags.contains(.isImported) { @@ -412,7 +418,7 @@ final class ChatMessageAvatarHeader: ListViewItemHeader { } func node(synchronousLoad: Bool) -> ListViewItemHeaderNode { - return ChatMessageAvatarHeaderNode(peerId: self.peerId, peer: self.peer, messageReference: self.messageReference, presentationData: self.presentationData, context: self.context, controllerInteraction: self.controllerInteraction, synchronousLoad: synchronousLoad) + return ChatMessageAvatarHeaderNode(peerId: self.peerId, peer: self.peer, messageReference: self.messageReference, adMessageId: self.adMessageId, presentationData: self.presentationData, context: self.context, controllerInteraction: self.controllerInteraction, synchronousLoad: synchronousLoad) } func updateNode(_ node: ListViewItemHeaderNode, previous: ListViewItemHeader?, next: ListViewItemHeader?) { @@ -435,6 +441,7 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode { private let peerId: PeerId private let messageReference: MessageReference? private let peer: Peer? + private let adMessageId: EngineMessage.Id? private let containerNode: ContextControllerSourceNode private let avatarNode: AvatarNode @@ -459,10 +466,11 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode { } } - init(peerId: PeerId, peer: Peer?, messageReference: MessageReference?, presentationData: ChatPresentationData, context: AccountContext, controllerInteraction: ChatControllerInteraction, synchronousLoad: Bool) { + init(peerId: PeerId, peer: Peer?, messageReference: MessageReference?, adMessageId: EngineMessage.Id?, presentationData: ChatPresentationData, context: AccountContext, controllerInteraction: ChatControllerInteraction, synchronousLoad: Bool) { self.peerId = peerId self.peer = peer self.messageReference = messageReference + self.adMessageId = adMessageId self.presentationData = presentationData self.context = context self.controllerInteraction = controllerInteraction @@ -636,10 +644,14 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode { if self.peerId.namespace == Namespaces.Peer.Empty, case let .message(_, id, _, _, _) = self.messageReference?.content { self.controllerInteraction.displayMessageTooltip(id, self.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, self.avatarNode.frame) } else if let peer = self.peer { - if let channel = peer as? TelegramChannel, case .broadcast = channel.info { - self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, false) + if let adMessageId = self.adMessageId { + self.controllerInteraction.activateAdAction(adMessageId) } else { - self.controllerInteraction.openPeer(EnginePeer(peer), .info, self.messageReference, false) + if let channel = peer as? TelegramChannel, case .broadcast = channel.info { + self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, false) + } else { + self.controllerInteraction.openPeer(EnginePeer(peer), .info, self.messageReference, false) + } } } } diff --git a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift index 1235d0631f..9556e8590c 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -63,28 +63,8 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { } self.contentNode.activateAction = { [weak self] in if let strongSelf = self, let item = strongSelf.item { - if let adAttribute = item.message.adAttribute { - switch adAttribute.target { - case let .peer(id, messageId, startParam): - let navigationData: ChatControllerInteractionNavigateToPeer - if let bot = item.message.author as? TelegramUser, bot.botInfo != nil, let startParam = startParam { - navigationData = .withBotStartPayload(ChatControllerInitialBotStart(payload: startParam, behavior: .interactive)) - } else { - var subject: ChatControllerSubject? - if let messageId = messageId { - subject = .message(id: .id(messageId), highlight: true, timecode: nil) - } - navigationData = .chat(textInputState: nil, subject: subject, peekData: nil) - } - let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: id)) - |> deliverOnMainQueue).start(next: { peer in - if let peer = peer { - item.controllerInteraction.openPeer(peer, navigationData, nil, false) - } - }) - case let .join(_, joinHash): - item.controllerInteraction.openJoinLink(joinHash) - } + if let _ = item.message.adAttribute { + item.controllerInteraction.activateAdAction(item.message.id) } else { var webPageContent: TelegramMediaWebpageLoadedContent? for media in item.message.media { diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index 9571a1fa18..ab3dbb4d04 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -540,6 +540,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in }, openWebView: { _, _, _, _ in + }, activateAdAction: { _ in }, requestMessageUpdate: { _, _ in }, cancelInteractiveKeyboardGestures: { }, dismissTextInput: { diff --git a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift index 471c914f81..c00caf0884 100644 --- a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift +++ b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift @@ -161,6 +161,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode { }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in }, openWebView: { _, _, _, _ in + }, activateAdAction: { _ in }, requestMessageUpdate: { _, _ in }, cancelInteractiveKeyboardGestures: { }, dismissTextInput: { diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index 9b99fb6e54..2e7429f1ef 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -154,6 +154,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in }, openWebView: { _, _, _, _ in + }, activateAdAction: { _ in }, requestMessageUpdate: { _, _ in }, cancelInteractiveKeyboardGestures: { }, dismissTextInput: { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index b99bca27ad..0bcda7515a 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -2599,6 +2599,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in }, openWebView: { _, _, _, _ in + }, activateAdAction: { _ in }, requestMessageUpdate: { _, _ in }, cancelInteractiveKeyboardGestures: { }, dismissTextInput: { diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index b195d0458d..0a7e5a3c94 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1348,6 +1348,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in }, openWebView: { _, _, _, _ in + }, activateAdAction: { _ in }, requestMessageUpdate: { _, _ in }, cancelInteractiveKeyboardGestures: { }, dismissTextInput: { diff --git a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm index 1c0cbe2633..32c1ddb7d2 100644 --- a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm +++ b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm @@ -626,7 +626,7 @@ tgcalls::VideoCaptureInterfaceObject *GetVideoCaptureAssumingSameThread(tgcalls: } std::shared_ptr interface = strongSelf->_interface; - if (false && requestClone) { + /*if (false && requestClone) { VideoSampleBufferView *remoteRenderer = [[VideoSampleBufferView alloc] initWithFrame:CGRectZero]; remoteRenderer.videoContentMode = UIViewContentModeScaleAspectFill; @@ -643,7 +643,7 @@ tgcalls::VideoCaptureInterfaceObject *GetVideoCaptureAssumingSameThread(tgcalls: } completion(remoteRenderer, cloneRenderer); - } else if ([VideoMetalView isSupported]) { + } else */if ([VideoMetalView isSupported]) { VideoMetalView *remoteRenderer = [[VideoMetalView alloc] initWithFrame:CGRectZero]; remoteRenderer.videoContentMode = UIViewContentModeScaleAspectFill; diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index c8f6a17325..07b225568f 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit c8f6a173253e88fc77ef4ceece919a786023108e +Subproject commit 07b225568fb596ba44d472c3fa413da2f8bd3f2e From 5e5571d3cd3fdbfe781401fb55889a98138280bc Mon Sep 17 00:00:00 2001 From: Mike Renoir <> Date: Tue, 1 Nov 2022 17:40:29 +0400 Subject: [PATCH 3/9] added hasVideo for TelegramImageRepresentation. This is better way to check that user or chat has video avatar. --- .../Sources/ApiUtils/ApiGroupOrChannel.swift | 7 +-- .../Sources/ApiUtils/TelegramMediaFile.swift | 6 +-- .../Sources/ApiUtils/TelegramMediaImage.swift | 6 +-- .../Sources/ApiUtils/TelegramUser.swift | 6 +-- .../StandaloneUploadedMedia.swift | 2 +- ...ecretChatIncomingDecryptedOperations.swift | 48 +++++++++---------- .../SyncCore_TelegramMediaImage.swift | 10 +++- ...OutgoingMessageWithChatContextResult.swift | 4 +- .../Peers/PeerPhotoUpdater.swift | 4 +- .../TelegramEngine/Stickers/StickerPack.swift | 6 +-- submodules/TelegramVoip/Package.swift | 6 +-- 11 files changed, 56 insertions(+), 49 deletions(-) diff --git a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift index fd6363820e..8eb613d13c 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift @@ -6,15 +6,16 @@ import TelegramApi func imageRepresentationsForApiChatPhoto(_ photo: Api.ChatPhoto) -> [TelegramMediaImageRepresentation] { var representations: [TelegramMediaImageRepresentation] = [] switch photo { - case let .chatPhoto(_, photoId, strippedThumb, dcId): + case let .chatPhoto(flags, photoId, strippedThumb, dcId): + let hasVideo = (flags & (1 << 0)) != 0 let smallResource: TelegramMediaResource let fullSizeResource: TelegramMediaResource smallResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: photoId, sizeSpec: .small, volumeId: nil, localId: nil) fullSizeResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: photoId, sizeSpec: .fullSize, volumeId: nil, localId: nil) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo)) case .chatPhotoEmpty: break } diff --git a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaFile.swift b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaFile.swift index c69d4e215d..3d4bf05c99 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaFile.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaFile.swift @@ -134,13 +134,13 @@ func telegramMediaFileThumbnailRepresentationsFromApiSizes(datacenterId: Int32, switch size { case let .photoCachedSize(type, w, h, _): let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case let .photoSize(type, w, h, _): let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case let .photoSizeProgressive(type, w, h, sizes): let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false)) case let .photoPathSize(_, data): immediateThumbnailData = data.makeData() case let .photoStrippedSize(_, data): diff --git a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaImage.swift b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaImage.swift index 4d0398ae58..662e5678bb 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaImage.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaImage.swift @@ -10,14 +10,14 @@ func telegramMediaImageRepresentationsFromApiSizes(datacenterId: Int32, photoId: switch size { case let .photoCachedSize(type, w, h, _): let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: nil, fileReference: fileReference) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case let .photoSize(type, w, h, size): let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case let .photoSizeProgressive(type, w, h, sizes): if !sizes.isEmpty { let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(sizes[sizes.count - 1]), fileReference: fileReference) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false)) } case let .photoStrippedSize(_, data): immediateThumbnailData = data.makeData() diff --git a/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift b/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift index 156b2c3610..3a06d1ff76 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift @@ -7,7 +7,7 @@ func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto) -> [TelegramMedia var representations: [TelegramMediaImageRepresentation] = [] switch photo { case let .userProfilePhoto(flags, id, strippedThumb, dcId): - let _ = (flags & (1 << 0)) != 0 + let hasVideo = (flags & (1 << 0)) != 0 let smallResource: TelegramMediaResource let fullSizeResource: TelegramMediaResource @@ -15,8 +15,8 @@ func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto) -> [TelegramMedia smallResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: .small, volumeId: nil, localId: nil) fullSizeResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: .fullSize, volumeId: nil, localId: nil) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo)) case .userProfilePhotoEmpty: break } diff --git a/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift b/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift index 47d33f6db9..6525f5e66d 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/StandaloneUploadedMedia.swift @@ -101,7 +101,7 @@ public func standaloneUploadedImage(account: Account, peerId: PeerId, text: Stri |> mapToSignal { result -> Signal in switch result { case let .encryptedFile(id, accessHash, size, dcId, _): - return .single(.result(.media(.standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int64(data.count), datacenterId: Int(dcId), key: key), progressiveSizes: [], immediateThumbnailData: nil)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []))))) + return .single(.result(.media(.standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int64(data.count), datacenterId: Int(dcId), key: key), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []))))) case .encryptedFileEmpty: return .fail(.generic) } diff --git a/submodules/TelegramCore/Sources/State/ProcessSecretChatIncomingDecryptedOperations.swift b/submodules/TelegramCore/Sources/State/ProcessSecretChatIncomingDecryptedOperations.swift index b1e7024af0..62bbdbbd6e 100644 --- a/submodules/TelegramCore/Sources/State/ProcessSecretChatIncomingDecryptedOperations.swift +++ b/submodules/TelegramCore/Sources/State/ProcessSecretChatIncomingDecryptedOperations.swift @@ -784,10 +784,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var representations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) parsedMedia.append(image) } @@ -810,7 +810,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -825,7 +825,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -843,7 +843,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .photoSize(_, location, w, h, size): switch location { case let .fileLocation(dcId, volumeId, localId, secret): - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } @@ -853,7 +853,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .fileLocation(dcId, volumeId, localId, secret): let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) resources.append((resource, bytes.makeData())) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } @@ -986,10 +986,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var representations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) parsedMedia.append(image) } @@ -1013,7 +1013,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -1044,7 +1044,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -1062,7 +1062,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .photoSize(_, location, w, h, size): switch location { case let .fileLocation(dcId, volumeId, localId, secret): - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } @@ -1072,7 +1072,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .fileLocation(dcId, volumeId, localId, secret): let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) resources.append((resource, bytes.makeData())) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } @@ -1265,10 +1265,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var representations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) parsedMedia.append(image) } @@ -1292,7 +1292,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -1323,7 +1323,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -1341,7 +1341,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .photoSize(_, location, w, h, size): switch location { case let .fileLocation(dcId, volumeId, localId, secret): - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } @@ -1351,7 +1351,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .fileLocation(dcId, volumeId, localId, secret): let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) resources.append((resource, bytes.makeData())) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } @@ -1466,10 +1466,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var representations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) parsedMedia.append(image) } @@ -1493,7 +1493,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -1524,7 +1524,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 var previewRepresentations: [TelegramMediaImageRepresentation] = [] if thumb.size != 0 { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resources.append((resource, thumb.makeData())) } let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) @@ -1542,7 +1542,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .photoSize(_, location, w, h, size): switch location { case let .fileLocation(dcId, volumeId, localId, secret): - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } @@ -1552,7 +1552,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 case let .fileLocation(dcId, volumeId, localId, secret): let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) resources.append((resource, bytes.makeData())) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case .fileLocationUnavailable: break } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaImage.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaImage.swift index c520f68477..c49dd9754f 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaImage.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaImage.swift @@ -305,12 +305,13 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C public let resource: TelegramMediaResource public let progressiveSizes: [Int32] public let immediateThumbnailData: Data? - - public init(dimensions: PixelDimensions, resource: TelegramMediaResource, progressiveSizes: [Int32], immediateThumbnailData: Data?) { + public let hasVideo: Bool + public init(dimensions: PixelDimensions, resource: TelegramMediaResource, progressiveSizes: [Int32], immediateThumbnailData: Data?, hasVideo: Bool) { self.dimensions = dimensions self.resource = resource self.progressiveSizes = progressiveSizes self.immediateThumbnailData = immediateThumbnailData + self.hasVideo = hasVideo } public init(decoder: PostboxDecoder) { @@ -318,6 +319,7 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C self.resource = decoder.decodeObjectForKey("r") as? TelegramMediaResource ?? EmptyMediaResource() self.progressiveSizes = decoder.decodeInt32ArrayForKey("ps") self.immediateThumbnailData = decoder.decodeDataForKey("th") + self.hasVideo = decoder.decodeBoolForKey("hv", orElse: false) } public func encode(_ encoder: PostboxEncoder) { @@ -330,6 +332,7 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C } else { encoder.encodeNil(forKey: "th") } + encoder.encodeBool(self.hasVideo, forKey: "hv") } public var description: String { @@ -349,6 +352,9 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C if self.immediateThumbnailData != other.immediateThumbnailData { return false } + if self.hasVideo != other.hasVideo { + return false + } return true } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift index 1dc74174a8..da8df52333 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/OutgoingMessageWithChatContextResult.swift @@ -69,7 +69,7 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId: arc4random_buf(&randomId, 8) let thumbnailResource = thumbnail.resource let imageDimensions = thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128) - let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) + let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: tmpImage), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []) } else { return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []) @@ -85,7 +85,7 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId: if thumbnail.mimeType.hasPrefix("video/") { videoThumbnails.append(TelegramMediaFile.VideoThumbnail(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource)) } else { - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } } var fileName = "file" diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerPhotoUpdater.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerPhotoUpdater.swift index 6847939507..06f7d4bbdb 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerPhotoUpdater.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/PeerPhotoUpdater.swift @@ -158,9 +158,9 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state for size in sizes { switch size { case let .photoSize(_, w, h, _): - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case let .photoSizeProgressive(_, w, h, sizes): - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: sizes, immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false)) default: break } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/StickerPack.swift b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/StickerPack.swift index 0687adba0d..9a13ff10f7 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Stickers/StickerPack.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Stickers/StickerPack.swift @@ -11,13 +11,13 @@ func telegramStickerPackThumbnailRepresentationFromApiSizes(datacenterId: Int32, switch size { case let .photoCachedSize(_, w, h, _): let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case let .photoSize(_, w, h, _): let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) case let .photoSizeProgressive(_, w, h, sizes): let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false)) case let .photoPathSize(_, data): immediateThumbnailData = data.makeData() case .photoStrippedSize: diff --git a/submodules/TelegramVoip/Package.swift b/submodules/TelegramVoip/Package.swift index b9ab0738de..1eeb60ca4b 100644 --- a/submodules/TelegramVoip/Package.swift +++ b/submodules/TelegramVoip/Package.swift @@ -26,9 +26,9 @@ let package = Package( .target( name: "TelegramVoip", dependencies: [ - .productItem(name: "TgVoipWebrtc", package: "TgVoipWebrtc", condition: nil), - .productItem(name: "SwiftSignalKit", package: "SSignalKit", condition: nil), - .productItem(name: "TelegramCore", package: "TelegramCore", condition: nil), + .product(name: "TgVoipWebrtc", package: "TgVoipWebrtc", condition: nil), + .product(name: "SwiftSignalKit", package: "SSignalKit", condition: nil), + .product(name: "TelegramCore", package: "TelegramCore", condition: nil), ], path: "Sources", exclude: [ From cbfcb0892072ce41947f5a56555d03cac942a917 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 1 Nov 2022 17:54:07 +0400 Subject: [PATCH 4/9] Roll back tgcalls --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 95ed8e1665..e9aa21b611 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,9 +17,6 @@ url=https://github.com/bazelbuild/rules_swift.git [submodule "build-system/tulsi"] path = build-system/tulsi url=https://github.com/bazelbuild/tulsi.git -[submodule "submodules/TgVoipWebrtc/tgcalls"] - path = submodules/TgVoipWebrtc/tgcalls -url=../tgcalls.git [submodule "third-party/libvpx/libvpx"] path = third-party/libvpx/libvpx url = https://github.com/webmproject/libvpx.git From d521d347c899684e1a0d3b856d0b85b449205584 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 1 Nov 2022 17:56:13 +0400 Subject: [PATCH 5/9] Fix tgcalls submodule --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitmodules b/.gitmodules index e9aa21b611..95ed8e1665 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,6 +17,9 @@ url=https://github.com/bazelbuild/rules_swift.git [submodule "build-system/tulsi"] path = build-system/tulsi url=https://github.com/bazelbuild/tulsi.git +[submodule "submodules/TgVoipWebrtc/tgcalls"] + path = submodules/TgVoipWebrtc/tgcalls +url=../tgcalls.git [submodule "third-party/libvpx/libvpx"] path = third-party/libvpx/libvpx url = https://github.com/webmproject/libvpx.git From a92f3fe73808de3581a078d3a150121089a0599b Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 1 Nov 2022 18:07:52 +0400 Subject: [PATCH 6/9] Fix build --- .../Sources/InstantPageGalleryController.swift | 2 +- .../Sources/ItemListStickerPackItem.swift | 2 +- .../Sources/LegacyMediaPickers.swift | 14 +++++++------- .../Sources/Themes/CustomWallpaperPicker.swift | 2 +- .../Sources/Themes/EditThemeController.swift | 2 +- .../Themes/SettingsThemeWallpaperNode.swift | 2 +- .../Themes/ThemeAccentColorControllerNode.swift | 2 +- .../Sources/Themes/ThemeGridSearchItem.swift | 4 ++-- .../Themes/ThemePreviewControllerNode.swift | 2 +- .../Sources/Themes/WallpaperGalleryItem.swift | 6 +++--- .../Sources/VoiceChatController.swift | 4 ++-- .../Sources/DefaultDayPresentationTheme.swift | 3 ++- .../Sources/ChatContextResultPeekContentNode.swift | 4 ++-- submodules/TelegramUI/Sources/ChatController.swift | 2 +- .../Sources/ChatMediaInputStickerPackItem.swift | 2 +- .../Sources/ChatMessageInteractiveMediaNode.swift | 2 +- .../Sources/CreateChannelController.swift | 4 ++-- .../TelegramUI/Sources/CreateGroupController.swift | 4 ++-- .../Sources/GifPaneSearchContentNode.swift | 3 ++- ...ontalListContextResultsChatInputPanelItem.swift | 2 +- .../Sources/LegacyInstantVideoController.swift | 2 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 4 ++-- .../Sources/StickerPaneTrendingListGridItem.swift | 2 +- .../TelegramUI/Sources/ThemeUpdateManager.swift | 2 +- .../Sources/TransformOutgoingMessageMedia.swift | 6 +++--- ...ticalListContextResultsChatInputPanelItem.swift | 2 +- .../UndoUI/Sources/UndoOverlayControllerNode.swift | 4 ++-- .../Sources/WallpaperBackgroundNode.swift | 4 ++-- .../Sources/WallpaperResources.swift | 4 ++-- .../Sources/LegacyWebSearchGallery.swift | 4 ++-- .../Sources/WebSearchGalleryController.swift | 2 +- submodules/WebSearchUI/Sources/WebSearchItem.swift | 4 ++-- 32 files changed, 55 insertions(+), 53 deletions(-) diff --git a/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift b/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift index 1fc8781286..9ef2083002 100644 --- a/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift +++ b/submodules/InstantPageUI/Sources/InstantPageGalleryController.swift @@ -117,7 +117,7 @@ public struct InstantPageGalleryEntry: Equatable { var representations: [TelegramMediaImageRepresentation] = [] representations.append(contentsOf: file.previewRepresentations) if let dimensions = file.dimensions { - representations.append(TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } let image = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: file.immediateThumbnailData, reference: nil, partialReference: nil, flags: []) return InstantImageGalleryItem(context: context, presentationData: presentationData, itemId: self.index, imageReference: .webPage(webPage: WebpageReference(webPage), media: image), caption: caption, credit: credit, location: self.location, openUrl: openUrl, openUrlOptions: openUrlOptions) diff --git a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift index db88c1e006..c997c00397 100644 --- a/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift +++ b/submodules/ItemListStickerPackItem/Sources/ItemListStickerPackItem.swift @@ -484,7 +484,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode { thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { - thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) } } diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift index 5cb18f1fd7..8df0e38ab7 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift @@ -326,7 +326,7 @@ public func legacyEnqueueGifMessage(account: Account, data: Data, correlationId: if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } var randomId: Int64 = 0 @@ -368,7 +368,7 @@ public func legacyEnqueueVideoMessage(account: Account, data: Data, correlationI if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } var randomId: Int64 = 0 @@ -421,7 +421,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) - let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } } switch data { @@ -435,7 +435,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) - let _ = try? scaledImageData.write(to: URL(fileURLWithPath: tempFilePath)) let resource = LocalFileReferenceMediaResource(localFilePath: tempFilePath, randomId: randomId) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) var imageFlags: TelegramMediaImageFlags = [] @@ -491,7 +491,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) - let size = CGSize(width: CGFloat(asset.pixelWidth), height: CGFloat(asset.pixelHeight)) let scaledSize = size.aspectFittedOrSmaller(CGSize(width: 1280.0, height: 1280.0)) let resource = PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier, uniqueId: Int64.random(in: Int64.min ... Int64.max)) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) var attributes: [MessageAttribute] = [] @@ -540,7 +540,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) - let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } } @@ -655,7 +655,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) - let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } } diff --git a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift index bab6a9ad5c..9f2c5ca045 100644 --- a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift +++ b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift @@ -174,7 +174,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE let apply: () -> Void = { let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: nil) - let wallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)], settings) + let wallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], settings) updateWallpaper(wallpaper) DispatchQueue.main.async { completion() diff --git a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift index 9e9e9349a7..801b529415 100644 --- a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift +++ b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift @@ -407,7 +407,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll |> mapToSignal { wallpaper -> Signal in if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) return wallpaperDatas(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal in guard complete, let fullSizeData = fullSizeData else { diff --git a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift index a1c8bb2e8b..168098f8c2 100644 --- a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift +++ b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift @@ -207,7 +207,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { } let fullDimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000) - let convertedFullRepresentations = [ImageRepresentationWithReference(representation: .init(dimensions: fullDimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))] + let convertedFullRepresentations = [ImageRepresentationWithReference(representation: .init(dimensions: fullDimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))] let imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> if wallpaper.isPattern { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index b975380659..9a66cf1c91 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -473,7 +473,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate for representation in file.file.previewRepresentations { convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource))) } - convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) } else if backgroundColors.count >= 2 { wallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors.map { $0.rgb }, settings: WallpaperSettings(rotation: state.rotation))) } else { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridSearchItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridSearchItem.swift index 0e506ac10b..8a7e582b4d 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridSearchItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridSearchItem.swift @@ -108,10 +108,10 @@ final class ThemeGridSearchItemNode: GridItemNode { var representations: [TelegramMediaImageRepresentation] = [] if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } if let imageResource = imageResource, let imageDimensions = imageDimensions { - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } if !representations.isEmpty { let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index 86f0e1b911..d20afe24df 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -252,7 +252,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { for representation in file.file.previewRepresentations { convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource))) } - convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) let signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> if wallpaper.isPattern { diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 342f3f8d08..b619de8b7b 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -383,7 +383,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { for representation in file.file.previewRepresentations { convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: representation.resource, media: file.file, message: message, slug: file.slug))) } - convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: reference(for: file.file.resource, media: file.file, message: message, slug: file.slug))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: reference(for: file.file.resource, media: file.file, message: message, slug: file.slug))) if wallpaper.isPattern { var patternColors: [UIColor] = [] @@ -541,9 +541,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode { var representations: [TelegramMediaImageRepresentation] = [] if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) signal = chatMessagePhoto(postbox: context.account.postbox, photoReference: .standalone(media: tmpImage)) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 428669cca3..83cfe1a95d 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -6251,7 +6251,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) self.call.account.postbox.mediaBox.storeResourceData(resource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) self.currentUpdatingAvatar = representation self.updateAvatarPromise.set(.single((representation, 0.0))) @@ -6286,7 +6286,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) self.currentUpdatingAvatar = representation self.updateAvatarPromise.set(.single((representation, 0.0))) diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 812ade905a..75df504744 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -1278,7 +1278,8 @@ public func defaultBuiltinWallpaper(data: BuiltinWallpaperData, colors: [UInt32] fileReference: Data() ), progressiveSizes: [], - immediateThumbnailData: nil + immediateThumbnailData: nil, + hasVideo: false ) ], videoThumbnails: [], diff --git a/submodules/TelegramUI/Sources/ChatContextResultPeekContentNode.swift b/submodules/TelegramUI/Sources/ChatContextResultPeekContentNode.swift index d53796a5e9..cd9f061c06 100644 --- a/submodules/TelegramUI/Sources/ChatContextResultPeekContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatContextResultPeekContentNode.swift @@ -171,7 +171,7 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont imageDimensions = externalReference.content?.dimensions?.cgSize if let content = externalReference.content, externalReference.type == "gif", let thumbnailResource = imageResource , let dimensions = content.dimensions { - videoFileReference = .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])])) + videoFileReference = .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])])) imageResource = nil } case let .internalReference(internalReference): @@ -233,7 +233,7 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont if updatedImageResource { if let imageResource = imageResource { - let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: Int32(fittedImageDimensions.width * 2.0), height: Int32(fittedImageDimensions.height * 2.0)), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil) + let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: Int32(fittedImageDimensions.width * 2.0), height: Int32(fittedImageDimensions.height * 2.0)), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) updateImageSignal = chatMessagePhoto(postbox: self.account.postbox, photoReference: .standalone(media: tmpImage)) } else { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index bb1d8f7c5a..015c3a98f7 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -12600,7 +12600,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let mimeType = guessMimeTypeByFileExtension((item.fileName as NSString).pathExtension) var previewRepresentations: [TelegramMediaImageRepresentation] = [] if mimeType.hasPrefix("image/") || mimeType == "application/pdf" { - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 320, height: 320), resource: ICloudFileResource(urlData: item.urlData, thumbnail: true), progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 320, height: 320), resource: ICloudFileResource(urlData: item.urlData, thumbnail: true), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } var attributes: [TelegramMediaFileAttribute] = [] attributes.append(.FileName(fileName: item.fileName)) diff --git a/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift b/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift index 930c96293f..618f7b8d2a 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputStickerPackItem.swift @@ -200,7 +200,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode { thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { - thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) } } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index 5553ae31ef..25fcb05613 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -1066,7 +1066,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio } else { var representations: [ImageRepresentationWithReference] = file.previewRepresentations.map({ ImageRepresentationWithReference(representation: $0, reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference($0.resource)) }) if file.mimeType == "image/svg+xml" || file.mimeType == "application/x-tgwallpattern" { - representations.append(ImageRepresentationWithReference(representation: .init(dimensions: PixelDimensions(width: 1440, height: 2960), resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource))) + representations.append(ImageRepresentationWithReference(representation: .init(dimensions: PixelDimensions(width: 1440, height: 2960), resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource))) } if ["image/png", "image/svg+xml", "application/x-tgwallpattern"].contains(file.mimeType) { return patternWallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, representations: representations, mode: .screen) diff --git a/submodules/TelegramUI/Sources/CreateChannelController.swift b/submodules/TelegramUI/Sources/CreateChannelController.swift index c0230b3824..cfb46210e1 100644 --- a/submodules/TelegramUI/Sources/CreateChannelController.swift +++ b/submodules/TelegramUI/Sources/CreateChannelController.swift @@ -329,7 +329,7 @@ public func createChannelController(context: AccountContext) -> ViewController { if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) uploadedAvatar.set(context.engine.peers.uploadedPeerPhoto(resource: resource)) uploadedVideoAvatar = nil updateState { current in @@ -344,7 +344,7 @@ public func createChannelController(context: AccountContext) -> ViewController { if let data = image.jpegData(compressionQuality: 0.6) { let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) updateState { state in var state = state state.avatar = .image(representation, true) diff --git a/submodules/TelegramUI/Sources/CreateGroupController.swift b/submodules/TelegramUI/Sources/CreateGroupController.swift index 0a8fc85c44..622ed1c423 100644 --- a/submodules/TelegramUI/Sources/CreateGroupController.swift +++ b/submodules/TelegramUI/Sources/CreateGroupController.swift @@ -594,7 +594,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] if let data = image.jpegData(compressionQuality: 0.6) { let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) uploadedAvatar.set(context.engine.peers.uploadedPeerPhoto(resource: resource)) uploadedVideoAvatar = nil updateState { current in @@ -609,7 +609,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] if let data = image.jpegData(compressionQuality: 0.6) { let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) updateState { state in var state = state state.avatar = .image(representation, true) diff --git a/submodules/TelegramUI/Sources/GifPaneSearchContentNode.swift b/submodules/TelegramUI/Sources/GifPaneSearchContentNode.swift index 845e95f258..30db8de0cb 100644 --- a/submodules/TelegramUI/Sources/GifPaneSearchContentNode.swift +++ b/submodules/TelegramUI/Sources/GifPaneSearchContentNode.swift @@ -88,7 +88,8 @@ func paneGifSearchForQuery(context: AccountContext, query: String, offset: Strin dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], - immediateThumbnailData: nil + immediateThumbnailData: nil, + hasVideo: false )) } } diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift index 655325e2b5..4cf85fe0fc 100644 --- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputPanelItem.swift @@ -352,7 +352,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode if let stickerFile = stickerFile { updateImageSignal = chatMessageSticker(account: item.account, file: stickerFile, small: false, fetched: true) } else { - let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(CGSize(width: fittedImageDimensions.width * 2.0, height: fittedImageDimensions.height * 2.0)), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil) + let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(CGSize(width: fittedImageDimensions.width * 2.0, height: fittedImageDimensions.height * 2.0)), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) updateImageSignal = chatMessagePhoto(postbox: item.account.postbox, photoReference: .standalone(media: tmpImage), synchronousLoad: true) } diff --git a/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift b/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift index 3b0c5b2fe9..bef2301778 100644 --- a/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift +++ b/submodules/TelegramUI/Sources/LegacyInstantVideoController.swift @@ -176,7 +176,7 @@ func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect, let thumbnailImage = TGScaleImageToPixelSize(previewImage, thumbnailSize)! if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { context.account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) - previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 0bcda7515a..d51db1c7e0 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -6551,7 +6551,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) self.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) self.state = self.state.withUpdatingAvatar(.image(representation)) if let (layout, navigationHeight) = self.validLayout { @@ -6596,7 +6596,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) - let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) + let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) self.state = self.state.withUpdatingAvatar(.image(representation)) if let (layout, navigationHeight) = self.validLayout { diff --git a/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift b/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift index 19dd723f22..d7e50225e7 100644 --- a/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift +++ b/submodules/TelegramUI/Sources/StickerPaneTrendingListGridItem.swift @@ -266,7 +266,7 @@ private final class FeaturedPackItemNode: ListViewItemNode { thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { - thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) } } diff --git a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift index 24952d8a24..674a0a82b4 100644 --- a/submodules/TelegramUI/Sources/ThemeUpdateManager.swift +++ b/submodules/TelegramUI/Sources/ThemeUpdateManager.swift @@ -103,7 +103,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager { |> mapToSignal { wallpaper -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in if let wallpaper = wallpaper, case let .file(file) = wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in guard complete, let fullSizeData = fullSizeData else { diff --git a/submodules/TelegramUI/Sources/TransformOutgoingMessageMedia.swift b/submodules/TelegramUI/Sources/TransformOutgoingMessageMedia.swift index e136eacc70..8e51acf4b8 100644 --- a/submodules/TelegramUI/Sources/TransformOutgoingMessageMedia.swift +++ b/submodules/TelegramUI/Sources/TransformOutgoingMessageMedia.swift @@ -74,7 +74,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me } } attributes.append(.ImageSize(size: PixelDimensions(imageDimensions))) - let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)]).withUpdatedAttributes(attributes) + let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)]).withUpdatedAttributes(attributes) subscriber.putNext(.standalone(media: updatedFile)) subscriber.putCompletion() } else { @@ -103,7 +103,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me let scaledImageSize = CGSize(width: scaledImage.size.width * scaledImage.scale, height: scaledImage.size.height * scaledImage.scale) - let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)]) + let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)]) subscriber.putNext(.standalone(media: updatedFile)) subscriber.putCompletion() } else { @@ -159,7 +159,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) postbox.mediaBox.storeResourceData(thumbnailResource.id, data: smallestData) - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(smallestSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(smallestSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let updatedImage = TelegramMediaImage(imageId: image.imageId, representations: representations, immediateThumbnailData: image.immediateThumbnailData, reference: image.reference, partialReference: image.partialReference, flags: []) return .single(.standalone(media: updatedImage)) } diff --git a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift index 02a03e6dc8..5550fd8721 100644 --- a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift +++ b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelItem.swift @@ -250,7 +250,7 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode { if let stickerFile = stickerFile { updateIconImageSignal = chatMessageSticker(account: item.account, file: stickerFile, small: false, fetched: true) } else { - let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 55, height: 55), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil) + let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 55, height: 55), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false) let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) updateIconImageSignal = chatWebpageSnippetPhoto(account: item.account, photoReference: .standalone(media: tmpImage)) } diff --git a/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift b/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift index eeb3f9ddd0..c41b61b7f0 100644 --- a/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift +++ b/submodules/UndoUI/Sources/UndoOverlayControllerNode.swift @@ -384,7 +384,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode { thumbnailItem = .animated(EngineMediaResource(item.file.resource), item.file.dimensions ?? PixelDimensions(width: 512, height: 512), item.file.isVideoSticker) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { - thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) } } @@ -668,7 +668,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode { thumbnailItem = .animated(EngineMediaResource(file.resource)) resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: file.resource) } else if let dimensions = file.dimensions, let resource = chatMessageStickerResource(file: file, small: true) as? TelegramMediaResource { - thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) + thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: resource) } diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index 9f7fcc78ab..28861aec25 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -949,7 +949,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: EngineMediaResource(representation.resource), media: EngineMedia(file.file)))) } let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000) - convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: reference(for: EngineMediaResource(file.file.resource), media: EngineMedia(file.file)))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: reference(for: EngineMediaResource(file.file.resource), media: EngineMedia(file.file)))) let signal = patternWallpaperImage(account: self.context.account, accountManager: self.context.sharedContext.accountManager, representations: convertedRepresentations, mode: .screen, autoFetchFullSize: true) self.patternImageDisposable.set((signal @@ -1801,7 +1801,7 @@ final class WallpaperBackgroundNodeMergedImpl: ASDisplayNode, WallpaperBackgroun gradientSpec = WallpaperGradiendComponentView.Spec(colors: file.settings.colors) } if let dimensions = file.file.dimensions { - let representation = TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: file.file.immediateThumbnailData) + let representation = TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: file.file.immediateThumbnailData, hasVideo: false) imageSpec = WallpaperImageComponentView.Spec.image(representation: representation, isPattern: file.isPattern, intensity: CGFloat(file.settings.intensity ?? 100) / 100.0) } } diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 691223bbb2..0c459b1e73 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -1169,7 +1169,7 @@ public func themeImage(account: Account, accountManager: AccountManager mapToSignal { wallpaper -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in guard complete, let fullSizeData = fullSizeData else { @@ -1417,7 +1417,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager mapToSignal { thumbnailData, fullSizeData, complete -> Signal<((UIColor, UIColor?, [UInt32]), [UIColor], [UIColor], UIImage?, Bool, Bool, CGFloat, Int32?), NoError> in guard complete, let fullSizeData = fullSizeData else { diff --git a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift index 2126fb09fb..c0d33b978d 100644 --- a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift +++ b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift @@ -260,9 +260,9 @@ func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyW var representations: [TelegramMediaImageRepresentation] = [] if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) thumbnailSignal = chatMessagePhotoDatas(postbox: account.postbox, photoReference: .standalone(media: tmpImage), autoFetchFullSize: false) |> mapToSignal { value -> Signal in diff --git a/submodules/WebSearchUI/Sources/WebSearchGalleryController.swift b/submodules/WebSearchUI/Sources/WebSearchGalleryController.swift index cebe2c86ab..db9156e61b 100644 --- a/submodules/WebSearchUI/Sources/WebSearchGalleryController.swift +++ b/submodules/WebSearchUI/Sources/WebSearchGalleryController.swift @@ -37,7 +37,7 @@ struct WebSearchGalleryEntry: Equatable { switch self.result { case let .externalReference(externalReference): if let content = externalReference.content, externalReference.type == "gif", let thumbnailResource = externalReference.thumbnail?.resource, let dimensions = content.dimensions { - let fileReference = FileMediaReference.standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])])) + let fileReference = FileMediaReference.standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])])) return WebSearchVideoGalleryItem(context: context, presentationData: presentationData, index: self.index, result: self.result, content: NativeVideoContent(id: .contextResult(self.result.queryId, self.result.id), fileReference: fileReference, loopVideo: true, enableSound: false, fetchAutomatically: true), controllerInteraction: controllerInteraction) } case let .internalReference(internalReference): diff --git a/submodules/WebSearchUI/Sources/WebSearchItem.swift b/submodules/WebSearchUI/Sources/WebSearchItem.swift index 433e9cbb81..3f31f78fff 100644 --- a/submodules/WebSearchUI/Sources/WebSearchItem.swift +++ b/submodules/WebSearchUI/Sources/WebSearchItem.swift @@ -130,10 +130,10 @@ final class WebSearchItemNode: GridItemNode { var representations: [TelegramMediaImageRepresentation] = [] if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } if let imageResource = imageResource, let imageDimensions = imageDimensions { - representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) + representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)) } if !representations.isEmpty { let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) From 5a445389ba362ab6059baefc9f6c4a134bff8a4f Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 1 Nov 2022 20:24:01 +0400 Subject: [PATCH 7/9] Update invoice API --- .../Telegram-iOS/en.lproj/Localizable.strings | 20 ++++++++--------- submodules/PlatformRestrictionMatching/BUILD | 1 + .../Sources/PlatformRestrictionMatching.swift | 12 +++++++++- submodules/TelegramApi/Sources/Api29.swift | 22 +++++++++++-------- .../Sources/ApiUtils/ChatContextResult.swift | 2 +- .../ApiUtils/StoreMessage_Telegram.swift | 2 +- .../Sources/Settings/ContentSettings.swift | 18 ++++++++++----- .../SyncCore_TelegramMediaInvoice.swift | 21 +++++++++++++++--- .../TelegramEngine/Messages/BotWebView.swift | 13 ++++++----- .../Messages/TelegramEngineMessages.swift | 8 +++---- .../Messages/UpdatePinnedMessage.swift | 8 +++++-- .../Payments/BotPaymentForm.swift | 5 +++-- .../Sources/Utils/MessageUtils.swift | 9 ++++++++ .../Sources/ServiceMessageStrings.swift | 22 +++++++++---------- .../TelegramUI/Sources/ChatController.swift | 12 +++++----- .../Sources/ChatHistoryListNode.swift | 3 +++ .../ChatMessageAnimatedStickerItemNode.swift | 5 ++++- .../ChatMessageAttachedContentNode.swift | 5 ++++- .../Sources/ChatMessageBubbleItemNode.swift | 9 +++++++- .../ChatMessageContactBubbleContentNode.swift | 5 ++++- .../ChatMessageInteractiveFileNode.swift | 5 ++++- ...atMessageInteractiveInstantVideoNode.swift | 5 ++++- .../ChatMessageMapBubbleContentNode.swift | 5 ++++- .../ChatMessageMediaBubbleContentNode.swift | 5 ++++- .../ChatMessagePollBubbleContentNode.swift | 5 ++++- ...atMessageRestrictedBubbleContentNode.swift | 5 ++++- .../Sources/ChatMessageStickerItemNode.swift | 5 ++++- .../ChatMessageTextBubbleContentNode.swift | 5 ++++- .../ChatPinnedMessageTitlePanelNode.swift | 2 +- .../WebUI/Sources/WebAppController.swift | 10 +++++---- 30 files changed, 177 insertions(+), 77 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index bf1da82240..20084fa97d 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8186,16 +8186,16 @@ Sorry for the inconvenience."; "ChatList.DeleteTopicConfirmationText" = "This will delete the topic with all its messages"; "ChatList.DeleteTopicConfirmationAction" = "Delete Topic"; -"Notification.TopicCreated" = "Topic created"; -"Notification.TopicClosed" = "Topic closed"; -"Notification.TopicReopened" = "Topic reopened"; -"Notification.TopicClosedAuthor" = "%1$@ closed topic"; -"Notification.TopicReopenedAuthor" = "%1$@ reopened topic"; -"Notification.TopicRenamed" = "Topic renamed to \"%1$@\""; -"Notification.TopicRenamedAuthor" = "%1$@ changed the topic title to \"%2$@\""; -"Notification.TopicIconChanged" = "Topic icon changed to %1$@"; -"Notification.TopicIconChangedAuthor" = "%1$@ changed the topic icon to %2$@"; -"Notification.TopicRenamedIconChangedAuthor" = "%1$@ changed the topic title and icon to %2$@ %3$@"; +"Notification.ForumTopicCreated" = "Topic created"; +"Notification.ForumTopicClosed" = "Topic closed"; +"Notification.ForumTopicReopened" = "Topic reopened"; +"Notification.ForumTopicClosedAuthor" = "%1$@ closed topic"; +"Notification.ForumTopicReopenedAuthor" = "%1$@ reopened topic"; +"Notification.ForumTopicRenamed" = "Topic renamed to \"%1$@\""; +"Notification.ForumTopicRenamedAuthor" = "%1$@ changed the topic title to \"%2$@\""; +"Notification.ForumTopicIconChanged" = "Topic icon changed to %1$@"; +"Notification.ForumTopicIconChangedAuthor" = "%1$@ changed the topic icon to %2$@"; +"Notification.ForumTopicRenamedIconChangedAuthor" = "%1$@ changed the topic title and icon to %2$@ %3$@"; "Notification.OverviewTopicCreated" = "%1$@ %2$@ was created"; "Notification.OverviewTopicClosed" = "%1$@ closed %2$@ %3$@"; "Notification.OverviewTopicReopened" = "%1$@ reopened %2$@ %3$@"; diff --git a/submodules/PlatformRestrictionMatching/BUILD b/submodules/PlatformRestrictionMatching/BUILD index aac02946cc..ac59329474 100644 --- a/submodules/PlatformRestrictionMatching/BUILD +++ b/submodules/PlatformRestrictionMatching/BUILD @@ -11,6 +11,7 @@ swift_library( ], deps = [ "//submodules/TelegramCore:TelegramCore", + "//submodules/Postbox:Postbox", ], visibility = [ "//visibility:public", diff --git a/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift b/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift index 5412e6466e..b3ed30e88a 100644 --- a/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift +++ b/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift @@ -1,10 +1,20 @@ import Foundation import TelegramCore +import Postbox + +public extension Message { + func isRestricted(platform: String, contentSettings: ContentSettings) -> Bool { + if let attribute = self.restrictedContentAttribute { + return attribute.platformText(platform: platform, contentSettings: contentSettings) != nil + } + return false + } +} public extension RestrictedContentMessageAttribute { func platformText(platform: String, contentSettings: ContentSettings) -> String? { for rule in self.rules { - if rule.platform == "all" || rule.platform == "ios" { + if rule.platform == "all" || rule.platform == "ios" || contentSettings.addContentRestrictionReasons.contains(rule.platform) { if !contentSettings.ignoreContentRestrictionReasons.contains(rule.reason) { return rule.text } diff --git a/submodules/TelegramApi/Sources/Api29.swift b/submodules/TelegramApi/Sources/Api29.swift index 12c4729078..dbfb3fc069 100644 --- a/submodules/TelegramApi/Sources/Api29.swift +++ b/submodules/TelegramApi/Sources/Api29.swift @@ -5364,16 +5364,17 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func prolongWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func prolongWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMsgId: Int32?, topMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-362824498) + buffer.appendInt32(2146648841) serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) bot.serialize(buffer, true) serializeInt64(queryId, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 0) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 9) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)} - return (FunctionDescription(name: "messages.prolongWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("queryId", String(describing: queryId)), ("replyToMsgId", String(describing: replyToMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in + return (FunctionDescription(name: "messages.prolongWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("queryId", String(describing: queryId)), ("replyToMsgId", String(describing: replyToMsgId)), ("topMsgId", String(describing: topMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in let reader = BufferReader(buffer) var result: Api.Bool? if let signature = reader.readInt32() { @@ -5718,9 +5719,9 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func requestWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, url: String?, startParam: String?, themeParams: Api.DataJSON?, platform: String, replyToMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func requestWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, url: String?, startParam: String?, themeParams: Api.DataJSON?, platform: String, replyToMsgId: Int32?, topMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-58219204) + buffer.appendInt32(395003915) serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) bot.serialize(buffer, true) @@ -5729,8 +5730,9 @@ public extension Api.functions.messages { if Int(flags) & Int(1 << 2) != 0 {themeParams!.serialize(buffer, true)} serializeString(platform, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 0) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 9) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)} - return (FunctionDescription(name: "messages.requestWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("url", String(describing: url)), ("startParam", String(describing: startParam)), ("themeParams", String(describing: themeParams)), ("platform", String(describing: platform)), ("replyToMsgId", String(describing: replyToMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.WebViewResult? in + return (FunctionDescription(name: "messages.requestWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("url", String(describing: url)), ("startParam", String(describing: startParam)), ("themeParams", String(describing: themeParams)), ("platform", String(describing: platform)), ("replyToMsgId", String(describing: replyToMsgId)), ("topMsgId", String(describing: topMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.WebViewResult? in let reader = BufferReader(buffer) var result: Api.WebViewResult? if let signature = reader.readInt32() { @@ -6542,11 +6544,13 @@ public extension Api.functions.messages { } } public extension Api.functions.messages { - static func unpinAllMessages(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func unpinAllMessages(flags: Int32, peer: Api.InputPeer, topMsgId: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(-265962357) + buffer.appendInt32(-299714136) + serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) - return (FunctionDescription(name: "messages.unpinAllMessages", parameters: [("peer", String(describing: peer))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.AffectedHistory? in + if Int(flags) & Int(1 << 0) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)} + return (FunctionDescription(name: "messages.unpinAllMessages", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("topMsgId", String(describing: topMsgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.AffectedHistory? in let reader = BufferReader(buffer) var result: Api.messages.AffectedHistory? if let signature = reader.readInt32() { diff --git a/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift b/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift index 31081d4f98..11f06f6a33 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ChatContextResult.swift @@ -478,7 +478,7 @@ extension ChatContextResultMessage { if let replyMarkup = replyMarkup { parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup) } - self = .invoice(media: TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: currency, totalAmount: totalAmount, startParam: "", extendedMedia: nil, flags: parsedFlags), replyMarkup: parsedReplyMarkup) + self = .invoice(media: TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: currency, totalAmount: totalAmount, startParam: "", extendedMedia: nil, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion), replyMarkup: parsedReplyMarkup) } } } diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index 26b42b12df..4385ed3812 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -336,7 +336,7 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI extendedMedia = nil } - return (TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: receiptMsgId.flatMap { MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }, currency: currency, totalAmount: totalAmount, startParam: startParam, extendedMedia: extendedMedia, flags: parsedFlags), nil, nil) + return (TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: receiptMsgId.flatMap { MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }, currency: currency, totalAmount: totalAmount, startParam: startParam, extendedMedia: extendedMedia, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion), nil, nil) case let .messageMediaPoll(poll, results): switch poll { case let .poll(id, flags, question, answers, closePeriod, _): diff --git a/submodules/TelegramCore/Sources/Settings/ContentSettings.swift b/submodules/TelegramCore/Sources/Settings/ContentSettings.swift index 077f47f26a..204fc79900 100644 --- a/submodules/TelegramCore/Sources/Settings/ContentSettings.swift +++ b/submodules/TelegramCore/Sources/Settings/ContentSettings.swift @@ -4,22 +4,30 @@ import TelegramApi import SwiftSignalKit public struct ContentSettings: Equatable { - public static var `default` = ContentSettings(ignoreContentRestrictionReasons: []) + public static var `default` = ContentSettings(ignoreContentRestrictionReasons: [], addContentRestrictionReasons: []) public var ignoreContentRestrictionReasons: Set + public var addContentRestrictionReasons: [String] - public init(ignoreContentRestrictionReasons: Set) { + public init(ignoreContentRestrictionReasons: Set, addContentRestrictionReasons: [String]) { self.ignoreContentRestrictionReasons = ignoreContentRestrictionReasons + self.addContentRestrictionReasons = addContentRestrictionReasons } } extension ContentSettings { init(appConfiguration: AppConfiguration) { var reasons: [String] = [] - if let data = appConfiguration.data, let reasonsData = data["ignore_restriction_reasons"] as? [String] { - reasons = reasonsData + var addContentRestrictionReasons: [String] = [] + if let data = appConfiguration.data { + if let reasonsData = data["ignore_restriction_reasons"] as? [String] { + reasons = reasonsData + } + if let addContentRestrictionReasonsData = data["restriction_add_platforms"] as? [String] { + addContentRestrictionReasons = addContentRestrictionReasonsData + } } - self.init(ignoreContentRestrictionReasons: Set(reasons)) + self.init(ignoreContentRestrictionReasons: Set(reasons), addContentRestrictionReasons: addContentRestrictionReasons) } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaInvoice.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaInvoice.swift index 9fd10615ea..b919f16065 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaInvoice.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaInvoice.swift @@ -17,7 +17,7 @@ public struct TelegramMediaInvoiceFlags: OptionSet { } public enum TelegramExtendedMedia: PostboxCoding, Equatable { - public static func == (lhs: TelegramExtendedMedia, rhs: TelegramExtendedMedia) -> Bool { + public static func ==(lhs: TelegramExtendedMedia, rhs: TelegramExtendedMedia) -> Bool { switch lhs { case let .preview(lhsDimensions, lhsImmediateThumbnailData, lhsVideoDuration): if case let .preview(rhsDimensions, rhsImmediateThumbnailData, rhsVideoDuration) = rhs, lhsDimensions == rhsDimensions, lhsImmediateThumbnailData == rhsImmediateThumbnailData, lhsVideoDuration == rhsVideoDuration { @@ -88,6 +88,8 @@ public enum TelegramExtendedMedia: PostboxCoding, Equatable { } public final class TelegramMediaInvoice: Media { + public static let lastVersion: Int32 = 1 + public var peerIds: [PeerId] = [] public var id: MediaId? = nil @@ -102,7 +104,9 @@ public final class TelegramMediaInvoice: Media { public let flags: TelegramMediaInvoiceFlags public let extendedMedia: TelegramExtendedMedia? - public init(title: String, description: String, photo: TelegramMediaWebFile?, receiptMessageId: MessageId?, currency: String, totalAmount: Int64, startParam: String, extendedMedia: TelegramExtendedMedia?, flags: TelegramMediaInvoiceFlags) { + public let version: Int32 + + public init(title: String, description: String, photo: TelegramMediaWebFile?, receiptMessageId: MessageId?, currency: String, totalAmount: Int64, startParam: String, extendedMedia: TelegramExtendedMedia?, flags: TelegramMediaInvoiceFlags, version: Int32) { self.title = title self.description = description self.photo = photo @@ -112,6 +116,7 @@ public final class TelegramMediaInvoice: Media { self.startParam = startParam self.flags = flags self.extendedMedia = extendedMedia + self.version = version } public init(decoder: PostboxDecoder) { @@ -129,6 +134,8 @@ public final class TelegramMediaInvoice: Media { } else { self.receiptMessageId = nil } + + self.version = decoder.decodeInt32ForKey("vrs", orElse: 0) } public func encode(_ encoder: PostboxEncoder) { @@ -160,6 +167,8 @@ public final class TelegramMediaInvoice: Media { encoder.encodeNil(forKey: "r.n") encoder.encodeNil(forKey: "r.i") } + + encoder.encodeInt32(self.version, forKey: "vrs") } public func isEqual(to other: Media) -> Bool { @@ -199,6 +208,10 @@ public final class TelegramMediaInvoice: Media { return false } + if self.version != other.version { + return false + } + return true } @@ -216,6 +229,8 @@ public final class TelegramMediaInvoice: Media { totalAmount: self.totalAmount, startParam: self.startParam, extendedMedia: extendedMedia, - flags: self.flags) + flags: self.flags, + version: self.version + ) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift index bbd3dc740c..2680c6d8fd 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/BotWebView.swift @@ -57,10 +57,10 @@ public enum RequestWebViewError { case generic } -private func keepWebViewSignal(network: Network, stateManager: AccountStateManager, flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMessageId: MessageId?, sendAs: Api.InputPeer?) -> Signal { +private func keepWebViewSignal(network: Network, stateManager: AccountStateManager, flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMessageId: MessageId?, threadId: Int64?, sendAs: Api.InputPeer?) -> Signal { let signal = Signal { subscriber in let poll = Signal { subscriber in - let signal: Signal = network.request(Api.functions.messages.prolongWebView(flags: flags, peer: peer, bot: bot, queryId: queryId, replyToMsgId: replyToMessageId?.id, sendAs: sendAs)) + let signal: Signal = network.request(Api.functions.messages.prolongWebView(flags: flags, peer: peer, bot: bot, queryId: queryId, replyToMsgId: replyToMessageId?.id, topMsgId: threadId.flatMap(Int32.init(clamping:)), sendAs: sendAs)) |> mapError { _ -> KeepWebViewError in return .generic } @@ -99,7 +99,7 @@ private func keepWebViewSignal(network: Network, stateManager: AccountStateManag return signal } -func _internal_requestWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?) -> Signal { +func _internal_requestWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?, threadId: Int64?) -> Signal { var serializedThemeParams: Api.DataJSON? if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) { serializedThemeParams = .dataJSON(data: dataString) @@ -128,17 +128,20 @@ func _internal_requestWebView(postbox: Postbox, network: Network, stateManager: if fromMenu { flags |= (1 << 4) } + if threadId != nil { + flags |= (1 << 9) + } // if _ { // flags |= (1 << 13) // } - return network.request(Api.functions.messages.requestWebView(flags: flags, peer: inputPeer, bot: inputBot, url: url, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform, replyToMsgId: replyToMsgId, sendAs: nil)) + return network.request(Api.functions.messages.requestWebView(flags: flags, peer: inputPeer, bot: inputBot, url: url, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform, replyToMsgId: replyToMsgId, topMsgId: threadId.flatMap(Int32.init(clamping:)), sendAs: nil)) |> mapError { _ -> RequestWebViewError in return .generic } |> mapToSignal { result -> Signal in switch result { case let .webViewResultUrl(queryId, url): - return .single(RequestWebViewResult(queryId: queryId, url: url, keepAliveSignal: keepWebViewSignal(network: network, stateManager: stateManager, flags: flags, peer: inputPeer, bot: inputBot, queryId: queryId, replyToMessageId: replyToMessageId, sendAs: nil))) + return .single(RequestWebViewResult(queryId: queryId, url: url, keepAliveSignal: keepWebViewSignal(network: network, stateManager: stateManager, flags: flags, peer: inputPeer, bot: inputBot, queryId: queryId, replyToMessageId: replyToMessageId, threadId: threadId, sendAs: nil))) } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index be02729d5a..f08a54605f 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -106,8 +106,8 @@ public extension TelegramEngine { return _internal_requestUpdatePinnedMessage(account: self.account, peerId: peerId, update: update) } - public func requestUnpinAllMessages(peerId: PeerId) -> Signal { - return _internal_requestUnpinAllMessages(account: self.account, peerId: peerId) + public func requestUnpinAllMessages(peerId: PeerId, threadId: Int64?) -> Signal { + return _internal_requestUnpinAllMessages(account: self.account, peerId: peerId, threadId: threadId) } public func fetchChannelReplyThreadMessage(messageId: MessageId, atMessageId: MessageId?) -> Signal { @@ -382,8 +382,8 @@ public extension TelegramEngine { return _internal_rateAudioTranscription(postbox: self.account.postbox, network: self.account.network, messageId: messageId, id: id, isGood: isGood) } - public func requestWebView(peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?) -> Signal { - return _internal_requestWebView(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, botId: botId, url: url, payload: payload, themeParams: themeParams, fromMenu: fromMenu, replyToMessageId: replyToMessageId) + public func requestWebView(peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?, threadId: Int64?) -> Signal { + return _internal_requestWebView(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, botId: botId, url: url, payload: payload, themeParams: themeParams, fromMenu: fromMenu, replyToMessageId: replyToMessageId, threadId: threadId) } public func requestSimpleWebView(botId: PeerId, url: String, themeParams: [String: Any]?) -> Signal { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift index 9e251da8a2..09ec98fd65 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/UpdatePinnedMessage.swift @@ -109,7 +109,7 @@ func _internal_requestUpdatePinnedMessage(account: Account, peerId: PeerId, upda } } -func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId) -> Signal { +func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId, threadId: Int64?) -> Signal { return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId)) } @@ -147,7 +147,11 @@ func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId) -> Sign case restart } - let request: Signal = account.network.request(Api.functions.messages.unpinAllMessages(peer: inputPeer)) + var flags: Int32 = 0 + if threadId != nil { + flags |= (1 << 0) + } + let request: Signal = account.network.request(Api.functions.messages.unpinAllMessages(flags: flags, peer: inputPeer, topMsgId: threadId.flatMap(Int32.init(clamping:)))) |> mapError { error -> InternalError in return .error(error.errorDescription) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift index d584cd3b32..afe99307af 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift @@ -239,7 +239,7 @@ func _internal_fetchBotPaymentInvoice(postbox: Postbox, network: Network, source parsedFlags.insert(.shippingAddressRequested) } - return TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: parsedInvoice.currency, totalAmount: 0, startParam: "", extendedMedia: nil, flags: parsedFlags) + return TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: parsedInvoice.currency, totalAmount: 0, startParam: "", extendedMedia: nil, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion) } } |> mapError { _ -> BotPaymentFormRequestError in } @@ -613,7 +613,8 @@ func _internal_requestBotPaymentReceipt(account: Account, messageId: MessageId) totalAmount: totalAmount, startParam: "", extendedMedia: nil, - flags: [] + flags: [], + version: TelegramMediaInvoice.lastVersion ) let botPaymentId = PeerId.init(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)) diff --git a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift index c19bd2855f..c64078714a 100644 --- a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift @@ -355,6 +355,15 @@ public extension Message { } return nil } + + var restrictedContentAttribute: RestrictedContentMessageAttribute? { + for attribute in self.attributes { + if let attribute = attribute as? RestrictedContentMessageAttribute { + return attribute + } + } + return nil + } } public func _internal_parseMediaAttachment(data: Data) -> Media? { diff --git a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift index 7a547eea0b..1fe65c511c 100644 --- a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift +++ b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift @@ -684,7 +684,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, let maybeFileId = iconFileId ?? 0 attributedString = addAttributesToStringWithRanges(strings.Notification_OverviewTopicCreated(".", title)._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) } else { - attributedString = NSAttributedString(string: strings.Notification_TopicCreated, font: titleFont, textColor: primaryTextColor) + attributedString = NSAttributedString(string: strings.Notification_ForumTopicCreated, font: titleFont, textColor: primaryTextColor) } case let .topicEdited(components): if let isClosed = components.compactMap({ item -> Bool? in @@ -712,16 +712,16 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, } } else { if isClosed { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicClosedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) + attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicClosedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) } else { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicReopenedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) + attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicReopenedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) } } } else { if isClosed { - attributedString = NSAttributedString(string: strings.Notification_TopicClosed, font: titleFont, textColor: primaryTextColor) + attributedString = NSAttributedString(string: strings.Notification_ForumTopicClosed, font: titleFont, textColor: primaryTextColor) } else { - attributedString = NSAttributedString(string: strings.Notification_TopicReopened, font: titleFont, textColor: primaryTextColor) + attributedString = NSAttributedString(string: strings.Notification_ForumTopicReopened, font: titleFont, textColor: primaryTextColor) } } } else if let maybeFileId = components.compactMap({ item -> Int64? in @@ -744,12 +744,12 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, if let info = message.associatedThreadInfo { iconColor = info.iconColor } - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicRenamedIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".", title)._tuple, body: bodyAttributes, argumentAttributes: [ + attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicRenamedIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".", title)._tuple, body: bodyAttributes, argumentAttributes: [ 0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)]) ]) } else { - attributedString = NSAttributedString(string: strings.Notification_TopicRenamed(title).string, font: titleFont, textColor: primaryTextColor) + attributedString = NSAttributedString(string: strings.Notification_ForumTopicRenamed(title).string, font: titleFont, textColor: primaryTextColor) } } else if let title = components.compactMap({ item -> String? in switch item { @@ -760,9 +760,9 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, } }).first { if case let .user(user) = message.author { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicRenamedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), title)._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) + attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicRenamedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), title)._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) } else { - attributedString = NSAttributedString(string: strings.Notification_TopicRenamed(title).string, font: titleFont, textColor: primaryTextColor) + attributedString = NSAttributedString(string: strings.Notification_ForumTopicRenamed(title).string, font: titleFont, textColor: primaryTextColor) } } else if let maybeFileId = components.compactMap({ item -> Int64? in switch item { @@ -779,9 +779,9 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, title = info.title } if case let .user(user) = message.author { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".")._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) + attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".")._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) } else { - attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChanged(".")._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) + attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicIconChanged(".")._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) } } case .unknown: diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index bb1d8f7c5a..9f7d62d360 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -3934,7 +3934,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, fromMenu: true, isSimple: false) - let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in + let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url in self?.openUrl(url, concealed: true, forceExternal: true) }, getInputContainerNode: { [weak self] in if let strongSelf = self, let layout = strongSelf.validLayout, case .compact = layout.metrics.widthClass { @@ -3978,7 +3978,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, fromMenu: false, isSimple: true) - let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in + let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url in self?.openUrl(url, concealed: true, forceExternal: true) }, getNavigationController: { [weak self] in return self?.effectiveNavigationController @@ -3993,7 +3993,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } })) } else { - strongSelf.messageActionCallbackDisposable.set(((strongSelf.context.engine.messages.requestWebView(peerId: peerId, botId: peerId, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(strongSelf.presentationData.theme), fromMenu: buttonText == "Menu", replyToMessageId: nil) + strongSelf.messageActionCallbackDisposable.set(((strongSelf.context.engine.messages.requestWebView(peerId: peerId, botId: peerId, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(strongSelf.presentationData.theme), fromMenu: buttonText == "Menu", replyToMessageId: nil, threadId: strongSelf.chatLocation.threadId) |> afterDisposed { updateProgress() }) @@ -4002,7 +4002,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: result.url, queryId: result.queryId, payload: nil, buttonText: buttonText, keepAliveSignal: result.keepAliveSignal, fromMenu: false, isSimple: false) - let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in + let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url in self?.openUrl(url, concealed: true, forceExternal: true) }, completion: { [weak self] in self?.chatDisplayNode.historyNode.scrollToEndOfHistory() @@ -12195,7 +12195,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G case let .app(bot, botName, _): let params = WebAppParameters(peerId: peer.id, botId: bot.id, botName: botName, url: nil, queryId: nil, payload: botPayload, buttonText: nil, keepAliveSignal: nil, fromMenu: false, isSimple: false) let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId - let controller = WebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, replyToMessageId: replyMessageId) + let controller = WebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, replyToMessageId: replyMessageId, threadId: strongSelf.chatLocation.threadId) controller.openUrl = { [weak self] url in self?.openUrl(url, concealed: true, forceExternal: true) } @@ -17028,7 +17028,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch action { case .commit: - let _ = (strongSelf.context.engine.messages.requestUnpinAllMessages(peerId: peerId) + let _ = (strongSelf.context.engine.messages.requestUnpinAllMessages(peerId: peerId, threadId: strongSelf.chatLocation.threadId) |> deliverOnMainQueue).start(error: { _ in }, completed: { guard let strongSelf = self else { diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index be1dcf86e8..d499b6df55 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -2042,6 +2042,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } } else if let invoice = media as? TelegramMediaInvoice, let extendedMedia = invoice.extendedMedia, case .preview = extendedMedia { messageIdsWithInactiveExtendedMedia.insert(message.id) + if invoice.version != TelegramMediaInvoice.lastVersion { + contentRequiredValidation = true + } } } if contentRequiredValidation { diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 468b75054a..1104efe85d 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -1077,7 +1077,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { var edited = false var viewCount: Int? = nil var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute, isEmoji { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift index 11944cc7a2..f3fb5f65a8 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift @@ -338,7 +338,10 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: associatedData.accountPeer, message: message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: associatedData.accountPeer, message: message) + if message.isRestricted(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 41a063a254..adf4396274 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -1465,6 +1465,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } + if firstMessage.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + replyMarkup = nil + } + if let forwardInfo = firstMessage.forwardInfo, forwardInfo.psaType != nil { inlineBotNameString = nil } @@ -1759,7 +1763,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: message) + if message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift index da8dc48a2e..86a485cd44 100644 --- a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift @@ -172,7 +172,10 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode { } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift index 8666a411cb..0e1c948392 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift @@ -781,7 +781,10 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: arguments.associatedData.accountPeer, message: arguments.topMessage) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: arguments.associatedData.accountPeer, message: arguments.topMessage) + if arguments.topMessage.isRestricted(platform: "ios", contentSettings: arguments.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in arguments.message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index fd0b3e6d64..801af4bd22 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -463,7 +463,10 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { let sentViaBot = false var viewCount: Int? = nil var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift index 2a327009bd..e2709d08e8 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift @@ -183,7 +183,10 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift index 750ef8b5bf..b6860844a4 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift @@ -218,7 +218,10 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute { if case .mosaic = preparePosition { diff --git a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift index ee9cfd6967..692ee29ba9 100644 --- a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift @@ -1053,7 +1053,10 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift index e4677a7bf0..2fe0f93251 100644 --- a/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift @@ -53,7 +53,10 @@ class ChatMessageRestrictedBubbleContentNode: ChatMessageBubbleContentNode { var viewCount: Int? var rawText = "" var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 110178d951..bd0fe45141 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -520,7 +520,10 @@ class ChatMessageStickerItemNode: ChatMessageItemView { var edited = false var viewCount: Int? = nil var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute, isEmoji { edited = !attribute.isHidden diff --git a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift index d16bc75b65..21532deaaa 100644 --- a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift @@ -157,7 +157,10 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } var viewCount: Int? var dateReplies = 0 - let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.topMessage) + var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.topMessage) + if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) { + dateReactionsAndPeers = ([], []) + } for attribute in item.message.attributes { if let attribute = attribute as? EditedMessageAttribute { diff --git a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift index ecb0b7d20c..6f139097d7 100644 --- a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift @@ -317,7 +317,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { messageUpdated = true } - if let message = interfaceState.pinnedMessage { + if let message = interfaceState.pinnedMessage, !message.message.isRestricted(platform: "ios", contentSettings: self.context.currentContentSettings.with { $0 }) { for attribute in message.message.attributes { if let attribute = attribute as? ReplyMarkupMessageAttribute, attribute.flags.contains(.inline), attribute.rows.count == 1, attribute.rows[0].buttons.count == 1 { actionTitle = attribute.rows[0].buttons[0].title diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift index 34801b396b..7a74c8deb1 100644 --- a/submodules/WebUI/Sources/WebAppController.swift +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -350,7 +350,7 @@ public final class WebAppController: ViewController, AttachmentContainable { }) } } else { - let _ = (context.engine.messages.requestWebView(peerId: controller.peerId, botId: controller.botId, url: controller.url, payload: controller.payload, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: controller.fromMenu, replyToMessageId: controller.replyToMessageId) + let _ = (context.engine.messages.requestWebView(peerId: controller.peerId, botId: controller.botId, url: controller.url, payload: controller.payload, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: controller.fromMenu, replyToMessageId: controller.replyToMessageId, threadId: controller.threadId) |> deliverOnMainQueue).start(next: { [weak self] result in guard let strongSelf = self else { return @@ -985,6 +985,7 @@ public final class WebAppController: ViewController, AttachmentContainable { private let isSimple: Bool private let keepAliveSignal: Signal? private let replyToMessageId: MessageId? + private let threadId: Int64? private var presentationData: PresentationData fileprivate let updatedPresentationData: (initial: PresentationData, signal: Signal)? @@ -994,7 +995,7 @@ public final class WebAppController: ViewController, AttachmentContainable { public var getNavigationController: () -> NavigationController? = { return nil } public var completion: () -> Void = {} - public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, params: WebAppParameters, replyToMessageId: MessageId?) { + public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, params: WebAppParameters, replyToMessageId: MessageId?, threadId: Int64?) { self.context = context self.peerId = params.peerId self.botId = params.botId @@ -1007,6 +1008,7 @@ public final class WebAppController: ViewController, AttachmentContainable { self.isSimple = params.isSimple self.keepAliveSignal = params.keepAliveSignal self.replyToMessageId = replyToMessageId + self.threadId = threadId self.updatedPresentationData = updatedPresentationData self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 } @@ -1285,13 +1287,13 @@ private final class WebAppContextReferenceContentSource: ContextReferenceContent } } -public func standaloneWebAppController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, params: WebAppParameters, openUrl: @escaping (String) -> Void, getInputContainerNode: @escaping () -> (CGFloat, ASDisplayNode, () -> AttachmentController.InputPanelTransition?)? = { return nil }, completion: @escaping () -> Void = {}, willDismiss: @escaping () -> Void = {}, didDismiss: @escaping () -> Void = {}, getNavigationController: @escaping () -> NavigationController? = { return nil }, getSourceRect: (() -> CGRect?)? = nil) -> ViewController { +public func standaloneWebAppController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, params: WebAppParameters, threadId: Int64?, openUrl: @escaping (String) -> Void, getInputContainerNode: @escaping () -> (CGFloat, ASDisplayNode, () -> AttachmentController.InputPanelTransition?)? = { return nil }, completion: @escaping () -> Void = {}, willDismiss: @escaping () -> Void = {}, didDismiss: @escaping () -> Void = {}, getNavigationController: @escaping () -> NavigationController? = { return nil }, getSourceRect: (() -> CGRect?)? = nil) -> ViewController { let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: params.peerId), buttons: [.standalone], initialButton: .standalone, fromMenu: params.fromMenu, hasTextInput: false, makeEntityInputView: { return nil }) controller.getInputContainerNode = getInputContainerNode controller.requestController = { _, present in - let webAppController = WebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, replyToMessageId: nil) + let webAppController = WebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, replyToMessageId: nil, threadId: threadId) webAppController.openUrl = openUrl webAppController.completion = completion webAppController.getNavigationController = getNavigationController From 98b3abad0bc5d51bfab8b879224751d0c4aa29d2 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 1 Nov 2022 20:25:21 +0400 Subject: [PATCH 8/9] Update tgcalls --- submodules/TgVoipWebrtc/tgcalls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index 07b225568f..53bb1711ae 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit 07b225568fb596ba44d472c3fa413da2f8bd3f2e +Subproject commit 53bb1711ae0b3810d34edb1c81982b18d70c5506 From 94637ac1a68a56b56918a6f3790818b1d26ab28f Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 1 Nov 2022 20:43:33 +0400 Subject: [PATCH 9/9] Fix emoji --- .../Sources/ChatMessageNotificationItem.swift | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift b/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift index 07e1fda1ae..6a9bff67e6 100644 --- a/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift +++ b/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift @@ -84,9 +84,6 @@ final class ChatMessageNotificationItemNode: NotificationItemNode { private var compact: Bool? private var validLayout: CGFloat? - private var animationCache: AnimationCache? - private var multiAnimationRenderer: MultiAnimationRenderer? - override init() { self.avatarNode = AvatarNode(font: avatarFont) @@ -115,8 +112,6 @@ final class ChatMessageNotificationItemNode: NotificationItemNode { func setupItem(_ item: ChatMessageNotificationItem, compact: Bool) { self.item = item - self.animationCache = item.context.animationCache - self.compact = compact if compact { self.avatarNode.font = compactAvatarFont @@ -412,12 +407,12 @@ final class ChatMessageNotificationItemNode: NotificationItemNode { let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: self.textAttributedText, backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .left, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets())) let _ = titleApply() - if let item = self.item, let cache = self.animationCache, let renderer = self.multiAnimationRenderer { + if let item = self.item { let theme = item.context.sharedContext.currentPresentationData.with({ $0 }).theme let _ = textApply(TextNodeWithEntities.Arguments( context: item.context, - cache: cache, - renderer: renderer, + cache: item.context.animationCache, + renderer: item.context.animationRenderer, placeholderColor: theme.list.mediaPlaceholderColor, attemptSynchronous: false ))