Filter failed peers

This commit is contained in:
Ali 2023-02-28 23:09:09 +04:00
parent bc5e989351
commit adf005cf0d
2 changed files with 98 additions and 64 deletions

View File

@ -10556,7 +10556,7 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in
} }
} }
let addMembers: ([ContactListPeerId]) -> Signal<Void, AddChannelMemberError> = { members -> Signal<Void, AddChannelMemberError> in let addMembers: ([ContactListPeerId]) -> Signal<[(PeerId, AddChannelMemberError)], NoError> = { members -> Signal<[(PeerId, AddChannelMemberError)], NoError> in
let memberIds = members.compactMap { contact -> PeerId? in let memberIds = members.compactMap { contact -> PeerId? in
switch contact { switch contact {
case let .peer(peerId): case let .peer(peerId):
@ -10568,15 +10568,17 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in
return context.account.postbox.multiplePeersView(memberIds) return context.account.postbox.multiplePeersView(memberIds)
|> take(1) |> take(1)
|> deliverOnMainQueue |> deliverOnMainQueue
|> castError(AddChannelMemberError.self) |> mapToSignal { view -> Signal<[(PeerId, AddChannelMemberError)], NoError> in
|> mapToSignal { view -> Signal<Void, AddChannelMemberError> in
if memberIds.count == 1 { if memberIds.count == 1 {
return context.peerChannelMemberCategoriesContextsManager.addMember(engine: context.engine, peerId: groupPeer.id, memberId: memberIds[0]) 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 { } 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,68 +10621,8 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in
contactsController?.displayProgress = true contactsController?.displayProgress = true
addMemberDisposable.set((addMembers(peers) addMemberDisposable.set((addMembers(peers)
|> deliverOnMainQueue).start(error: { error in |> deliverOnMainQueue).start(next: { failedPeerIds in
if let exportedInvitation, let link = exportedInvitation.link { if failedPeerIds.isEmpty {
switch error {
case .restricted, .notMutualContact, .kicked:
let _ = (context.engine.data.get(
EngineDataList(peers.compactMap { item -> EnginePeer.Id? in
switch item {
case let .peer(peerId):
return peerId
default:
return nil
}
}.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
)
|> deliverOnMainQueue).start(next: { peerItems in
let peers = peerItems.compactMap { $0 }
if !peers.isEmpty, let contactsController, let navigationController = contactsController.navigationController as? NavigationController {
var viewControllers = navigationController.viewControllers
if let index = viewControllers.firstIndex(where: { $0 === contactsController }) {
let inviteScreen = SendInviteLinkScreen(context: context, link: link, peers: peers)
viewControllers.remove(at: index)
viewControllers.append(inviteScreen)
navigationController.setViewControllers(viewControllers, animated: true)
}
} else {
contactsController?.dismiss()
}
})
return
default:
break
}
}
if peers.count == 1, case .restricted = error {
switch peers[0] {
case let .peer(peerId):
let _ = (context.account.postbox.loadedPeerWithId(peerId)
|> 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
}
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() contactsController?.dismiss()
let mappedPeerIds: [EnginePeer.Id] = peers.compactMap { peer -> EnginePeer.Id? in let mappedPeerIds: [EnginePeer.Id] = peers.compactMap { peer -> EnginePeer.Id? in
@ -10706,6 +10648,58 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in
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) 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(failedPeerIds.compactMap { item -> EnginePeer.Id? in
return item.0
}.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
)
|> deliverOnMainQueue).start(next: { peerItems in
let peers = peerItems.compactMap { $0 }
if !peers.isEmpty, let contactsController, let navigationController = contactsController.navigationController as? NavigationController {
var viewControllers = navigationController.viewControllers
if let index = viewControllers.firstIndex(where: { $0 === contactsController }) {
let inviteScreen = SendInviteLinkScreen(context: context, link: link, peers: peers)
viewControllers.remove(at: index)
viewControllers.append(inviteScreen)
navigationController.setViewControllers(viewControllers, animated: true)
}
} else {
contactsController?.dismiss()
}
})
return
}
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
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 = 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))
}
contactsController?.dismiss()
}
})) }))
})) }))
contactsController.dismissed = { contactsController.dismissed = {

View File

@ -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<Int32, NoError> { public func recentOnline(account: Account, accountPeerId: PeerId, peerId: PeerId) -> Signal<Int32, NoError> {
return Signal { [weak self] subscriber in return Signal { [weak self] subscriber in
guard let strongSelf = self else { guard let strongSelf = self else {