diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index bd1dc5bfab..bbc6f7dca5 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14059,3 +14059,33 @@ Sorry for the inconvenience."; "ChatbotSetup.Rights.ManageStories" = "Manage Stories"; "Gift.Send.Upgrade.ForcedInfo" = "%1$@ accepts only unique gifts. [Learn More >]()"; + +"Privacy.Gifts.ShowGiftButton" = "Show Gift Icon in Chats"; +"Privacy.Gifts.ShowGiftButtonInfo" = "Display the #Gift icon in the message input field for both participants in all chats."; + +"Privacy.Gifts.AcceptedTypes" = "ACCEPTED GIFT TYPES"; +"Privacy.Gifts.AcceptedTypes.Unlimited" = "Unlimited"; +"Privacy.Gifts.AcceptedTypes.Limited" = "Limited-Edition"; +"Privacy.Gifts.AcceptedTypes.Unique" = "Unique"; +"Privacy.Gifts.AcceptedTypes.Premium" = "Premium Subscriptions"; +"Privacy.Gifts.AcceptedTypes.Info" = "Choose the types of gifts that you allow others to send you."; + +"Chat.PanelFrozenAccount.Title" = "You account is frozen"; +"Chat.PanelFrozenAccount.Text" = "Tap to view details"; + +"FrozenAccount.Title" = "Your Account is Frozen"; +"FrozenAccount.Violation.Title" = "Violation of Terms"; +"FrozenAccount.Violation.Text" = "Your account was frozen for breaking Telegram's Terms and Conditions."; +"FrozenAccount.ReadOnly.Title" = "Read-Only Mode"; +"FrozenAccount.ReadOnly.Text" = "You can access your account but can't send messages or take actions."; +"FrozenAccount.Appeal.Title" = "Appeal Before Deactivation"; +"FrozenAccount.Appeal.Text" = "Appeal via [@SpamBot]() before %@, or your account will be deleted."; +"FrozenAccount.SubmitAppeal" = "Submit an Appeal"; +"FrozenAccount.Understood" = "Understood"; + +"AdsInfo.Search.Respect.Text" = "Ads like this do not use your personal information and are based on the search query you entered."; +"AdsInfo.Search.Ads.Text" = "You can turn off ads by subscribing to [Telegram Premium]()."; +"AdsInfo.Search.Launch.Text" = "Anyone can create an ad to display in search results for any query. Check out the Telegram Ad Platform for details. [Learn More >]()"; + +"ChatList.FrozenAccount.Title" = "Your account is frozen"; +"ChatList.FrozenAccount.Text" = "Tap to view details and submit an appeal."; diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutController.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutController.swift index 69d5d0a7c5..95baaa332f 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutController.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutController.swift @@ -11,6 +11,7 @@ public final class BotCheckoutController: ViewController { public final class InputData { public enum FetchError { case generic + case disallowedStarGifts } public let form: BotPaymentForm @@ -53,8 +54,13 @@ public final class BotCheckoutController: ViewController { } return context.engine.payments.fetchBotPaymentForm(source: source, themeParams: themeParams) - |> mapError { _ -> FetchError in - return .generic + |> mapError { error -> FetchError in + switch error { + case .disallowedStarGift: + return .disallowedStarGifts + default: + return .generic + } } |> mapToSignal { paymentForm -> Signal in let botPeer: Signal diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index b90f8608a1..e1374e6a86 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -6139,7 +6139,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController let context = self.context let presentationData = context.sharedContext.currentPresentationData.with { $0 } - //TODO:localize var actions: [ContextMenuItem] = [] if adPeer.sponsorInfo != nil || adPeer.additionalInfo != nil { actions.append(.action(ContextMenuActionItem(text: presentationData.strings.Chat_ContextMenu_AdSponsorInfo, textColor: .primary, icon: { theme in @@ -6191,7 +6190,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController }))) } - actions.append(.action(ContextMenuActionItem(text: "About These Ads", textColor: .primary, textLayout: .twoLinesMax, textFont: .custom(font: Font.regular(presentationData.listsFontSize.baseDisplaySize - 1.0), height: nil, verticalOffset: nil), badge: nil, icon: { theme in + actions.append(.action(ContextMenuActionItem(text: presentationData.strings.Chat_ContextMenu_AboutAd, textColor: .primary, textLayout: .twoLinesMax, textFont: .custom(font: Font.regular(presentationData.listsFontSize.baseDisplaySize - 1.0), height: nil, verticalOffset: nil), badge: nil, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.actionSheet.primaryTextColor) }, iconSource: nil, action: { [weak self] _, f in f(.default) diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index 388e03209f..8ce513b4a2 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -855,6 +855,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable { return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .generalSearch(isSavedMessages: false), peer: .peer(peer: peer.peer, chatPeer: peer.peer), status: .addressName(suffixString), badge: nil, requiresPremiumForMessaging: false, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, searchQuery: nil, isAd: true, action: { _ in interaction.peerSelected(peer.peer, nil, nil, nil, false) + context.engine.messages.markAdAction(opaqueId: peer.opaqueId, media: false, fullscreen: false) }, disabledAction: { _ in interaction.disabledPeerSelected(peer.peer, nil, .generic) }, contextAction: peerContextAction.flatMap { peerContextAction in diff --git a/submodules/ChatListUI/Sources/Node/ChatListNoticeItem.swift b/submodules/ChatListUI/Sources/Node/ChatListNoticeItem.swift index 14f4e82614..383079142f 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNoticeItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNoticeItem.swift @@ -289,9 +289,8 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode { textString = NSAttributedString(string: item.strings.ChatList_AddPhoto_Text, font: smallTextFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor) avatarPeer = accountPeer case .accountFreeze: - //TODO:localize - titleString = NSAttributedString(string: "Your account is frozen", font: titleFont, textColor: item.theme.list.itemDestructiveColor) - textString = NSAttributedString(string: "Tap to view details and submit an appeal.", font: smallTextFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor) + titleString = NSAttributedString(string: item.strings.ChatList_FrozenAccount_Title, font: titleFont, textColor: item.theme.list.itemDestructiveColor) + textString = NSAttributedString(string: item.strings.ChatList_FrozenAccount_Text, font: smallTextFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor) } var leftInset: CGFloat = sideInset diff --git a/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift b/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift index 10b25f28dc..b3eec18ce1 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListCheckboxItem.swift @@ -36,12 +36,13 @@ public class ItemListCheckboxItem: ListViewItem, ItemListItem { let color: ItemListCheckboxItemColor let textColor: TextColor let checked: Bool + let enabled: Bool let zeroSeparatorInsets: Bool public let sectionId: ItemListSectionId let action: () -> Void let deleteAction: (() -> Void)? - public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, iconSize: CGSize? = nil, iconPlacement: IconPlacement = .default, title: String, subtitle: String? = nil, style: ItemListCheckboxItemStyle, color: ItemListCheckboxItemColor = .accent, textColor: TextColor = .primary, checked: Bool, zeroSeparatorInsets: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void, deleteAction: (() -> Void)? = nil) { + public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, iconSize: CGSize? = nil, iconPlacement: IconPlacement = .default, title: String, subtitle: String? = nil, style: ItemListCheckboxItemStyle, color: ItemListCheckboxItemColor = .accent, textColor: TextColor = .primary, checked: Bool, enabled: Bool = true, zeroSeparatorInsets: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void, deleteAction: (() -> Void)? = nil) { self.presentationData = presentationData self.icon = icon self.iconSize = iconSize @@ -52,6 +53,7 @@ public class ItemListCheckboxItem: ListViewItem, ItemListItem { self.color = color self.textColor = textColor self.checked = checked + self.enabled = enabled self.zeroSeparatorInsets = zeroSeparatorInsets self.sectionId = sectionId self.action = action @@ -95,7 +97,9 @@ public class ItemListCheckboxItem: ListViewItem, ItemListItem { public func selected(listView: ListView){ listView.clearHighlightAnimated(true) - self.action() + if self.enabled { + self.action() + } } } @@ -209,7 +213,7 @@ public class ItemListCheckboxItemNode: ItemListRevealOptionsItemNode { let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize) let subtitleFont = Font.regular(floor(item.presentationData.fontSize.itemListBaseFontSize * 15.0 / 17.0)) - let titleColor: UIColor + var titleColor: UIColor let subtitleColor: UIColor = item.presentationData.theme.list.itemSecondaryTextColor switch item.textColor { case .primary: @@ -217,6 +221,9 @@ public class ItemListCheckboxItemNode: ItemListRevealOptionsItemNode { case .accent: titleColor = item.presentationData.theme.list.itemAccentColor } + if !item.enabled { + titleColor = item.presentationData.theme.list.itemDisabledTextColor + } let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: titleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 28.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) @@ -239,12 +246,16 @@ public class ItemListCheckboxItemNode: ItemListRevealOptionsItemNode { updatedTheme = item.presentationData.theme } - if currentItem?.presentationData.theme !== item.presentationData.theme || currentItem?.color != item.color { - switch item.color { - case .accent: - updateCheckImage = PresentationResourcesItemList.checkIconImage(item.presentationData.theme) - case .secondary: - updateCheckImage = PresentationResourcesItemList.secondaryCheckIconImage(item.presentationData.theme) + if currentItem?.presentationData.theme !== item.presentationData.theme || currentItem?.color != item.color || currentItem?.enabled != item.enabled { + if !item.enabled { + updateCheckImage = PresentationResourcesItemList.disabledCheckIconImage(item.presentationData.theme) + } else { + switch item.color { + case .accent: + updateCheckImage = PresentationResourcesItemList.checkIconImage(item.presentationData.theme) + case .secondary: + updateCheckImage = PresentationResourcesItemList.secondaryCheckIconImage(item.presentationData.theme) + } } } @@ -261,6 +272,11 @@ public class ItemListCheckboxItemNode: ItemListRevealOptionsItemNode { } else { strongSelf.activateArea.accessibilityValue = "" } + if item.enabled { + strongSelf.activateArea.accessibilityTraits = [] + } else { + strongSelf.activateArea.accessibilityTraits = [.notEnabled] + } strongSelf.activateArea.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 0.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: layout.contentSize.height)) @@ -368,7 +384,7 @@ public class ItemListCheckboxItemNode: ItemListRevealOptionsItemNode { override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { super.setHighlighted(highlighted, at: point, animated: animated) - if highlighted { + if highlighted && (self.item?.enabled ?? false) { self.highlightedBackgroundNode.alpha = 1.0 if self.highlightedBackgroundNode.supernode == nil { var anchorNode: ASDisplayNode? diff --git a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift index 083328e071..57d3941518 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift @@ -141,13 +141,13 @@ private enum SelectivePrivacySettingsEntry: ItemListNodeEntry { case forwardsPreview(PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationChatBubbleCorners, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, String, Bool, String) case birthdayHeader(PresentationTheme, String) case settingHeader(PresentationTheme, String) - case everybody(PresentationTheme, String, Bool, Bool) - case contacts(PresentationTheme, String, Bool, Bool) - case nobody(PresentationTheme, String, Bool, Bool) + case everybody(PresentationTheme, String, Bool, Bool, Bool) + case contacts(PresentationTheme, String, Bool, Bool, Bool) + case nobody(PresentationTheme, String, Bool, Bool, Bool) case settingInfo(PresentationTheme, String, String) case exceptionsHeader(PresentationTheme, String) - case disableFor(PresentationTheme, String, String) - case enableFor(PresentationTheme, String, String) + case disableFor(PresentationTheme, String, String, Bool) + case enableFor(PresentationTheme, String, String, Bool) case peersInfo(PresentationTheme, String) case callsP2PHeader(PresentationTheme, String) case callsP2PAlways(PresentationTheme, String, Bool) @@ -323,20 +323,20 @@ private enum SelectivePrivacySettingsEntry: ItemListNodeEntry { } else { return false } - case let .everybody(lhsTheme, lhsText, lhsValue, lhsIsLocked): - if case let .everybody(rhsTheme, rhsText, rhsValue, rhsIsLocked) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsIsLocked == rhsIsLocked { + case let .everybody(lhsTheme, lhsText, lhsValue, lhsIsLocked, lhsEnabled): + if case let .everybody(rhsTheme, rhsText, rhsValue, rhsIsLocked, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsIsLocked == rhsIsLocked, lhsEnabled == rhsEnabled { return true } else { return false } - case let .contacts(lhsTheme, lhsText, lhsValue, lhsIsLocked): - if case let .contacts(rhsTheme, rhsText, rhsValue, rhsIsLocked) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsIsLocked == rhsIsLocked { + case let .contacts(lhsTheme, lhsText, lhsValue, lhsIsLocked, lhsEnabled): + if case let .contacts(rhsTheme, rhsText, rhsValue, rhsIsLocked, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsIsLocked == rhsIsLocked, lhsEnabled == rhsEnabled { return true } else { return false } - case let .nobody(lhsTheme, lhsText, lhsValue, lhsIsLocked): - if case let .nobody(rhsTheme, rhsText, rhsValue, rhsIsLocked) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsIsLocked == rhsIsLocked { + case let .nobody(lhsTheme, lhsText, lhsValue, lhsIsLocked, lhsEnabled): + if case let .nobody(rhsTheme, rhsText, rhsValue, rhsIsLocked, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsIsLocked == rhsIsLocked, lhsEnabled == rhsEnabled { return true } else { return false @@ -353,14 +353,14 @@ private enum SelectivePrivacySettingsEntry: ItemListNodeEntry { } else { return false } - case let .disableFor(lhsTheme, lhsText, lhsValue): - if case let .disableFor(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + case let .disableFor(lhsTheme, lhsText, lhsValue, lhsEnabled): + if case let .disableFor(rhsTheme, rhsText, rhsValue, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsEnabled == rhsEnabled { return true } else { return false } - case let .enableFor(lhsTheme, lhsText, lhsValue): - if case let .enableFor(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + case let .enableFor(lhsTheme, lhsText, lhsValue, lhsEnabled): + if case let .enableFor(rhsTheme, rhsText, rhsValue, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsEnabled == rhsEnabled { return true } else { return false @@ -565,23 +565,23 @@ private enum SelectivePrivacySettingsEntry: ItemListNodeEntry { }) case let .settingHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, multiline: true, sectionId: self.section) - case let .everybody(_, text, value, isLocked): - return ItemListCheckboxItem(presentationData: presentationData, icon: !isLocked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: text, style: .left, checked: value && !isLocked, zeroSeparatorInsets: false, sectionId: self.section, action: { + case let .everybody(_, text, value, isLocked, isEnabled): + return ItemListCheckboxItem(presentationData: presentationData, icon: !isLocked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: text, style: .left, checked: value && !isLocked, enabled: isEnabled, zeroSeparatorInsets: false, sectionId: self.section, action: { if isLocked { } else { arguments.updateType(.everybody) } }) - case let .contacts(_, text, value, isLocked): - return ItemListCheckboxItem(presentationData: presentationData, icon: !isLocked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: text, style: .left, checked: value && !isLocked, zeroSeparatorInsets: false, sectionId: self.section, action: { + case let .contacts(_, text, value, isLocked, isEnabled): + return ItemListCheckboxItem(presentationData: presentationData, icon: !isLocked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: text, style: .left, checked: value && !isLocked, enabled: isEnabled, zeroSeparatorInsets: false, sectionId: self.section, action: { if isLocked { arguments.displayLockedInfo() } else { arguments.updateType(.contacts) } }) - case let .nobody(_, text, value, isLocked): - return ItemListCheckboxItem(presentationData: presentationData, icon: !isLocked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: text, style: .left, checked: value && !isLocked, zeroSeparatorInsets: false, sectionId: self.section, action: { + case let .nobody(_, text, value, isLocked, isEnabled): + return ItemListCheckboxItem(presentationData: presentationData, icon: !isLocked ? nil : generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: presentationData.theme.list.itemSecondaryTextColor), iconPlacement: .check, title: text, style: .left, checked: value && !isLocked, enabled: isEnabled, zeroSeparatorInsets: false, sectionId: self.section, action: { if isLocked { arguments.displayLockedInfo() } else { @@ -594,12 +594,12 @@ private enum SelectivePrivacySettingsEntry: ItemListNodeEntry { }) case let .exceptionsHeader(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) - case let .disableFor(_, title, value): - return ItemListDisclosureItem(presentationData: presentationData, title: title, label: value, sectionId: self.section, style: .blocks, action: { - arguments.openSelective(.main, false) - }) - case let .enableFor(_, title, value): - return ItemListDisclosureItem(presentationData: presentationData, title: title, label: value, sectionId: self.section, style: .blocks, action: { + case let .disableFor(_, title, value, isEnabled): + return ItemListDisclosureItem(presentationData: presentationData, title: title, enabled: isEnabled, label: value, sectionId: self.section, style: .blocks, action: { + arguments.openSelective(.main, false) + }) + case let .enableFor(_, title, value, isEnabled): + return ItemListDisclosureItem(presentationData: presentationData, title: title, enabled: isEnabled, label: value, sectionId: self.section, style: .blocks, action: { arguments.openSelective(.main, true) }) case let .peersInfo(_, text): @@ -1000,9 +1000,14 @@ private func selectivePrivacySettingsControllerEntries(presentationData: Present enableForText = presentationData.strings.Privacy_GroupsAndChannels_AlwaysAllow } + var permisisonsEnabled = true if case .giftsAutoSave = kind { - entries.append(.showGiftButton(presentationData.theme, "Show Gift Icon in Chats", !isPremium, state.showGiftButton == true && state.disallowedGifts != TelegramDisallowedGifts.All, state.disallowedGifts != TelegramDisallowedGifts.All)) - entries.append(.showGiftButtonInfo(presentationData.theme, "Display the # Gift icon in the message input field for both participants in all chats.")) + entries.append(.showGiftButton(presentationData.theme, presentationData.strings.Privacy_Gifts_ShowGiftButton, !isPremium, state.showGiftButton == true, true)) + entries.append(.showGiftButtonInfo(presentationData.theme, presentationData.strings.Privacy_Gifts_ShowGiftButtonInfo.replacingOccurrences(of: "#", with: " # "))) + + if state.disallowedGifts == TelegramDisallowedGifts.All { + permisisonsEnabled = false + } } if case .forwards = kind { @@ -1030,13 +1035,13 @@ private func selectivePrivacySettingsControllerEntries(presentationData: Present entries.append(.settingHeader(presentationData.theme, settingTitle)) if case .voiceMessages = kind { - entries.append(.everybody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenEverybody, state.setting == .everybody || !isPremium, false)) - entries.append(.contacts(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenContacts, state.setting == .contacts && isPremium, !isPremium)) - entries.append(.nobody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenNobody, state.setting == .nobody && isPremium, !isPremium)) + entries.append(.everybody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenEverybody, state.setting == .everybody || !isPremium, false, permisisonsEnabled)) + entries.append(.contacts(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenContacts, state.setting == .contacts && isPremium, !isPremium, permisisonsEnabled)) + entries.append(.nobody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenNobody, state.setting == .nobody && isPremium, !isPremium, permisisonsEnabled)) } else { - entries.append(.everybody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenEverybody, state.setting == .everybody, false)) - entries.append(.contacts(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenContacts, state.setting == .contacts, false)) - entries.append(.nobody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenNobody, state.setting == .nobody, false)) + entries.append(.everybody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenEverybody, state.setting == .everybody, false, permisisonsEnabled)) + entries.append(.contacts(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenContacts, state.setting == .contacts, false, permisisonsEnabled)) + entries.append(.nobody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenNobody, state.setting == .nobody, false, permisisonsEnabled)) } if let settingInfoText = settingInfoText { @@ -1059,12 +1064,12 @@ private func selectivePrivacySettingsControllerEntries(presentationData: Present switch state.setting { case .everybody: - entries.append(.disableFor(presentationData.theme, disableForText, stringForUserCount(state.disableFor, enableForPremium: false, enableForBots: false, strings: presentationData.strings))) + entries.append(.disableFor(presentationData.theme, disableForText, stringForUserCount(state.disableFor, enableForPremium: false, enableForBots: false, strings: presentationData.strings), permisisonsEnabled)) case .contacts: - entries.append(.disableFor(presentationData.theme, disableForText, stringForUserCount(state.disableFor, enableForPremium: false, enableForBots: false, strings: presentationData.strings))) - entries.append(.enableFor(presentationData.theme, enableForText, stringForUserCount(state.enableFor, enableForPremium: state.enableForPremium, enableForBots: state.enableForBots, strings: presentationData.strings))) + entries.append(.disableFor(presentationData.theme, disableForText, stringForUserCount(state.disableFor, enableForPremium: false, enableForBots: false, strings: presentationData.strings), permisisonsEnabled)) + entries.append(.enableFor(presentationData.theme, enableForText, stringForUserCount(state.enableFor, enableForPremium: state.enableForPremium, enableForBots: state.enableForBots, strings: presentationData.strings), permisisonsEnabled)) case .nobody: - entries.append(.enableFor(presentationData.theme, enableForText, stringForUserCount(state.enableFor, enableForPremium: state.enableForPremium, enableForBots: state.enableForBots, strings: presentationData.strings))) + entries.append(.enableFor(presentationData.theme, enableForText, stringForUserCount(state.enableFor, enableForPremium: state.enableForPremium, enableForBots: state.enableForBots, strings: presentationData.strings), permisisonsEnabled)) } let exceptionsInfo: String if case .profilePhoto = kind { @@ -1146,13 +1151,12 @@ private func selectivePrivacySettingsControllerEntries(presentationData: Present } if case .giftsAutoSave = kind { - //TODO:localize - entries.append(.disallowedGiftsHeader(presentationData.theme, "ACCEPTED GIFT TYPES")) - entries.append(.disallowedGiftsUnlimited(presentationData.theme, "Unlimited", !isPremium, !(state.disallowedGifts?.contains(.unlimited) ?? false))) - entries.append(.disallowedGiftsLimited(presentationData.theme, "Limited-Edition", !isPremium, !(state.disallowedGifts?.contains(.limited) ?? false))) - entries.append(.disallowedGiftsUnique(presentationData.theme, "Unique", !isPremium, !(state.disallowedGifts?.contains(.unique) ?? false))) - entries.append(.disallowedGiftsPremium(presentationData.theme, "Premium Subscriptions", !isPremium, !(state.disallowedGifts?.contains(.premium) ?? false))) - entries.append(.disallowedGiftsInfo(presentationData.theme, "Choose the types of gifts that you allow others to send you.")) + entries.append(.disallowedGiftsHeader(presentationData.theme, presentationData.strings.Privacy_Gifts_AcceptedTypes.uppercased())) + entries.append(.disallowedGiftsUnlimited(presentationData.theme, presentationData.strings.Privacy_Gifts_AcceptedTypes_Unlimited, !isPremium, !(state.disallowedGifts?.contains(.unlimited) ?? false))) + entries.append(.disallowedGiftsLimited(presentationData.theme, presentationData.strings.Privacy_Gifts_AcceptedTypes_Limited, !isPremium, !(state.disallowedGifts?.contains(.limited) ?? false))) + entries.append(.disallowedGiftsUnique(presentationData.theme, presentationData.strings.Privacy_Gifts_AcceptedTypes_Unique, !isPremium, !(state.disallowedGifts?.contains(.unique) ?? false))) + entries.append(.disallowedGiftsPremium(presentationData.theme, presentationData.strings.Privacy_Gifts_AcceptedTypes_Premium, !isPremium, !(state.disallowedGifts?.contains(.premium) ?? false))) + entries.append(.disallowedGiftsInfo(presentationData.theme, presentationData.strings.Privacy_Gifts_AcceptedTypes_Info)) } return entries diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift index 4c9aea792a..aa8dc08c35 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift @@ -1000,7 +1000,7 @@ public final class CachedUserData: CachedPeerData { public let starRefProgram: TelegramStarRefProgram? public let verification: PeerVerification? public let sendPaidMessageStars: StarsAmount? - public let disallowedGifts: TelegramDisallowedGifts + public let disallowedGifts: TelegramDisallowedGifts? public let peerIds: Set public let messageIds: Set @@ -1042,10 +1042,10 @@ public final class CachedUserData: CachedPeerData { self.starRefProgram = nil self.verification = nil self.sendPaidMessageStars = nil - self.disallowedGifts = [] + self.disallowedGifts = nil } - public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, themeEmoticon: String?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags, businessHours: TelegramBusinessHours?, businessLocation: TelegramBusinessLocation?, greetingMessage: TelegramBusinessGreetingMessage?, awayMessage: TelegramBusinessAwayMessage?, connectedBot: TelegramAccountConnectedBot?, businessIntro: CachedTelegramBusinessIntro, birthday: TelegramBirthday?, personalChannel: CachedTelegramPersonalChannel, botPreview: BotPreview?, starGiftsCount: Int32?, starRefProgram: TelegramStarRefProgram?, verification: PeerVerification?, sendPaidMessageStars: StarsAmount?, disallowedGifts: TelegramDisallowedGifts) { + public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, themeEmoticon: String?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags, businessHours: TelegramBusinessHours?, businessLocation: TelegramBusinessLocation?, greetingMessage: TelegramBusinessGreetingMessage?, awayMessage: TelegramBusinessAwayMessage?, connectedBot: TelegramAccountConnectedBot?, businessIntro: CachedTelegramBusinessIntro, birthday: TelegramBirthday?, personalChannel: CachedTelegramPersonalChannel, botPreview: BotPreview?, starGiftsCount: Int32?, starRefProgram: TelegramStarRefProgram?, verification: PeerVerification?, sendPaidMessageStars: StarsAmount?, disallowedGifts: TelegramDisallowedGifts?) { self.about = about self.botInfo = botInfo self.editableBotInfo = editableBotInfo @@ -1153,7 +1153,7 @@ public final class CachedUserData: CachedPeerData { self.sendPaidMessageStars = decoder.decodeCodable(StarsAmount.self, forKey: "sendPaidMessageStars") - self.disallowedGifts = TelegramDisallowedGifts(rawValue: decoder.decodeInt32ForKey("disallowedGifts", orElse: 0)) + self.disallowedGifts = decoder.decodeOptionalInt32ForKey("disallowedGifts").flatMap { TelegramDisallowedGifts(rawValue: $0) } } public func encode(_ encoder: PostboxEncoder) { @@ -1283,7 +1283,11 @@ public final class CachedUserData: CachedPeerData { encoder.encodeNil(forKey: "sendPaidMessageStars") } - encoder.encodeInt32(self.disallowedGifts.rawValue, forKey: "disallowedGifts") + if let disallowedGifts = self.disallowedGifts { + encoder.encodeInt32(disallowedGifts.rawValue, forKey: "disallowedGifts") + } else { + encoder.encodeNil(forKey: "disallowedGifts") + } } public func isEqual(to: CachedPeerData) -> Bool { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift index 7bdbaa3b01..44fabb5b5a 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift @@ -617,9 +617,6 @@ func _internal_markAdAction(account: Account, opaqueId: Data, media: Bool, fulls let _ = signal.start() } - - - func _internal_markAsSeen(account: Account, opaqueId: Data) -> Signal { return account.network.request(Api.functions.messages.viewSponsoredMessage(randomId: Buffer(data: opaqueId))) |> `catch` { _ -> Signal in diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift index 60233f2ca0..1691444d0b 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift @@ -43,6 +43,7 @@ public enum PresentationResourceKey: Int32 { case itemListDisclosureLocked case itemListCheckIcon case itemListSecondaryCheckIcon + case itemListDisabledCheckIcon case itemListPlusIcon case itemListRoundPlusIcon case itemListAccentDeleteIcon diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift index 677ba5637c..1c42e81b23 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift @@ -57,6 +57,12 @@ public struct PresentationResourcesItemList { }) } + public static func disabledCheckIconImage(_ theme: PresentationTheme) -> UIImage? { + return theme.image(PresentationResourceKey.itemListDisabledCheckIcon.rawValue, { theme in + return generateItemListCheckIcon(color: theme.list.itemDisabledTextColor) + }) + } + public static func plusIconImage(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.itemListPlusIcon.rawValue, { theme in return generateItemListPlusIcon(theme.list.itemAccentColor) diff --git a/submodules/TelegramUI/Components/Ads/AdsInfoScreen/Sources/AdsInfoScreen.swift b/submodules/TelegramUI/Components/Ads/AdsInfoScreen/Sources/AdsInfoScreen.swift index 9050d1f148..0ad2cb1e8e 100644 --- a/submodules/TelegramUI/Components/Ads/AdsInfoScreen/Sources/AdsInfoScreen.swift +++ b/submodules/TelegramUI/Components/Ads/AdsInfoScreen/Sources/AdsInfoScreen.swift @@ -193,10 +193,9 @@ private final class ScrollContent: CombinedComponent { adsText = strings.AdsInfo_Bot_Ads_Text infoRawText = strings.AdsInfo_Bot_Launch_Text case .search: - //TODO:localize - respectText = "Ads like this do not use your personal information and are based on the search query you entered." - adsText = strings.AdsInfo_Bot_Ads_Text - infoRawText = "Anyone can create an ad to display in search results for any query. Check out the Telegram Ad Platform for details. [Learn More >]()" + respectText = strings.AdsInfo_Search_Respect_Text + adsText = strings.AdsInfo_Search_Ads_Text + infoRawText = strings.AdsInfo_Search_Launch_Text } var items: [AnyComponentWithIdentity] = [] diff --git a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift index 0ffe72ca7c..dbc7448ec6 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift @@ -692,6 +692,10 @@ final class GiftOptionsScreenComponent: Component { } self.component = component + if let disallowedGifts = self.state?.disallowedGifts, disallowedGifts == .All { + controller()?.dismiss() + } + if (state.starGifts ?? []).isEmpty && !(state.transferStarGifts ?? []).isEmpty { self.starsFilter = .transfer } @@ -1344,19 +1348,26 @@ final class GiftOptionsScreenComponent: Component { self.disposable = combineLatest( queue: Queue.mainQueue(), context.engine.data.get( - TelegramEngine.EngineData.Item.Peer.Peer.init(id: peerId), + TelegramEngine.EngineData.Item.Peer.Peer.init(id: peerId) + ), + context.engine.data.subscribe( TelegramEngine.EngineData.Item.Peer.DisallowedGifts(id: peerId) ), availableProducts, context.engine.payments.cachedStarGifts(), self.starGiftsContext.state - ).start(next: { [weak self] data, availableProducts, starGifts, profileGiftsState in + ).start(next: { [weak self] peer, disallowedGifts, availableProducts, starGifts, profileGiftsState in guard let self else { return } - self.peer = data.0 - self.disallowedGifts = data.1 ?? [] + if disallowedGifts == nil && self.peer == nil, case .user = peer { + let _ = context.engine.peers.fetchAndUpdateCachedPeerData(peerId: peerId).startStandalone() + } + + self.peer = peer + self.disallowedGifts = disallowedGifts ?? [] + if peerId != context.account.peerId { if availableProducts.isEmpty { var premiumProducts: [PremiumGiftProduct] = [] diff --git a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift index 70c92c1082..1b45895133 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift @@ -390,8 +390,13 @@ final class GiftSetupScreenComponent: Component { let completion = component.completion let signal = BotCheckoutController.InputData.fetch(context: component.context, source: source) - |> `catch` { _ -> Signal in - return .fail(.generic) + |> `catch` { error -> Signal in + switch error { + case .disallowedStarGifts: + return .fail(.disallowedStarGift) + default: + return .fail(.generic) + } } |> mapToSignal { inputData -> Signal in return component.context.engine.payments.sendStarsPaymentForm(formId: inputData.form.id, source: source) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index be5e628289..614714d300 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -14363,7 +14363,7 @@ private final class AccountPeerContextItemNode: ASDisplayNode, ContextMenuCustom action: nil )), environment: {}, - containerSize: CGSize(width: 28.0, height: 28.0) + containerSize: CGSize(width: 24.0, height: 24.0) ) if let view = self.emojiStatusView.view { if view.superview == nil { diff --git a/submodules/TelegramUI/Components/Settings/AccountFreezeInfoScreen/Sources/AccountFreezeInfoScreen.swift b/submodules/TelegramUI/Components/Settings/AccountFreezeInfoScreen/Sources/AccountFreezeInfoScreen.swift index 9de68c6b39..e6b664a823 100644 --- a/submodules/TelegramUI/Components/Settings/AccountFreezeInfoScreen/Sources/AccountFreezeInfoScreen.swift +++ b/submodules/TelegramUI/Components/Settings/AccountFreezeInfoScreen/Sources/AccountFreezeInfoScreen.swift @@ -111,7 +111,7 @@ private final class SheetContent: CombinedComponent { let title = title.update( component: BalancedTextComponent( - text: .plain(NSAttributedString(string: "Your Account is Frozen", font: titleFont, textColor: textColor)), + text: .plain(NSAttributedString(string: strings.FrozenAccount_Title, font: titleFont, textColor: textColor)), horizontalAlignment: .center, maximumNumberOfLines: 0, lineSpacing: 0.1 @@ -125,15 +125,14 @@ private final class SheetContent: CombinedComponent { contentSize.height += title.size.height contentSize.height += spacing - 2.0 - //TODO:localize var items: [AnyComponentWithIdentity] = [] items.append( AnyComponentWithIdentity( - id: "ads", + id: "violation", component: AnyComponent(ParagraphComponent( - title: "Violation of Terms", + title: strings.FrozenAccount_Violation_Title, titleColor: textColor, - text: "Your account was frozen for breaking Telegram's Terms and Conditions.", + text: strings.FrozenAccount_Violation_Text, textColor: secondaryTextColor, iconName: "Account Freeze/Violation", iconColor: linkColor @@ -142,11 +141,11 @@ private final class SheetContent: CombinedComponent { ) items.append( AnyComponentWithIdentity( - id: "split", + id: "readOnly", component: AnyComponent(ParagraphComponent( - title: "Read-Only Mode", + title: strings.FrozenAccount_ReadOnly_Title, titleColor: textColor, - text: "You can access your account but can't send messages or take actions.", + text: strings.FrozenAccount_ReadOnly_Text, textColor: secondaryTextColor, iconName: "Ads/Privacy", iconColor: linkColor @@ -156,19 +155,17 @@ private final class SheetContent: CombinedComponent { let dateString = stringForFullDate(timestamp: component.configuration.freezeUntilDate ?? 0, strings: strings, dateTimeFormat: environment.dateTimeFormat) items.append( AnyComponentWithIdentity( - id: "withdrawal", + id: "appeal", component: AnyComponent(ParagraphComponent( - title: "Appeal Before Deactivation", + title: strings.FrozenAccount_Appeal_Title, titleColor: textColor, - text: "Appeal via [@SpamBot]() before \(dateString), or your account will be deleted.", + text: strings.FrozenAccount_Appeal_Text(dateString).string, textColor: secondaryTextColor, iconName: "Account Freeze/Appeal", iconColor: linkColor, action: { + component.submitAppeal() component.dismiss() - Queue.mainQueue().after(0.5) { - component.submitAppeal() - } } )) ) @@ -185,7 +182,7 @@ private final class SheetContent: CombinedComponent { contentSize.height += list.size.height contentSize.height += spacing + 2.0 - let buttonAttributedString = NSMutableAttributedString(string: "Submit an Appeal", font: Font.semibold(17.0), textColor: environment.theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center) + let buttonAttributedString = NSMutableAttributedString(string: strings.FrozenAccount_SubmitAppeal, font: Font.semibold(17.0), textColor: environment.theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center) let actionButton = actionButton.update( component: ButtonComponent( background: ButtonComponent.Background( @@ -201,10 +198,8 @@ private final class SheetContent: CombinedComponent { isEnabled: true, displaysProgress: false, action: { + component.submitAppeal() component.dismiss() - Queue.mainQueue().after(0.5) { - component.submitAppeal() - } } ), availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0), @@ -217,7 +212,7 @@ private final class SheetContent: CombinedComponent { contentSize.height += actionButton.size.height contentSize.height += 8.0 - let closeAttributedString = NSMutableAttributedString(string: "Understood", font: Font.regular(17.0), textColor: environment.theme.list.itemCheckColors.fillColor, paragraphAlignment: .center) + let closeAttributedString = NSMutableAttributedString(string: strings.FrozenAccount_Understood, font: Font.regular(17.0), textColor: environment.theme.list.itemCheckColors.fillColor, paragraphAlignment: .center) let closeButton = closeButton.update( component: ButtonComponent( background: ButtonComponent.Background( @@ -390,10 +385,12 @@ public final class AccountFreezeInfoScreen: ViewControllerComponentContainer { self.navigationPresentation = .flatModal submitAppealImpl = { [weak self] in - guard let self, let url = configuration.freezeAppealUrl else { + guard let self, let navigationController = self.navigationController as? NavigationController, let url = configuration.freezeAppealUrl else { return } - context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: url, forceExternal: false, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: self.navigationController as? NavigationController, dismissInput: {}) + Queue.mainQueue().after(0.4) { + context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: url, forceExternal: false, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: navigationController, dismissInput: {}) + } } } diff --git a/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSetupScreen.swift b/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSetupScreen.swift index 5b644960ad..52368d0e33 100644 --- a/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSetupScreen.swift +++ b/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSetupScreen.swift @@ -1061,11 +1061,16 @@ final class ChatbotSetupScreenComponent: Component { ) if let subpermissions = permission.subpermissions { - value = false + value = true var selectedCount = 0 for subpermission in subpermissions { - if subpermission.value == true { - value = true + if let key = subpermission.key { + if self.botRights.contains(key) { + selectedCount += 1 + } else { + value = false + } + } else if subpermission.value == true { selectedCount += 1 } } @@ -1138,8 +1143,10 @@ final class ChatbotSetupScreenComponent: Component { if let subpermissions = permission.subpermissions, permission.expanded == true { for subpermission in subpermissions { var value = false - if let key = permission.key { + if let key = subpermission.key { value = self.botRights.contains(key) + } else if subpermission.value == true { + value = true } permissionsItems.append( diff --git a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift index 2f3fe48f6a..2c1c834767 100644 --- a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift @@ -89,10 +89,9 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode { if let context = self.context { accountFreezeConfiguration = AccountFreezeConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) } - //TODO:localize if let _ = accountFreezeConfiguration?.freezeUntilDate { - self.textNode.attributedText = NSAttributedString(string: "You account is frozen", font: Font.semibold(15.0), textColor: interfaceState.theme.list.itemDestructiveColor) - self.subtitleNode.attributedText = NSAttributedString(string: "Tap to view details", font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor) + self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelFrozenAccount_Title, font: Font.semibold(15.0), textColor: interfaceState.theme.list.itemDestructiveColor) + self.subtitleNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelFrozenAccount_Text, font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor) isUserInteractionEnabled = true } else if case let .replyThread(message) = interfaceState.chatLocation, message.peerId == self.context?.account.peerId { self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelStatusAuthorHidden, font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)