mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-29 19:35:08 +00:00
no message
This commit is contained in:
parent
1bd781669c
commit
ec6c3b451d
@ -386,8 +386,6 @@
|
|||||||
D08CAA881ED81DD40000FDA8 /* LocalizationInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */; };
|
D08CAA881ED81DD40000FDA8 /* LocalizationInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */; };
|
||||||
D08CAA8C1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; };
|
D08CAA8C1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; };
|
||||||
D08CAA8D1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; };
|
D08CAA8D1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; };
|
||||||
D08D7E8120A0F3E10005D80C /* GroupPeerMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */; };
|
|
||||||
D08D7E8220A0F3E10005D80C /* GroupPeerMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */; };
|
|
||||||
D08F4A661E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
|
D08F4A661E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
|
||||||
D08F4A671E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
|
D08F4A671E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
|
||||||
D08F4A691E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */; };
|
D08F4A691E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */; };
|
||||||
@ -922,7 +920,6 @@
|
|||||||
D08CAA831ED8164B0000FDA8 /* Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = "<group>"; };
|
D08CAA831ED8164B0000FDA8 /* Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = "<group>"; };
|
||||||
D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizationInfo.swift; sourceTree = "<group>"; };
|
D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizationInfo.swift; sourceTree = "<group>"; };
|
||||||
D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizations.swift; sourceTree = "<group>"; };
|
D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizations.swift; sourceTree = "<group>"; };
|
||||||
D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupPeerMembers.swift; sourceTree = "<group>"; };
|
|
||||||
D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
|
D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
|
||||||
D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
|
D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
|
||||||
D093D7ED206413F600BC3599 /* SecureIdDataTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdDataTypes.swift; sourceTree = "<group>"; };
|
D093D7ED206413F600BC3599 /* SecureIdDataTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdDataTypes.swift; sourceTree = "<group>"; };
|
||||||
@ -1790,7 +1787,6 @@
|
|||||||
D0C44B601FC616E200227BE0 /* SearchGroupMembers.swift */,
|
D0C44B601FC616E200227BE0 /* SearchGroupMembers.swift */,
|
||||||
D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */,
|
D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */,
|
||||||
D018EE042045E95000CBB130 /* CheckPeerChatServiceActions.swift */,
|
D018EE042045E95000CBB130 /* CheckPeerChatServiceActions.swift */,
|
||||||
D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */,
|
|
||||||
);
|
);
|
||||||
name = Peers;
|
name = Peers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2092,7 +2088,6 @@
|
|||||||
D0F3A8A21E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift in Sources */,
|
D0F3A8A21E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift in Sources */,
|
||||||
D01C7ED61EF5E468008305F1 /* ProxySettings.swift in Sources */,
|
D01C7ED61EF5E468008305F1 /* ProxySettings.swift in Sources */,
|
||||||
D049EAE81E44B67100A2CD3A /* RecentPeerItem.swift in Sources */,
|
D049EAE81E44B67100A2CD3A /* RecentPeerItem.swift in Sources */,
|
||||||
D08D7E8120A0F3E10005D80C /* GroupPeerMembers.swift in Sources */,
|
|
||||||
D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
||||||
C2E064681ECEEF0A00387BB8 /* TelegramMediaInvoice.swift in Sources */,
|
C2E064681ECEEF0A00387BB8 /* TelegramMediaInvoice.swift in Sources */,
|
||||||
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
|
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
|
||||||
@ -2448,7 +2443,6 @@
|
|||||||
D01A21A71F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */,
|
D01A21A71F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */,
|
||||||
D0E68776207534CA0064BDB2 /* Api0.swift in Sources */,
|
D0E68776207534CA0064BDB2 /* Api0.swift in Sources */,
|
||||||
D00C7CEC1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
|
D00C7CEC1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
|
||||||
D08D7E8220A0F3E10005D80C /* GroupPeerMembers.swift in Sources */,
|
|
||||||
D048B4AD20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */,
|
D048B4AD20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */,
|
||||||
D0B844481DAB91FD005F29E1 /* ManagedMessageHistoryHoles.swift in Sources */,
|
D0B844481DAB91FD005F29E1 /* ManagedMessageHistoryHoles.swift in Sources */,
|
||||||
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */,
|
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */,
|
||||||
|
|||||||
@ -1031,30 +1031,6 @@ public extension Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func editMessage(flags: Int32, peer: Api.InputPeer, id: Int32, message: String?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, geoPoint: Api.InputGeoPoint?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Updates?) {
|
|
||||||
let buffer = Buffer()
|
|
||||||
buffer.appendInt32(97630429)
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
peer.serialize(buffer, true)
|
|
||||||
serializeInt32(id, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 11) != 0 {serializeString(message!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {replyMarkup!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(entities!.count))
|
|
||||||
for item in entities! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 13) != 0 {geoPoint!.serialize(buffer, true)}
|
|
||||||
return (FunctionDescription({return "(messages.editMessage flags: \(flags), peer: \(peer), id: \(id), message: \(String(describing: message)), replyMarkup: \(String(describing: replyMarkup)), entities: \(String(describing: entities)), geoPoint: \(String(describing: geoPoint)))"}), buffer, { (buffer: Buffer) -> Api.Updates? in
|
|
||||||
let reader = BufferReader(buffer)
|
|
||||||
var result: Api.Updates?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
result = Api.parse(reader, signature: signature) as? Api.Updates
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func editInlineBotMessage(flags: Int32, id: Api.InputBotInlineMessageID, message: String?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
|
public static func editInlineBotMessage(flags: Int32, id: Api.InputBotInlineMessageID, message: String?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(319564933)
|
buffer.appendInt32(319564933)
|
||||||
@ -1800,6 +1776,31 @@ public extension Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func editMessage(flags: Int32, peer: Api.InputPeer, id: Int32, message: String?, media: Api.InputMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, geoPoint: Api.InputGeoPoint?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Updates?) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-1073683256)
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeInt32(id, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 11) != 0 {serializeString(message!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 14) != 0 {media!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {replyMarkup!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(entities!.count))
|
||||||
|
for item in entities! {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}}
|
||||||
|
if Int(flags) & Int(1 << 13) != 0 {geoPoint!.serialize(buffer, true)}
|
||||||
|
return (FunctionDescription({return "(messages.editMessage flags: \(flags), peer: \(peer), id: \(id), message: \(String(describing: message)), media: \(String(describing: media)), replyMarkup: \(String(describing: replyMarkup)), entities: \(String(describing: entities)), geoPoint: \(String(describing: geoPoint)))"}), buffer, { (buffer: Buffer) -> Api.Updates? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Updates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public static func getStickers(emoticon: String, hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Stickers?) {
|
public static func getStickers(emoticon: String, hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Stickers?) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(71126828)
|
buffer.appendInt32(71126828)
|
||||||
|
|||||||
@ -132,15 +132,36 @@ public func channelBlacklistParticipants(account: Account, peerId: PeerId) -> Si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, memberId: PeerId, rights: TelegramChannelBannedRights) -> Signal<Void, NoError> {
|
public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, memberId: PeerId, rights: TelegramChannelBannedRights?) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> {
|
||||||
return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId)
|
return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId)
|
||||||
|> mapToSignal { currentParticipant -> Signal<Void, NoError> in
|
|> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> in
|
||||||
return account.postbox.modify { modifier -> Signal<Void, NoError> in
|
return account.postbox.modify { modifier -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> in
|
||||||
if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer), let memberPeer = modifier.getPeer(memberId), let inputUser = apiInputUser(memberPeer) {
|
if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer), let _ = modifier.getPeer(account.peerId), let memberPeer = modifier.getPeer(memberId), let inputUser = apiInputUser(memberPeer) {
|
||||||
return account.network.request(Api.functions.channels.editBanned(channel: inputChannel, userId: inputUser, bannedRights: rights.apiBannedRights))
|
let updatedParticipant: ChannelParticipant
|
||||||
|
if let currentParticipant = currentParticipant, case let .member(_, invitedAt, _, currentBanInfo) = currentParticipant {
|
||||||
|
let banInfo: ChannelParticipantBannedInfo?
|
||||||
|
if let rights = rights, !rights.flags.isEmpty {
|
||||||
|
banInfo = ChannelParticipantBannedInfo(rights: rights, restrictedBy: currentBanInfo?.restrictedBy ?? account.peerId, isMember: currentBanInfo?.isMember ?? true)
|
||||||
|
} else {
|
||||||
|
banInfo = nil
|
||||||
|
}
|
||||||
|
updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: invitedAt, adminInfo: nil, banInfo: banInfo)
|
||||||
|
} else {
|
||||||
|
let banInfo: ChannelParticipantBannedInfo?
|
||||||
|
if let rights = rights, !rights.flags.isEmpty {
|
||||||
|
banInfo = ChannelParticipantBannedInfo(rights: rights, restrictedBy: account.peerId, isMember: false)
|
||||||
|
} else {
|
||||||
|
banInfo = nil
|
||||||
|
}
|
||||||
|
updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: nil, banInfo: banInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
let effectiveRights: TelegramChannelBannedRights = rights ?? TelegramChannelBannedRights(flags: [], untilDate: 0)
|
||||||
|
|
||||||
|
return account.network.request(Api.functions.channels.editBanned(channel: inputChannel, userId: inputUser, bannedRights: effectiveRights.apiBannedRights))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
|> mapToSignal { result -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> in
|
||||||
return account.postbox.modify { modifier -> Void in
|
return account.postbox.modify { modifier -> (ChannelParticipant?, RenderedChannelParticipant) in
|
||||||
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||||
if let cachedData = cachedData as? CachedChannelData {
|
if let cachedData = cachedData as? CachedChannelData {
|
||||||
var updatedData = cachedData
|
var updatedData = cachedData
|
||||||
@ -166,13 +187,13 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me
|
|||||||
|
|
||||||
var isKicked = false
|
var isKicked = false
|
||||||
var isBanned = false
|
var isBanned = false
|
||||||
if rights.flags.contains(.banReadMessages) {
|
if effectiveRights.flags.contains(.banReadMessages) {
|
||||||
isKicked = true
|
isKicked = true
|
||||||
} else if !rights.flags.isEmpty {
|
} else if !effectiveRights.flags.isEmpty {
|
||||||
isBanned = true
|
isBanned = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let isMember = !wasKicked && !rights.flags.contains(.banReadMessages)
|
let isMember = !wasKicked && !effectiveRights.flags.contains(.banReadMessages)
|
||||||
|
|
||||||
if isKicked != wasKicked {
|
if isKicked != wasKicked {
|
||||||
if let kickedCount = updatedData.participantsSummary.kickedCount {
|
if let kickedCount = updatedData.participantsSummary.kickedCount {
|
||||||
@ -206,6 +227,18 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me
|
|||||||
return cachedData
|
return cachedData
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
var peers: [PeerId: Peer] = [:]
|
||||||
|
var presences: [PeerId: PeerPresence] = [:]
|
||||||
|
peers[memberPeer.id] = memberPeer
|
||||||
|
if let presence = modifier.getPeerPresence(peerId: memberPeer.id) {
|
||||||
|
presences[memberPeer.id] = presence
|
||||||
|
}
|
||||||
|
if case let .member(_, _, _, maybeBanInfo) = updatedParticipant, let banInfo = maybeBanInfo {
|
||||||
|
if let peer = modifier.getPeer(banInfo.restrictedBy) {
|
||||||
|
peers[peer.id] = peer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (currentParticipant, RenderedChannelParticipant(participant: updatedParticipant, peer: memberPeer, peers: peers, presences: presences))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -9,24 +9,51 @@ import Foundation
|
|||||||
import MtProtoKitDynamic
|
import MtProtoKitDynamic
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public enum ChannelMembersFilter {
|
public enum ChannelMembersCategoryFilter {
|
||||||
case none
|
case all
|
||||||
case search(String)
|
case search(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, filter: ChannelMembersFilter = .none) -> Signal<[RenderedChannelParticipant], NoError> {
|
public enum ChannelMembersCategory {
|
||||||
|
case recent(ChannelMembersCategoryFilter)
|
||||||
|
case admins
|
||||||
|
case restricted(ChannelMembersCategoryFilter)
|
||||||
|
case banned(ChannelMembersCategoryFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, category: ChannelMembersCategory = .recent(.all), offset: Int32 = 0, limit: Int32 = 64) -> Signal<[RenderedChannelParticipant], NoError> {
|
||||||
return postbox.modify { modifier -> Signal<[RenderedChannelParticipant], NoError> in
|
return postbox.modify { modifier -> Signal<[RenderedChannelParticipant], NoError> in
|
||||||
if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
||||||
let apiFilter: Api.ChannelParticipantsFilter
|
let apiFilter: Api.ChannelParticipantsFilter
|
||||||
|
switch category {
|
||||||
|
case let .recent(filter):
|
||||||
switch filter {
|
switch filter {
|
||||||
case .none:
|
case .all:
|
||||||
apiFilter = .channelParticipantsRecent
|
apiFilter = .channelParticipantsRecent
|
||||||
case let .search(query):
|
case let .search(query):
|
||||||
apiFilter = .channelParticipantsSearch(q: query)
|
apiFilter = .channelParticipantsSearch(q: query)
|
||||||
}
|
}
|
||||||
return network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: apiFilter, offset: 0, limit: 100, hash: 0))
|
case .admins:
|
||||||
|
apiFilter = .channelParticipantsAdmins
|
||||||
|
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: 0))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> map { result -> [RenderedChannelParticipant] in
|
|> mapToSignal { result -> Signal<[RenderedChannelParticipant], NoError> in
|
||||||
|
return postbox.modify { modifier -> [RenderedChannelParticipant] in
|
||||||
var items: [RenderedChannelParticipant] = []
|
var items: [RenderedChannelParticipant] = []
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelParticipants(_, participants, users):
|
case let .channelParticipants(_, participants, users):
|
||||||
@ -39,6 +66,10 @@ public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, f
|
|||||||
presences[peer.id] = presence
|
presences[peer.id] = presence
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updatePeers(modifier: modifier, peers: Array(peers.values), update: { _, updated in
|
||||||
|
return updated
|
||||||
|
})
|
||||||
|
modifier.updatePeerPresences(presences)
|
||||||
|
|
||||||
for participant in CachedChannelParticipants(apiParticipants: participants).participants {
|
for participant in CachedChannelParticipants(apiParticipants: participants).participants {
|
||||||
if let peer = peers[participant.peerId] {
|
if let peer = peers[participant.peerId] {
|
||||||
@ -51,6 +82,7 @@ public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, f
|
|||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return .single([])
|
return .single([])
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
#if os(macOS)
|
|
||||||
import PostboxMac
|
|
||||||
import SwiftSignalKitMac
|
|
||||||
#else
|
|
||||||
import Postbox
|
|
||||||
import SwiftSignalKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public final class GroupPeerMembersContext {
|
|
||||||
private let postbox: Postbox
|
|
||||||
private let network: Network
|
|
||||||
private let peerId: PeerId
|
|
||||||
|
|
||||||
public init(postbox: Postbox, network: Network, peerId: PeerId) {
|
|
||||||
self.postbox = postbox
|
|
||||||
self.network = network
|
|
||||||
self.peerId = peerId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -225,15 +225,34 @@ public func fetchChannelParticipant(account: Account, peerId: PeerId, participan
|
|||||||
} |> switchToLatest
|
} |> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: PeerId, rights: TelegramChannelAdminRights) -> Signal<Void, UpdatePeerAdminRightsError> {
|
public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: PeerId, rights: TelegramChannelAdminRights) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> {
|
||||||
return fetchChannelParticipant(account: account, peerId: peerId, participantId: adminId)
|
return fetchChannelParticipant(account: account, peerId: peerId, participantId: adminId)
|
||||||
|> mapError { error -> UpdatePeerAdminRightsError in
|
|> mapError { error -> UpdatePeerAdminRightsError in
|
||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
|> mapToSignal { currentParticipant -> Signal<Void, UpdatePeerAdminRightsError> in
|
|> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> in
|
||||||
return account.postbox.modify { modifier -> Signal<Void, UpdatePeerAdminRightsError> in
|
return account.postbox.modify { modifier -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> in
|
||||||
|
|
||||||
if let peer = modifier.getPeer(peerId), let adminPeer = modifier.getPeer(adminId), let inputUser = apiInputUser(adminPeer) {
|
if let peer = modifier.getPeer(peerId), let adminPeer = modifier.getPeer(adminId), let inputUser = apiInputUser(adminPeer) {
|
||||||
if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {
|
if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {
|
||||||
|
let updatedParticipant: ChannelParticipant
|
||||||
|
if let currentParticipant = currentParticipant, case let .member(_, invitedAt, currentAdminInfo, _) = currentParticipant {
|
||||||
|
let adminInfo: ChannelParticipantAdminInfo?
|
||||||
|
if !rights.flags.isEmpty {
|
||||||
|
adminInfo = ChannelParticipantAdminInfo(rights: rights, promotedBy: currentAdminInfo?.promotedBy ?? account.peerId, canBeEditedByAccountPeer: true)
|
||||||
|
} else {
|
||||||
|
adminInfo = nil
|
||||||
|
}
|
||||||
|
updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: invitedAt, adminInfo: adminInfo, banInfo: nil)
|
||||||
|
} else {
|
||||||
|
let adminInfo: ChannelParticipantAdminInfo?
|
||||||
|
if !rights.flags.isEmpty {
|
||||||
|
adminInfo = ChannelParticipantAdminInfo(rights: rights, promotedBy: account.peerId, canBeEditedByAccountPeer: true)
|
||||||
|
} else {
|
||||||
|
adminInfo = nil
|
||||||
|
}
|
||||||
|
updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: adminInfo, banInfo: nil)
|
||||||
|
}
|
||||||
return account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights))
|
return account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights))
|
||||||
|> map { [$0] }
|
|> map { [$0] }
|
||||||
|> `catch` { error -> Signal<[Api.Updates], UpdatePeerAdminRightsError> in
|
|> `catch` { error -> Signal<[Api.Updates], UpdatePeerAdminRightsError> in
|
||||||
@ -253,11 +272,11 @@ public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: Pee
|
|||||||
}
|
}
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<Void, UpdatePeerAdminRightsError> in
|
|> mapToSignal { result -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> in
|
||||||
for updates in result {
|
for updates in result {
|
||||||
account.stateManager.addUpdates(updates)
|
account.stateManager.addUpdates(updates)
|
||||||
}
|
}
|
||||||
return account.postbox.modify { modifier -> Void in
|
return account.postbox.modify { modifier -> (ChannelParticipant?, RenderedChannelParticipant) in
|
||||||
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||||
if let cachedData = cachedData as? CachedChannelData, let adminCount = cachedData.participantsSummary.adminCount {
|
if let cachedData = cachedData as? CachedChannelData, let adminCount = cachedData.participantsSummary.adminCount {
|
||||||
var updatedAdminCount = adminCount
|
var updatedAdminCount = adminCount
|
||||||
@ -283,6 +302,18 @@ public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: Pee
|
|||||||
return cachedData
|
return cachedData
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
var peers: [PeerId: Peer] = [:]
|
||||||
|
var presences: [PeerId: PeerPresence] = [:]
|
||||||
|
peers[adminPeer.id] = adminPeer
|
||||||
|
if let presence = modifier.getPeerPresence(peerId: adminPeer.id) {
|
||||||
|
presences[adminPeer.id] = presence
|
||||||
|
}
|
||||||
|
if case let .member(_, _, maybeAdminInfo, _) = updatedParticipant, let adminInfo = maybeAdminInfo {
|
||||||
|
if let peer = modifier.getPeer(adminInfo.promotedBy) {
|
||||||
|
peers[peer.id] = peer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (currentParticipant, RenderedChannelParticipant(participant: updatedParticipant, peer: adminPeer, peers: peers, presences: presences))
|
||||||
} |> mapError { _ -> UpdatePeerAdminRightsError in return .generic }
|
} |> mapError { _ -> UpdatePeerAdminRightsError in return .generic }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -65,7 +65,14 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
|
|||||||
return .ready(.forward(forwardInfo))
|
return .ready(.forward(forwardInfo))
|
||||||
} else if let contextResult = contextResult {
|
} else if let contextResult = contextResult {
|
||||||
return .ready(.chatContextResult(contextResult))
|
return .ready(.chatContextResult(contextResult))
|
||||||
} else if let media = media.first {
|
} else if let media = media.first, let mediaResult = mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, peerId: peerId, media: media, text: text, autoremoveAttribute: autoremoveAttribute, messageId: messageId, attributes: attributes) {
|
||||||
|
return mediaResult
|
||||||
|
} else {
|
||||||
|
return .ready(.text(text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, peerId: PeerId, media: Media, text: String, autoremoveAttribute: AutoremoveTimeoutMessageAttribute?, messageId: MessageId?, attributes: [MessageAttribute]) -> PendingMessageUploadContent? {
|
||||||
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
|
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
|
||||||
if let reference = image.reference, case let .cloud(id, accessHash) = reference {
|
if let reference = image.reference, case let .cloud(id, accessHash) = reference {
|
||||||
return .ready(.media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash), ttlSeconds: nil), text))
|
return .ready(.media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash), ttlSeconds: nil), text))
|
||||||
@ -96,10 +103,7 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
|
|||||||
}
|
}
|
||||||
return .ready(.media(input, text))
|
return .ready(.media(input, text))
|
||||||
} else {
|
} else {
|
||||||
return .ready(.text(text))
|
return nil
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .ready(.text(text))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,9 @@ public func removePeerMember(account: Account, peerId: PeerId, memberId: PeerId)
|
|||||||
|
|
||||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
return updateChannelMemberBannedRights(account: account, peerId: peerId, memberId: memberId, rights: TelegramChannelBannedRights(flags: [.banReadMessages], untilDate: 0))
|
return updateChannelMemberBannedRights(account: account, peerId: peerId, memberId: memberId, rights: TelegramChannelBannedRights(flags: [.banReadMessages], untilDate: 0))
|
||||||
|
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return account.postbox.modify { modifier -> Signal<Void, NoError> in
|
return account.postbox.modify { modifier -> Signal<Void, NoError> in
|
||||||
|
|||||||
@ -9,7 +9,55 @@ import Foundation
|
|||||||
import MtProtoKitDynamic
|
import MtProtoKitDynamic
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public func requestEditMessage(account: Account, messageId: MessageId, text: String, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false) -> Signal<Bool, NoError> {
|
public enum RequestEditMessageMedia {
|
||||||
|
case keep
|
||||||
|
case update(Media)
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RequestEditMessageResult {
|
||||||
|
case progress(Float)
|
||||||
|
case done(Bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false) -> Signal<RequestEditMessageResult, NoError> {
|
||||||
|
let uploadedMedia: Signal<PendingMessageUploadedContentResult?, NoError>
|
||||||
|
switch media {
|
||||||
|
case .keep:
|
||||||
|
uploadedMedia = .single(.progress(0.0)) |> then(.single(nil))
|
||||||
|
case let .update(media):
|
||||||
|
if let uploadData = mediaContentToUpload(network: account.network, postbox: account.postbox, auxiliaryMethods: account.auxiliaryMethods, transformOutgoingMessageMedia: account.transformOutgoingMessageMedia, messageMediaPreuploadManager: account.messageMediaPreuploadManager, peerId: messageId.peerId, media: media, text: "", autoremoveAttribute: nil, messageId: nil, attributes: []) {
|
||||||
|
switch uploadData {
|
||||||
|
case let .ready(content):
|
||||||
|
uploadedMedia = .single(.content(content))
|
||||||
|
case let .upload(upload):
|
||||||
|
uploadedMedia = .single(.progress(0.027)) |> then(upload)
|
||||||
|
|> map { result -> PendingMessageUploadedContentResult? in
|
||||||
|
switch result {
|
||||||
|
case let .progress(value):
|
||||||
|
return .progress(max(value, 0.027))
|
||||||
|
case let .content(content):
|
||||||
|
return .content(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> `catch` { _ -> Signal<PendingMessageUploadedContentResult?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uploadedMedia = .single(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uploadedMedia
|
||||||
|
|> mapToSignal { uploadedMediaResult -> Signal<RequestEditMessageResult, NoError> in
|
||||||
|
var pendingMediaContent: PendingMessageUploadedContent?
|
||||||
|
if let uploadedMediaResult = uploadedMediaResult {
|
||||||
|
switch uploadedMediaResult {
|
||||||
|
case let .progress(value):
|
||||||
|
return .single(.progress(value))
|
||||||
|
case let .content(content):
|
||||||
|
pendingMediaContent = content
|
||||||
|
}
|
||||||
|
}
|
||||||
return account.postbox.modify { modifier -> (Peer?, SimpleDictionary<PeerId, Peer>) in
|
return account.postbox.modify { modifier -> (Peer?, SimpleDictionary<PeerId, Peer>) in
|
||||||
guard let message = modifier.getMessage(messageId) else {
|
guard let message = modifier.getMessage(messageId) else {
|
||||||
return (nil, SimpleDictionary())
|
return (nil, SimpleDictionary())
|
||||||
@ -37,7 +85,7 @@ public func requestEditMessage(account: Account, messageId: MessageId, text: Str
|
|||||||
}
|
}
|
||||||
return (modifier.getPeer(messageId.peerId), peers)
|
return (modifier.getPeer(messageId.peerId), peers)
|
||||||
}
|
}
|
||||||
|> mapToSignal { peer, associatedPeers in
|
|> mapToSignal { peer, associatedPeers -> Signal<RequestEditMessageResult, NoError> in
|
||||||
if let peer = peer, let inputPeer = apiInputPeer(peer) {
|
if let peer = peer, let inputPeer = apiInputPeer(peer) {
|
||||||
var flags: Int32 = 1 << 11
|
var flags: Int32 = 1 << 11
|
||||||
|
|
||||||
@ -51,7 +99,20 @@ public func requestEditMessage(account: Account, messageId: MessageId, text: Str
|
|||||||
flags |= Int32(1 << 1)
|
flags |= Int32(1 << 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return account.network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, replyMarkup: nil, entities: apiEntities, geoPoint: nil))
|
var inputMedia: Api.InputMedia? = nil
|
||||||
|
if let pendingMediaContent = pendingMediaContent {
|
||||||
|
switch pendingMediaContent {
|
||||||
|
case let .media(media, _):
|
||||||
|
inputMedia = media
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let _ = inputMedia {
|
||||||
|
flags |= Int32(1 << 14)
|
||||||
|
}
|
||||||
|
|
||||||
|
return account.network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, geoPoint: nil))
|
||||||
|> map { result -> Api.Updates? in
|
|> map { result -> Api.Updates? in
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -65,16 +126,29 @@ public func requestEditMessage(account: Account, messageId: MessageId, text: Str
|
|||||||
|> mapError { _ -> NoError in
|
|> mapError { _ -> NoError in
|
||||||
return NoError()
|
return NoError()
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<Bool, NoError> in
|
|> mapToSignal { result -> Signal<RequestEditMessageResult, NoError> in
|
||||||
if let result = result {
|
if let result = result {
|
||||||
|
return account.postbox.modify { modifier -> RequestEditMessageResult in
|
||||||
|
var toMedia: Media?
|
||||||
|
if let message = result.messages.first.flatMap(StoreMessage.init(apiMessage:)) {
|
||||||
|
toMedia = message.media.first
|
||||||
|
}
|
||||||
|
|
||||||
|
if case let .update(fromMedia) = media, let toMedia = toMedia {
|
||||||
|
applyMediaResourceChanges(from: fromMedia, to: toMedia, postbox: account.postbox)
|
||||||
|
}
|
||||||
account.stateManager.addUpdates(result)
|
account.stateManager.addUpdates(result)
|
||||||
return .single(true)
|
|
||||||
|
return .done(true)
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return .single(false)
|
return .single(.done(false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return .single(false)
|
return .single(.done(false))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,7 +165,7 @@ public func requestEditLiveLocation(postbox: Postbox, network: Network, stateMan
|
|||||||
} else {
|
} else {
|
||||||
flags |= 1 << 12
|
flags |= 1 << 12
|
||||||
}
|
}
|
||||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, replyMarkup: nil, entities: nil, geoPoint: coordinate.flatMap { Api.InputGeoPoint.inputGeoPoint(lat: $0.latitude, long: $0.longitude) }))
|
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: nil, replyMarkup: nil, entities: nil, geoPoint: coordinate.flatMap { Api.InputGeoPoint.inputGeoPoint(lat: $0.latitude, long: $0.longitude) }))
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
|
|||||||
@ -33,7 +33,7 @@ public func searchGroupMembers(postbox: Postbox, network: Network, peerId: PeerI
|
|||||||
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
|
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
|
||||||
|> mapToSignal { local -> Signal<[Peer], NoError> in
|
|> mapToSignal { local -> Signal<[Peer], NoError> in
|
||||||
return .single(local)
|
return .single(local)
|
||||||
|> then(channelMembers(postbox: postbox, network: network, peerId: peerId, filter: .search(query))
|
|> then(channelMembers(postbox: postbox, network: network, peerId: peerId, category: .recent(.search(query)))
|
||||||
|> map { participants -> [Peer] in
|
|> map { participants -> [Peer] in
|
||||||
var result: [Peer] = local
|
var result: [Peer] = local
|
||||||
let existingIds = Set(local.map { $0.id })
|
let existingIds = Set(local.map { $0.id })
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user