From 999db0b76a8364f6dcf4b66100c35e2bcb93a1b3 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 20 Apr 2022 21:03:41 +0400 Subject: [PATCH] Improve recently searched list filtering --- .../ChatListUI/Sources/ChatContextMenus.swift | 21 ++++++--- .../Sources/ChatListSearchListPaneNode.swift | 43 ++++++++++++++++++- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index c6998bfda4..7752f8e0c5 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -49,10 +49,13 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch let presentationData = context.sharedContext.currentPresentationData.with({ $0 }) let strings = presentationData.strings - return context.account.postbox.transaction { transaction -> (PeerGroupId, ChatListIndex)? in - transaction.getPeerChatListIndex(peerId) - } - |> mapToSignal { groupAndIndex -> Signal<[ContextMenuItem], NoError> in + return combineLatest( + context.account.postbox.transaction { transaction -> (PeerGroupId, ChatListIndex)? in + transaction.getPeerChatListIndex(peerId) + }, + context.engine.peers.recentlySearchedPeers() |> take(1) + ) + |> mapToSignal { groupAndIndex, recentlySearchedPeers -> Signal<[ContextMenuItem], NoError> in let location: TogglePeerChatPinnedLocation var chatListFilter: ChatListFilter? if case let .chatList(filter) = source, let chatFilter = filter { @@ -100,7 +103,15 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch }))) items.append(.separator) case .search: - break + if recentlySearchedPeers.contains(where: { $0.peer.peerId == peerId }) { + items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_RemoveFromRecents, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.destructiveColor) }, action: { _, f in + let _ = (context.engine.peers.removeRecentlySearchedPeer(peerId: peerId) + |> deliverOnMainQueue).start(completed: { + f(.default) + }) + }))) + items.append(.separator) + } } } diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index d214616847..01c0fc33cb 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -1082,6 +1082,12 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { downloadItems = .single(([], [])) } + struct SearchedPeersState { + var ids: [EnginePeer.Id] = [] + var query: String? + } + let previousRecentlySearchedPeersState = Atomic(value: nil) + let foundItems = combineLatest(queue: .mainQueue(), searchQuery, searchOptions, downloadItems) |> mapToSignal { [weak self] query, options, downloadItems -> Signal<([ChatListSearchEntry], Bool)?, NoError> in if query == nil && options == nil && key == .chats { @@ -1185,9 +1191,42 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { let accountPeer = context.account.postbox.loadedPeerWithId(context.account.peerId) |> take(1) let foundLocalPeers: Signal<(peers: [EngineRenderedPeer], unread: [EnginePeer.Id: (Int32, Bool)], recentlySearchedPeerIds: Set), NoError> if let query = query { + let fixedOrRemovedRecentlySearchedPeers = context.engine.peers.recentlySearchedPeers() + |> map { peers -> [RecentlySearchedPeer] in + let allIds = peers.map(\.peer.peerId) + + let updatedState = previousRecentlySearchedPeersState.modify { current in + if var current = current, current.query == query { + current.ids = current.ids.filter { id in + allIds.contains(id) + } + + return current + } else { + var state = SearchedPeersState() + state.ids = allIds + state.query = query + return state + } + } + + var result: [RecentlySearchedPeer] = [] + if let updatedState = updatedState { + for id in updatedState.ids { + for peer in peers { + if id == peer.peer.peerId { + result.append(peer) + } + } + } + } + + return result + } + foundLocalPeers = combineLatest( context.engine.contacts.searchLocalPeers(query: query.lowercased()), - context.engine.peers.recentlySearchedPeers() |> take(1) + fixedOrRemovedRecentlySearchedPeers ) |> mapToSignal { local, allRecentlySearched -> Signal<([EnginePeer.Id: Optional], [EnginePeer.Id: Int], [EngineRenderedPeer], Set), NoError> in let recentlySearched = allRecentlySearched.filter { peer in @@ -1251,6 +1290,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode { } } else { foundLocalPeers = .single((peers: [], unread: [:], recentlySearchedPeerIds: Set())) + + let _ = previousRecentlySearchedPeersState.swap(nil) } let foundRemotePeers: Signal<([FoundPeer], [FoundPeer], Bool), NoError>