UI improvements

This commit is contained in:
Ali 2023-01-27 17:16:26 +01:00
parent df5fba7d51
commit b65d4c2243
24 changed files with 265 additions and 193 deletions

View File

@ -8746,3 +8746,101 @@ Sorry for the inconvenience.";
"Premium.Translation.Proceed" = "About Telegram Premium";
"Settings.PauseMusicOnRecording" = "Pause Music While Recoding";
"Settings.SuggestSetupPasswordTitle" = "Protect Your Account";
"Settings.SuggestSetupPasswordText" = "Set a password that will be required each time you log in with this phone number.";
"Settings.SuggestSetupPasswordAction" = "Set Additional Password";
"Chat.SendNotAllowedText" = "Sending messages is not allowed in this group";
"Chat.SendNotAllowedPeerText" = "Sending messages is not allowed in %@";
"Chat.SendNotAllowedPhoto" = "Sending photos is not allowed in this group";
"Chat.SendNotAllowedVideo" = "Sending videos is not allowed in this group";
"Chat.SendNotAllowedFile" = "Sending files is not allowed in this group";
"Chat.SendNotAllowedAudioMessage" = "Sending audio messages is not allowed in this group";
"Chat.SendNotAllowedVideoMessage" = "Sending video messages is not allowed in this group";
"Chat.SendNotAllowedMusic" = "Sending music is not allowed in this group";
"Chat.SendAllowedContentText" = "The admins of this group only allow to send %1$@.";
"Chat.SendAllowedContentPeerText" = "The admins of %1$@ only allow to send %2$@.";
"Chat.SendAllowedContentTypeText" = "text messages";
"Chat.SendAllowedContentTypePhoto" = "photos";
"Chat.SendAllowedContentTypeVideo" = "videos";
"Chat.SendAllowedContentTypeVoiceMessage" = "voice messages";
"Chat.SendAllowedContentTypeVideoMessage" = "video messages";
"Chat.SendAllowedContentTypeFile" = "files";
"Chat.SendAllowedContentTypeMusic" = "music";
"Chat.SendAllowedContentTypeSticker" = "stickers & GIFs";
"Channel.BanUser.PermissionSendPhoto" = "Send Photos";
"Channel.BanUser.PermissionSendVideo" = "Send Videos";
"Channel.BanUser.PermissionSendMusic" = "Send Music";
"Channel.BanUser.PermissionSendVoiceMessage" = "Send Audio Messages";
"Channel.BanUser.PermissionSendVideoMessage" = "Send Video Messages";
"Channel.BanUser.PermissionSendFile" = "Send Files";
"GroupPermission.NoSendPhoto" = "no photos";
"GroupPermission.NoSendVideo" = "no videos";
"GroupPermission.NoSendMusic" = "no music";
"GroupPermission.NoSendVoiceMessage" = "no audio messages";
"GroupPermission.NoSendVideoMessage" = "no video messages";
"GroupPermission.NoSendFile" = "no files";
"Settings.AutosaveMediaOn" = "On";
"Settings.AutosaveMediaOff" = "Off";
"Settings.AutosaveMediaOn" = "On";
"Settings.AutosaveMediaAllMedia" = "All Media (%@)";
"Settings.AutosaveMediaPhoto" = "Photos";
"Settings.AutosaveMediaNoPhoto" = "No Photos";
"Settings.AutosaveMediaVideo" = "Videos up to %@";
"Settings.AutosaveMediaNoVideo" = "No Videos";
"Settings.SaveToCameraRollSection" = "SAVE TO CAMERA ROLL";
"Settings.SaveToCameraRollInfo" = "Automatically save all new photos and videos from these chats to your Cameral Roll.";
"Autosave.TypesSection" = "SAVE TO CAMERA ROLL";
"Autosave.TypePhoto" = "Photos";
"Autosave.TypeVideo" = "Videos";
"Autosave.TypesInfo" = "Automatically save all new media from private chats to your Cameral Roll.";
"Autosave.VideoSizeSection" = "MAXIMUM VIDEO SIZE";
"Autosave.VideoInfo" = "All downloaded videos in private chats less than %@ will be saved to Cameral Roll.";
"Autosave.ExceptionsSection" = "EXCEPTIONS";
"Autosave.AddException" = "Add Exception";
"Autosave.Exception" = "Exception";
"Autosave.DeleteAllExceptions" = "Delete All Exceptions";
"Chat.ErrorInvoiceNotFound" = "Invoice not found.";
"EmojiStatus.AppliedText" = "Your emoji status has been updated.";
"EmojiPreview.SendEmoji" = "Send Emoji";
"EmojiPreview.SetAsStatus" = "Set as Status";
"EmojiPreview.CopyEmoji" = "Copy Emoji";
"EmojiSearch.SearchStickersEmptyResult" = "No emoji found";
"DataUsage.MediaDirectionIncoming" = "Incoming";
"DataUsage.MediaDirectionOutgoing" = "Outgoing";
"DataUsage.InfoTotalUsageSinceTime" = "Your data usage since %@";
"DataUsage.InfoMobileUsageSinceTime" = "Your mobile data usage since %@";
"DataUsage.InfoWifiUsageSinceTime" = "Your Wi-Fi data usage since %@";
"DataUsage.SectionsInfo" = "Tap on each section for detailed view.";
"DataUsage.SectionUsageTotal" = "TOTAL NETWORK USAGE";
"DataUsage.SectionUsageMobile" = "MOBILE NETWORK USAGE";
"DataUsage.SectionUsageWifi" = "WI-FI NETWORK USAGE";
"DataUsage.AutoDownloadSettings" = "Auto-Download Settings";
"StorageManagement.SectionMessages" = "Messages";
"StorageManagement.SectionVoiceMessages" = "Voice Messages";
"StorageManagement.SectionCalls" = "Calls";
"DataUsage.SectionTotalIncoming" = "Data Received";
"DataUsage.SectionTotalOutgoing" = "Data Sent";
"EmojiInput.TabMasks" = "Masks";
"EmojiInput.TabGifs" = "GIFs";
"EmojiInput.TabStickers" = "Stickers";
"EmojiInput.TabEmoji" = "Emoji";
"EmojiInput.TrendingEmoji" = "TRENDING EMOJI";
"Chat.PlaceholderTextNotAllowed" = "Text not allowed";

View File

@ -138,9 +138,8 @@ class ChatListStorageInfoItemNode: ListViewItemNode {
textString = NSAttributedString(string: item.strings.ChatList_StorageHintText, font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
case .setupPassword:
//TODO:localize
titleString = NSAttributedString(string: "Protect Your Account", font: titleFont, textColor: item.theme.rootController.navigationBar.primaryTextColor)
textString = NSAttributedString(string: "Set a password that will be required each time you log in with this phone number.", font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
titleString = NSAttributedString(string: item.strings.Settings_SuggestSetupPasswordTitle, font: titleFont, textColor: item.theme.rootController.navigationBar.primaryTextColor)
textString = NSAttributedString(string: item.strings.Settings_SuggestSetupPasswordText, font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
case let .premiumUpgrade(discount):
let discountString = "\(discount)%"
let rawTitleString = item.strings.ChatList_PremiumAnnualUpgradeTitle(discountString)

View File

@ -1178,30 +1178,26 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
}
if let _ = item as? TGMediaPickerGalleryPhotoItem {
if self.bannedSendPhotos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending photos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}
} else if let _ = item as? TGMediaPickerGalleryVideoItem {
if self.bannedSendVideos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending videos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}
} else if let asset = item as? TGMediaAsset {
if asset.isVideo {
if self.bannedSendVideos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending videos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}
} else {
if self.bannedSendPhotos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending photos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}
@ -1280,30 +1276,26 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
if let self = self, let selectionState = self.interaction?.selectionState {
if let _ = item as? TGMediaPickerGalleryPhotoItem {
if self.bannedSendPhotos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending photos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}
} else if let _ = item as? TGMediaPickerGalleryVideoItem {
if self.bannedSendVideos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending videos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}
} else if let asset = item as? TGMediaAsset {
if asset.isVideo {
if self.bannedSendVideos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending videos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedVideo, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}
} else {
if self.bannedSendPhotos != nil {
//TODO:localize
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "Sending photos is not allowed", actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Chat_SendNotAllowedPhoto, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
return false
}

View File

@ -379,7 +379,6 @@ private struct ChannelPermissionsControllerState: Equatable {
}
func stringForGroupPermission(strings: PresentationStrings, right: TelegramChatBannedRightsFlags, isForum: Bool) -> String {
//TODO:localize
if right.contains(.banSendText) {
return strings.Channel_BanUser_PermissionSendMessages
} else if right.contains(.banSendMedia) {
@ -399,19 +398,19 @@ func stringForGroupPermission(strings: PresentationStrings, right: TelegramChatB
} else if right.contains(.banManageTopics) {
return strings.Channel_EditAdmin_PermissionCreateTopics
} else if right.contains(.banSendPhotos) {
return "Send Photos"
return strings.Channel_BanUser_PermissionSendPhoto
} else if right.contains(.banSendVideos) {
return "Send Videos"
return strings.Channel_BanUser_PermissionSendVideo
} else if right.contains(.banSendStickers) {
return strings.Channel_BanUser_PermissionSendStickersAndGifs
} else if right.contains(.banSendMusic) {
return "Send Music"
return strings.Channel_BanUser_PermissionSendMusic
} else if right.contains(.banSendFiles) {
return "Send Files"
return strings.Channel_BanUser_PermissionSendFile
} else if right.contains(.banSendVoice) {
return "Send Voice Messages"
return strings.Channel_BanUser_PermissionSendVoiceMessage
} else if right.contains(.banSendInstantVideos) {
return "Send Video Messages"
return strings.Channel_BanUser_PermissionSendVideoMessage
} else {
return ""
}
@ -423,17 +422,17 @@ func compactStringForGroupPermission(strings: PresentationStrings, right: Telegr
} else if right.contains(.banSendMedia) {
return strings.GroupPermission_NoSendMedia
} else if right.contains(.banSendPhotos) {
return "no photos"
return strings.GroupPermission_NoSendPhoto
} else if right.contains(.banSendVideos) {
return "no videos"
return strings.GroupPermission_NoSendVideo
} else if right.contains(.banSendMusic) {
return "no music"
return strings.GroupPermission_NoSendMusic
} else if right.contains(.banSendFiles) {
return "no files"
return strings.GroupPermission_NoSendFile
} else if right.contains(.banSendVoice) {
return "no voice messages"
return strings.GroupPermission_NoSendVoiceMessage
} else if right.contains(.banSendInstantVideos) {
return "no video messages"
return strings.GroupPermission_NoSendVideoMessage
} else if right.contains(.banSendGifs) {
return strings.GroupPermission_NoSendGifs
} else if right.contains(.banEmbedLinks) {

View File

@ -253,7 +253,11 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
private let emojiSearchDisposable = MetaDisposable()
private let emojiSearchState = Promise<EmojiSearchState>(EmojiSearchState(result: nil, isSearching: false))
private var emojiSearchStateValue: EmojiSearchState = EmojiSearchState(result: nil, isSearching: false)
private var emojiSearchStateValue = EmojiSearchState(result: nil, isSearching: false) {
didSet {
self.emojiSearchState.set(.single(self.emojiSearchStateValue))
}
}
private var emptyResultEmojis: [TelegramMediaFile] = []
private var stableEmptyResultEmoji: TelegramMediaFile?

View File

@ -574,28 +574,27 @@ private func autosaveLabelAndValue(presentationData: PresentationData, settings:
}
}
//TODO:localize
let value: String
if configuration.photo || configuration.video {
value = "On"
value = presentationData.strings.Settings_AutosaveMediaOn
} else {
value = "Off"
value = presentationData.strings.Settings_AutosaveMediaOff
}
var label = ""
if configuration.photo && configuration.video {
label.append("All Media (\(dataSizeString(Int(configuration.maximumVideoSize), formatting: DataSizeStringFormatting(presentationData: presentationData))))")
label.append(presentationData.strings.Settings_AutosaveMediaAllMedia(dataSizeString(Int(configuration.maximumVideoSize), formatting: DataSizeStringFormatting(presentationData: presentationData))).string)
} else {
if configuration.photo {
if !label.isEmpty {
label.append(", ")
}
label.append("Photos")
label.append(presentationData.strings.Settings_AutosaveMediaPhoto)
} else if configuration.video {
if !label.isEmpty {
label.append(", ")
}
label.append("Videos up to \(dataSizeString(Int(configuration.maximumVideoSize), formatting: DataSizeStringFormatting(presentationData: presentationData)))")
label.append(presentationData.strings.Settings_AutosaveMediaVideo(dataSizeString(Int(configuration.maximumVideoSize), formatting: DataSizeStringFormatting(presentationData: presentationData))).string)
}
}
@ -622,17 +621,16 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat
let defaultSettings = MediaAutoDownloadSettings.defaultSettings
entries.append(.automaticDownloadReset(presentationData.theme, presentationData.strings.ChatSettings_AutoDownloadReset, data.automaticMediaDownloadSettings.cellular != defaultSettings.cellular || data.automaticMediaDownloadSettings.wifi != defaultSettings.wifi))
//TODO:localize
entries.append(.autoSaveHeader("SAVE TO CAMERA ROLL"))
entries.append(.autoSaveHeader(presentationData.strings.Settings_SaveToCameraRollSection))
let privateLabelAndValue = autosaveLabelAndValue(presentationData: presentationData, settings: mediaAutoSaveSettings, peerType: .privateChats, exceptionPeers: autosaveExceptionPeers)
let groupsLabelAndValue = autosaveLabelAndValue(presentationData: presentationData, settings: mediaAutoSaveSettings, peerType: .groups, exceptionPeers: autosaveExceptionPeers)
let channelsLabelAndValue = autosaveLabelAndValue(presentationData: presentationData, settings: mediaAutoSaveSettings, peerType: .channels, exceptionPeers: autosaveExceptionPeers)
entries.append(.autoSaveItem(index: 0, type: .privateChats, title: "Private Chats", label: privateLabelAndValue.label, value: privateLabelAndValue.value))
entries.append(.autoSaveItem(index: 1, type: .groups, title: "Groups", label: groupsLabelAndValue.label, value: groupsLabelAndValue.value))
entries.append(.autoSaveItem(index: 2, type: .channels, title: "Channels", label: channelsLabelAndValue.label, value: channelsLabelAndValue.value))
entries.append(.autoSaveInfo("Automatically save all new photos and videos from these chats to your Cameral Roll."))
entries.append(.autoSaveItem(index: 0, type: .privateChats, title: presentationData.strings.Notifications_PrivateChats, label: privateLabelAndValue.label, value: privateLabelAndValue.value))
entries.append(.autoSaveItem(index: 1, type: .groups, title: presentationData.strings.Notifications_GroupChats, label: groupsLabelAndValue.label, value: groupsLabelAndValue.value))
entries.append(.autoSaveItem(index: 2, type: .channels, title: presentationData.strings.Notifications_Channels, label: channelsLabelAndValue.label, value: channelsLabelAndValue.value))
entries.append(.autoSaveInfo(presentationData.strings.Settings_SaveToCameraRollInfo))
let dataSaving = effectiveDataSaving(for: data.voiceCallSettings, autodownloadSettings: data.autodownloadSettings)

View File

@ -258,12 +258,11 @@ private func saveIncomingMediaControllerEntries(presentationData: PresentationDa
entries.append(.peer(peer: peer, presence: peerPresence))
}
entries.append(.typesHeader("SAVE TO CAMERA ROLL"))
entries.append(.typesHeader(presentationData.strings.Autosave_TypesSection))
//TODO:localize
entries.append(.typePhotos("Photos", configuration.photo))
entries.append(.typeVideos("Videos", configuration.video))
entries.append(.typesInfo("Automatically save all new media from private chats to your Cameral Roll."))
entries.append(.typePhotos(presentationData.strings.Autosave_TypePhoto, configuration.photo))
entries.append(.typeVideos(presentationData.strings.Autosave_TypeVideo, configuration.video))
entries.append(.typesInfo(presentationData.strings.Autosave_TypesInfo))
if configuration.video {
let sizeText: String
@ -275,9 +274,9 @@ private func saveIncomingMediaControllerEntries(presentationData: PresentationDa
let text = presentationData.strings.AutoDownloadSettings_UpTo(sizeText).string
entries.append(.videoSizeHeader("MAXIMUM VIDEO SIZE"))
entries.append(.videoSizeHeader(presentationData.strings.Autosave_VideoSizeSection))
entries.append(.videoSize(decimalSeparator: presentationData.dateTimeFormat.decimalSeparator, text: text, value: configuration.maximumVideoSize))
entries.append(.videoInfo("All downloaded videos in private chats less than \(sizeText) will be saved to Cameral Roll."))
entries.append(.videoInfo(presentationData.strings.Autosave_VideoInfo(sizeText).string))
}
if case let .peerType(peerType) = scope {
@ -306,13 +305,12 @@ private func saveIncomingMediaControllerEntries(presentationData: PresentationDa
}
if filteredExceptions.isEmpty {
//TODO:localize
entries.append(.exceptionsHeader("EXCEPTIONS"))
entries.append(.exceptionsHeader(presentationData.strings.Autosave_ExceptionsSection))
} else {
entries.append(.exceptionsHeader(presentationData.strings.Notifications_CategoryExceptions(Int32(filteredExceptions.count)).uppercased()))
}
entries.append(.addException("Add Exception"))
entries.append(.addException(presentationData.strings.Autosave_AddException))
var index = 0
for (exceptionPeer, exceptionConfiguration) in filteredExceptions {
@ -321,23 +319,23 @@ private func saveIncomingMediaControllerEntries(presentationData: PresentationDa
if !label.isEmpty {
label.append(", ")
}
label.append("Photos")
label.append(presentationData.strings.Settings_AutosaveMediaPhoto)
} else {
if !label.isEmpty {
label.append(", ")
}
label.append("No Photos")
label.append(presentationData.strings.Settings_AutosaveMediaNoPhoto)
}
if exceptionConfiguration.video {
if !label.isEmpty {
label.append(", ")
}
label.append("Videos up to \(dataSizeString(Int(exceptionConfiguration.maximumVideoSize), formatting: DataSizeStringFormatting(presentationData: presentationData)))")
label.append(presentationData.strings.Settings_AutosaveMediaVideo(dataSizeString(Int(exceptionConfiguration.maximumVideoSize), formatting: DataSizeStringFormatting(presentationData: presentationData))).string)
} else {
if !label.isEmpty {
label.append(", ")
}
label.append("No Videos")
label.append(presentationData.strings.Settings_AutosaveMediaNoVideo)
}
entries.append(.exceptionItem(index: index, peer: exceptionPeer, label: label))
@ -345,7 +343,7 @@ private func saveIncomingMediaControllerEntries(presentationData: PresentationDa
}
if !filteredExceptions.isEmpty {
entries.append(.deleteAllExceptions("Delete All Exceptions"))
entries.append(.deleteAllExceptions(presentationData.strings.Autosave_DeleteAllExceptions))
}
}
@ -588,8 +586,7 @@ func saveIncomingMediaController(context: AccountContext, scope: SaveIncomingMed
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationData: presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
//ActionSheetTextItem(title: presentationData.strings.AutoDownloadSettings_ResetHelp),
ActionSheetButtonItem(title: "Delete All Exceptions", color: .destructive, action: { [weak actionSheet] in
ActionSheetButtonItem(title: presentationData.strings.Autosave_DeleteAllExceptions, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let _ = updateMediaAutoSaveSettingsInteractively(account: context.account, { settings in
@ -674,28 +671,27 @@ func saveIncomingMediaController(context: AccountContext, scope: SaveIncomingMed
let title: String
switch scope {
case let .peer(id):
//TODO:localize
if let data = mediaAutoSaveSettings.exceptions.first(where: { $0.id == id }) {
configuration = data.configuration
} else {
configuration = .default
}
title = "Exception"
title = presentationData.strings.Autosave_Exception
case .addPeer:
configuration = state.pendingConfiguration
title = "Add Exception"
title = presentationData.strings.Autosave_AddException
case let .peerType(peerType):
exceptions = mediaAutoSaveSettings.exceptions
switch peerType {
case .privateChats:
configuration = mediaAutoSaveSettings.configurations[.users] ?? .default
title = "Private Chats"
title = presentationData.strings.Notifications_PrivateChats
case .groups:
configuration = mediaAutoSaveSettings.configurations[.groups] ?? .default
title = "Groups"
title = presentationData.strings.Notifications_GroupChats
case .channels:
configuration = mediaAutoSaveSettings.configurations[.channels] ?? .default
title = "Channels"
title = presentationData.strings.Notifications_Channels
}
}

View File

@ -1743,7 +1743,6 @@ public func presentExternalShare(context: AccountContext, text: String, parentCo
}
private func restrictedSendingContentsText(peer: EnginePeer, presentationData: PresentationData) -> String {
//TODO:localize
var itemList: [String] = []
let order: [TelegramChatBannedRightsFlags] = [
@ -1771,21 +1770,21 @@ private func restrictedSendingContentsText(peer: EnginePeer, presentationData: P
var title: String?
switch right {
case .banSendText:
title = "text messages"
title = presentationData.strings.Chat_SendAllowedContentTypeText
case .banSendPhotos:
title = "photos"
title = presentationData.strings.Chat_SendAllowedContentTypePhoto
case .banSendVideos:
title = "videos"
title = presentationData.strings.Chat_SendAllowedContentTypeVideo
case .banSendVoice:
title = "voice messages"
title = presentationData.strings.Chat_SendAllowedContentTypeVoiceMessage
case .banSendInstantVideos:
title = "video messages"
title = presentationData.strings.Chat_SendAllowedContentTypeVideoMessage
case .banSendFiles:
title = "files"
title = presentationData.strings.Chat_SendAllowedContentTypeFile
case .banSendMusic:
title = "music"
title = presentationData.strings.Chat_SendAllowedContentTypeMusic
case .banSendStickers:
title = "Stickers & GIFs"
title = presentationData.strings.Chat_SendAllowedContentTypeSticker
default:
break
}
@ -1795,19 +1794,27 @@ private func restrictedSendingContentsText(peer: EnginePeer, presentationData: P
}
if itemList.isEmpty {
return "Sending messages is disabled in \(peer.compactDisplayTitle)"
return presentationData.strings.Chat_SendNotAllowedPeerText(peer.compactDisplayTitle).string
}
var itemListString = ""
for i in 0 ..< itemList.count {
if i != 0 {
itemListString.append(", ")
if #available(iOS 13.0, *) {
let listFormatter = ListFormatter()
listFormatter.locale = localeWithStrings(presentationData.strings)
if let value = listFormatter.string(from: itemList) {
itemListString = value
}
if i == itemList.count - 1 && i != 0 {
itemListString.append("and ")
}
itemListString.append(itemList[i])
}
return "The admins of \(peer.compactDisplayTitle) group only allow to send \(itemListString)."
if itemListString.isEmpty {
for i in 0 ..< itemList.count {
if i != 0 {
itemListString.append(", ")
}
itemListString.append(itemList[i])
}
}
return presentationData.strings.Chat_SendAllowedContentPeerText(peer.compactDisplayTitle, itemListString).string
}

View File

@ -619,8 +619,7 @@ private final class StickerPackContainer: ASDisplayNode {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
let undoController = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Your emoji status has been updated.", undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
let undoController = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: presentationData.strings.EmojiStatus_AppliedText, undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
controller.present(undoController, in: .window(.root))
}
let copyEmoji: (TelegramMediaFile) -> Void = { file in
@ -643,9 +642,8 @@ private final class StickerPackContainer: ASDisplayNode {
}
}
//TODO:localize
if strongSelf.sendEmoji != nil {
menuItems.append(.action(ContextMenuActionItem(text: "Send Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SendEmoji, icon: { theme in
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) {
return generateImage(image.size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
@ -663,8 +661,7 @@ private final class StickerPackContainer: ASDisplayNode {
})))
}
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Set as Status", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SetAsStatus, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Smile"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.default)
@ -688,8 +685,7 @@ private final class StickerPackContainer: ASDisplayNode {
}
})))
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Copy Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_CopyEmoji, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
copyEmoji(file)

View File

@ -230,7 +230,11 @@ final class AvatarEditorScreenComponent: Component {
private let emojiSearchDisposable = MetaDisposable()
private let emojiSearchState = Promise<EmojiSearchState>(EmojiSearchState(result: nil, isSearching: false))
private var emojiSearchStateValue: EmojiSearchState = EmojiSearchState(result: nil, isSearching: false)
private var emojiSearchStateValue = EmojiSearchState(result: nil, isSearching: false) {
didSet {
self.emojiSearchState.set(.single(self.emojiSearchStateValue))
}
}
private var scheduledEmojiContentAnimationHint: EmojiPagerContentComponent.ContentAnimation?

View File

@ -637,8 +637,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Your emoji status has been updated.", undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: presentationData.strings.EmojiStatus_AppliedText, undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
strongSelf.currentUndoOverlayController = controller
controllerInteraction.presentController(controller, nil)
},
@ -673,8 +672,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Emoji copied to clipboard.", undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: presentationData.strings.EmojiPreview_CopyEmoji, undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
strongSelf.currentUndoOverlayController = controller
controllerInteraction.presentController(controller, nil)
}
@ -1488,9 +1486,8 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
if let stickerSearchResult = stickerSearchState.result {
var stickerSearchResults: EmojiPagerContentComponent.EmptySearchResults?
if !stickerSearchResult.groups.contains(where: { !$0.items.isEmpty }) {
//TODO:localize
stickerSearchResults = EmojiPagerContentComponent.EmptySearchResults(
text: "No stickers found",
text: presentationData.strings.EmojiSearch_SearchStickersEmptyResult,
iconFile: nil
)
}
@ -2506,8 +2503,7 @@ public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
}
if let _ = strongSelf.chatPeerId {
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Send Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SendEmoji, icon: { theme in
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) {
return generateImage(image.size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
@ -2524,8 +2520,7 @@ public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
f(.default)
})))
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Set as Status", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SetAsStatus, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Smile"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.default)
@ -2549,8 +2544,7 @@ public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
}
})))
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Copy Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_CopyEmoji, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
copyEmoji(file)

View File

@ -672,7 +672,6 @@ final class EmojiStatusPreviewScreenComponent: Component {
}
))))
}
//TODO:localize
menuItems.append(AnyComponentWithIdentity(id: "Other", component: AnyComponent(ContextMenuActionItem(
title: component.strings.EmojiStatusSetup_TimerOther,
action: { [weak self] in

View File

@ -276,7 +276,11 @@ public final class EmojiStatusSelectionController: ViewController {
private let emojiSearchDisposable = MetaDisposable()
private let emojiSearchState = Promise<EmojiSearchState>(EmojiSearchState(result: nil, isSearching: false))
private var emojiSearchStateValue: EmojiSearchState = EmojiSearchState(result: nil, isSearching: false)
private var emojiSearchStateValue = EmojiSearchState(result: nil, isSearching: false) {
didSet {
self.emojiSearchState.set(.single(self.emojiSearchStateValue))
}
}
private var emptyResultEmojis: [TelegramMediaFile] = []
private var stableEmptyResultEmoji: TelegramMediaFile?

View File

@ -6977,8 +6977,7 @@ public final class EmojiPagerContentComponent: Component {
} else {
itemGroupIndexById[groupId] = itemGroups.count
//TODO:localize
let title = "TRENDING EMOJI"
let title = context.sharedContext.currentPresentationData.with({ $0 }).strings.EmojiInput_TrendingEmoji
itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: title, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 0, isClearable: false, headerItem: nil, items: [resultItem]))
}
}
@ -7668,8 +7667,7 @@ public final class EmojiPagerContentComponent: Component {
} else if isEmojiSelection {
displaySearchWithPlaceholder = strings.EmojiSearch_SearchEmojiPlaceholder
} else if isProfilePhotoEmojiSelection || isGroupPhotoEmojiSelection {
//TODO:localize
displaySearchWithPlaceholder = "Search"
displaySearchWithPlaceholder = strings.Common_Search
}
}

View File

@ -59,7 +59,11 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
private let emojiSearchDisposable = MetaDisposable()
private let emojiSearchState = Promise<EmojiSearchState>(EmojiSearchState(result: nil, isSearching: false))
private var emojiSearchStateValue: EmojiSearchState = EmojiSearchState(result: nil, isSearching: false)
private var emojiSearchStateValue = EmojiSearchState(result: nil, isSearching: false) {
didSet {
self.emojiSearchState.set(.single(self.emojiSearchStateValue))
}
}
private var immediateEmojiSearchState: EmojiSearchState = EmojiSearchState(result: nil, isSearching: false)
private var dataDisposable: Disposable?
@ -106,13 +110,12 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
groupItems.append(resultItem)
}
//TODO:localize
self.itemGroups.append(EmojiPagerContentComponent.ItemGroup(
supergroupId: AnyHashable(groupItem.info.id),
groupId: AnyHashable(groupItem.info.id),
title: groupItem.info.title,
subtitle: nil,
actionButtonTitle: "Add \(groupItem.info.title)",
actionButtonTitle: self.presentationData.strings.EmojiInput_AddPack(groupItem.info.title).string,
isFeatured: true,
isPremiumLocked: !self.hasPremiumForInstallation,
isEmbedded: false,
@ -413,7 +416,6 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
let params = Params(size: size, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, inputHeight: inputHeight, deviceMetrics: deviceMetrics)
self.params = params
//TODO:localize
var emojiContent = EmojiPagerContentComponent(
id: "emoji",
context: self.context,
@ -427,7 +429,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode
itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: "main", version: 0),
searchState: .empty(hasResults: false),
warpContentsOnEdges: false,
displaySearchWithPlaceholder: "Search Emoji",
displaySearchWithPlaceholder: self.presentationData.strings.EmojiSearch_SearchEmojiPlaceholder,
searchCategories: nil,
searchInitiallyHidden: false,
searchAlwaysActive: true,

View File

@ -377,8 +377,7 @@ public final class EntityKeyboardComponent: Component {
strongSelf.reorderPacks(category: .masks, items: items)
}
))))
//TODO:localize
contentIcons.append(PagerComponentContentIcon(id: "masks", imageName: "Chat/Input/Media/EntityInputMasksIcon", title: "Masks"))
contentIcons.append(PagerComponentContentIcon(id: "masks", imageName: "Chat/Input/Media/EntityInputMasksIcon", title: component.strings.EmojiInput_TabMasks))
if let _ = component.maskContent?.inputInteractionHolder.inputInteraction?.openStickerSettings {
contentAccessoryRightButtons.append(AnyComponentWithIdentity(id: "masks", component: AnyComponent(Button(
content: AnyComponent(BundleIconComponent(
@ -464,8 +463,7 @@ public final class EntityKeyboardComponent: Component {
reorderItems: { _ in
}
))))*/
//TODO:localize
contentIcons.append(PagerComponentContentIcon(id: "gifs", imageName: "Chat/Input/Media/EntityInputGifsIcon", title: "GIFs"))
contentIcons.append(PagerComponentContentIcon(id: "gifs", imageName: "Chat/Input/Media/EntityInputGifsIcon", title: component.strings.EmojiInput_TabGifs))
}
if let stickerContent = component.stickerContent {
@ -571,8 +569,7 @@ public final class EntityKeyboardComponent: Component {
strongSelf.reorderPacks(category: .stickers, items: items)
}
))))
//TODO:localize
contentIcons.append(PagerComponentContentIcon(id: "stickers", imageName: "Chat/Input/Media/EntityInputStickersIcon", title: "Stickers"))
contentIcons.append(PagerComponentContentIcon(id: "stickers", imageName: "Chat/Input/Media/EntityInputStickersIcon", title: component.strings.EmojiInput_TabStickers))
if let _ = component.stickerContent?.inputInteractionHolder.inputInteraction?.openStickerSettings {
contentAccessoryRightButtons.append(AnyComponentWithIdentity(id: "stickers", component: AnyComponent(Button(
content: AnyComponent(BundleIconComponent(
@ -671,8 +668,7 @@ public final class EntityKeyboardComponent: Component {
strongSelf.reorderPacks(category: .emoji, items: items)
}
))))
//TODO:localize
contentIcons.append(PagerComponentContentIcon(id: "emoji", imageName: "Chat/Input/Media/EntityInputEmojiIcon", title: "Emoji"))
contentIcons.append(PagerComponentContentIcon(id: "emoji", imageName: "Chat/Input/Media/EntityInputEmojiIcon", title: component.strings.EmojiInput_TabEmoji))
if let _ = deleteBackwards {
contentAccessoryLeftButtons.append(AnyComponentWithIdentity(id: "emoji", component: AnyComponent(Button(
content: AnyComponent(BundleIconComponent(

View File

@ -169,10 +169,9 @@ private final class SubItemComponent: Component {
)
availableWidth = max(1.0, availableWidth - titleValueSize.width - 4.0)
//TODO:localize
let titleSize = self.title.update(
transition: transition,
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: component.isIncoming ? "Incoming" : "Outgoing", font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor)))),
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: component.isIncoming ? component.strings.DataUsage_MediaDirectionIncoming : component.strings.DataUsage_MediaDirectionOutgoing, font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor)))),
environment: {},
containerSize: CGSize(width: availableWidth, height: 100.0)
)

View File

@ -266,18 +266,17 @@ final class DataUsageScreenComponent: Component {
case .music:
return strings.StorageManagement_SectionMusic
case .messages:
//TODO:localize
return "Messages"
return strings.StorageManagement_SectionMessages
case .stickers:
return strings.StorageManagement_SectionStickers
case .voiceMessages:
return "Voice Messages"
return strings.StorageManagement_SectionVoiceMessages
case .calls:
return "Calls"
return strings.StorageManagement_SectionCalls
case .totalIn:
return "Data Received"
return strings.DataUsage_SectionTotalIncoming
case .totalOut:
return "Data Sent"
return strings.DataUsage_SectionTotalOutgoing
}
}
}
@ -809,17 +808,16 @@ final class DataUsageScreenComponent: Component {
let body = MarkdownAttributeSet(font: Font.regular(13.0), textColor: environment.theme.list.freeTextColor)
let bold = MarkdownAttributeSet(font: Font.semibold(13.0), textColor: environment.theme.list.freeTextColor)
//TODO:localize
let timestampString: String
if let allStats = self.allStats, allStats.resetTimestamp != 0 {
let dateStringPlain = stringForFullDate(timestamp: allStats.resetTimestamp, strings: environment.strings, dateTimeFormat: PresentationDateTimeFormat())
switch self.selectedStats {
case .all:
timestampString = "Your data usage since \(dateStringPlain)"
timestampString = environment.strings.DataUsage_InfoTotalUsageSinceTime(dateStringPlain).string
case .mobile:
timestampString = "Your mobile data usage since \(dateStringPlain)"
timestampString = environment.strings.DataUsage_InfoMobileUsageSinceTime(dateStringPlain).string
case .wifi:
timestampString = "Your Wi-Fi data usage since \(dateStringPlain)"
timestampString = environment.strings.DataUsage_InfoWifiUsageSinceTime(dateStringPlain).string
}
} else {
timestampString = ""
@ -972,10 +970,9 @@ final class DataUsageScreenComponent: Component {
contentHeight += categoriesSize.height
contentHeight += 8.0
//TODO:localize
let categoriesDescriptionSize = self.categoriesDescriptionView.update(
transition: transition,
component: AnyComponent(MultilineTextComponent(text: .markdown(text: "Tap on each section for detailed view.", attributes: MarkdownAttributes(
component: AnyComponent(MultilineTextComponent(text: .markdown(text: environment.strings.DataUsage_SectionsInfo, attributes: MarkdownAttributes(
body: body,
bold: bold,
link: body,
@ -996,15 +993,14 @@ final class DataUsageScreenComponent: Component {
contentHeight += categoriesDescriptionSize.height
contentHeight += 40.0
//TODO:localize
let totalTitle: String
switch self.selectedStats {
case .all:
totalTitle = "TOTAL NETWORK USAGE"
totalTitle = environment.strings.DataUsage_SectionUsageTotal
case .mobile:
totalTitle = "MOBILE NETWORK USAGE"
totalTitle = environment.strings.DataUsage_SectionUsageMobile
case .wifi:
totalTitle = "WI-FI NETWORK USAGE"
totalTitle = environment.strings.DataUsage_SectionUsageWifi
}
let totalCategoriesTitleSize = self.totalCategoriesTitleView.update(
transition: transition,
@ -1053,7 +1049,6 @@ final class DataUsageScreenComponent: Component {
contentHeight += 40.0
var autoDownloadSettingsContentHeight: CGFloat = 0.0
//TODO:localize
let autoDownloadSettingsSize: CGSize
if case .all = self.selectedStats, let autoDownloadSettingsComponentView = self.autoDownloadSettingsView.view {
autoDownloadSettingsSize = autoDownloadSettingsComponentView.bounds.size
@ -1063,7 +1058,7 @@ final class DataUsageScreenComponent: Component {
component: AnyComponent(StoragePeerTypeItemComponent(
theme: environment.theme,
iconName: self.selectedStats == .mobile ? "Settings/Menu/Cellular" : "Settings/Menu/WiFi",
title: "Auto-Download Settings",
title: environment.strings.DataUsage_AutoDownloadSettings,
subtitle: stringForAutoDownloadSetting(strings: environment.strings, decimalSeparator: environment.dateTimeFormat.decimalSeparator, settings: self.mediaAutoDownloadSettings, isCellular: self.selectedStats == .mobile),
value: "",
hasNext: false,
@ -1215,9 +1210,8 @@ final class DataUsageScreenComponent: Component {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationData: presentationData)
//TODO:localize
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: "Reset Statistics", color: .destructive, action: { [weak self, weak actionSheet] in
ActionSheetButtonItem(title: presentationData.strings.NetworkUsageSettings_ResetStats, color: .destructive, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated()
self?.commitClear()

View File

@ -18219,9 +18219,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
func restrictedSendingContentsText() -> String {
//TODO:localize
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
return "Sending messages is disabled in this chat"
return self.presentationData.strings.Chat_SendNotAllowedText
}
var itemList: [String] = []
@ -18251,21 +18250,21 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var title: String?
switch right {
case .banSendText:
title = "text messages"
title = self.presentationData.strings.Chat_SendAllowedContentTypeText
case .banSendPhotos:
title = "photos"
title = self.presentationData.strings.Chat_SendAllowedContentTypePhoto
case .banSendVideos:
title = "videos"
title = self.presentationData.strings.Chat_SendAllowedContentTypeVideo
case .banSendVoice:
title = "voice messages"
title = self.presentationData.strings.Chat_SendAllowedContentTypeVoiceMessage
case .banSendInstantVideos:
title = "video messages"
title = self.presentationData.strings.Chat_SendAllowedContentTypeVideoMessage
case .banSendFiles:
title = "files"
title = self.presentationData.strings.Chat_SendAllowedContentTypeFile
case .banSendMusic:
title = "music"
title = self.presentationData.strings.Chat_SendAllowedContentTypeMusic
case .banSendStickers:
title = "Stickers & GIFs"
title = self.presentationData.strings.Chat_SendAllowedContentTypeSticker
default:
break
}
@ -18275,21 +18274,28 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if itemList.isEmpty {
return "Sending messages is disabled in this chat"
return self.presentationData.strings.Chat_SendNotAllowedText
}
var itemListString = ""
for i in 0 ..< itemList.count {
if i != 0 {
itemListString.append(", ")
if #available(iOS 13.0, *) {
let listFormatter = ListFormatter()
listFormatter.locale = localeWithStrings(presentationData.strings)
if let value = listFormatter.string(from: itemList) {
itemListString = value
}
if i == itemList.count - 1 && i != 0 {
itemListString.append("and ")
}
itemListString.append(itemList[i])
}
return "The admins of this group only allow to send \(itemListString)."
if itemListString.isEmpty {
for i in 0 ..< itemList.count {
if i != 0 {
itemListString.append(", ")
}
itemListString.append(itemList[i])
}
}
return self.presentationData.strings.Chat_SendAllowedContentText(itemListString).string
}
}

View File

@ -1017,8 +1017,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}), in: .current)*/
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
} else {
//TODO:localize
strongSelf.controllerInteraction.presentController(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, title: nil, text: "Invoice not found", actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil)
strongSelf.controllerInteraction.presentController(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Chat_ErrorInvoiceNotFound, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil)
}
case let .instantView(webpage, anchor):
strongSelf.pushController(InstantPageController(context: strongSelf.context, webPage: webpage, sourceLocation: InstantPageSourceLocation(userLocation: .peer(strongSelf.peer.id), peerType: .channel), anchor: anchor))

View File

@ -932,7 +932,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
guard let controller = strongSelf.interfaceInteraction?.chatController() as? ChatControllerImpl else {
return
}
//TODO:localize
controller.controllerInteraction?.displayUndo(.universal(animation: "premium_unlock", scale: 1.0, colors: ["__allcolors__": UIColor(white: 1.0, alpha: 1.0)], title: nil, text: controller.restrictedSendingContentsText(), customUndoText: nil))
} else {
strongSelf.ensureFocused()
@ -1384,8 +1383,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
}
} else {
if sendingTextDisabled {
//TODO:localize
placeholder = "Text not allowed"
placeholder = interfaceState.strings.Chat_PlaceholderTextNotAllowed
} else {
if let channel = peer as? TelegramChannel, case .group = channel.info, channel.hasPermission(.canBeAnonymous) {
placeholder = interfaceState.strings.Conversation_InputTextAnonymousPlaceholder
@ -2865,8 +2863,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
let undoController = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Your emoji status has been updated.", undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
let undoController = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: presentationData.strings.EmojiStatus_AppliedText, undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
//strongSelf.currentUndoOverlayController = controller
controller.controllerInteraction?.presentController(undoController, nil)
}
@ -2890,8 +2887,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
}
}
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Send Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SendEmoji, icon: { theme in
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) {
return generateImage(image.size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
@ -2908,8 +2904,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
f(.default)
})))
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Set as Status", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SetAsStatus, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Smile"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.default)
@ -2933,8 +2928,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
}
})))
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Copy Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_CopyEmoji, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
copyEmoji(file)

View File

@ -342,8 +342,7 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
let undoController = UndoOverlayController(presentationData: presentationData, content: .sticker(context: self.context, file: file, title: nil, text: "Your emoji status has been updated.", undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
let undoController = UndoOverlayController(presentationData: presentationData, content: .sticker(context: self.context, file: file, title: nil, text: presentationData.strings.EmojiStatus_AppliedText, undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
//strongSelf.currentUndoOverlayController = controller
controller.controllerInteraction?.presentController(undoController, nil)
}
@ -367,8 +366,7 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
}
}
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Send Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SendEmoji, icon: { theme in
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) {
return generateImage(image.size, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
@ -385,8 +383,7 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
f(.default)
})))
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Set as Status", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_SetAsStatus, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Smile"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.default)
@ -410,8 +407,7 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
}
})))
//TODO:localize
menuItems.append(.action(ContextMenuActionItem(text: "Copy Emoji", icon: { theme in
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.EmojiPreview_CopyEmoji, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
copyEmoji(file)

View File

@ -713,8 +713,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
navigationController.pushViewController(checkoutController)
}
} else {
//TODO:localize
present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: "Invoice not found", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Chat_ErrorInvoiceNotFound, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
}
}
}

View File

@ -727,10 +727,9 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
interaction.openSettings(.rememberPassword)
}))
} else if settings.suggestPasswordSetup {
//TODO:localize
items[.phone]!.append(PeerInfoScreenInfoItem(id: 0, title: "Protect Your Account", text: .markdown("Set a password that will be required each time log in with this phone number."), linkAction: { _ in
items[.phone]!.append(PeerInfoScreenInfoItem(id: 0, title: presentationData.strings.Settings_SuggestSetupPasswordTitle, text: .markdown(presentationData.strings.Settings_SuggestSetupPasswordText), linkAction: { _ in
}))
items[.phone]!.append(PeerInfoScreenActionItem(id: 2, text: "Set Additional Password", action: {
items[.phone]!.append(PeerInfoScreenActionItem(id: 2, text: presentationData.strings.Settings_SuggestSetupPasswordAction, action: {
interaction.openSettings(.passwordSetup)
}))
}