diff --git a/TelegramUI/ChannelAdminController.swift b/TelegramUI/ChannelAdminController.swift index c11fdacd0b..0d9031d8af 100644 --- a/TelegramUI/ChannelAdminController.swift +++ b/TelegramUI/ChannelAdminController.swift @@ -677,38 +677,50 @@ public func channelAdminController(account: Account, peerId: PeerId, adminId: Pe updateFlags = defaultFlags } - if let updateFlags = updateFlags, updateFlags != defaultFlags { - let signal = convertGroupToSupergroup(account: account, peerId: peerId) - |> map(Optional.init) - |> `catch` { _ -> Signal in - return .single(nil) - } - |> mapToSignal { upgradedPeerId -> Signal in - guard let upgradedPeerId = upgradedPeerId else { + if let updateFlags = updateFlags { + if initialParticipant?.adminInfo == nil && updateFlags == defaultFlags { + updateState { current in + return current.withUpdatedUpdating(true) + } + updateRightsDisposable.set((addGroupAdmin(account: account, peerId: peerId, adminId: adminId) + |> deliverOnMainQueue).start(completed: { + dismissImpl?() + })) + } else if updateFlags != defaultFlags { + let signal = convertGroupToSupergroup(account: account, peerId: peerId) + |> map(Optional.init) + |> `catch` { _ -> Signal in return .single(nil) } - return account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: account, peerId: upgradedPeerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags)) - |> mapToSignal { _ -> Signal in - return .complete() + |> mapToSignal { upgradedPeerId -> Signal in + guard let upgradedPeerId = upgradedPeerId else { + return .single(nil) + } + return account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: account, peerId: upgradedPeerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags)) + |> mapToSignal { _ -> Signal in + return .complete() + } + |> then(.single(upgradedPeerId)) } - |> then(.single(upgradedPeerId)) - } - |> deliverOnMainQueue - - updateState { current in - return current.withUpdatedUpdating(true) - } - updateRightsDisposable.set(signal.start(next: { upgradedPeerId in - if let upgradedPeerId = upgradedPeerId { - upgradedToSupergroup(upgradedPeerId, { - dismissImpl?() - }) - } - }, error: { _ in + |> deliverOnMainQueue + updateState { current in - return current.withUpdatedUpdating(false) + return current.withUpdatedUpdating(true) } - })) + updateRightsDisposable.set(signal.start(next: { upgradedPeerId in + if let upgradedPeerId = upgradedPeerId { + upgradedToSupergroup(upgradedPeerId, { + dismissImpl?() + }) + } + }, error: { _ in + updateState { current in + return current.withUpdatedUpdating(false) + } + })) + } else { + dismissImpl?() + } } else { dismissImpl?() } diff --git a/TelegramUI/ChannelAdminsController.swift b/TelegramUI/ChannelAdminsController.swift index dc88298e53..77ee1e687c 100644 --- a/TelegramUI/ChannelAdminsController.swift +++ b/TelegramUI/ChannelAdminsController.swift @@ -490,6 +490,9 @@ public func channelAdminsController(account: Account, peerId: PeerId, loadComple upgradedToSupergroupImpl?(upgradedPeerId, f) } + let peerView = Promise() + peerView.set(account.viewTracker.peerView(peerId)) + let arguments = ChannelAdminsControllerArguments(account: account, openRecentActions: { let _ = (account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { peer in @@ -526,21 +529,12 @@ public func channelAdminsController(account: Account, peerId: PeerId, loadComple })) } }, addAdmin: { - updateState { current in - var dismissController: (() -> Void)? - let controller = ChannelMembersSearchController(account: account, peerId: peerId, mode: .promote, filters: [], openPeer: { peer, participant in - if peerId.namespace == Namespaces.Peer.CloudGroup { - let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } - let progress = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil)) - presentControllerImpl?(progress, nil) - - addAdminDisposable.set((addGroupAdmin(account: account, peerId: peerId, adminId: peer.id) - |> deliverOnMainQueue).start(completed: { - [weak progress] in - dismissController?() - progress?.dismiss() - })) - } else { + let _ = (peerView.get() + |> take(1) + |> deliverOnMainQueue).start(next: { peerView in + updateState { current in + var dismissController: (() -> Void)? + let controller = ChannelMembersSearchController(account: account, peerId: peerId, mode: .promote, filters: [], openPeer: { peer, participant in dismissController?() let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } if peer.id == account.peerId { @@ -551,32 +545,39 @@ public func channelAdminsController(account: Account, peerId: PeerId, loadComple case .creator: return case let .member(_, _, _, banInfo): - if let banInfo = banInfo, banInfo.restrictedBy != account.peerId { - presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.Channel_Members_AddAdminErrorBlacklisted, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) - return + if let banInfo = banInfo { + var canUnban = false + if banInfo.restrictedBy != account.peerId { + canUnban = true + } + if let channel = peerView.peers[peerId] as? TelegramChannel { + if channel.hasPermission(.banMembers) { + canUnban = true + } + } + if !canUnban { + presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.Channel_Members_AddAdminErrorBlacklisted, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) + return + } } } } presentControllerImpl?(channelAdminController(account: account, peerId: peerId, adminId: peer.id, initialParticipant: participant?.participant, updated: { _ in }, upgradedToSupergroup: upgradedToSupergroup), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + }) + dismissController = { [weak controller] in + controller?.dismiss() } - }) - dismissController = { [weak controller] in - controller?.dismiss() + presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + + return current } - presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) - - return current - } - + }) }, openAdmin: { participant in presentControllerImpl?(channelAdminController(account: account, peerId: peerId, adminId: participant.peerId, initialParticipant: participant, updated: { _ in }, upgradedToSupergroup: upgradedToSupergroup), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) }) - let peerView = Promise() - peerView.set(account.viewTracker.peerView(peerId)) - let membersAndLoadMoreControl: (Disposable, PeerChannelMemberCategoryControl?) if peerId.namespace == Namespaces.Peer.CloudChannel { var didReportLoadCompleted = false diff --git a/TelegramUI/ChannelInfoController.swift b/TelegramUI/ChannelInfoController.swift index 5a55a65f3e..891c1c5138 100644 --- a/TelegramUI/ChannelInfoController.swift +++ b/TelegramUI/ChannelInfoController.swift @@ -451,7 +451,7 @@ private func channelInfoEntries(account: Account, presentationData: Presentation } if let cachedChannelData = view.cachedData as? CachedChannelData { - if state.editingState != nil && canEditMembers { + if canEditMembers { if peer.adminRights != nil || peer.flags.contains(.isCreator) { let adminCount = cachedChannelData.participantsSummary.adminCount ?? 0 entries.append(.admins(theme: presentationData.theme, text: presentationData.strings.GroupInfo_Administrators, value: "\(adminCount == 0 ? "" : "\(adminCount)")")) diff --git a/TelegramUI/ChannelPermissionsController.swift b/TelegramUI/ChannelPermissionsController.swift index 8ab17ac368..8070cf33c3 100644 --- a/TelegramUI/ChannelPermissionsController.swift +++ b/TelegramUI/ChannelPermissionsController.swift @@ -14,8 +14,9 @@ private final class ChannelPermissionsControllerArguments { let openPeer: (ChannelParticipant) -> Void let openPeerInfo: (Peer) -> Void let openKicked: () -> Void + let presentRestrictedPublicGroupPermissionsAlert: () -> Void - init(account: Account, updatePermission: @escaping (TelegramChatBannedRightsFlags, Bool) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addPeer: @escaping () -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (ChannelParticipant) -> Void, openPeerInfo: @escaping (Peer) -> Void, openKicked: @escaping () -> Void) { + init(account: Account, updatePermission: @escaping (TelegramChatBannedRightsFlags, Bool) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addPeer: @escaping () -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (ChannelParticipant) -> Void, openPeerInfo: @escaping (Peer) -> Void, openKicked: @escaping () -> Void, presentRestrictedPublicGroupPermissionsAlert: @escaping () -> Void) { self.account = account self.updatePermission = updatePermission self.addPeer = addPeer @@ -24,6 +25,7 @@ private final class ChannelPermissionsControllerArguments { self.openPeer = openPeer self.openPeerInfo = openPeerInfo self.openKicked = openKicked + self.presentRestrictedPublicGroupPermissionsAlert = presentRestrictedPublicGroupPermissionsAlert } } @@ -40,7 +42,7 @@ private enum ChannelPermissionsEntryStableId: Hashable { private enum ChannelPermissionsEntry: ItemListNodeEntry { case permissionsHeader(PresentationTheme, String) - case permission(PresentationTheme, Int, String, Bool, TelegramChatBannedRightsFlags, Bool) + case permission(PresentationTheme, Int, String, Bool, TelegramChatBannedRightsFlags, Bool?) case kicked(PresentationTheme, String, String) case exceptionsHeader(PresentationTheme, String) case add(PresentationTheme, String) @@ -173,8 +175,12 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry { case let .permissionsHeader(theme, text): return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section) case let .permission(theme, _, title, value, rights, enabled): - return ItemListSwitchItem(theme: theme, title: title, value: value, type: .icon, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in - arguments.updatePermission(rights, value) + return ItemListSwitchItem(theme: theme, title: title, value: value, type: .icon, enabled: enabled ?? true, sectionId: self.section, style: .blocks, updated: { value in + if let _ = enabled { + arguments.updatePermission(rights, value) + } else { + arguments.presentRestrictedPublicGroupPermissionsAlert() + } }) case let .kicked(theme, text, value): return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .blocks, action: { @@ -341,9 +347,9 @@ private func channelPermissionsControllerEntries(presentationData: PresentationD entries.append(.permissionsHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SectionTitle)) var rightIndex: Int = 0 for rights in allGroupPermissionList { - var enabled = true - if channel.addressName != nil { - enabled = !publicGroupRestrictedPermissions.contains(rights) + var enabled: Bool? = true + if channel.addressName != nil && !publicGroupRestrictedPermissions.contains(rights) { + enabled = nil } entries.append(.permission(presentationData.theme, rightIndex, stringForGroupPermission(strings: presentationData.strings, right: rights), !effectiveRightsFlags.contains(rights), rights, enabled)) rightIndex += 1 @@ -566,6 +572,9 @@ public func channelPermissionsController(account: Account, peerId: PeerId, loadC } }, openKicked: { pushControllerImpl?(channelBlacklistController(account: account, peerId: peerId)) + }, presentRestrictedPublicGroupPermissionsAlert: { + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.GroupPermission_NotAvailableInPublicGroups, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) }) let previousParticipants = Atomic<[RenderedChannelParticipant]?>(value: nil) diff --git a/TelegramUI/ChatController.swift b/TelegramUI/ChatController.swift index 9b1bbe7526..1437b50496 100644 --- a/TelegramUI/ChatController.swift +++ b/TelegramUI/ChatController.swift @@ -2578,8 +2578,10 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal let banDescription: String switch subject { case .stickers: - if personal { - banDescription = strongSelf.presentationInterfaceState.strings.Group_ErrorSendRestrictedStickers + if untilDate != 0 && untilDate != Int32.max { + banDescription = strongSelf.presentationInterfaceState.strings.Conversation_RestrictedStickersTimed(stringForFullDate(timestamp: untilDate, strings: strongSelf.presentationInterfaceState.strings, dateTimeFormat: strongSelf.presentationInterfaceState.dateTimeFormat)).0 + } else if personal { + banDescription = strongSelf.presentationInterfaceState.strings.Conversation_RestrictedStickers } else { banDescription = strongSelf.presentationInterfaceState.strings.Conversation_DefaultRestrictedStickers } @@ -3739,10 +3741,21 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal strongSelf.chatDisplayNode.dismissInput() var bannedSendMedia: (Int32, Bool)? - if let channel = peer as? TelegramChannel, let value = channel.hasBannedPermission(.banSendMedia) { - bannedSendMedia = value - } else if let group = peer as? TelegramGroup, group.hasBannedPermission(.banSendMedia) { - bannedSendMedia = (Int32.max, false) + var canSendPolls = true + if let channel = peer as? TelegramChannel { + if let value = channel.hasBannedPermission(.banSendMedia) { + bannedSendMedia = value + } + if channel.hasBannedPermission(.banSendPolls) != nil { + canSendPolls = false + } + } else if let group = peer as? TelegramGroup { + if group.hasBannedPermission(.banSendMedia) { + bannedSendMedia = (Int32.max, false) + } + if group.hasBannedPermission(.banSendPolls) { + canSendPolls = false + } } if editMediaOptions == nil, let (untilDate, personal) = bannedSendMedia { @@ -3756,16 +3769,24 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal } let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme) + var items: [ActionSheetItem] = [] + items.append(ActionSheetTextItem(title: banDescription)) + items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_Location, color: .accent, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + self?.presentMapPicker(editingMessage: false) + })) + if canSendPolls { + items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.AttachmentMenu_Poll, color: .accent, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + self?.presentPollCreation() + })) + } + items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_Contact, color: .accent, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + self?.presentContactPicker() + })) actionSheet.setItemGroups([ActionSheetItemGroup(items: [ - ActionSheetTextItem(title: banDescription), - ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_Location, color: .accent, action: { [weak actionSheet] in - actionSheet?.dismissAnimated() - self?.presentMapPicker(editingMessage: false) - }), - ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_Contact, color: .accent, action: { [weak actionSheet] in - actionSheet?.dismissAnimated() - self?.presentContactPicker() - }) + ]), ActionSheetItemGroup(items: [ ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in actionSheet?.dismissAnimated() diff --git a/TelegramUI/ChatHistoryEntriesForView.swift b/TelegramUI/ChatHistoryEntriesForView.swift index d0cf004fed..2563ffd7b6 100644 --- a/TelegramUI/ChatHistoryEntriesForView.swift +++ b/TelegramUI/ChatHistoryEntriesForView.swift @@ -17,7 +17,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, } var groupBucket: [(Message, Bool, ChatHistoryMessageSelection, Bool)] = [] - for entry in view.entries { + loop: for entry in view.entries { switch entry { case let .HoleEntry(hole, _): if !groupBucket.isEmpty { @@ -28,6 +28,19 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, entries.append(.HoleEntry(hole, presentationData)) } case let .MessageEntry(message, read, _, monthLocation): + if message.id.peerId.namespace == Namespaces.Peer.CloudChannel { + for media in message.media { + if let action = media as? TelegramMediaAction { + switch action.action { + case .channelMigratedFromGroup, .groupMigratedToChannel: + continue loop + default: + break + } + } + } + } + var isAdmin = false if let author = message.author { isAdmin = adminIds.contains(author.id) diff --git a/TelegramUI/ChatInterfaceStateContextMenus.swift b/TelegramUI/ChatInterfaceStateContextMenus.swift index e9aa9e4c8d..279a1f2554 100644 --- a/TelegramUI/ChatInterfaceStateContextMenus.swift +++ b/TelegramUI/ChatInterfaceStateContextMenus.swift @@ -585,12 +585,6 @@ private func canPerformEditingActions(limits: LimitsConfiguration, accountPeerId return true } - if let peer = message.peers[message.id.peerId] as? TelegramChannel { - if peer.hasPermission(.pinMessages) { - return true - } - } - return false } diff --git a/TelegramUI/ChatListController.swift b/TelegramUI/ChatListController.swift index abb235df54..377e963c7d 100644 --- a/TelegramUI/ChatListController.swift +++ b/TelegramUI/ChatListController.swift @@ -969,7 +969,7 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie let signal: Signal = strongSelf.account.postbox.transaction { transaction -> Void in for peerId in peerIds { - removePeerChat(transaction: transaction, mediaBox: account.postbox.mediaBox, peerId: peerId, reportChatSpam: false) + removePeerChat(transaction: transaction, mediaBox: account.postbox.mediaBox, peerId: peerId, reportChatSpam: false, deleteGloballyIfPossible: false) } } |> afterDisposed { diff --git a/TelegramUI/ChatTextInputPanelNode.swift b/TelegramUI/ChatTextInputPanelNode.swift index 4727cf8561..56df3d885e 100644 --- a/TelegramUI/ChatTextInputPanelNode.swift +++ b/TelegramUI/ChatTextInputPanelNode.swift @@ -20,11 +20,17 @@ private let searchLayoutProgressImage = generateImage(CGSize(width: 22.0, height private let accessoryButtonFont = Font.medium(14.0) -private final class AccessoryItemIconButton: HighlightableButton { +private final class AccessoryItemIconButton: HighlightTrackingButton { private let item: ChatTextInputAccessoryItem private var width: CGFloat + private let imageNode: ASImageNode init(item: ChatTextInputAccessoryItem, theme: PresentationTheme, strings: PresentationStrings) { + self.imageNode = ASImageNode() + self.imageNode.isLayerBacked = true + self.imageNode.displaysAsynchronously = false + self.imageNode.displayWithoutProcessing = true + self.item = item let (image, text, alpha, insets) = AccessoryItemIconButton.imageAndInsets(item: item, theme: theme, strings: strings) @@ -33,15 +39,29 @@ private final class AccessoryItemIconButton: HighlightableButton { super.init(frame: CGRect()) + self.addSubnode(self.imageNode) + if let text = text { self.titleLabel?.font = accessoryButtonFont self.setTitleColor(theme.chat.inputPanel.inputControlColor, for: []) self.setTitle(text, for: []) } - self.setImage(image, for: []) + self.imageNode.image = image + self.imageNode.alpha = alpha self.imageEdgeInsets = insets - self.imageView?.alpha = alpha + + self.highligthedChanged = { [weak self] highlighted in + if let strongSelf = self { + if highlighted { + strongSelf.layer.removeAnimation(forKey: "opacity") + strongSelf.alpha = 0.4 + } else { + strongSelf.alpha = 1.0 + strongSelf.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) + } + } + } } func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { @@ -57,9 +77,9 @@ private final class AccessoryItemIconButton: HighlightableButton { self.setTitle("", for: []) } - self.setImage(image, for: []) + self.imageNode.image = image self.imageEdgeInsets = insets - self.imageView?.alpha = alpha + self.imageNode.alpha = alpha } required init?(coder aDecoder: NSCoder) { @@ -105,6 +125,12 @@ private final class AccessoryItemIconButton: HighlightableButton { } } + func updateLayout(size: CGSize) { + if let image = self.imageNode.image { + self.imageNode.frame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.width - image.size.width) / 2.0) - self.imageEdgeInsets.bottom), size: image.size) + } + } + var buttonWidth: CGFloat { return self.width } @@ -984,6 +1010,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { var nextButtonTopRight = CGPoint(x: width - rightInset - textFieldInsets.right - accessoryButtonInset, y: panelHeight - textFieldInsets.bottom - minimalInputHeight + audioRecordingItemsVerticalOffset) for (_, button) in self.accessoryItemButtons.reversed() { let buttonSize = CGSize(width: button.buttonWidth, height: minimalInputHeight) + button.updateLayout(size: buttonSize) let buttonFrame = CGRect(origin: CGPoint(x: nextButtonTopRight.x - buttonSize.width, y: nextButtonTopRight.y + floor((minimalInputHeight - buttonSize.height) / 2.0)), size: buttonSize) if button.superview == nil { self.view.addSubview(button) diff --git a/TelegramUI/ContactListNode.swift b/TelegramUI/ContactListNode.swift index a7d33cd0ee..c3fcb777cc 100644 --- a/TelegramUI/ContactListNode.swift +++ b/TelegramUI/ContactListNode.swift @@ -730,6 +730,9 @@ final class ContactListNode: ASDisplayNode { self.selectionStatePromise.set(.single(self.selectionStateValue)) } } + var selectionState: ContactListNodeGroupSelectionState? { + return self.selectionStateValue + } private var enableUpdatesValue = false var enableUpdates: Bool { diff --git a/TelegramUI/ContactMultiselectionController.swift b/TelegramUI/ContactMultiselectionController.swift index 46653766f8..80319e1cf0 100644 --- a/TelegramUI/ContactMultiselectionController.swift +++ b/TelegramUI/ContactMultiselectionController.swift @@ -131,7 +131,8 @@ class ContactMultiselectionController: ViewController { switch self.mode { case .groupCreation: let maxCount: Int32 = self.limitsConfiguration?.maxSupergroupMemberCount ?? 5000 - self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.Compose_NewGroupTitle, counter: "0/\(maxCount)") + let count = self.contactsNode.contactListNode.selectionState?.selectedPeerIndices.count ?? 0 + self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.Compose_NewGroupTitle, counter: "\(count)/\(maxCount)") let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed)) self.rightNavigationButton = rightNavigationButton self.navigationItem.rightBarButtonItem = self.rightNavigationButton diff --git a/TelegramUI/GroupInfoController.swift b/TelegramUI/GroupInfoController.swift index 06adaa6e32..5590588bcd 100644 --- a/TelegramUI/GroupInfoController.swift +++ b/TelegramUI/GroupInfoController.swift @@ -698,9 +698,7 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa var canAddMembers = false var isPublic = false var isCreator = false - var isGroup = false if let group = view.peers[view.peerId] as? TelegramGroup { - isGroup = true if case .creator = group.role { isCreator = true } @@ -713,10 +711,13 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa case .member: break } - } else if let channel = view.peers[view.peerId] as? TelegramChannel { - if case .group = channel.info { - isGroup = true + if !group.hasBannedPermission(.banChangeInfo) { + canEditGroupInfo = true } + if !group.hasBannedPermission(.banAddMembers) { + canAddMembers = true + } + } else if let channel = view.peers[view.peerId] as? TelegramChannel { highlightAdmins = true isPublic = channel.username != nil isCreator = channel.flags.contains(.isCreator) @@ -1074,8 +1075,18 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) } } else if let channel = view.peers[view.peerId] as? TelegramChannel { - if case .member = channel.participationStatus, let cachedChannelData = view.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount, memberCount <= 200 { - entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) + if case .member = channel.participationStatus { + if channel.flags.contains(.isCreator) { + if let cachedChannelData = view.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount, memberCount <= 200 { + if state.editingState != nil { + entries.append(.leave(presentationData.theme, presentationData.strings.ChannelInfo_DeleteGroup)) + } else { + entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) + } + } + } else { + entries.append(.leave(presentationData.theme, presentationData.strings.Group_LeaveGroup)) + } } } @@ -1177,6 +1188,9 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl var upgradedToSupergroupImpl: ((PeerId, @escaping () -> Void) -> Void)? + let peerView = Promise() + peerView.set(account.viewTracker.peerView(peerId)) + let arguments = GroupInfoArguments(account: account, peerId: peerId, avatarAndNameInfoContext: avatarAndNameInfoContext, tapAvatarAction: { let _ = (account.postbox.loadedPeerWithId(peerId) |> take(1) @@ -1427,7 +1441,7 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl return account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.addMember(account: account, peerId: peerId, memberId: memberId) } - return account.postbox.peerView(id: memberId) + return peerView.get() |> take(1) |> deliverOnMainQueue |> mapToSignal { view -> Signal in @@ -1648,28 +1662,55 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl }, convertToSupergroup: { pushControllerImpl?(convertToSupergroupController(account: account, peerId: peerId)) }, leave: { - let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } - let controller = ActionSheetController(presentationTheme: presentationData.theme) - let dismissAction: () -> Void = { [weak controller] in - controller?.dismissAnimated() - } - - var items: [ActionSheetItem] = [] - if peerId.namespace == Namespaces.Peer.CloudGroup { - items.append(ActionSheetTextItem(title: presentationData.strings.GroupInfo_DeleteAndExitConfirmation)) - } - items.append(ActionSheetButtonItem(title: presentationData.strings.Group_LeaveGroup, color: .destructive, action: { - dismissAction() - let _ = (removePeerChat(postbox: account.postbox, peerId: peerId, reportChatSpam: false) - |> deliverOnMainQueue).start(completed: { - popToRootImpl?() - }) - })) - controller.setItemGroups([ - ActionSheetItemGroup(items: items), - ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })]) - ]) - presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + let _ = (peerView.get() + |> take(1) + |> deliverOnMainQueue).start(next: { peerView in + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + + if let channel = peerView.peers[peerId] as? TelegramChannel, channel.flags.contains(.isCreator), stateValue.with({ $0 }).editingState != nil { + let controller = ActionSheetController(presentationTheme: presentationData.theme) + let dismissAction: () -> Void = { [weak controller] in + controller?.dismissAnimated() + } + + var items: [ActionSheetItem] = [] + items.append(ActionSheetTextItem(title: presentationData.strings.ChannelInfo_DeleteGroupConfirmation)) + items.append(ActionSheetButtonItem(title: presentationData.strings.ChannelInfo_DeleteGroup, color: .destructive, action: { + dismissAction() + let _ = (removePeerChat(postbox: account.postbox, peerId: peerId, reportChatSpam: false, deleteGloballyIfPossible: true) + |> deliverOnMainQueue).start(completed: { + popToRootImpl?() + }) + })) + controller.setItemGroups([ + ActionSheetItemGroup(items: items), + ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })]) + ]) + presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + } else { + let controller = ActionSheetController(presentationTheme: presentationData.theme) + let dismissAction: () -> Void = { [weak controller] in + controller?.dismissAnimated() + } + + var items: [ActionSheetItem] = [] + if peerId.namespace == Namespaces.Peer.CloudGroup { + items.append(ActionSheetTextItem(title: presentationData.strings.GroupInfo_DeleteAndExitConfirmation)) + } + items.append(ActionSheetButtonItem(title: presentationData.strings.Group_LeaveGroup, color: .destructive, action: { + dismissAction() + let _ = (removePeerChat(postbox: account.postbox, peerId: peerId, reportChatSpam: false) + |> deliverOnMainQueue).start(completed: { + popToRootImpl?() + }) + })) + controller.setItemGroups([ + ActionSheetItemGroup(items: items), + ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })]) + ]) + presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) + } + }) }, displayUsernameShareMenu: { text in let shareController = ShareController(account: account, subject: .url(text)) presentControllerImpl?(shareController, nil) @@ -1709,7 +1750,7 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl let previousChannelMembers = Atomic<[PeerId]?>(value: nil) let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.globalNotifications])) - let signal = combineLatest(queue: .mainQueue(), (account.applicationContext as! TelegramApplicationContext).presentationData, statePromise.get(), account.viewTracker.peerView(peerId), account.postbox.combinedView(keys: [globalNotificationsKey]), channelMembersPromise.get()) + let signal = combineLatest(queue: .mainQueue(), (account.applicationContext as! TelegramApplicationContext).presentationData, statePromise.get(), peerView.get(), account.postbox.combinedView(keys: [globalNotificationsKey]), channelMembersPromise.get()) |> map { presentationData, state, view, combinedView, channelMembers -> (ItemListControllerState, (ItemListNodeState, GroupInfoEntry.ItemGenerationArguments)) in let peer = peerViewMainPeer(view) diff --git a/TelegramUI/PresentationStrings.swift b/TelegramUI/PresentationStrings.swift index ae8c23d475..42ff2e510f 100644 --- a/TelegramUI/PresentationStrings.swift +++ b/TelegramUI/PresentationStrings.swift @@ -3322,509 +3322,510 @@ public final class PresentationStrings { return formatWithArgumentRanges(self._s[2858]!, self._r[2858]!, [_1, _2]) } public var Group_Info_AdminLog: String { return self._s[2859]! } - public var Channel_AdminLog_InfoPanelAlertText: String { return self._s[2860]! } - public var Conversation_Admin: String { return self._s[2862]! } - public var Conversation_GifTooltip: String { return self._s[2863]! } - public var Passport_NotLoggedInMessage: String { return self._s[2864]! } - public var Profile_MessageLifetimeForever: String { return self._s[2865]! } + public var GroupPermission_NotAvailableInPublicGroups: String { return self._s[2860]! } + public var Channel_AdminLog_InfoPanelAlertText: String { return self._s[2861]! } + public var Conversation_Admin: String { return self._s[2863]! } + public var Conversation_GifTooltip: String { return self._s[2864]! } + public var Passport_NotLoggedInMessage: String { return self._s[2865]! } + public var Profile_MessageLifetimeForever: String { return self._s[2866]! } public func MESSAGE_POLL_SEPARATED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2867]!, self._r[2867]!, [_1]) + return formatWithArgumentRanges(self._s[2868]!, self._r[2868]!, [_1]) } - public var SharedMedia_EmptyTitle: String { return self._s[2868]! } - public var Channel_Edit_PrivatePublicLinkAlert: String { return self._s[2869]! } - public var Username_Help: String { return self._s[2870]! } - public var DialogList_LanguageTooltip: String { return self._s[2872]! } - public var Map_LoadError: String { return self._s[2873]! } - public var Notification_Exceptions_NewException: String { return self._s[2874]! } - public var TwoStepAuth_EmailTitle: String { return self._s[2875]! } - public var WatchRemote_AlertText: String { return self._s[2876]! } - public var ChatSettings_ConnectionType_Title: String { return self._s[2878]! } + public var SharedMedia_EmptyTitle: String { return self._s[2869]! } + public var Channel_Edit_PrivatePublicLinkAlert: String { return self._s[2870]! } + public var Username_Help: String { return self._s[2871]! } + public var DialogList_LanguageTooltip: String { return self._s[2873]! } + public var Map_LoadError: String { return self._s[2874]! } + public var Notification_Exceptions_NewException: String { return self._s[2875]! } + public var TwoStepAuth_EmailTitle: String { return self._s[2876]! } + public var WatchRemote_AlertText: String { return self._s[2877]! } + public var ChatSettings_ConnectionType_Title: String { return self._s[2879]! } public func CHANNEL_MESSAGE_GEOLIVE_SEPARATED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2879]!, self._r[2879]!, [_1]) - } - public func LOCKED_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2880]!, self._r[2880]!, [_1]) } - public var Passport_Address_CountryPlaceholder: String { return self._s[2881]! } + public func LOCKED_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2881]!, self._r[2881]!, [_1]) + } + public var Passport_Address_CountryPlaceholder: String { return self._s[2882]! } public func DialogList_AwaitingEncryption(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2882]!, self._r[2882]!, [_0]) + return formatWithArgumentRanges(self._s[2883]!, self._r[2883]!, [_0]) } public func Time_PreciseDate_m6(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2883]!, self._r[2883]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[2884]!, self._r[2884]!, [_1, _2, _3]) } - public var Group_AdminLog_EmptyText: String { return self._s[2884]! } - public var AccessDenied_VideoMicrophone: String { return self._s[2886]! } - public var Conversation_ContextMenuStickerPackAdd: String { return self._s[2887]! } - public var Cache_ClearNone: String { return self._s[2888]! } - public var SocksProxySetup_FailedToConnect: String { return self._s[2889]! } - public var Permissions_NotificationsTitle_v0: String { return self._s[2890]! } + public var Group_AdminLog_EmptyText: String { return self._s[2885]! } + public var AccessDenied_VideoMicrophone: String { return self._s[2887]! } + public var Conversation_ContextMenuStickerPackAdd: String { return self._s[2888]! } + public var Cache_ClearNone: String { return self._s[2889]! } + public var SocksProxySetup_FailedToConnect: String { return self._s[2890]! } + public var Permissions_NotificationsTitle_v0: String { return self._s[2891]! } public func Channel_AdminLog_MessageEdited(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2891]!, self._r[2891]!, [_0]) + return formatWithArgumentRanges(self._s[2892]!, self._r[2892]!, [_0]) } - public var Passport_Identity_Country: String { return self._s[2892]! } + public var Passport_Identity_Country: String { return self._s[2893]! } public func Notification_CreatedChat(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2893]!, self._r[2893]!, [_0]) + return formatWithArgumentRanges(self._s[2894]!, self._r[2894]!, [_0]) } - public var AccessDenied_Settings: String { return self._s[2894]! } - public var Passport_Address_TypeUtilityBillUploadScan: String { return self._s[2895]! } - public var Month_ShortMay: String { return self._s[2896]! } - public var Compose_NewGroup: String { return self._s[2897]! } - public var Group_Setup_TypePrivate: String { return self._s[2899]! } - public var Login_PadPhoneHelpTitle: String { return self._s[2900]! } - public var Appearance_ThemeDayClassic: String { return self._s[2901]! } - public var Channel_AdminLog_MessagePreviousCaption: String { return self._s[2902]! } - public var Privacy_GroupsAndChannels_WhoCanAddMe: String { return self._s[2903]! } - public var Conversation_typing: String { return self._s[2905]! } - public var Paint_Masks: String { return self._s[2906]! } + public var AccessDenied_Settings: String { return self._s[2895]! } + public var Passport_Address_TypeUtilityBillUploadScan: String { return self._s[2896]! } + public var Month_ShortMay: String { return self._s[2897]! } + public var Compose_NewGroup: String { return self._s[2898]! } + public var Group_Setup_TypePrivate: String { return self._s[2900]! } + public var Login_PadPhoneHelpTitle: String { return self._s[2901]! } + public var Appearance_ThemeDayClassic: String { return self._s[2902]! } + public var Channel_AdminLog_MessagePreviousCaption: String { return self._s[2903]! } + public var Privacy_GroupsAndChannels_WhoCanAddMe: String { return self._s[2904]! } + public var Conversation_typing: String { return self._s[2906]! } + public var Paint_Masks: String { return self._s[2907]! } public func PINNED_DOC_SEPARATED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2907]!, self._r[2907]!, [_1]) + return formatWithArgumentRanges(self._s[2908]!, self._r[2908]!, [_1]) } - public var Username_InvalidTaken: String { return self._s[2908]! } + public var Username_InvalidTaken: String { return self._s[2909]! } public func CHAT_PHOTO_EDITED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2909]!, self._r[2909]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2910]!, self._r[2910]!, [_1, _2]) } - public var Call_StatusNoAnswer: String { return self._s[2910]! } - public var TwoStepAuth_EmailAddSuccess: String { return self._s[2911]! } - public var Passport_Identity_Selfie: String { return self._s[2912]! } - public var Login_InfoLastNamePlaceholder: String { return self._s[2913]! } - public var Privacy_SecretChatsLinkPreviewsHelp: String { return self._s[2914]! } - public var Conversation_ClearSecretHistory: String { return self._s[2915]! } - public var NetworkUsageSettings_Title: String { return self._s[2917]! } - public var Your_cards_security_code_is_invalid: String { return self._s[2919]! } + public var Call_StatusNoAnswer: String { return self._s[2911]! } + public var TwoStepAuth_EmailAddSuccess: String { return self._s[2912]! } + public var Passport_Identity_Selfie: String { return self._s[2913]! } + public var Login_InfoLastNamePlaceholder: String { return self._s[2914]! } + public var Privacy_SecretChatsLinkPreviewsHelp: String { return self._s[2915]! } + public var Conversation_ClearSecretHistory: String { return self._s[2916]! } + public var NetworkUsageSettings_Title: String { return self._s[2918]! } + public var Your_cards_security_code_is_invalid: String { return self._s[2920]! } public func Notification_LeftChannel(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2921]!, self._r[2921]!, [_0]) + return formatWithArgumentRanges(self._s[2922]!, self._r[2922]!, [_0]) } public func Call_CallInProgressMessage(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2922]!, self._r[2922]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2923]!, self._r[2923]!, [_1, _2]) } - public var SaveIncomingPhotosSettings_From: String { return self._s[2924]! } - public var Map_LiveLocationTitle: String { return self._s[2925]! } - public var Login_InfoAvatarAdd: String { return self._s[2926]! } - public var Passport_Identity_FilesView: String { return self._s[2927]! } - public var UserInfo_GenericPhoneLabel: String { return self._s[2928]! } - public var Privacy_Calls_NeverAllow: String { return self._s[2929]! } + public var SaveIncomingPhotosSettings_From: String { return self._s[2925]! } + public var Map_LiveLocationTitle: String { return self._s[2926]! } + public var Login_InfoAvatarAdd: String { return self._s[2927]! } + public var Passport_Identity_FilesView: String { return self._s[2928]! } + public var UserInfo_GenericPhoneLabel: String { return self._s[2929]! } + public var Privacy_Calls_NeverAllow: String { return self._s[2930]! } public func Contacts_AddPhoneNumber(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2930]!, self._r[2930]!, [_0]) + return formatWithArgumentRanges(self._s[2931]!, self._r[2931]!, [_0]) } - public var TwoStepAuth_ConfirmationText: String { return self._s[2931]! } - public var ChatSettings_AutomaticVideoMessageDownload: String { return self._s[2932]! } - public var Channel_AdminLogFilter_AdminsAll: String { return self._s[2933]! } - public var Tour_Title2: String { return self._s[2934]! } - public var Conversation_FileOpenIn: String { return self._s[2935]! } - public var Checkout_ErrorPrecheckoutFailed: String { return self._s[2936]! } - public var Wallpaper_Set: String { return self._s[2937]! } - public var Passport_Identity_Translations: String { return self._s[2939]! } + public var TwoStepAuth_ConfirmationText: String { return self._s[2932]! } + public var ChatSettings_AutomaticVideoMessageDownload: String { return self._s[2933]! } + public var Channel_AdminLogFilter_AdminsAll: String { return self._s[2934]! } + public var Tour_Title2: String { return self._s[2935]! } + public var Conversation_FileOpenIn: String { return self._s[2936]! } + public var Checkout_ErrorPrecheckoutFailed: String { return self._s[2937]! } + public var Wallpaper_Set: String { return self._s[2938]! } + public var Passport_Identity_Translations: String { return self._s[2940]! } public func Channel_AdminLog_MessageChangedChannelAbout(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2940]!, self._r[2940]!, [_0]) + return formatWithArgumentRanges(self._s[2941]!, self._r[2941]!, [_0]) } - public var Channel_LeaveChannel: String { return self._s[2941]! } + public var Channel_LeaveChannel: String { return self._s[2942]! } public func MESSAGE_NOTEXT_SEPARATED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2942]!, self._r[2942]!, [_1]) - } - public func PINNED_INVOICE(_ _1: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2943]!, self._r[2943]!, [_1]) } - public var PhotoEditor_HighlightsTint: String { return self._s[2944]! } - public var Passport_Email_Delete: String { return self._s[2945]! } - public var Conversation_Mute: String { return self._s[2947]! } - public var Channel_AdminLog_CanSendMessages: String { return self._s[2949]! } + public func PINNED_INVOICE(_ _1: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2944]!, self._r[2944]!, [_1]) + } + public var PhotoEditor_HighlightsTint: String { return self._s[2945]! } + public var Passport_Email_Delete: String { return self._s[2946]! } + public var Conversation_Mute: String { return self._s[2948]! } + public var Channel_AdminLog_CanSendMessages: String { return self._s[2950]! } public func Notification_PassportValuesSentMessage(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2950]!, self._r[2950]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2951]!, self._r[2951]!, [_1, _2]) } - public var Calls_CallTabDescription: String { return self._s[2951]! } - public var Passport_Identity_NativeNameHelp: String { return self._s[2952]! } - public var Common_No: String { return self._s[2953]! } - public var Weekday_Sunday: String { return self._s[2954]! } - public var Notification_Reply: String { return self._s[2955]! } - public var Conversation_ViewMessage: String { return self._s[2956]! } + public var Calls_CallTabDescription: String { return self._s[2952]! } + public var Passport_Identity_NativeNameHelp: String { return self._s[2953]! } + public var Common_No: String { return self._s[2954]! } + public var Weekday_Sunday: String { return self._s[2955]! } + public var Notification_Reply: String { return self._s[2956]! } + public var Conversation_ViewMessage: String { return self._s[2957]! } public func Checkout_SavePasswordTimeoutAndFaceId(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2957]!, self._r[2957]!, [_0]) - } - public func Map_LiveLocationPrivateDescription(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2958]!, self._r[2958]!, [_0]) } - public var Message_PinnedDocumentMessage: String { return self._s[2959]! } - public var DialogList_TabTitle: String { return self._s[2961]! } - public var Passport_FieldEmail: String { return self._s[2962]! } - public var Conversation_UnpinMessageAlert: String { return self._s[2963]! } - public var Passport_Address_TypeBankStatement: String { return self._s[2964]! } - public var Passport_Identity_ExpiryDate: String { return self._s[2965]! } - public var Privacy_Calls_P2P: String { return self._s[2966]! } - public func CancelResetAccount_Success(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2968]!, self._r[2968]!, [_0]) + public func Map_LiveLocationPrivateDescription(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2959]!, self._r[2959]!, [_0]) } - public var SocksProxySetup_UseForCallsHelp: String { return self._s[2969]! } - public var EnterPasscode_ChangeTitle: String { return self._s[2970]! } - public var Passport_InfoText: String { return self._s[2971]! } - public var Checkout_NewCard_SaveInfoEnableHelp: String { return self._s[2972]! } + public var Message_PinnedDocumentMessage: String { return self._s[2960]! } + public var DialogList_TabTitle: String { return self._s[2962]! } + public var Passport_FieldEmail: String { return self._s[2963]! } + public var Conversation_UnpinMessageAlert: String { return self._s[2964]! } + public var Passport_Address_TypeBankStatement: String { return self._s[2965]! } + public var Passport_Identity_ExpiryDate: String { return self._s[2966]! } + public var Privacy_Calls_P2P: String { return self._s[2967]! } + public func CancelResetAccount_Success(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2969]!, self._r[2969]!, [_0]) + } + public var SocksProxySetup_UseForCallsHelp: String { return self._s[2970]! } + public var EnterPasscode_ChangeTitle: String { return self._s[2971]! } + public var Passport_InfoText: String { return self._s[2972]! } + public var Checkout_NewCard_SaveInfoEnableHelp: String { return self._s[2973]! } public func Login_InvalidPhoneEmailSubject(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2973]!, self._r[2973]!, [_0]) + return formatWithArgumentRanges(self._s[2974]!, self._r[2974]!, [_0]) } public func Time_PreciseDate_m3(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2974]!, self._r[2974]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[2975]!, self._r[2975]!, [_1, _2, _3]) } - public var Passport_Identity_EditDriversLicense: String { return self._s[2975]! } - public var Conversation_TapAndHoldToRecord: String { return self._s[2977]! } + public var Passport_Identity_EditDriversLicense: String { return self._s[2976]! } + public var Conversation_TapAndHoldToRecord: String { return self._s[2978]! } public func Notification_CallTimeFormat(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2978]!, self._r[2978]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2979]!, self._r[2979]!, [_1, _2]) } public func MESSAGE_ROUND_SEPARATED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2979]!, self._r[2979]!, [_1]) + return formatWithArgumentRanges(self._s[2980]!, self._r[2980]!, [_1]) } public func PHONE_CALL_MISSED_SEPARATED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2981]!, self._r[2981]!, [_1]) + return formatWithArgumentRanges(self._s[2982]!, self._r[2982]!, [_1]) } public func Generic_OpenHiddenLinkAlert(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2983]!, self._r[2983]!, [_0]) + return formatWithArgumentRanges(self._s[2984]!, self._r[2984]!, [_0]) } - public var DialogList_Unread: String { return self._s[2984]! } - public var User_DeletedAccount: String { return self._s[2985]! } + public var DialogList_Unread: String { return self._s[2985]! } + public var User_DeletedAccount: String { return self._s[2986]! } public func Watch_Time_ShortYesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2986]!, self._r[2986]!, [_0]) + return formatWithArgumentRanges(self._s[2987]!, self._r[2987]!, [_0]) } - public var UserInfo_NotificationsDefault: String { return self._s[2987]! } - public var SharedMedia_CategoryMedia: String { return self._s[2988]! } - public var SocksProxySetup_ProxyStatusUnavailable: String { return self._s[2989]! } - public var Channel_AdminLog_MessageRestrictedForever: String { return self._s[2990]! } - public var Watch_ChatList_Compose: String { return self._s[2991]! } - public var Notifications_MessageNotificationsExceptionsHelp: String { return self._s[2992]! } - public var Watch_Microphone_Access: String { return self._s[2993]! } - public var Group_Setup_HistoryHeader: String { return self._s[2994]! } - public var Activity_UploadingPhoto: String { return self._s[2995]! } + public var UserInfo_NotificationsDefault: String { return self._s[2988]! } + public var SharedMedia_CategoryMedia: String { return self._s[2989]! } + public var SocksProxySetup_ProxyStatusUnavailable: String { return self._s[2990]! } + public var Channel_AdminLog_MessageRestrictedForever: String { return self._s[2991]! } + public var Watch_ChatList_Compose: String { return self._s[2992]! } + public var Notifications_MessageNotificationsExceptionsHelp: String { return self._s[2993]! } + public var Watch_Microphone_Access: String { return self._s[2994]! } + public var Group_Setup_HistoryHeader: String { return self._s[2995]! } + public var Activity_UploadingPhoto: String { return self._s[2996]! } public func MESSAGE_VIDEO_SECRET_SEPARATED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2997]!, self._r[2997]!, [_1]) + return formatWithArgumentRanges(self._s[2998]!, self._r[2998]!, [_1]) } - public var Conversation_Edit: String { return self._s[2998]! } - public var Group_ErrorSendRestrictedMedia: String { return self._s[2999]! } - public var Login_TermsOfServiceDecline: String { return self._s[3000]! } - public var Message_PinnedContactMessage: String { return self._s[3001]! } + public var Conversation_Edit: String { return self._s[2999]! } + public var Group_ErrorSendRestrictedMedia: String { return self._s[3000]! } + public var Login_TermsOfServiceDecline: String { return self._s[3001]! } + public var Message_PinnedContactMessage: String { return self._s[3002]! } public func Channel_AdminLog_MessageRestrictedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3002]!, self._r[3002]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3003]!, self._r[3003]!, [_1, _2]) } public func Login_PhoneBannedEmailBody(_ _1: String, _ _2: String, _ _3: String, _ _4: String, _ _5: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3003]!, self._r[3003]!, [_1, _2, _3, _4, _5]) + return formatWithArgumentRanges(self._s[3004]!, self._r[3004]!, [_1, _2, _3, _4, _5]) } - public var TwoStepAuth_AdditionalPassword: String { return self._s[3005]! } - public var Passport_Phone_EnterOtherNumber: String { return self._s[3006]! } - public var Message_PinnedPhotoMessage: String { return self._s[3007]! } - public var Passport_FieldPhone: String { return self._s[3008]! } - public var TwoStepAuth_RecoveryEmailAddDescription: String { return self._s[3009]! } - public var InfoPlist_NSCameraUsageDescription: String { return self._s[3011]! } - public var Conversation_Call: String { return self._s[3012]! } - public var Common_TakePhoto: String { return self._s[3014]! } - public var Channel_NotificationLoading: String { return self._s[3015]! } + public var TwoStepAuth_AdditionalPassword: String { return self._s[3006]! } + public var Passport_Phone_EnterOtherNumber: String { return self._s[3007]! } + public var Message_PinnedPhotoMessage: String { return self._s[3008]! } + public var Passport_FieldPhone: String { return self._s[3009]! } + public var TwoStepAuth_RecoveryEmailAddDescription: String { return self._s[3010]! } + public var InfoPlist_NSCameraUsageDescription: String { return self._s[3012]! } + public var Conversation_Call: String { return self._s[3013]! } + public var Common_TakePhoto: String { return self._s[3015]! } + public var Channel_NotificationLoading: String { return self._s[3016]! } public func Notification_Exceptions_Sound(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3016]!, self._r[3016]!, [_0]) + return formatWithArgumentRanges(self._s[3017]!, self._r[3017]!, [_0]) } - public var Permissions_SiriTitle_v0: String { return self._s[3017]! } + public var Permissions_SiriTitle_v0: String { return self._s[3018]! } public func Login_ResetAccountProtected_Text(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3018]!, self._r[3018]!, [_0]) + return formatWithArgumentRanges(self._s[3019]!, self._r[3019]!, [_0]) } - public var Channel_MessagePhotoRemoved: String { return self._s[3019]! } - public var Common_edit: String { return self._s[3020]! } - public var PrivacySettings_AuthSessions: String { return self._s[3021]! } - public var Month_ShortJune: String { return self._s[3022]! } - public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[3023]! } - public var Call_ReportSend: String { return self._s[3024]! } - public var Watch_LastSeen_JustNow: String { return self._s[3025]! } - public var Notifications_MessageNotifications: String { return self._s[3026]! } - public var BroadcastListInfo_AddRecipient: String { return self._s[3028]! } - public var Group_Status: String { return self._s[3029]! } + public var Channel_MessagePhotoRemoved: String { return self._s[3020]! } + public var Common_edit: String { return self._s[3021]! } + public var PrivacySettings_AuthSessions: String { return self._s[3022]! } + public var Month_ShortJune: String { return self._s[3023]! } + public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[3024]! } + public var Call_ReportSend: String { return self._s[3025]! } + public var Watch_LastSeen_JustNow: String { return self._s[3026]! } + public var Notifications_MessageNotifications: String { return self._s[3027]! } + public var BroadcastListInfo_AddRecipient: String { return self._s[3029]! } + public var Group_Status: String { return self._s[3030]! } public func AutoNightTheme_LocationHelp(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3030]!, self._r[3030]!, [_0, _1]) + return formatWithArgumentRanges(self._s[3031]!, self._r[3031]!, [_0, _1]) } - public var ShareMenu_ShareTo: String { return self._s[3031]! } - public var Conversation_Moderate_Ban: String { return self._s[3032]! } + public var ShareMenu_ShareTo: String { return self._s[3032]! } + public var Conversation_Moderate_Ban: String { return self._s[3033]! } public func Conversation_DeleteMessagesFor(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3033]!, self._r[3033]!, [_0]) + return formatWithArgumentRanges(self._s[3034]!, self._r[3034]!, [_0]) } - public var SharedMedia_ViewInChat: String { return self._s[3034]! } - public var Map_LiveLocationFor8Hours: String { return self._s[3035]! } + public var SharedMedia_ViewInChat: String { return self._s[3035]! } + public var Map_LiveLocationFor8Hours: String { return self._s[3036]! } public func Map_AccurateTo(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3037]!, self._r[3037]!, [_0]) + return formatWithArgumentRanges(self._s[3038]!, self._r[3038]!, [_0]) } - public var Appearance_ReduceMotion: String { return self._s[3038]! } - public var Map_OpenInHereMaps: String { return self._s[3039]! } - public var Channel_Setup_TypePublicHelp: String { return self._s[3040]! } - public var Passport_Identity_EditInternalPassport: String { return self._s[3041]! } - public var PhotoEditor_Skip: String { return self._s[3042]! } - public func LastSeen_MinutesAgo(_ value: Int32) -> String { + public var Appearance_ReduceMotion: String { return self._s[3039]! } + public var Map_OpenInHereMaps: String { return self._s[3040]! } + public var Channel_Setup_TypePublicHelp: String { return self._s[3041]! } + public var Passport_Identity_EditInternalPassport: String { return self._s[3042]! } + public var PhotoEditor_Skip: String { return self._s[3043]! } + public func CHANNEL_MESSAGE_PHOTOS_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedVideos(_ value: Int32) -> String { + public func MessageTimer_Minutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedGifs(_ value: Int32) -> String { + public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { + public func Call_ShortSeconds(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, "\(value)") } - public func CHANNEL_MESSAGES_SEPARATED(_ value: Int32) -> String { + public func Call_Minutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String { + public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { + public func Notifications_Exceptions(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, "\(value)") } - public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { + public func CHANNEL_MESSAGE_FWDS_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, "\(value)") } - public func CHAT_MESSAGES_SEPARATED(_ value: Int32) -> String { + public func ForwardedPhotos(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MESSAGE_PHOTOS_SEPARATED(_ value: Int32) -> String { + public func MessageTimer_Years(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, "\(value)") } - public func SharedMedia_Generic(_ value: Int32) -> String { + public func Map_ETAHours(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, "\(value)") } - public func StickerPack_StickerCount(_ value: Int32) -> String { + public func Conversation_StatusOnline(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Media_SharePhoto(_ value: Int32) -> String { + public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, "\(value)") } - public func LastSeen_HoursAgo(_ value: Int32) -> String { + public func ForwardedPolls(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Conversation_StatusOnline(_ value: Int32) -> String { + public func MuteExpires_Hours(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, "\(value)") } - public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String { + public func UserCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedMessages(_ value: Int32) -> String { + public func Call_Seconds(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { + public func MessageTimer_Days(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { + public func Call_ShortMinutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedAuthorsOthers(_ value: Int32) -> String { + public func MuteFor_Hours(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notification_GameScoreExtended(_ value: Int32) -> String { + public func CHANNEL_MESSAGES_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_Days(_ value: Int32) -> String { + public func ForwardedAudios(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { + public func InviteText_ContactsCountText(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, "\(value)") } - public func SharedMedia_Photo(_ value: Int32) -> String { + public func Watch_UserInfo_Mute(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Contacts_ImportersCount(_ value: Int32) -> String { + public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, "\(value)") } - public func CHAT_MESSAGE_FWDS_SEPARATED(_ value: Int32) -> String { + public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Call_Minutes(_ value: Int32) -> String { + public func AttachmentMenu_SendPhoto(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, "\(value)") } - public func AttachmentMenu_SendVideo(_ value: Int32) -> String { + public func MESSAGE_FWDS_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Map_ETAMinutes(_ value: Int32) -> String { + public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, "\(value)") } - public func InviteText_ContactsCountText(_ value: Int32) -> String { + public func SharedMedia_Video(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ChatList_DeleteConfirmation(_ value: Int32) -> String { + public func ForwardedVideoMessages(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { + public func MessageTimer_Seconds(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_ShortSeconds(_ value: Int32) -> String { + public func Passport_Scans(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, "\(value)") } - public func CHANNEL_MESSAGE_PHOTOS_SEPARATED(_ value: Int32) -> String { + public func AttachmentMenu_SendItem(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notifications_Exceptions(_ value: Int32) -> String { + public func MuteExpires_Minutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Invitation_Members(_ value: Int32) -> String { + public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_ShortHours(_ value: Int32) -> String { + public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { + public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MuteExpires_Minutes(_ value: Int32) -> String { + public func CHAT_MESSAGES_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_ShortWeeks(_ value: Int32) -> String { + public func MessageTimer_ShortSeconds(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, "\(value)") } - public func AttachmentMenu_SendGif(_ value: Int32) -> String { + public func ForwardedGifs(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedVideoMessages(_ value: Int32) -> String { + public func SharedMedia_Link(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { + public func ChatList_DeleteConfirmation(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, "\(value)") } - public func AttachmentMenu_SendPhoto(_ value: Int32) -> String { + public func ForwardedAuthorsOthers(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, "\(value)") } - public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { + public func Media_SharePhoto(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, "\(value)") } - public func SharedMedia_File(_ value: Int32) -> String { + public func ForwardedStickers(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Watch_UserInfo_Mute(_ value: Int32) -> String { + public func MessageTimer_Weeks(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MESSAGES_SEPARATED(_ value: Int32) -> String { + public func LastSeen_MinutesAgo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, "\(value)") } - public func StickerPack_AddMaskCount(_ value: Int32) -> String { + public func GroupInfo_ParticipantCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, "\(value)") } - public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { + public func ForwardedLocations(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Media_ShareVideo(_ value: Int32) -> String { + public func MessagePoll_VotedCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { + public func MESSAGES_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MuteFor_Hours(_ value: Int32) -> String { + public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_Minutes(_ value: Int32) -> String { + public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MuteFor_Days(_ value: Int32) -> String { + public func QuickSend_Photos(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_ShortDays(_ value: Int32) -> String { + public func MessageTimer_ShortWeeks(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Passport_Scans(_ value: Int32) -> String { + public func MESSAGE_PHOTOS_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, "\(value)") } - public func StickerPack_AddStickerCount(_ value: Int32) -> String { + public func MuteFor_Days(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, "\(value)") } - public func UserCount(_ value: Int32) -> String { + public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_Months(_ value: Int32) -> String { + public func ForwardedMessages(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_Seconds(_ value: Int32) -> String { + public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedAudios(_ value: Int32) -> String { + public func Conversation_StatusSubscribers(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_Hours(_ value: Int32) -> String { + public func StickerPack_AddMaskCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_Years(_ value: Int32) -> String { + public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Call_ShortSeconds(_ value: Int32) -> String { + public func SharedMedia_Photo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, "\(value)") } - public func GroupInfo_ParticipantCount(_ value: Int32) -> String { + public func MessageTimer_Months(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedStickers(_ value: Int32) -> String { + public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notification_GameScoreSimple(_ value: Int32) -> String { + public func MuteExpires_Days(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { + public func Media_ShareItem(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, "\(value)") } - public func QuickSend_Photos(_ value: Int32) -> String { + public func ForwardedVideos(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, "\(value)") } @@ -3832,115 +3833,115 @@ public final class PresentationStrings { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String { + public func Notification_GameScoreExtended(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, "\(value)") } - public func SharedMedia_Link(_ value: Int32) -> String { + public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, "\(value)") } - public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { + public func AttachmentMenu_SendVideo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Map_ETAHours(_ value: Int32) -> String { + public func SharedMedia_Generic(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MESSAGE_FWDS_SEPARATED(_ value: Int32) -> String { + public func MessageTimer_ShortHours(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Call_ShortMinutes(_ value: Int32) -> String { + public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Conversation_StatusSubscribers(_ value: Int32) -> String { + public func ForwardedFiles(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, "\(value)") } - public func CHANNEL_MESSAGE_FWDS_SEPARATED(_ value: Int32) -> String { + public func Map_ETAMinutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessagePoll_VotedCount(_ value: Int32) -> String { + public func Invitation_Members(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Conversation_StatusMembers(_ value: Int32) -> String { + public func MessageTimer_Hours(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedContacts(_ value: Int32) -> String { + public func LastSeen_HoursAgo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedPolls(_ value: Int32) -> String { + public func StickerPack_StickerCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, "\(value)") } - public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { + public func ForwardedContacts(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Call_Seconds(_ value: Int32) -> String { + public func Contacts_ImportersCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_ShortMinutes(_ value: Int32) -> String { + public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, "\(value)") } - public func Media_ShareItem(_ value: Int32) -> String { + public func Notification_GameScoreSimple(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { + public func MessageTimer_ShortMinutes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, "\(value)") } - public func SharedMedia_Video(_ value: Int32) -> String { + public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MessageTimer_Weeks(_ value: Int32) -> String { + public func Conversation_StatusMembers(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedPhotos(_ value: Int32) -> String { + public func SharedMedia_File(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedLocations(_ value: Int32) -> String { + public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, "\(value)") } - public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { + public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MuteExpires_Days(_ value: Int32) -> String { + public func CHAT_MESSAGE_FWDS_SEPARATED(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, "\(value)") } - public func MuteExpires_Hours(_ value: Int32) -> String { + public func Media_ShareVideo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, "\(value)") } - public func ForwardedFiles(_ value: Int32) -> String { + public func StickerPack_AddStickerCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, "\(value)") } - public func AttachmentMenu_SendItem(_ value: Int32) -> String { + public func AttachmentMenu_SendGif(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, "\(value)") } - public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { + public func MessageTimer_ShortDays(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, "\(value)") } - public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { + public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, "\(value)") } diff --git a/TelegramUI/Resources/PresentationStrings.mapping b/TelegramUI/Resources/PresentationStrings.mapping index dcc2adc265..39ad32e5a2 100644 Binary files a/TelegramUI/Resources/PresentationStrings.mapping and b/TelegramUI/Resources/PresentationStrings.mapping differ