diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 595c415843..7562f928ee 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -9411,6 +9411,9 @@ Sorry for the inconvenience."; "StoryFeed.TooltipStoryLimitValue_any" = "%d stories"; "StoryFeed.TooltipStoryLimit" = "You can't post more than **%@** stories in **24 hours**."; +"StoryFeed.MyStory" = "My Story"; +"StoryFeed.MyUploading" = "Uploading..."; + "MediaPicker.AddImage" = "Add Image"; "Premium.Stories" = "Story Posting"; @@ -9429,3 +9432,105 @@ Sorry for the inconvenience."; "Settings.MyStories" = "My Stories"; "Settings.StoriesArchive" = "Stories Archive"; + +"ArchiveSettings.Title" = "Archive Settings"; + +"ArchiveSettings.UnmutedChatsHeader" = "UNMUTED CHATS"; +"ArchiveSettings.UnmutedChatsFooter" = "Keep archived chats in the Archive even if they are unmuted and get a new message."; +"ArchiveSettings.FolderChatsHeader" = "CHATS FROM FOLDERS"; +"ArchiveSettings.FolderChatsFooter" = "Keep archived chats from folders in the Archive even if they are unmuted and get a new message."; + +"ArchiveSettings.UnknownChatsHeader" = "NEW CHATS FROM UNKNOWN USERS"; +"ArchiveSettings.UnknownChatsFooter" = "Automatically archive and mute new private chats, groups and channels from non-contacts."; + +"ArchiveSettings.KeepArchived" = "Always Keep Archived"; +"ArchiveSettings.TooltipPremiumRequired" = "This setting is available only to the subscribers of [Telegram Premium]()."; + +"NotificationSettings.Stories.ShowAll" = "Show All Notifications"; +"NotificationSettings.Stories.ShowImportant" = "Show Important Notifications"; +"NotificationSettings.Stories.ShowImportantFooter" = "Always on for top 5 contacts."; +"NotificationSettings.Stories.DisplayAuthorName" = "Display Author Name"; + +"NotificationSettings.Stories.AutomaticValue" = "%@ (automatic)"; +"NotificationSettings.Stories.CompactShowName" = "Show name"; +"NotificationSettings.Stories.CompactHideName" = "Hide name"; + +"Notifications.StoriesTitle" = "Stories"; + +"Message.Story" = "Story"; + +"Notification.Exceptions.StoriesHeader" = "STORY NOTIFICATIONS"; +"Notification.Exceptions.StoriesDisplayAuthorName" = "DISPLAY AUTHOR NAME"; + +"StorageManagement.SectionStories" = "Stories"; + +"PeerInfo.PaneStories" = "Stories"; + +"Story.TooltipExpired" = "This story is no longer available"; + +"Chat.ReplyExpiredStory" = "Expired story"; +"Chat.ReplyStory" = "Story"; + +"Chat.StoryMentionAction" = "View Story"; + +"StoryList.ContextSaveToGallery" = "Save to Gallery"; +"StoryList.ContextShowArchive" = "Show Archive"; + +"StoryList.TooltipStoriesDeleted_1" = "1 story deleted."; +"StoryList.TooltipStoriesDeleted_any" = "%d stories deleted."; + +"Story.TooltipSaving" = "Saving"; +"Story.TooltipSaved" = "Saved"; + +"StoryList.SaveToProfile" = "Save to Profile"; +"StoryList.TooltipStoriesSavedToProfile_1" = "Story saved to your profile"; +"StoryList.TooltipStoriesSavedToProfile_any" = "%d stories saved to your profile."; +"StoryList.TooltipStoriesSavedToProfileText" = "Saved stories can be viewed by others on your profile until you remove them."; + +"StoryList.TitleSaved" = "My Stories"; +"StoryList.TitleArchive" = "Stories Archive"; +"StoryList.SubtitleSelected_1" = "1 story selected"; +"StoryList.SubtitleSelected_any" = "%d stories selected"; + +"StoryList.SubtitleSaved_1" = "1 saved story"; +"StoryList.SubtitleSaved_any" = "%d saved stories"; + +"StoryList.SubtitleCount_1" = "1 story"; +"StoryList.SubtitleCount_any" = "%d stories"; + +"StoryList.ArchiveDescription" = "Only you can see archived stories unless you choose to save them to your profile."; + +"StoryList.SavedEmptyState.Title" = "No saved stories"; +"StoryList.SavedEmptyState.Text" = "Open the Archive to select stories you\nwant to be displayed in your profile."; +"StoryList.ArchivedEmptyState.Title" = "No Archived Stories"; +"StoryList.ArchivedEmptyState.Text" = "Upload a new story to view it here"; +"StoryList.SavedEmptyAction" = "Open Archive"; + +"ArchiveInfo.Title" = "This is Your Archive"; + +"ArchiveInfo.TextKeepArchivedUnmuted" = "Archived chats will remain in the Archive when you receive a new message. [Tap to change >]()"; +"ArchiveInfo.TextKeepArchivedDefault" = "When you receive a new message, muted chats will remain in the Archive, while unmuted chats will be moved to Chats. [Tap to change >]()"; + +"ArchiveInfo.ChatsTitle" = "Archived Chats"; +"ArchiveInfo.ChatsText" = "Move any chat into your Archive and back by swiping on it."; +"ArchiveInfo.HideTitle" = "Hiding Archive"; +"ArchiveInfo.HideText" = "Hide the Archive from your Main screen by swiping on it."; +"ArchiveInfo.StoriesTitle" = "Stories"; +"ArchiveInfo.StoriesText" = "Archive Stories from your contacts separately from chats with them."; +"ArchiveInfo.CloseAction" = "Got it"; + +"Story.HeaderYourStory" = "Your story"; +"Story.HeaderEdited" = "edited"; +"Story.CaptionShowMore" = "Show more"; + +"Story.UnsupportedText" = "This story is not supported by\nyour version of Telegram."; +"Story.UnsupportedAction" = "Update Telegram"; + +"Story.ScreenshotBlockedTitle" = "Screenshot Blocked"; +"Story.ScreenshotBlockedText" = "The story you tried to take a\nscreenshot of is protected from\ncopying by its creator."; + +"Story.Footer.NoViews" = "No views"; +"Story.Footer.Views_1" = "1 view"; +"Story.Footer.Views_any" = "%d views"; + +"Story.Footer.Uploading" = "Uploading..."; diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 4bcbeee8e0..8100206837 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -2576,7 +2576,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController text = self.presentationData.strings.StoryFeed_TooltipPremiumPosting } else if reachedCountLimit { let valueText = self.presentationData.strings.StoryFeed_TooltipStoryLimitValue(Int32(storiesCountLimit)) - text = self.presentationData.strings.StoryFeed_TooltipStoryLimit + text = self.presentationData.strings.StoryFeed_TooltipStoryLimit(valueText).string } else { text = "" } diff --git a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift index 60d855ddf9..862b20bc01 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift @@ -303,7 +303,7 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder: messageText = strings.Conversation_StoryMentionTextOutgoing(peer.compactDisplayTitle).string } } else { - messageText = strongs.Notification_Story + messageText = strings.Notification_Story } default: break diff --git a/submodules/ContactListUI/Sources/ContactContextMenus.swift b/submodules/ContactListUI/Sources/ContactContextMenus.swift index ada3673f3a..40d1918d0f 100644 --- a/submodules/ContactListUI/Sources/ContactContextMenus.swift +++ b/submodules/ContactListUI/Sources/ContactContextMenus.swift @@ -68,7 +68,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con "Bottom.Group 1.Fill 1": iconColor, "EXAMPLE.Group 1.Fill 1": iconColor, "Line.Group 1.Stroke 1": iconColor - ], title: nil, text: presentationData.strings.StoryFeed.TooltipNotifyOn(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string, customUndoText: nil, timeout: nil), + ], title: nil, text: presentationData.strings.StoryFeed_TooltipNotifyOn(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false } @@ -82,7 +82,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con "Bottom.Group 1.Fill 1": iconColor, "EXAMPLE.Group 1.Fill 1": iconColor, "Line.Group 1.Stroke 1": iconColor - ], title: nil, text: presentationData.strings.StoryFeed.TooltipNotifyOff(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)), customUndoText: nil, timeout: nil), + ], title: nil, text: presentationData.strings.StoryFeed_TooltipNotifyOff(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false } diff --git a/submodules/ContactListUI/Sources/ContactListNode.swift b/submodules/ContactListUI/Sources/ContactListNode.swift index 9c7752464e..9d8e81aa1d 100644 --- a/submodules/ContactListUI/Sources/ContactListNode.swift +++ b/submodules/ContactListUI/Sources/ContactListNode.swift @@ -391,7 +391,6 @@ private func contactListNodeEntries(accountPeer: EnginePeer?, peers: [ContactLis } if addHeader { - //TODO:localize commonHeader = ChatListSearchItemHeader(type: .text(strings.Contacts_SortedByPresence.uppercased(), AnyHashable(1)), theme: theme, strings: strings, actionTitle: nil, action: nil) } diff --git a/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift b/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift index 189ed3c9ee..ed47632b05 100644 --- a/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift +++ b/submodules/PeerInfoAvatarListNode/Sources/PeerInfoAvatarListNode.swift @@ -1265,6 +1265,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode { transition: indicatorTransition, component: AnyComponent(StorySetIndicatorComponent( context: self.context, + strings: self.context.sharedContext.currentPresentationData.with({ $0 }).strings, peer: storyParams.peer, items: storyParams.items, hasUnseen: storyParams.hasUnseen, diff --git a/submodules/SettingsUI/Sources/ArchiveSettingsController.swift b/submodules/SettingsUI/Sources/ArchiveSettingsController.swift index ae382e651e..1a35e1f3ee 100644 --- a/submodules/SettingsUI/Sources/ArchiveSettingsController.swift +++ b/submodules/SettingsUI/Sources/ArchiveSettingsController.swift @@ -85,34 +85,33 @@ private enum ArchiveSettingsControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! ArchiveSettingsControllerArguments - //TODO:localize switch self { case .unmutedHeader: - return ItemListSectionHeaderItem(presentationData: presentationData, text: "UNMUTED CHATS", sectionId: self.section) + return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_UnmutedChatsHeader, sectionId: self.section) case let .unmutedValue(value): - return ItemListSwitchItem(presentationData: presentationData, title: "Always Keep Archived", value: value, sectionId: self.section, style: .blocks, updated: { value in + return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.updateUnmuted(value) }) case .unmutedFooter: - return ItemListTextItem(presentationData: presentationData, text: .markdown("Keep archived chats in the Archive even if they are unmuted and get a new message."), sectionId: self.section) + return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_UnmutedChatsFooter), sectionId: self.section) case .foldersHeader: - return ItemListSectionHeaderItem(presentationData: presentationData, text: "CHATS FROM FOLDERS", sectionId: self.section) + return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_FolderChatsHeader, sectionId: self.section) case let .foldersValue(value): - return ItemListSwitchItem(presentationData: presentationData, title: "Always Keep Archived", value: value, sectionId: self.section, style: .blocks, updated: { value in + return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.updateFolders(value) }) case .foldersFooter: - return ItemListTextItem(presentationData: presentationData, text: .markdown("Keep archived chats from folders in the Archive even if they are unmuted and get a new message."), sectionId: self.section) + return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_FolderChatsFooter), sectionId: self.section) case .unknownHeader: - return ItemListSectionHeaderItem(presentationData: presentationData, text: "NEW CHATS FROM UNKNOWN USERS", sectionId: self.section) + return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_UnknownChatsHeader, sectionId: self.section) case let .unknownValue(isOn, isLocked): - return ItemListSwitchItem(presentationData: presentationData, title: "Always Keep Archived", value: isOn, enableInteractiveChanges: !isLocked, enabled: true, displayLocked: isLocked, sectionId: self.section, style: .blocks, updated: { value in + return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: isOn, enableInteractiveChanges: !isLocked, enabled: true, displayLocked: isLocked, sectionId: self.section, style: .blocks, updated: { value in arguments.updateUnknown(value) }, activatedWhileDisabled: { arguments.updateUnknown(nil) }) case .unknownFooter: - return ItemListTextItem(presentationData: presentationData, text: .markdown("Automatically archive and mute new private chats, groups and channels from non-contacts."), sectionId: self.section) + return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_UnknownChatsFooter), sectionId: self.section) } } } @@ -163,7 +162,8 @@ public func archiveSettingsController(context: AccountContext) -> ViewController if let value { let _ = context.engine.privacy.updateAccountAutoArchiveChats(value: value).start() } else { - presentUndoImpl?(.premiumPaywall(title: nil, text: "This setting is available only to the subscribers of [Telegram Premium]().", customUndoText: nil, timeout: nil, linkAction: { _ in + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + presentUndoImpl?(.premiumPaywall(title: nil, text: presentationData.strings.ArchiveSettings_TooltipPremiumRequired, customUndoText: nil, timeout: nil, linkAction: { _ in presentPremiumImpl?() })) } @@ -181,8 +181,7 @@ public func archiveSettingsController(context: AccountContext) -> ViewController let isPremium = accountPeer?.isPremium ?? false let isPremiumDisabled = PremiumConfiguration.with(appConfiguration: appConfiguration).isPremiumDisabled - //TODO:localize - let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Archive Settings"), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back)) + let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ArchiveSettings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back)) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: archiveSettingsControllerEntries( presentationData: presentationData, settings: settings, diff --git a/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift b/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift index 01cc16da5d..5abe4912b5 100644 --- a/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift +++ b/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift @@ -345,17 +345,16 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor importantEnabled = true } - //TODO:localize - entries.append(.enable(presentationData.theme, "Show All Notifications", allEnabled)) + entries.append(.enable(presentationData.theme, presentationData.strings.NotificationSettings_Stories_ShowAll, allEnabled)) if !allEnabled { - entries.append(.enableImportant(presentationData.theme, "Show Important Notifications", importantEnabled)) - entries.append(.importantInfo(presentationData.theme, "Always on for top 5 contacts.")) + entries.append(.enableImportant(presentationData.theme, presentationData.strings.NotificationSettings_Stories_ShowImportant, importantEnabled)) + entries.append(.importantInfo(presentationData.theme, presentationData.strings.NotificationSettings_Stories_ShowImportantFooter)) } if notificationSettings.enabled || !notificationExceptions.isEmpty { entries.append(.optionsHeader(presentationData.theme, presentationData.strings.Notifications_Options.uppercased())) - entries.append(.previews(presentationData.theme, "Display Author Name", notificationSettings.storySettings.hideSender != .hide)) + entries.append(.previews(presentationData.theme, presentationData.strings.NotificationSettings_Stories_DisplayAuthorName, notificationSettings.storySettings.hideSender != .hide)) entries.append(.sound(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsSound, localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: filteredGlobalSound(notificationSettings.storySettings.sound)), filteredGlobalSound(notificationSettings.storySettings.sound))) } } else { @@ -413,8 +412,7 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor var title: String = "" if automaticSet.contains(value.peer.id) { - //TODO:localize - title = "\(presentationData.strings.Notification_Exceptions_AlwaysOn) (automatic)" + title = presentationData.strings.NotificationSettings_Stories_AutomaticValue(presentationData.strings.Notification_Exceptions_AlwaysOn).string canRemove = false } else { if case .stories = category { @@ -443,11 +441,10 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor if !title.isEmpty { title += ", " } - //TODO:localize if case .show = value.settings.storySettings.hideSender { - title += "Show Name" + title += presentationData.strings.NotificationSettings_Stories_CompactShowName } else { - title += "Hide Name" + title += presentationData.strings.NotificationSettings_Stories_CompactHideName } } } @@ -1068,8 +1065,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor case .channel: title = presentationData.strings.Notifications_ChannelsTitle case .stories: - //TODO:localize - title = "Stories" + title = presentationData.strings.Notifications_StoriesTitle } let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: entries, style: .blocks, ensureVisibleItemTag: focusOnItemTag, initialScrollToItem: scrollToItem) diff --git a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift index 05c0941f9f..4efe89b396 100644 --- a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift +++ b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift @@ -396,8 +396,7 @@ public func stringForMediaKind(_ kind: MessageContentKind, strings: Presentation case let .invoice(text): return (NSAttributedString(string: text), true) case .story: - //TODO:localize - return (NSAttributedString(string: "Story"), true) + return (NSAttributedString(string: strings.Message_Story), true) } } diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift index 4c19dec0ff..e8283aa3c8 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift @@ -283,7 +283,6 @@ public final class ChatListNavigationBar: Component { placeholder = component.strings.Common_Search compactPlaceholder = component.strings.Common_Search - //TODO:localize searchContentNode = NavigationBarSearchContentNode( theme: component.theme, placeholder: placeholder, diff --git a/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift b/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift index 13250d0502..1306d1275f 100644 --- a/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift +++ b/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift @@ -726,8 +726,7 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData if isStories == nil || isStories == true { if case .user = peer { - //TODO:localize - entries.append(.storyNotificationsHeader(index: index, theme: presentationData.theme, title: "STORY NOTIFICATIONS")) + entries.append(.storyNotificationsHeader(index: index, theme: presentationData.theme, title: presentationData.strings.Notification_Exceptions_StoriesHeader)) index += 1 entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storiesMuted == .alwaysOn)) index += 1 @@ -735,7 +734,7 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData index += 1 if state.storiesMuted != .alwaysOff { - entries.append(.displayPreviewsHeader(index: index, theme: presentationData.theme, title: "DISPLAY AUTHOR NAME")) + entries.append(.displayPreviewsHeader(index: index, theme: presentationData.theme, title: presentationData.strings.Notification_Exceptions_StoriesDisplayAuthorName)) index += 1 entries.append(.showSender(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storiesHideSender == .alwaysOn)) index += 1 diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift index 81120c734c..b2ba55ea2f 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen/Sources/PeerInfoStoryGridScreen.swift @@ -88,9 +88,7 @@ final class PeerInfoStoryGridScreenComponent: Component { let strings = presentationData.strings if self.selectedCount != 0 { - //TODO:localize - //TODO:update icon - items.append(.action(ContextMenuActionItem(text: "Save to Photos", icon: { theme in + items.append(.action(ContextMenuActionItem(text: presentationData.strings.StoryList_ContextSaveToGallery, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, a in a(.default) @@ -113,16 +111,10 @@ final class PeerInfoStoryGridScreenComponent: Component { return } let _ = component.context.engine.messages.deleteStories(ids: Array(paneNode.selectedIds)).start() - - //TODO:localize - let text: String - if paneNode.selectedIds.count == 1 { - text = "1 story deleted." - } else { - text = "\(paneNode.selectedIds.count) stories deleted." - } - + let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: environment.theme) + let text: String = presentationData.strings.StoryList_TooltipStoriesDeleted(Int32(paneNode.selectedIds.count)) + environment.controller()?.present(UndoOverlayController( presentationData: presentationData, content: .info(title: nil, text: text, timeout: nil), @@ -163,8 +155,7 @@ final class PeerInfoStoryGridScreenComponent: Component { if component.peerId == component.context.account.peerId, case .saved = component.scope { var ignoreNextActions = false - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Show Archive", icon: { theme in + items.append(.action(ContextMenuActionItem(text: presentationData.strings.StoryList_ContextShowArchive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/StoryArchive"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, a in if ignoreNextActions { @@ -305,8 +296,8 @@ final class PeerInfoStoryGridScreenComponent: Component { return } - //TODO:localize - let saveScreen = SaveProgressScreen(context: component.context, content: .progress("Saving", 0.0)) + let strings = (component.context.sharedContext.currentPresentationData.with { $0 }).strings + let saveScreen = SaveProgressScreen(context: component.context, content: .progress(strings.Story_TooltipSaving, 0.0)) self.environment?.controller()?.present(saveScreen, in: .current) let valueNorm: Float = 1.0 / Float(sortedItems.count) @@ -330,12 +321,12 @@ final class PeerInfoStoryGridScreenComponent: Component { guard let saveScreen else { return } - saveScreen.content = .progress("Saving", progress) + saveScreen.content = .progress(strings.Story_TooltipSaving, progress) }, completed: { [weak saveScreen] in guard let saveScreen else { return } - saveScreen.content = .completion("Saved") + saveScreen.content = .completion(strings.Story_TooltipSaved) Queue.mainQueue().after(3.0, { [weak saveScreen] in saveScreen?.dismiss() }) @@ -376,12 +367,11 @@ final class PeerInfoStoryGridScreenComponent: Component { self.selectionPanel = selectionPanel } - //TODO:localize let selectionPanelSize = selectionPanel.update( transition: selectionPanelTransition, component: AnyComponent(BottomButtonPanelComponent( theme: environment.theme, - title: "Save to Profile", + title: environment.strings.StoryList_SaveToProfile, label: nil, isEnabled: true, insets: UIEdgeInsets(top: 0.0, left: sideInset, bottom: environment.safeInsets.bottom, right: sideInset), @@ -395,18 +385,12 @@ final class PeerInfoStoryGridScreenComponent: Component { let _ = component.context.engine.messages.updateStoriesArePinned(ids: paneNode.selectedItems, isPinned: true).start() - //TODO:localize - let title: String - if paneNode.selectedIds.count == 1 { - title = "Story saved to your profile" - } else { - title = "\(paneNode.selectedIds.count) saved to your profile" - } - let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: environment.theme) + + let title: String = presentationData.strings.StoryList_TooltipStoriesSavedToProfile(Int32(paneNode.selectedIds.count)) environment.controller()?.present(UndoOverlayController( presentationData: presentationData, - content: .info(title: title, text: "Saved stories can be viewed by others on your profile until you remove them.", timeout: nil), + content: .info(title: title, text: presentationData.strings.StoryList_TooltipStoriesSavedToProfileText, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false } @@ -596,7 +580,8 @@ public class PeerInfoStoryGridScreen: ViewControllerComponentContainer { } func updateTitle() { - //TODO:localize + let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } + switch self.scope { case .saved: guard let componentView = self.node.hostView.componentView as? PeerInfoStoryGridScreenComponent.View else { @@ -608,16 +593,16 @@ public class PeerInfoStoryGridScreen: ViewControllerComponentContainer { } else { title = nil } - self.titleView?.titleContent = .custom("My Stories", title, false) + self.titleView?.titleContent = .custom(presentationData.strings.StoryList_TitleSaved, title, false) case .archive: guard let componentView = self.node.hostView.componentView as? PeerInfoStoryGridScreenComponent.View else { return } let title: String if componentView.selectedCount != 0 { - title = "\(componentView.selectedCount) Selected" + title = presentationData.strings.StoryList_SubtitleSelected(Int32(componentView.selectedCount)) } else { - title = "Stories Archive" + title = presentationData.strings.StoryList_TitleArchive } self.titleView?.titleContent = .custom(title, nil, false) } diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift index 52be5dd889..1c317bad07 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift @@ -1560,17 +1560,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr let title: String if state.totalCount == 0 { title = "" - } else if state.totalCount == 1 { - if self.isSaved { - title = "1 saved story" - } else { - title = "1 story" - } } else { if self.isSaved { - title = "\(state.totalCount) saved stories" + title = self.presentationData.strings.StoryList_SubtitleSaved(Int32(state.totalCount)) } else { - title = "\(state.totalCount) stories" + title = self.presentationData.strings.StoryList_SubtitleCount(Int32(state.totalCount)) } } self.statusPromise.set(.single(PeerInfoStatusData(text: title, isActivity: false, key: .stories))) @@ -1607,8 +1601,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr var headerText: String? if strongSelf.isArchive && !mappedItems.isEmpty { - //TODO:localize - headerText = "Only you can see archived stories unless you choose to save them to your profile." + headerText = strongSelf.presentationData.strings.StoryList_ArchiveDescription } let items = SparseItemGrid.Items( @@ -1914,16 +1907,15 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr emptyStateView = ComponentView() self.emptyStateView = emptyStateView } - //TODO:localize let emptyStateSize = emptyStateView.update( transition: emptyStateTransition, component: AnyComponent(EmptyStateIndicatorComponent( context: self.context, theme: presentationData.theme, animationName: "StoryListEmpty", - title: self.isArchive ? "No Archived Stories" : "No saved stories", - text: self.isArchive ? "Upload a new story to view it here" : "Open the Archive to select stories you\nwant to be displayed in your profile.", - actionTitle: self.isArchive ? nil : "Open Archive", + title: self.isArchive ? presentationData.strings.StoryList_ArchivedEmptyState_Title : presentationData.strings.StoryList_SavedEmptyState_Title, + text: self.isArchive ? presentationData.strings.StoryList_ArchivedEmptyState_Text : presentationData.strings.StoryList_SavedEmptyState_Text, + actionTitle: self.isArchive ? nil : presentationData.strings.StoryList_SavedEmptyAction, action: { [weak self] in guard let self else { return diff --git a/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoContentComponent.swift b/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoContentComponent.swift index 0d365fb1ec..023da0812a 100644 --- a/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoContentComponent.swift +++ b/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoContentComponent.swift @@ -128,12 +128,11 @@ public final class ArchiveInfoContentComponent: Component { contentHeight += 15.0 let titleString = NSMutableAttributedString() - titleString.append(NSAttributedString(string: "This is Your Archive", font: Font.semibold(19.0), textColor: component.theme.list.itemPrimaryTextColor)) + titleString.append(NSAttributedString(string: component.strings.ArchiveInfo_Title, font: Font.semibold(19.0), textColor: component.theme.list.itemPrimaryTextColor)) let imageAttachment = NSTextAttachment() imageAttachment.image = self.iconBackground.image titleString.append(NSAttributedString(attachment: imageAttachment)) - //TODO:localize let titleSize = self.title.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( @@ -153,11 +152,10 @@ public final class ArchiveInfoContentComponent: Component { contentHeight += 16.0 let text: String - //TODO:localize if component.settings.keepArchivedUnmuted { - text = "Archived chats will remain in the Archive when you receive a new message. [Tap to change >]()" + text = component.strings.ArchiveInfo_TextKeepArchivedUnmuted } else { - text = "When you receive a new message, muted chats will remain in the Archive, while unmuted chats will be moved to Chats. [Tap to change >]()" + text = component.strings.ArchiveInfo_TextKeepArchivedDefault } let mainText = NSMutableAttributedString() @@ -229,18 +227,18 @@ public final class ArchiveInfoContentComponent: Component { let itemDescs: [ItemDesc] = [ ItemDesc( icon: "Chat List/Archive/IconArchived", - title: "Archived Chats", - text: "Move any chat into your Archive and back by swiping on it." + title: component.strings.ArchiveInfo_ChatsTitle, + text: component.strings.ArchiveInfo_ChatsText ), ItemDesc( icon: "Chat List/Archive/IconHide", - title: "Hiding Archive", - text: "Hide the Archive from your Main screen by swiping on it." + title: component.strings.ArchiveInfo_HideTitle, + text: component.strings.ArchiveInfo_HideText ), ItemDesc( icon: "Chat List/Archive/IconStories", - title: "Stories", - text: "Archive Stories from your contacts separately from chats with them." + title: component.strings.ArchiveInfo_StoriesTitle, + text: component.strings.ArchiveInfo_StoriesText ) ] for i in 0 ..< itemDescs.count { diff --git a/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoScreen.swift b/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoScreen.swift index a28728c9d2..59df7851f9 100644 --- a/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoScreen.swift +++ b/submodules/TelegramUI/Components/Settings/ArchiveInfoScreen/Sources/ArchiveInfoScreen.swift @@ -76,7 +76,6 @@ private final class ArchiveInfoSheetContentComponent: Component { contentHeight += contentSize.height contentHeight += 30.0 - //TODO:localize let buttonSize = self.button.update( transition: transition, component: AnyComponent(ButtonComponent( @@ -86,7 +85,7 @@ private final class ArchiveInfoSheetContentComponent: Component { pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8) ), content: AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent( - Text(text: "Got it", font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor) + Text(text: environment.strings.ArchiveInfo_CloseAction, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor) )), isEnabled: true, displaysProgress: false, diff --git a/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift b/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift index 3779bd27c1..796b5da509 100644 --- a/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift +++ b/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift @@ -310,8 +310,7 @@ final class StorageUsageScreenComponent: Component { case .misc: return strings.StorageManagement_SectionMiscellaneous case .stories: - //TODO:localize - return "Stories" + return strings.StorageManagement_SectionStories } } @@ -1810,8 +1809,7 @@ final class StorageUsageScreenComponent: Component { mappedCategory = .groups case 3: iconName = "Settings/Menu/Stories" - //TODO:localized - title = "Stories" + title = environment.strings.Notifications_Stories mappedCategory = .stories default: iconName = "Settings/Menu/Channels" diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryAuthorInfoComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryAuthorInfoComponent.swift index ed343a9dfc..f2dd959ca4 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryAuthorInfoComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryAuthorInfoComponent.swift @@ -6,6 +6,7 @@ import AccountContext import TelegramCore import TelegramStringFormatting import MultilineTextComponent +import TelegramPresentationData final class StoryAuthorInfoComponent: Component { struct Counters: Equatable { @@ -14,13 +15,15 @@ final class StoryAuthorInfoComponent: Component { } let context: AccountContext + let strings: PresentationStrings let peer: EnginePeer? let timestamp: Int32 let counters: Counters? let isEdited: Bool - init(context: AccountContext, peer: EnginePeer?, timestamp: Int32, counters: Counters?, isEdited: Bool) { + init(context: AccountContext, strings: PresentationStrings, peer: EnginePeer?, timestamp: Int32, counters: Counters?, isEdited: Bool) { self.context = context + self.strings = strings self.peer = peer self.timestamp = timestamp self.counters = counters @@ -31,6 +34,9 @@ final class StoryAuthorInfoComponent: Component { if lhs.context !== rhs.context { return false } + if lhs.strings !== rhs.strings { + return false + } if lhs.peer != rhs.peer { return false } @@ -75,8 +81,7 @@ final class StoryAuthorInfoComponent: Component { let title: String if component.peer?.id == component.context.account.peerId { - //TODO:localize - title = "Your story" + title = component.strings.Story_HeaderYourStory } else { title = component.peer?.debugDisplayTitle ?? "" } @@ -86,7 +91,7 @@ final class StoryAuthorInfoComponent: Component { if component.isEdited { subtitle.append(" • ") - subtitle.append("edited") + subtitle.append(component.strings.Story_HeaderEdited) } let titleSize = self.title.update( diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift index 482b437abb..c47cac2141 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift @@ -9,6 +9,7 @@ import TextNodeWithEntities import TextFormat import InvisibleInkDustNode import UrlEscaping +import TelegramPresentationData final class StoryContentCaptionComponent: Component { enum Action { @@ -41,6 +42,7 @@ final class StoryContentCaptionComponent: Component { let externalState: ExternalState let context: AccountContext + let strings: PresentationStrings let text: String let entities: [MessageTextEntity] let entityFiles: [EngineMedia.Id: TelegramMediaFile] @@ -50,6 +52,7 @@ final class StoryContentCaptionComponent: Component { init( externalState: ExternalState, context: AccountContext, + strings: PresentationStrings, text: String, entities: [MessageTextEntity], entityFiles: [EngineMedia.Id: TelegramMediaFile], @@ -58,6 +61,7 @@ final class StoryContentCaptionComponent: Component { ) { self.externalState = externalState self.context = context + self.strings = strings self.text = text self.entities = entities self.entityFiles = entityFiles @@ -72,6 +76,9 @@ final class StoryContentCaptionComponent: Component { if lhs.context !== rhs.context { return false } + if lhs.strings !== rhs.strings { + return false + } if lhs.text != rhs.text { return false } @@ -425,9 +432,8 @@ final class StoryContentCaptionComponent: Component { let truncationToken = NSMutableAttributedString() truncationToken.append(NSAttributedString(string: "\u{2026} ", font: Font.regular(16.0), textColor: .white)) - truncationToken.append(NSAttributedString(string: "Show more", font: Font.semibold(16.0), textColor: .white)) + truncationToken.append(NSAttributedString(string: component.strings.Story_CaptionShowMore, font: Font.semibold(16.0), textColor: .white)) - //TODO:localize let collapsedTextLayout = TextNodeWithEntities.asyncLayout(self.collapsedText.textNode)(TextNodeLayoutArguments( attributedString: attributedText, maximumNumberOfLines: 3, diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift index 331f629e80..2961649fef 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift @@ -592,11 +592,10 @@ final class StoryItemContentComponent: Component { self.unsupportedButton = unsupportedButton } - //TODO:localize let unsupportedTextSize = unsupportedText.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: "This story is not supported by\nyour version of Telegram.", font: Font.regular(17.0), textColor: .white)), + text: .plain(NSAttributedString(string: component.strings.Story_UnsupportedText, font: Font.regular(17.0), textColor: .white)), horizontalAlignment: .center, maximumNumberOfLines: 0 )), @@ -611,7 +610,7 @@ final class StoryItemContentComponent: Component { foreground: environment.theme.list.itemCheckColors.foregroundColor, pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.7) ), - content: AnyComponentWithIdentity(id: AnyHashable(""), component: AnyComponent(Text(text: "Update Telegram", font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor + content: AnyComponentWithIdentity(id: AnyHashable(""), component: AnyComponent(Text(text: component.strings.Story_UnsupportedAction, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor ))), isEnabled: true, displaysProgress: false, @@ -655,7 +654,10 @@ final class StoryItemContentComponent: Component { self.updateProgressMode(update: false) if reloadMedia && synchronousLoad { + let _ = startTime + #if DEBUG print("\(CFAbsoluteTimeGetCurrent()) Synchronous: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms") + #endif } if !self.contentLoaded { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemImageView.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemImageView.swift index fbcb76a3a0..ef6423d674 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemImageView.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemImageView.swift @@ -34,11 +34,6 @@ final class StoryItemImageView: UIView { super.init(frame: frame) self.addSubview(self.contentView) - #if DEBUG - if "".isEmpty { - self.contentView.isHidden = true - } - #endif } required init?(coder: NSCoder) { @@ -292,11 +287,10 @@ final class CaptureProtectedInfoComponent: Component { environment: {}, containerSize: availableSize ) - //TODO:localize let titleSize = self.title.update( transition: transition, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: "Screenshot Blocked", font: Font.semibold(20.0), textColor: .white)), + text: .plain(NSAttributedString(string: component.strings.Story_ScreenshotBlockedTitle, font: Font.semibold(20.0), textColor: .white)), horizontalAlignment: .center, maximumNumberOfLines: 0 )), @@ -306,7 +300,7 @@ final class CaptureProtectedInfoComponent: Component { let textSize = self.text.update( transition: transition, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: "The story you tried to take a\nscreenshot of is protected from\ncopying by its creator.", font: Font.regular(17.0), textColor: UIColor(white: 1.0, alpha: 0.6))), + text: .plain(NSAttributedString(string: component.strings.Story_ScreenshotBlockedText, font: Font.regular(17.0), textColor: UIColor(white: 1.0, alpha: 0.6))), horizontalAlignment: .center, maximumNumberOfLines: 0 )), diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 26169cb6e6..76f8ae0b3c 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -2541,6 +2541,7 @@ public final class StoryItemSetContainerComponent: Component { let centerInfoComponent = AnyComponent(StoryAuthorInfoComponent( context: component.context, + strings: component.strings, peer: component.slice.peer, timestamp: component.slice.item.storyItem.timestamp, counters: counters, @@ -2679,6 +2680,7 @@ public final class StoryItemSetContainerComponent: Component { component: AnyComponent(StoryContentCaptionComponent( externalState: captionItem.externalState, context: component.context, + strings: component.strings, text: component.slice.item.storyItem.text, entities: component.slice.item.storyItem.entities, entityFiles: component.slice.item.entityFiles, diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift index 606a5a949f..09fa50b4c1 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift @@ -685,6 +685,7 @@ final class StoryItemSetViewListComponent: Component { transition: transition, component: AnyComponent(StoryFooterPanelComponent( context: component.context, + strings: component.strings, storyItem: component.storyItem, externalViews: externalViews, expandFraction: dismissFraction, diff --git a/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift b/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift index abe0f5deed..b22810d66c 100644 --- a/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift @@ -10,9 +10,11 @@ import TelegramCore import MoreHeaderButton import SemanticStatusNode import SwiftSignalKit +import TelegramPresentationData public final class StoryFooterPanelComponent: Component { public let context: AccountContext + public let strings: PresentationStrings public let storyItem: EngineStoryItem? public let externalViews: EngineStoryItem.Views? public let expandFraction: CGFloat @@ -22,6 +24,7 @@ public final class StoryFooterPanelComponent: Component { public init( context: AccountContext, + strings: PresentationStrings, storyItem: EngineStoryItem?, externalViews: EngineStoryItem.Views?, expandFraction: CGFloat, @@ -30,6 +33,7 @@ public final class StoryFooterPanelComponent: Component { moreAction: @escaping (UIView, ContextGesture?) -> Void ) { self.context = context + self.strings = strings self.storyItem = storyItem self.externalViews = externalViews self.expandViewStats = expandViewStats @@ -42,6 +46,9 @@ public final class StoryFooterPanelComponent: Component { if lhs.context !== rhs.context { return false } + if lhs.strings !== rhs.strings { + return false + } if lhs.storyItem != rhs.storyItem { return false } @@ -200,10 +207,9 @@ public final class StoryFooterPanelComponent: Component { statusNode.transitionToState(.progress(value: CGFloat(max(0.08, self.uploadProgress)), cancelEnabled: true, appearance: SemanticStatusNodeState.ProgressAppearance(inset: 0.0, lineWidth: 2.0))) - //TODO:localize let uploadingTextSize = uploadingText.update( transition: .immediate, - component: AnyComponent(Text(text: "Uploading...", font: Font.regular(15.0), color: .white)), + component: AnyComponent(Text(text: component.strings.Story_Footer_Uploading, font: Font.regular(15.0), color: .white)), environment: {}, containerSize: CGSize(width: 200.0, height: 100.0) ) @@ -260,11 +266,9 @@ public final class StoryFooterPanelComponent: Component { let viewsText: String if viewCount == 0 { - viewsText = "No Views" - } else if viewCount == 1 { - viewsText = "1 view" + viewsText = component.strings.Story_Footer_NoViews } else { - viewsText = "\(viewCount) views" + viewsText = component.strings.Story_Footer_Views(Int32(viewCount)) } self.viewStatsButton.isEnabled = viewCount != 0 diff --git a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift index b1edf8c56f..eaf2c5e1bb 100644 --- a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift @@ -778,13 +778,12 @@ public final class StoryPeerListItemComponent: Component { Transition.immediate.setShapeLayerPath(layer: self.indicatorShapeSeenLayer, path: calculateMergingCircleShape(center: indicatorCenter, leftCenter: mappedLeftCenter, rightCenter: mappedRightCenter, radius: indicatorRadius - indicatorLineUnseenWidth * 0.5, totalCount: component.totalCount, unseenCount: component.unseenCount, isSeen: true, segmentFraction: component.expandedAlphaFraction)) Transition.immediate.setShapeLayerPath(layer: self.indicatorShapeUnseenLayer, path: calculateMergingCircleShape(center: indicatorCenter, leftCenter: mappedLeftCenter, rightCenter: mappedRightCenter, radius: indicatorRadius - indicatorLineUnseenWidth * 0.5, totalCount: component.totalCount, unseenCount: component.unseenCount, isSeen: false, segmentFraction: component.expandedAlphaFraction)) - //TODO:localize let titleString: String if component.peer.id == component.context.account.peerId { if let ringAnimation = component.ringAnimation, case .progress = ringAnimation { - titleString = "Uploading..." + titleString = component.strings.StoryFeed_MyUploading } else { - titleString = "My story" + titleString = component.strings.StoryFeed_MyStory } } else { titleString = component.peer.compactDisplayTitle.trimmingCharacters(in: .whitespacesAndNewlines) diff --git a/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift b/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift index 98856c4da9..6bc6da6ba5 100644 --- a/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StorySetIndicatorComponent/Sources/StorySetIndicatorComponent.swift @@ -89,6 +89,7 @@ private final class ShapeImageView: UIView { public final class StorySetIndicatorComponent: Component { public let context: AccountContext + public let strings: PresentationStrings public let peer: EnginePeer public let items: [EngineStoryItem] public let hasUnseen: Bool @@ -99,6 +100,7 @@ public final class StorySetIndicatorComponent: Component { public init( context: AccountContext, + strings: PresentationStrings, peer: EnginePeer, items: [EngineStoryItem], hasUnseen: Bool, @@ -108,6 +110,7 @@ public final class StorySetIndicatorComponent: Component { action: @escaping () -> Void ) { self.context = context + self.strings = strings self.peer = peer self.items = items self.hasUnseen = hasUnseen @@ -118,6 +121,9 @@ public final class StorySetIndicatorComponent: Component { } public static func ==(lhs: StorySetIndicatorComponent, rhs: StorySetIndicatorComponent) -> Bool { + if lhs.strings !== rhs.strings { + return false + } if lhs.items != rhs.items { return false } @@ -378,14 +384,11 @@ public final class StorySetIndicatorComponent: Component { self.imageView.setNeedsDisplay() } - //TODO:localize let textValue: String if component.totalCount == 0 { textValue = "" - } else if component.totalCount == 1 { - textValue = "1 story" } else { - textValue = "\(component.totalCount) stories" + textValue = component.strings.Story_Footer_Views(Int32(component.totalCount)) } let textSize = self.text.update( transition: .immediate, diff --git a/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/Contents.json index 0d1e12bb58..5312a6642c 100644 --- a/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/Contents.json +++ b/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "smoothGradient 0.4.png", + "filename" : "smoothGradient 0.6.png", "idiom" : "universal" } ], diff --git a/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.4.png b/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.4.png deleted file mode 100644 index 49a5faf1c2..0000000000 Binary files a/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.4.png and /dev/null differ diff --git a/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.6.png b/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.6.png new file mode 100644 index 0000000000..82f7e1820c Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.6.png differ diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index e4d1c236cf..e0334c1a6d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -4524,8 +4524,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } if let story = message.associatedStories[storyId], story.data.isEmpty { - //TODO:localize - self.present(UndoOverlayController(presentationData: self.presentationData, content: .info(title: nil, text: "This story is no longer available", timeout: nil), elevatedLayout: false, action: { _ in return true }), in: .current) + self.present(UndoOverlayController(presentationData: self.presentationData, content: .info(title: nil, text: self.presentationData.strings.Story_TooltipExpired, timeout: nil), elevatedLayout: false, action: { _ in return true }), in: .current) return } diff --git a/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift b/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift index cc0b7751b3..6ce46af50a 100644 --- a/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift @@ -137,15 +137,14 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { } else { titleString = arguments.strings.User_DeletedAccount } - //TODO:localize isText = false if let storyItem = arguments.parentMessage.associatedStories[story], storyItem.data.isEmpty { isExpiredStory = true - textString = NSAttributedString(string: "Expired story") + textString = NSAttributedString(string: arguments.strings.Chat_ReplyExpiredStory) isMedia = false } else { isStory = true - textString = NSAttributedString(string: "Story") + textString = NSAttributedString(string: arguments.strings.Chat_ReplyStory) isMedia = true } } else { diff --git a/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift index e6cc1345f0..5039ef1c52 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStoryMentionContentNode.swift @@ -194,9 +194,7 @@ class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode { let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: text, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) - //TODO:localize - - let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "View Story", font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) + let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Chat_StoryMentionAction, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets())) let backgroundSize = CGSize(width: width, height: subtitleLayout.size.height + 186.0) diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 6080a8b5bb..15ad5463c6 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -833,12 +833,11 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur navigationController?.pushViewController(storyContainerScreen) }) } else { - //TODO:localize var elevatedLayout = true if case .chat = urlContext { elevatedLayout = false } - present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "story_expired", scale: 0.066, colors: [:], title: nil, text: "This story does not exist", customUndoText: nil, timeout: nil), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in + present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "story_expired", scale: 0.066, colors: [:], title: nil, text: presentationData.strings.Story_TooltipExpired, customUndoText: nil, timeout: nil), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in return true }), nil) } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift index ffb8b71625..3efaf6a169 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift @@ -956,8 +956,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat let title: String switch key { case .stories: - //TODO:localize - title = "Stories" + title = presentationData.strings.PeerInfo_PaneStories case .media: title = presentationData.strings.PeerInfo_PaneMedia case .files: diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 44699bce61..3831a9f6bc 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -792,8 +792,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p } } - //TODO:localize - items[.stories]!.append(PeerInfoScreenDisclosureItem(id: 0, text: "My Stories", icon: PresentationResourcesSettings.stories, action: { + items[.stories]!.append(PeerInfoScreenDisclosureItem(id: 0, text: presentationData.strings.Settings_MyStories, icon: PresentationResourcesSettings.stories, action: { interaction.openSettings(.stories) })) diff --git a/submodules/TelegramUI/Sources/WebpagePreviewAccessoryPanelNode.swift b/submodules/TelegramUI/Sources/WebpagePreviewAccessoryPanelNode.swift index 0257a9b038..2083075499 100644 --- a/submodules/TelegramUI/Sources/WebpagePreviewAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Sources/WebpagePreviewAccessoryPanelNode.swift @@ -141,8 +141,7 @@ final class WebpagePreviewAccessoryPanelNode: AccessoryPanelNode { } else if content.type == "video" { text = stringForMediaKind(.video, strings: self.strings).0.string } else if content.type == "telegram_story" { - //TODO:localize - text = "Story" + text = stringForMediaKind(.story, strings: self.strings).0.string } else if let _ = content.image { text = stringForMediaKind(.image, strings: self.strings).0.string }