import Foundation import Postbox import SwiftSignalKit import TelegramApi import MtProtoKit public struct FoundPeer: Equatable { public let peer: Peer public let subscribers: Int32? public init(peer: Peer, subscribers: Int32?) { self.peer = peer self.subscribers = subscribers } public static func ==(lhs: FoundPeer, rhs: FoundPeer) -> Bool { return lhs.peer.isEqual(rhs.peer) && lhs.subscribers == rhs.subscribers } } public enum TelegramSearchPeersScope { case everywhere case channels } public func _internal_searchPeers(accountPeerId: PeerId, postbox: Postbox, network: Network, query: String, scope: TelegramSearchPeersScope) -> Signal<([FoundPeer], [FoundPeer]), NoError> { let searchResult = network.request(Api.functions.contacts.search(q: query, limit: 20), automaticFloodWait: false) |> map(Optional.init) |> `catch` { _ in return Signal.single(nil) } let processedSearchResult = searchResult |> mapToSignal { result -> Signal<([FoundPeer], [FoundPeer]), NoError> in if let result = result { switch result { case let .found(myResults, results, chats, users): return postbox.transaction { transaction -> ([FoundPeer], [FoundPeer]) in var subscribers: [PeerId: Int32] = [:] let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users) for chat in chats { if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) { switch chat { case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _): if let participantsCount = participantsCount { subscribers[groupOrChannel.id] = participantsCount } default: break } } } updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers) var renderedMyPeers: [FoundPeer] = [] for result in myResults { let peerId: PeerId = result.peerId if let peer = parsedPeers.get(peerId) { if let group = peer as? TelegramGroup, group.migrationReference != nil { continue } renderedMyPeers.append(FoundPeer(peer: peer, subscribers: subscribers[peerId])) } } var renderedPeers: [FoundPeer] = [] for result in results { let peerId: PeerId = result.peerId if let peer = parsedPeers.get(peerId) { if let group = peer as? TelegramGroup, group.migrationReference != nil { continue } renderedPeers.append(FoundPeer(peer: peer, subscribers: subscribers[peerId])) } } switch scope { case .everywhere: break case .channels: renderedMyPeers = renderedMyPeers.filter { item in if let channel = item.peer as? TelegramChannel, case .broadcast = channel.info { return true } else { return false } } renderedPeers = renderedPeers.filter { item in if let channel = item.peer as? TelegramChannel, case .broadcast = channel.info { return true } else { return false } } } return (renderedMyPeers, renderedPeers) } } } else { return .single(([], [])) } } return processedSearchResult } func _internal_searchLocalSavedMessagesPeers(account: Account, query: String, indexNameMapping: [EnginePeer.Id: [PeerIndexNameRepresentation]]) -> Signal<[EnginePeer], NoError> { return account.postbox.transaction { transaction -> [EnginePeer] in return transaction.searchSubPeers(peerId: account.peerId, query: query, indexNameMapping: indexNameMapping).map(EnginePeer.init) } }