diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 5cb7701a87..72c0de8514 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -7533,3 +7533,6 @@ Sorry for the inconvenience."; "StickerPack.PremiumStickers_any" = "+%@ PREMIUM STICKERS"; "Stickers.PremiumStickers" = "Premium Stickers"; + +"Channel.AddUserKickedError" = "Sorry, you can't add this user because they are on the list of Removed Users and you can't unban them."; +"Channel.AddAdminKickedError" = "Sorry, you can't add this user as an admin because they are in the Removed Users list and you can't unban them."; diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift index 5c55690259..ed4f5ec7dd 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift @@ -1217,7 +1217,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz strongSelf.present(textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Checkout_LiabilityAlertTitle, text: paymentText, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { if let strongSelf = self { - let _ = ApplicationSpecificNotice.setBotPaymentLiability(accountManager: strongSelf.context.sharedContext.accountManager, peerId: strongSelf.messageId.peerId).start() + let _ = ApplicationSpecificNotice.setBotPaymentLiability(accountManager: strongSelf.context.sharedContext.accountManager, peerId: paymentForm.paymentBotId).start() strongSelf.pay(savedCredentialsToken: savedCredentialsToken, liabilityNoticeAccepted: true) } })]), nil) diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 39c8dd642c..c93b2712c2 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -2327,7 +2327,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return } - strongSelf.chatListDisplayNode.containerNode.updateState({ state in + strongSelf.chatListDisplayNode.containerNode.updateState(onlyCurrent: false, { state in var state = state for peerId in peerIds { state.pendingRemovalPeerIds.insert(peerId) @@ -2365,7 +2365,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController let _ = (signal |> deliverOnMainQueue).start() - strongSelf.chatListDisplayNode.containerNode.updateState({ state in + strongSelf.chatListDisplayNode.containerNode.updateState(onlyCurrent: false, { state in var state = state for peerId in peerIds { state.selectedPeerIds.remove(peerId) @@ -2376,7 +2376,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return true } else if value == .undo { strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(peerIds.first!) - strongSelf.chatListDisplayNode.containerNode.updateState({ state in + strongSelf.chatListDisplayNode.containerNode.updateState(onlyCurrent: false, { state in var state = state for peerId in peerIds { state.pendingRemovalPeerIds.remove(peerId) diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index 88705ad474..c091b3d921 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -778,16 +778,20 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate { } } - func updateState(_ f: (ChatListNodeState) -> ChatListNodeState) { + func updateState(onlyCurrent: Bool = true, _ f: (ChatListNodeState) -> ChatListNodeState) { self.currentItemNode.updateState(f) let updatedState = self.currentItemNode.currentState for (id, itemNode) in self.itemNodes { if id != self.selectedId { - itemNode.listNode.updateState { state in - var state = state - state.editing = updatedState.editing - state.selectedPeerIds = updatedState.selectedPeerIds - return state + if onlyCurrent { + itemNode.listNode.updateState { state in + var state = state + state.editing = updatedState.editing + state.selectedPeerIds = updatedState.selectedPeerIds + return state + } + } else { + itemNode.listNode.updateState(f) } } } diff --git a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift index 1a3ed013e5..d53c04e557 100644 --- a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift @@ -1313,6 +1313,8 @@ public func channelAdminController(context: AccountContext, updatedPresentationD text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string } else if case .tooMuchJoined = error { text = presentationData.strings.Invite_ChannelsTooMuch + } else if case .kicked = error { + text = presentationData.strings.Channel_AddAdminKickedError } presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) } else if case .adminsTooMuch = error { diff --git a/submodules/PeerInfoUI/Sources/ChannelMembersController.swift b/submodules/PeerInfoUI/Sources/ChannelMembersController.swift index bf2acac945..0ba1e105df 100644 --- a/submodules/PeerInfoUI/Sources/ChannelMembersController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelMembersController.swift @@ -479,6 +479,8 @@ public func channelMembersController(context: AccountContext, updatedPresentatio text = presentationData.strings.Channel_BotDoesntSupportGroups case .tooMuchBots: text = presentationData.strings.Channel_TooMuchBots + case .kicked: + text = presentationData.strings.Channel_AddUserKickedError } presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) contactsController?.dismiss() diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index dd33684392..f8fd6ec532 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -1346,6 +1346,8 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController text = presentationData.strings.Channel_TooMuchBots case .bot: text = presentationData.strings.Login_UnknownError + case .kicked: + text = presentationData.strings.Channel_AddUserKickedError } strongSelf.controller?.present(textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) }, completed: { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift index ab4f0daf18..06987d9d40 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift @@ -76,6 +76,7 @@ public enum AddChannelMemberError { case bot(PeerId) case botDoesntSupportGroups case tooMuchBots + case kicked } func _internal_addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), AddChannelMemberError> { @@ -110,6 +111,8 @@ func _internal_addChannelMember(account: Account, peerId: PeerId, memberId: Peer return .fail(.botDoesntSupportGroups) case "BOTS_TOO_MUCH": return .fail(.tooMuchBots) + case "USER_KICKED": + return .fail(.kicked) default: return .fail(.generic) } @@ -204,6 +207,8 @@ func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [P return .notMutualContact case "USERS_TOO_MUCH": return .limitExceeded + case "USER_KICKED": + return .kicked default: return .generic } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 722a91d29d..17a2608ac0 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -8541,14 +8541,58 @@ func presentAddMembers(context: AccountContext, updatedPresentationData: (initia } } - let addMember: (ContactListPeer) -> Signal = { memberPeer -> Signal in + let addMember: (ContactListPeer) -> Signal = { [weak contactsController] memberPeer -> Signal in if case let .peer(selectedPeer, _, _) = memberPeer { let memberId = selectedPeer.id if groupPeer.id.namespace == Namespaces.Peer.CloudChannel { return context.peerChannelMemberCategoriesContextsManager.addMember(engine: context.engine, peerId: groupPeer.id, memberId: memberId) |> map { _ -> Void in } - |> `catch` { _ -> Signal in + |> `catch` { error -> Signal in + let text: String + switch error { + case .limitExceeded: + text = presentationData.strings.Channel_ErrorAddTooMuch + case .tooMuchJoined: + text = presentationData.strings.Invite_ChannelsTooMuch + case .generic: + text = presentationData.strings.Login_UnknownError + case .restricted: + text = presentationData.strings.Channel_ErrorAddBlocked + case .notMutualContact: + if let peer = groupPeer as? TelegramChannel, case .broadcast = peer.info { + text = presentationData.strings.Channel_AddUserLeftError + } else { + text = presentationData.strings.GroupInfo_AddUserLeftError + } + case let .bot(memberId): + guard let peer = groupPeer as? TelegramChannel else { + parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + contactsController?.dismiss() + return .complete() + } + + if peer.hasPermission(.addAdmins) { + parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Channel_AddBotErrorHaveRights, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Channel_AddBotAsAdmin, action: { + contactsController?.dismiss() + + parentController?.push(channelAdminController(context: context, updatedPresentationData: updatedPresentationData, peerId: groupPeer.id, adminId: memberId, initialParticipant: nil, updated: { _ in + }, upgradedToSupergroup: { _, f in f () }, transferedOwnership: { _ in })) + })]), in: .window(.root)) + } else { + parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Channel_AddBotErrorHaveRights, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + } + + contactsController?.dismiss() + return .complete() + case .botDoesntSupportGroups: + text = presentationData.strings.Channel_BotDoesntSupportGroups + case .tooMuchBots: + text = presentationData.strings.Channel_TooMuchBots + case .kicked: + text = presentationData.strings.Channel_AddUserKickedError + } + parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) return .complete() } } else { @@ -8702,6 +8746,8 @@ func presentAddMembers(context: AccountContext, updatedPresentationData: (initia 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()