From b1d2eda2460171a89c508594f5b3f8a2761df2ee Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 6 Oct 2020 17:59:46 +0100 Subject: [PATCH] [WIP] --- ...hannelDiscussionGroupSetupController.swift | 18 ++++--- .../Sources/SearchPeerMembers.swift | 48 ++++++++++++------- submodules/TelegramApi/Sources/Api0.swift | 2 +- submodules/TelegramApi/Sources/Api1.swift | 28 +++++++---- .../TelegramCore/Sources/ChannelMembers.swift | 19 ++++++++ .../Sources/ChatSearchInputPanelNode.swift | 3 -- .../ChannelMemberCategoryListContext.swift | 13 ++++- ...annelMemberCategoriesContextsManager.swift | 6 +++ 8 files changed, 100 insertions(+), 37 deletions(-) diff --git a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift index 3e8231b162..7ffe6a614b 100644 --- a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift @@ -560,9 +560,15 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI var isEmptyState = false var displayGroupList = false if let cachedData = view.cachedData as? CachedChannelData { - let isEmpty = cachedData.linkedDiscussionPeerId == nil + var isEmpty = true + switch cachedData.linkedDiscussionPeerId { + case .unknown: + isEmpty = true + case let .known(value): + isEmpty = value == nil + } if let peer = view.peers[view.peerId] as? TelegramChannel, case .broadcast = peer.info { - if cachedData.linkedDiscussionPeerId == nil { + if isEmpty { if groups == nil { isEmptyState = true } else { @@ -570,13 +576,13 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI } } } - if let wasEmpty = wasEmpty, wasEmpty != isEmpty { - crossfade = true - } - wasEmpty = isEmpty } else { isEmptyState = true } + if let wasEmpty = wasEmpty, wasEmpty != isEmptyState { + crossfade = true + } + wasEmpty = isEmptyState var emptyStateItem: ItemListControllerEmptyStateItem? if isEmptyState { diff --git a/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift b/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift index df45680f8d..05c001fd06 100644 --- a/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift +++ b/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift @@ -11,14 +11,12 @@ public enum SearchPeerMembersScope { } public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocation: ChatLocation, query: String, scope: SearchPeerMembersScope) -> Signal<[Peer], NoError> { - if case .replyThread = chatLocation { - return .single([]) - } else if peerId.namespace == Namespaces.Peer.CloudChannel { + if peerId.namespace == Namespaces.Peer.CloudChannel { return context.account.postbox.transaction { transaction -> CachedChannelData? in return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData } |> mapToSignal { cachedData -> Signal<([Peer], Bool), NoError> in - if let cachedData = cachedData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 64 { + if case .peer = chatLocation, let cachedData = cachedData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 64 { return Signal { subscriber in let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, requestUpdate: false, updated: { state in if case .ready = state.loadingState { @@ -54,19 +52,37 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat } return Signal { subscriber in - let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query.isEmpty ? nil : query, updated: { state in - if case .ready = state.loadingState { - subscriber.putNext((state.list.compactMap { participant in - if participant.peer.isDeleted { - return nil - } - return participant.peer - }, true)) + switch chatLocation { + case let .peer(peerId): + let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query.isEmpty ? nil : query, updated: { state in + if case .ready = state.loadingState { + subscriber.putNext((state.list.compactMap { participant in + if participant.peer.isDeleted { + return nil + } + return participant.peer + }, true)) + } + }) + + return ActionDisposable { + disposable.dispose() + } + case let .replyThread(replyThreadMessage): + let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.mentions(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, threadMessageId: replyThreadMessage.messageId, searchQuery: query.isEmpty ? nil : query, updated: { state in + if case .ready = state.loadingState { + subscriber.putNext((state.list.compactMap { participant in + if participant.peer.isDeleted { + return nil + } + return participant.peer + }, true)) + } + }) + + return ActionDisposable { + disposable.dispose() } - }) - - return ActionDisposable { - disposable.dispose() } } |> runOn(Queue.mainQueue()) } diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index dd824ff79f..874ebaa025 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -322,7 +322,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[106343499] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsSearch($0) } dict[-1548400251] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsKicked($0) } dict[-1150621555] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsContacts($0) } - dict[915357814] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsMentions($0) } + dict[-531931925] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsMentions($0) } dict[-350980120] = { return Api.WebPage.parse_webPageEmpty($0) } dict[-981018084] = { return Api.WebPage.parse_webPagePending($0) } dict[-392411726] = { return Api.WebPage.parse_webPage($0) } diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift index 8e35f0b9c5..1dd38eed77 100644 --- a/submodules/TelegramApi/Sources/Api1.swift +++ b/submodules/TelegramApi/Sources/Api1.swift @@ -9991,7 +9991,7 @@ public extension Api { case channelParticipantsSearch(q: String) case channelParticipantsKicked(q: String) case channelParticipantsContacts(q: String) - case channelParticipantsMentions(q: String) + case channelParticipantsMentions(flags: Int32, q: String?, topMsgId: Int32?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -10037,11 +10037,13 @@ public extension Api { } serializeString(q, buffer: buffer, boxed: false) break - case .channelParticipantsMentions(let q): + case .channelParticipantsMentions(let flags, let q, let topMsgId): if boxed { - buffer.appendInt32(915357814) + buffer.appendInt32(-531931925) } - serializeString(q, buffer: buffer, boxed: false) + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {serializeString(q!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 1) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)} break } } @@ -10062,8 +10064,8 @@ public extension Api { return ("channelParticipantsKicked", [("q", q)]) case .channelParticipantsContacts(let q): return ("channelParticipantsContacts", [("q", q)]) - case .channelParticipantsMentions(let q): - return ("channelParticipantsMentions", [("q", q)]) + case .channelParticipantsMentions(let flags, let q, let topMsgId): + return ("channelParticipantsMentions", [("flags", flags), ("q", q), ("topMsgId", topMsgId)]) } } @@ -10121,11 +10123,17 @@ public extension Api { } } public static func parse_channelParticipantsMentions(_ reader: BufferReader) -> ChannelParticipantsFilter? { - var _1: String? - _1 = parseString(reader) + var _1: Int32? + _1 = reader.readInt32() + var _2: String? + if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) } + var _3: Int32? + if Int(_1!) & Int(1 << 1) != 0 {_3 = reader.readInt32() } let _c1 = _1 != nil - if _c1 { - return Api.ChannelParticipantsFilter.channelParticipantsMentions(q: _1!) + let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil + let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil + if _c1 && _c2 && _c3 { + return Api.ChannelParticipantsFilter.channelParticipantsMentions(flags: _1!, q: _2, topMsgId: _3) } else { return nil diff --git a/submodules/TelegramCore/Sources/ChannelMembers.swift b/submodules/TelegramCore/Sources/ChannelMembers.swift index e2bcdf9e5f..2fe9cbed67 100644 --- a/submodules/TelegramCore/Sources/ChannelMembers.swift +++ b/submodules/TelegramCore/Sources/ChannelMembers.swift @@ -18,6 +18,7 @@ public enum ChannelMembersCategory { case bots(ChannelMembersCategoryFilter) case restricted(ChannelMembersCategoryFilter) case banned(ChannelMembersCategoryFilter) + case mentions(threadId: MessageId?, filter: ChannelMembersCategoryFilter) } public func channelMembers(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, category: ChannelMembersCategory = .recent(.all), offset: Int32 = 0, limit: Int32 = 64, hash: Int32 = 0) -> Signal<[RenderedChannelParticipant]?, NoError> { @@ -32,6 +33,24 @@ public func channelMembers(postbox: Postbox, network: Network, accountPeerId: Pe case let .search(query): apiFilter = .channelParticipantsSearch(q: query) } + case let .mentions(threadId, filter): + switch filter { + case .all: + var flags: Int32 = 0 + if threadId != nil { + flags |= 1 << 1 + } + apiFilter = .channelParticipantsMentions(flags: flags, q: nil, topMsgId: threadId?.id) + case let .search(query): + var flags: Int32 = 0 + if threadId != nil { + flags |= 1 << 1 + } + if !query.isEmpty { + flags |= 1 << 0 + } + apiFilter = .channelParticipantsMentions(flags: flags, q: query.isEmpty ? nil : query, topMsgId: threadId?.id) + } case .admins: apiFilter = .channelParticipantsAdmins case let .contacts(filter): diff --git a/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift index 0f88c5822b..8cbe14652a 100644 --- a/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatSearchInputPanelNode.swift @@ -189,9 +189,6 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode { canSearchMembers = false } } - if case .replyThread = interfaceState.chatLocation { - canSearchMembers = false - } self.membersButton.isHidden = (!(interfaceState.search?.query.isEmpty ?? true)) || self.displayActivity || !canSearchMembers let resultsEnabled = (resultCount ?? 0) > 0 diff --git a/submodules/TemporaryCachedPeerDataManager/Sources/ChannelMemberCategoryListContext.swift b/submodules/TemporaryCachedPeerDataManager/Sources/ChannelMemberCategoryListContext.swift index 21045ada0f..0b20956993 100644 --- a/submodules/TemporaryCachedPeerDataManager/Sources/ChannelMemberCategoryListContext.swift +++ b/submodules/TemporaryCachedPeerDataManager/Sources/ChannelMemberCategoryListContext.swift @@ -64,6 +64,7 @@ public struct ChannelMemberListState { enum ChannelMemberListCategory { case recent case recentSearch(String) + case mentions(MessageId?, String?) case admins(String?) case contacts(String?) case bots(String?) @@ -211,6 +212,12 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor requestCategory = .recent(.all) case let .recentSearch(query): requestCategory = .recent(.search(query)) + case let .mentions(threadId, query): + if let query = query, !query.isEmpty { + requestCategory = .mentions(threadId: threadId, filter: .search(query)) + } else { + requestCategory = .mentions(threadId: threadId, filter: .all) + } case let .admins(query): requestCategory = .admins adminQuery = query @@ -521,6 +528,8 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor } } } + case .mentions: + break } } if updatedList { @@ -728,7 +737,7 @@ final class PeerChannelMemberCategoriesContext { emptyTimeout = 0.0 } switch key { - case .recent, .recentSearch, .admins, .contacts, .bots: + case .recent, .recentSearch, .admins, .contacts, .bots, .mentions: let mappedCategory: ChannelMemberListCategory switch key { case .recent: @@ -741,6 +750,8 @@ final class PeerChannelMemberCategoriesContext { mappedCategory = .contacts(query) case let .bots(query): mappedCategory = .bots(query) + case let .mentions(threadId, query): + mappedCategory = .mentions(threadId, query) default: mappedCategory = .recent } diff --git a/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift b/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift index b5e386a3a8..a2329de73c 100644 --- a/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift +++ b/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift @@ -8,6 +8,7 @@ import TelegramStringFormatting enum PeerChannelMemberContextKey: Equatable, Hashable { case recent case recentSearch(String) + case mentions(threadId: MessageId?, query: String?) case admins(String?) case contacts(String?) case bots(String?) @@ -321,6 +322,11 @@ public final class PeerChannelMemberCategoriesContextsManager { return self.getContext(postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, key: key, requestUpdate: requestUpdate, updated: updated) } + public func mentions(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, threadMessageId: MessageId?, searchQuery: String? = nil, requestUpdate: Bool = true, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) { + let key: PeerChannelMemberContextKey = .mentions(threadId: threadMessageId, query: searchQuery) + return self.getContext(postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, key: key, requestUpdate: requestUpdate, updated: updated) + } + public func admins(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, searchQuery: String? = nil, updated: @escaping (ChannelMemberListState) -> Void) -> (Disposable, PeerChannelMemberCategoryControl?) { return self.getContext(postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, key: .admins(searchQuery), requestUpdate: true, updated: updated) }