From adf005cf0d91554a00839b8925152fa7a96e6154 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 28 Feb 2023 23:09:09 +0400 Subject: [PATCH] Filter failed peers --- .../Sources/PeerInfo/PeerInfoScreen.swift | 122 +++++++++--------- ...annelMemberCategoriesContextsManager.swift | 40 ++++++ 2 files changed, 98 insertions(+), 64 deletions(-) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 3feee34f1e..d7408752ba 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -10556,7 +10556,7 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in } } - let addMembers: ([ContactListPeerId]) -> Signal = { members -> Signal in + let addMembers: ([ContactListPeerId]) -> Signal<[(PeerId, AddChannelMemberError)], NoError> = { members -> Signal<[(PeerId, AddChannelMemberError)], NoError> in let memberIds = members.compactMap { contact -> PeerId? in switch contact { case let .peer(peerId): @@ -10568,15 +10568,17 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in return context.account.postbox.multiplePeersView(memberIds) |> take(1) |> deliverOnMainQueue - |> castError(AddChannelMemberError.self) - |> mapToSignal { view -> Signal in + |> mapToSignal { view -> Signal<[(PeerId, AddChannelMemberError)], NoError> in if memberIds.count == 1 { return context.peerChannelMemberCategoriesContextsManager.addMember(engine: context.engine, peerId: groupPeer.id, memberId: memberIds[0]) - |> map { _ -> Void in + |> map { _ -> [(PeerId, AddChannelMemberError)] in + } + |> then(Signal<[(PeerId, AddChannelMemberError)], AddChannelMemberError>.single([])) + |> `catch` { error -> Signal<[(PeerId, AddChannelMemberError)], NoError> in + return .single([(memberIds[0], error)]) } } else { - return context.peerChannelMemberCategoriesContextsManager.addMembers(engine: context.engine, peerId: groupPeer.id, memberIds: memberIds) |> map { _ in - } + return context.peerChannelMemberCategoriesContextsManager.addMembersAllowPartial(engine: context.engine, peerId: groupPeer.id, memberIds: memberIds) } } } @@ -10619,18 +10621,38 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in contactsController?.displayProgress = true addMemberDisposable.set((addMembers(peers) - |> deliverOnMainQueue).start(error: { error in - if let exportedInvitation, let link = exportedInvitation.link { - switch error { - case .restricted, .notMutualContact, .kicked: + |> deliverOnMainQueue).start(next: { failedPeerIds in + if failedPeerIds.isEmpty { + contactsController?.dismiss() + + let mappedPeerIds: [EnginePeer.Id] = peers.compactMap { peer -> EnginePeer.Id? in + switch peer { + case let .peer(id): + return id + default: + return nil + } + } + if !mappedPeerIds.isEmpty { + let _ = (context.engine.data.get(EngineDataMap(mappedPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))) + |> deliverOnMainQueue).start(next: { maybePeers in + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + let peers = maybePeers.compactMap { $0.value } + + let text: String + if peers.count == 1 { + text = presentationData.strings.PeerInfo_NotificationMemberAdded(peers[0].displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string + } else { + text = presentationData.strings.PeerInfo_NotificationMultipleMembersAdded(Int32(peers.count)) + } + parentController?.present(UndoOverlayController(presentationData: presentationData, content: .peers(context: context, peers: peers, title: nil, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) + }) + } + } else { + if let exportedInvitation, let link = exportedInvitation.link { let _ = (context.engine.data.get( - EngineDataList(peers.compactMap { item -> EnginePeer.Id? in - switch item { - case let .peer(peerId): - return peerId - default: - return nil - } + EngineDataList(failedPeerIds.compactMap { item -> EnginePeer.Id? in + return item.0 }.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:))) ) |> deliverOnMainQueue).start(next: { peerItems in @@ -10649,62 +10671,34 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in }) return - default: - break } - } - - if peers.count == 1, case .restricted = error { - switch peers[0] { + + if peers.count == 1, case .restricted = failedPeerIds[0].1 { + switch peers[0] { case let .peer(peerId): let _ = (context.account.postbox.loadedPeerWithId(peerId) - |> deliverOnMainQueue).start(next: { peer in + |> deliverOnMainQueue).start(next: { peer in parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(peer).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) }) default: break - } - } else if peers.count == 1, case .notMutualContact = error { - let text: String - if let peer = groupPeer as? TelegramChannel, case .broadcast = peer.info { - text = presentationData.strings.Channel_AddUserLeftError - } else { - text = presentationData.strings.GroupInfo_AddUserLeftError + } + } else if peers.count == 1, case .notMutualContact = failedPeerIds[0].1 { + let text: String + if let peer = groupPeer as? TelegramChannel, case .broadcast = peer.info { + text = presentationData.strings.Channel_AddUserLeftError + } else { + text = presentationData.strings.GroupInfo_AddUserLeftError + } + + parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + } else if case .tooMuchJoined = failedPeerIds[0].1 { + parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + } else if peers.count == 1, case .kicked = failedPeerIds[0].1 { + parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Channel_AddUserKickedError, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) } - parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - } else if case .tooMuchJoined = error { - parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - } else if peers.count == 1, case .kicked = error { - parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Channel_AddUserKickedError, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - } - - contactsController?.dismiss() - }, completed: { - contactsController?.dismiss() - - let mappedPeerIds: [EnginePeer.Id] = peers.compactMap { peer -> EnginePeer.Id? in - switch peer { - case let .peer(id): - return id - default: - return nil - } - } - if !mappedPeerIds.isEmpty { - let _ = (context.engine.data.get(EngineDataMap(mappedPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))) - |> deliverOnMainQueue).start(next: { maybePeers in - let presentationData = context.sharedContext.currentPresentationData.with { $0 } - let peers = maybePeers.compactMap { $0.value } - - let text: String - if peers.count == 1 { - text = presentationData.strings.PeerInfo_NotificationMemberAdded(peers[0].displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string - } else { - text = presentationData.strings.PeerInfo_NotificationMultipleMembersAdded(Int32(peers.count)) - } - parentController?.present(UndoOverlayController(presentationData: presentationData, content: .peers(context: context, peers: peers, title: nil, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current) - }) + contactsController?.dismiss() } })) })) diff --git a/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift b/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift index c410435c02..a5b9b8513b 100644 --- a/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift +++ b/submodules/TemporaryCachedPeerDataManager/Sources/PeerChannelMemberCategoriesContextsManager.swift @@ -491,6 +491,46 @@ public final class PeerChannelMemberCategoriesContextsManager { } } + public func addMembersAllowPartial(engine: TelegramEngine, peerId: PeerId, memberIds: [PeerId]) -> Signal<[(PeerId, AddChannelMemberError)], NoError> { + let signals: [Signal<((ChannelParticipant?, RenderedChannelParticipant)?, PeerId, AddChannelMemberError?), NoError>] = memberIds.map({ memberId in + return engine.peers.addChannelMember(peerId: peerId, memberId: memberId) + |> map { result -> ((ChannelParticipant?, RenderedChannelParticipant)?, PeerId, AddChannelMemberError?) in + return (result, memberId, nil) + } + |> `catch` { error -> Signal<((ChannelParticipant?, RenderedChannelParticipant)?, PeerId, AddChannelMemberError?), NoError> in + return .single((nil, memberId, error)) + } + }) + return combineLatest(signals) + |> deliverOnMainQueue + |> beforeNext { [weak self] results in + if let strongSelf = self { + strongSelf.impl.with { impl in + for (result, _, _) in results { + if let (previous, updated) = result { + for (contextPeerId, context) in impl.contexts { + if peerId == contextPeerId { + context.replayUpdates([(previous, updated, nil)]) + } + } + } + } + } + } + } + |> map { results -> [(PeerId, AddChannelMemberError)] in + var failedIds: [(PeerId, AddChannelMemberError)] = [] + + for (_, memberId, error) in results { + if let error = error { + failedIds.append((memberId, error)) + } + } + + return failedIds + } + } + public func recentOnline(account: Account, accountPeerId: PeerId, peerId: PeerId) -> Signal { return Signal { [weak self] subscriber in guard let strongSelf = self else {