Add remote topic search

This commit is contained in:
Isaac 2023-12-17 22:44:14 +04:00
parent d4964e205c
commit 628e794bfd
5 changed files with 87 additions and 9 deletions

View File

@ -1690,7 +1690,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}) })
let foundThreads: Signal<[EngineChatList.Item], NoError> let foundThreads: Signal<[EngineChatList.Item], NoError>
if case .forum = location, (key == .topics || key == .chats) { if case let .forum(peerId) = location, (key == .topics || key == .chats) {
foundThreads = chatListViewForLocation(chatListLocation: location, location: .initial(count: 1000, filter: nil), account: context.account) foundThreads = chatListViewForLocation(chatListLocation: location, location: .initial(count: 1000, filter: nil), account: context.account)
|> map { view -> [EngineChatList.Item] in |> map { view -> [EngineChatList.Item] in
var filteredItems: [EngineChatList.Item] = [] var filteredItems: [EngineChatList.Item] = []
@ -1708,6 +1708,24 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return filteredItems return filteredItems
} }
|> mapToSignal { local -> Signal<[EngineChatList.Item], NoError> in
return .single(local)
|> then(context.engine.messages.searchForumTopics(peerId: peerId, query: finalQuery)
|> map { remoteResult in
var mergedResult = local
for item in remoteResult {
guard case let .forum(threadId) = item.id else {
continue
}
if !mergedResult.contains(where: { $0.id == .forum(threadId) }) {
mergedResult.append(item)
}
}
return mergedResult
})
}
|> distinctUntilChanged
} else { } else {
foundThreads = .single([]) foundThreads = .single([])
} }

View File

@ -570,7 +570,7 @@ enum LoadMessageHistoryThreadsError {
case generic case generic
} }
func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, offsetIndex: StoredPeerThreadCombinedState.Index?, limit: Int) -> Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> { func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, query: String?, offsetIndex: StoredPeerThreadCombinedState.Index?, limit: Int) -> Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> {
let signal: Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> = postbox.transaction { transaction -> Api.InputChannel? in let signal: Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> = postbox.transaction { transaction -> Api.InputChannel? in
guard let channel = transaction.getPeer(peerId) as? TelegramChannel else { guard let channel = transaction.getPeer(peerId) as? TelegramChannel else {
return nil return nil
@ -585,7 +585,12 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post
guard let inputChannel = inputChannel else { guard let inputChannel = inputChannel else {
return .fail(.generic) return .fail(.generic)
} }
let flags: Int32 = 0 var flags: Int32 = 0
if query != nil {
flags |= 1 << 0
}
var offsetDate: Int32 = 0 var offsetDate: Int32 = 0
var offsetId: Int32 = 0 var offsetId: Int32 = 0
var offsetTopic: Int32 = 0 var offsetTopic: Int32 = 0
@ -597,7 +602,7 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post
let signal: Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> = network.request(Api.functions.channels.getForumTopics( let signal: Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> = network.request(Api.functions.channels.getForumTopics(
flags: flags, flags: flags,
channel: inputChannel, channel: inputChannel,
q: nil, q: query,
offsetDate: offsetDate, offsetDate: offsetDate,
offsetId: offsetId, offsetId: offsetId,
offsetTopic: offsetTopic, offsetTopic: offsetTopic,
@ -839,6 +844,59 @@ func _internal_forumChannelTopicNotificationExceptions(account: Account, id: Eng
} }
} }
public func _internal_searchForumTopics(account: Account, peerId: EnginePeer.Id, query: String) -> Signal<[EngineChatList.Item], NoError> {
return _internal_requestMessageHistoryThreads(accountPeerId: account.peerId, postbox: account.postbox, network: account.network, peerId: peerId, query: query, offsetIndex: nil, limit: 100)
|> map(Optional.init)
|> `catch` { _ -> Signal<LoadMessageHistoryThreadsResult?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<[EngineChatList.Item], NoError> in
guard let result else {
return .single([])
}
return account.postbox.transaction { transcation -> [EngineChatList.Item] in
guard let peer = transcation.getPeer(peerId) else {
return []
}
var items: [EngineChatList.Item] = []
for item in result.items {
guard let index = item.index else {
continue
}
items.append(EngineChatList.Item(
id: .forum(item.threadId),
index: .forum(pinnedIndex: .none, timestamp: index.timestamp, threadId: index.threadId, namespace: Namespaces.Message.Cloud, id: index.messageId),
messages: [],
readCounters: nil,
isMuted: false,
draft: nil,
threadData: item.data,
renderedPeer: EngineRenderedPeer(peer: EnginePeer(peer)),
presence: nil,
hasUnseenMentions: false,
hasUnseenReactions: false,
forumTopicData: EngineChatList.ForumTopicData(
id: item.threadId,
title: item.data.info.title,
iconFileId: item.data.info.icon,
iconColor: item.data.info.iconColor,
maxOutgoingReadMessageId: EngineMessage.Id(peerId: peerId, namespace: Namespaces.Message.Cloud, id: item.data.maxOutgoingReadId),
isUnread: false
),
topForumTopicItems: [],
hasFailed: false,
isContact: false,
autoremoveTimeout: nil,
storyStats: nil
))
}
return items
}
}
}
public final class ForumChannelTopics { public final class ForumChannelTopics {
private final class Impl { private final class Impl {
private let queue: Queue private let queue: Queue
@ -859,8 +917,6 @@ public final class ForumChannelTopics {
self.account = account self.account = account
self.peerId = peerId self.peerId = peerId
//let _ = _internal_loadMessageHistoryThreads(account: self.account, peerId: peerId, offsetIndex: nil, limit: 100).start()
self.updateDisposable.set(account.viewTracker.polledChannel(peerId: peerId).start()) self.updateDisposable.set(account.viewTracker.polledChannel(peerId: peerId).start())
} }

View File

@ -2833,7 +2833,7 @@ func resetChannels(accountPeerId: PeerId, postbox: Postbox, network: Network, pe
var resetTopicsSignals: [Signal<StateResetForumTopics, NoError>] = [] var resetTopicsSignals: [Signal<StateResetForumTopics, NoError>] = []
for resetForumTopicPeerId in resetForumTopics { for resetForumTopicPeerId in resetForumTopics {
resetTopicsSignals.append(_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: resetForumTopicPeerId, offsetIndex: nil, limit: 20) resetTopicsSignals.append(_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: resetForumTopicPeerId, query: nil, offsetIndex: nil, limit: 20)
|> map(StateResetForumTopics.result) |> map(StateResetForumTopics.result)
|> `catch` { _ -> Signal<StateResetForumTopics, NoError> in |> `catch` { _ -> Signal<StateResetForumTopics, NoError> in
return .single(.error(resetForumTopicPeerId)) return .single(.error(resetForumTopicPeerId))
@ -3113,7 +3113,7 @@ private func pollChannel(accountPeerId: PeerId, postbox: Postbox, network: Netwo
var resetTopicsSignals: [Signal<StateResetForumTopics, NoError>] = [] var resetTopicsSignals: [Signal<StateResetForumTopics, NoError>] = []
for resetForumTopicPeerId in resetForumTopics { for resetForumTopicPeerId in resetForumTopics {
resetTopicsSignals.append(_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: resetForumTopicPeerId, offsetIndex: nil, limit: 20) resetTopicsSignals.append(_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: resetForumTopicPeerId, query: nil, offsetIndex: nil, limit: 20)
|> map(StateResetForumTopics.result) |> map(StateResetForumTopics.result)
|> `catch` { _ -> Signal<StateResetForumTopics, NoError> in |> `catch` { _ -> Signal<StateResetForumTopics, NoError> in
return .single(.error(resetForumTopicPeerId)) return .single(.error(resetForumTopicPeerId))

View File

@ -143,7 +143,7 @@ func managedForumTopicListHoles(network: Network, postbox: Postbox, accountPeerI
} }
for (entry, disposable) in added { for (entry, disposable) in added {
disposable.set((_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: entry.peerId, offsetIndex: entry.index, limit: 100) disposable.set((_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: entry.peerId, query: nil, offsetIndex: entry.index, limit: 100)
|> mapToSignal { result -> Signal<Never, LoadMessageHistoryThreadsError> in |> mapToSignal { result -> Signal<Never, LoadMessageHistoryThreadsError> in
return postbox.transaction { transaction in return postbox.transaction { transaction in
return applyLoadMessageHistoryThreadsResults(accountPeerId: accountPeerId, transaction: transaction, results: [result]) return applyLoadMessageHistoryThreadsResults(accountPeerId: accountPeerId, transaction: transaction, results: [result])

View File

@ -637,6 +637,10 @@ public extension TelegramEngine {
|> ignoreValues |> ignoreValues
} }
public func searchForumTopics(peerId: EnginePeer.Id, query: String) -> Signal<[EngineChatList.Item], NoError> {
return _internal_searchForumTopics(account: self.account, peerId: peerId, query: query)
}
public func debugAddHoles() -> Signal<Never, NoError> { public func debugAddHoles() -> Signal<Never, NoError> {
return self.account.postbox.transaction { transaction -> Void in return self.account.postbox.transaction { transaction -> Void in
transaction.addHolesEverywhere(peerNamespaces: [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel], holeNamespace: Namespaces.Message.Cloud) transaction.addHolesEverywhere(peerNamespaces: [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel], holeNamespace: Namespaces.Message.Cloud)