import Foundation #if os(macOS) import PostboxMac import SwiftSignalKitMac import MtProtoKitMac import TelegramApiMac #else import Postbox import SwiftSignalKit import TelegramApi #if BUCK import MtProtoKit #else import MtProtoKitDynamic #endif #endif import SyncCore public enum ChannelMembersCategoryFilter { case all case search(String) } public enum ChannelMembersCategory { case recent(ChannelMembersCategoryFilter) case admins case contacts(ChannelMembersCategoryFilter) case bots(ChannelMembersCategoryFilter) case restricted(ChannelMembersCategoryFilter) case banned(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> { return postbox.transaction { transaction -> Signal<[RenderedChannelParticipant]?, NoError> in if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) { let apiFilter: Api.ChannelParticipantsFilter switch category { case let .recent(filter): switch filter { case .all: apiFilter = .channelParticipantsRecent case let .search(query): apiFilter = .channelParticipantsSearch(q: query) } case .admins: apiFilter = .channelParticipantsAdmins case let .contacts(filter): switch filter { case .all: apiFilter = .channelParticipantsContacts(q: "") case let .search(query): apiFilter = .channelParticipantsContacts(q: query) } case .bots: apiFilter = .channelParticipantsBots case let .restricted(filter): switch filter { case .all: apiFilter = .channelParticipantsBanned(q: "") case let .search(query): apiFilter = .channelParticipantsBanned(q: query) } case let .banned(filter): switch filter { case .all: apiFilter = .channelParticipantsKicked(q: "") case let .search(query): apiFilter = .channelParticipantsKicked(q: query) } } return network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: apiFilter, offset: offset, limit: limit, hash: hash)) |> retryRequest |> mapToSignal { result -> Signal<[RenderedChannelParticipant]?, NoError> in return postbox.transaction { transaction -> [RenderedChannelParticipant]? in var items: [RenderedChannelParticipant] = [] switch result { case let .channelParticipants(_, participants, users): var peers: [PeerId: Peer] = [:] var presences: [PeerId: PeerPresence] = [:] for user in users { let peer = TelegramUser(user: user) peers[peer.id] = peer if let presence = TelegramUserPresence(apiUser: user) { presences[peer.id] = presence } } updatePeers(transaction: transaction, peers: Array(peers.values), update: { _, updated in return updated }) updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: presences) for participant in CachedChannelParticipants(apiParticipants: participants).participants { if let peer = peers[participant.peerId] { items.append(RenderedChannelParticipant(participant: participant, peer: peer, peers: peers, presences: presences)) } } case .channelParticipantsNotModified: return nil } return items } } } else { return .single([]) } } |> switchToLatest }