diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 84d31a91ec..feacd249f6 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -10152,3 +10152,48 @@ Sorry for the inconvenience."; "Chat.ErrorQuoteOutdatedActionEdit" = "Edit"; "Premium.BoostByGiftDescription" = "Boost your channel by gifting your subscribers Telegram Premium. [Get boosts >]()"; + +"ChatContextMenu.QuoteSelectionTip" = "Hold on a word, then move cursor to select more| text to quote."; + +"Chat.ReplyPanel.ReplyToQuoteBy" = "Reply to Quote by %@"; +"Chat.ReplyPanel.ReplyTo" = "Reply to %@"; +"Chat.ReplyPanel.AccessibilityReplyToMessageFrom" = "Reply to message. From: %@"; +"Chat.ReplyPanel.AccessibilityReplyToYourMessage" = "Reply to your message."; +"Chat.ReplyPanel.AccessibilityReplyToMessage" = "Reply to message."; +"Chat.ReplyPanel.HintReplyOptions" = "Tap here for reply options"; +"Chat.ReplyPanel.HintReplyOptionsShort" = "Tap here for options"; + +"Chat.ToastQuoteChatUnavailbalePrivateChannel" = "This quote is from a private channel"; +"Chat.ToastQuoteChatUnavailbalePrivateGroup" = "This quote is from a private group"; +"Chat.ToastQuoteChatUnavailbalePrivateChat" = "This quote is from a private chat"; + +"Chat.TitleQuoteSelection" = "Reply to Quote"; +"Chat.TitleReply" = "Reply to Message"; +"Chat.TitleLinkOptions" = "Link Preview Settings"; +"Chat.SubtitleQuoteSelectionTip" = "You can select a specific part to quote"; +"Chat.SubtitleLinkListTip" = "Tap on a link to generate its preview"; + +"Chat.ToastQuoteNotFound" = "Quote not found"; + +"TextFormat.Quote" = "Quote"; + +"TextSelection.SelectAll" = "Select All"; + +"Conversation.MessageOptionsApplyChanges" = "Apply Changes"; +"Conversation.ForwardOptionsCancel" = "Do Not Forward"; +"Conversation.MessageOptionsTabForward" = "Forward"; +"Conversation.MessageOptionsQuoteSelectedPart" = "Quote Selected Part"; +"Conversation.MessageOptionsQuoteSelect" = "Select Specific Quote"; +"Conversation.MessageOptionsQuoteRemove" = "Remove Quote"; +"Conversation.MessageOptionsReplyInAnotherChat" = "Reply in Another Chat"; +"Conversation.MessageOptionsReplyCancel" = "Do Not Reply"; +"Conversation.MessageOptionsTabReply" = "Reply"; +"Conversation.MoveReplyToAnotherChatTitle" = "Reply in..."; +"Conversation.MessageOptionsLinkMoveUp" = "Move Up"; +"Conversation.MessageOptionsLinkMoveDown" = "Move Down"; +"Conversation.MessageOptionsShrinkImage" = "Shrink Photo"; +"Conversation.MessageOptionsEnlargeImage" = "Enlarge Photo"; +"Conversation.MessageOptionsShrinkVideo" = "Shrink Video"; +"Conversation.MessageOptionsEnlargeVideo" = "Enlarge Video"; +"Conversation.LinkOptionsCancel" = "Do Not Preview"; +"Conversation.MessageOptionsTabLink" = "Link"; diff --git a/submodules/ContextUI/Sources/ContextActionsContainerNode.swift b/submodules/ContextUI/Sources/ContextActionsContainerNode.swift index 5b303a74f5..59f89de751 100644 --- a/submodules/ContextUI/Sources/ContextActionsContainerNode.swift +++ b/submodules/ContextUI/Sources/ContextActionsContainerNode.swift @@ -404,8 +404,7 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode { } icon = UIImage(bundleImageName: "Chat/Context Menu/Tip") case .quoteSelection: - //TODO:localize - var rawText = "Hold on a word, then move cursor to select more| text to quote." + var rawText = presentationData.strings.ChatContextMenu_QuoteSelectionTip if let range = rawText.range(of: "|") { rawText.removeSubrange(range) self.text = rawText diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift index da1b9037a8..dd17d394cf 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift @@ -318,8 +318,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { titleString = NSAttributedString(string: rawTitleString, font: titleFont, textColor: titleColor) } - //TODO:localize - textString = NSAttributedString(string: replyForward.quote?.text ?? "Message") + textString = NSAttributedString(string: replyForward.quote?.text ?? arguments.presentationData.strings.VoiceOver_ChatList_Message) if let media = replyForward.quote?.media { if let text = replyForward.quote?.text, !text.isEmpty { } else { @@ -327,7 +326,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { let (string, _) = stringForMediaKind(contentKind, strings: arguments.strings) textString = string } else { - textString = NSAttributedString(string: "Message") + textString = NSAttributedString(string: arguments.presentationData.strings.VoiceOver_ChatList_Message) } } isMedia = true diff --git a/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift b/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift index 101a027a0a..28ebc31ffb 100644 --- a/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ReplyAccessoryPanelNode/Sources/ReplyAccessoryPanelNode.swift @@ -242,26 +242,33 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode { let icon: UIImage? icon = UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextChannelIcon")?.withRenderingMode(.alwaysTemplate) - //TODO:localize - if let _ = strongSelf.quote { - if let icon { - let string = "Reply to Quote by " - titleText = [.text(NSAttributedString(string: string, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))] - titleText.append(.icon(icon)) - titleText.append(.text(NSAttributedString(string: peer.debugDisplayTitle, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))) + if let icon { + let rawString: PresentationStrings.FormattedString + if strongSelf.quote != nil { + rawString = strongSelf.strings.Chat_ReplyPanel_ReplyToQuoteBy(peer.debugDisplayTitle) + } else { + rawString = strongSelf.strings.Chat_ReplyPanel_ReplyTo(peer.debugDisplayTitle) } - } else { - if let icon { - let string = "Reply to " - titleText = [.text(NSAttributedString(string: string, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))] + if let nameRange = rawString.ranges.first { + titleText = [] + + let rawNsString = rawString.string as NSString + if nameRange.range.lowerBound != 0 { + titleText.append(.text(NSAttributedString(string: rawNsString.substring(with: NSRange(location: 0, length: nameRange.range.lowerBound)), font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))) + } titleText.append(.icon(icon)) titleText.append(.text(NSAttributedString(string: peer.debugDisplayTitle, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))) + + if nameRange.range.upperBound != rawNsString.length { + titleText.append(.text(NSAttributedString(string: rawNsString.substring(with: NSRange(location: nameRange.range.upperBound, length: rawNsString.length - nameRange.range.upperBound)), font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))) + } + } else { + titleText.append(.text(NSAttributedString(string: rawString.string, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))) } } } else { if let _ = strongSelf.quote { - //TODO:localize - let string = "Reply to Quote by \(authorName)" + let string = strongSelf.strings.Chat_ReplyPanel_ReplyToQuoteBy(authorName).string titleText = [.text(NSAttributedString(string: string, font: Font.medium(15.0), textColor: strongSelf.theme.chat.inputPanel.panelControlAccentColor))] } else { let string = strongSelf.strings.Conversation_ReplyMessagePanelTitle(authorName).string @@ -297,11 +304,11 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode { let headerString: String if let message = message, message.flags.contains(.Incoming), let author = message.author { - headerString = "Reply to message. From: \(EnginePeer(author).displayTitle(strings: strings, displayOrder: nameDisplayOrder))" + headerString = strongSelf.strings.Chat_ReplyPanel_AccessibilityReplyToMessageFrom(EnginePeer(author).displayTitle(strings: strings, displayOrder: nameDisplayOrder)).string } else if let message = message, !message.flags.contains(.Incoming) { - headerString = "Reply to your message" + headerString = strongSelf.strings.Chat_ReplyPanel_AccessibilityReplyToYourMessage } else { - headerString = "Reply to message" + headerString = strongSelf.strings.Chat_ReplyPanel_AccessibilityReplyToMessage } strongSelf.actionArea.accessibilityLabel = "\(headerString).\n\(text)" @@ -326,11 +333,10 @@ public final class ReplyAccessoryPanelNode: AccessoryPanelNode { Queue.mainQueue().after(3.0) { if let snapshotView = strongSelf.textNode.view.snapshotContentTree() { let text: String - //TODO:localize if let (size, _, _) = strongSelf.validLayout, size.width > 320.0 { - text = "Tap here for reply options" + text = strongSelf.strings.Chat_ReplyPanel_HintReplyOptions } else { - text = "Tap here for forwarding options" + text = strongSelf.strings.Chat_ReplyPanel_HintReplyOptionsShort } strongSelf.textIsOptions = true diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index ecdbe06690..333e6297dc 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -2708,8 +2708,6 @@ public final class StoryItemSetContainerComponent: Component { let inputPlaceholder: MessageInputPanelComponent.Placeholder if let stealthModeTimeout = component.stealthModeTimeout { - //TODO:localize - let minutes = Int(stealthModeTimeout / 60) let seconds = Int(stealthModeTimeout % 60) diff --git a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift index 2a034732cb..cc72586e4a 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift @@ -229,28 +229,11 @@ private func chatForwardOptions(selfController: ChatControllerImpl, sourceNode: f(.default) }))) - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Apply Changes", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_MessageOptionsApplyChanges, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in f(.default) }))) - /*items.append(.action(ContextMenuActionItem(text: messagesCount == 1 ? presentationData.strings.Conversation_ForwardOptions_SendMessage : presentationData.strings.Conversation_ForwardOptions_SendMessages, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController, weak chatController] c, f in - guard let selfController else { - return - } - if let selectedMessageIds = (chatController as? ChatControllerImpl)?.selectedMessageIds { - var forwardMessageIds = selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? [] - forwardMessageIds = forwardMessageIds.filter { selectedMessageIds.contains($0) } - selfController.updateChatPresentationInterfaceState(interactive: false, { $0.updatedInterfaceState({ $0.withUpdatedForwardMessageIds(forwardMessageIds) }) }) - } - - selfController.controllerInteraction?.sendCurrentMessage(false) - - f(.default) - })))*/ - - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Do Not Forward", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptionsCancel, textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in f(.default) guard let selfController else { @@ -273,10 +256,9 @@ private func chatForwardOptions(selfController: ChatControllerImpl, sourceNode: } } - //TODO:localize return (ContextController.Source( id: AnyHashable(OptionsId.forward), - title: "Forward", + title: selfController.presentationData.strings.Conversation_MessageOptionsTabForward, source: .controller(ChatContextControllerContentSourceImpl(controller: chatController, sourceNode: sourceNode, passthroughTouches: true)), items: items |> map { ContextController.Items(id: AnyHashable("forward"), content: .list($0)) } ), dismissedForCancel) @@ -304,8 +286,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch var items: [ContextMenuItem] = [] if replySubject.quote != nil { - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Quote Selected Part", icon: { theme in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsQuoteSelectedPart, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/QuoteSelected"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController, weak chatController] _, f in guard let selfController, let chatController else { @@ -345,8 +326,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch f(.default) }))) } else if let message = messages.first, !message.text.isEmpty { - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Select Specific Quote", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Quote"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController, weak chatController] c, _ in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsQuoteSelect, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Quote"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController, weak chatController] c, _ in guard let selfController, let chatController else { return } @@ -371,8 +351,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch }))) subItems.append(.separator) - //TODO:localize - subItems.append(.action(ContextMenuActionItem(text: "Quote Selected Part", icon: { theme in + subItems.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsQuoteSelectedPart, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/QuoteSelected"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController, weak contentNode] _, f in guard let selfController, let contentNode else { @@ -438,8 +417,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch } if canReplyInAnotherChat { - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Reply in Another Chat", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Replace"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsReplyInAnotherChat, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Replace"), color: theme.contextMenu.primaryColor) }, action: { [weak selfController] c, f in f(.default) guard let selfController else { @@ -455,13 +433,13 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch if !items.isEmpty { items.append(.separator) - items.append(.action(ContextMenuActionItem(text: "Apply Changes", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsApplyChanges, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in f(.default) }))) } if replySubject.quote != nil { - items.append(.action(ContextMenuActionItem(text: "Remove Quote", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/QuoteRemove"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsQuoteRemove, textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/QuoteRemove"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in f(.default) guard let selfController else { @@ -472,7 +450,7 @@ private func generateChatReplyOptionItems(selfController: ChatControllerImpl, ch selfController.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withUpdatedReplyMessageSubject(replySubject).withoutSelectionState() }).updatedSearch(nil) }) }))) } else { - items.append(.action(ContextMenuActionItem(text: "Do Not Reply", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsReplyCancel, textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController] c, f in f(.default) guard let selfController else { @@ -539,10 +517,9 @@ private func chatReplyOptions(selfController: ChatControllerImpl, sourceNode: AS selfController.controllerInteraction?.performTextSelectionAction(message, canCopy, text, action) } - //TODO:localize return ContextController.Source( id: AnyHashable(OptionsId.reply), - title: "Reply", + title: selfController.presentationData.strings.Conversation_MessageOptionsTabReply, source: .controller(ChatContextControllerContentSourceImpl(controller: chatController, sourceNode: sourceNode, passthroughTouches: true)), items: items ) @@ -564,7 +541,7 @@ func moveReplyMessageToAnotherChat(selfController: ChatControllerImpl, replySubj updatedPresentationData: selfController.updatedPresentationData, filter: filter, hasFilters: true, - title: "Reply in...", //TODO:localize + title: selfController.presentationData.strings.Conversation_MoveReplyToAnotherChatTitle, attemptSelection: { peer, _ in attemptSelectionImpl?(peer) }, @@ -759,8 +736,7 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD var items: [ContextMenuItem] = [] do { - //TODO:localize - items.append(.action(ContextMenuActionItem(text: linkOptions.linkBelowText ? "Move Up" : "Move Down", icon: { theme in + items.append(.action(ContextMenuActionItem(text: linkOptions.linkBelowText ? selfController.presentationData.strings.Conversation_MessageOptionsLinkMoveUp : selfController.presentationData.strings.Conversation_MessageOptionsLinkMoveDown, icon: { theme in return nil }, iconAnimation: ContextMenuActionItem.IconAnimation( name: linkOptions.linkBelowText ? "message_preview_sort_above" : "message_preview_sort_below" @@ -784,15 +760,14 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD } if case let .Loaded(content) = linkOptions.webpage.content, let isMediaLargeByDefault = content.isMediaLargeByDefault, isMediaLargeByDefault { - //TODO:localize let shrinkTitle: String let enlargeTitle: String if let file = content.file, file.isVideo { - shrinkTitle = "Shrink Video" - enlargeTitle = "Enlarge Video" + shrinkTitle = selfController.presentationData.strings.Conversation_MessageOptionsShrinkVideo + enlargeTitle = selfController.presentationData.strings.Conversation_MessageOptionsEnlargeVideo } else { - shrinkTitle = "Shrink Photo" - enlargeTitle = "Enlarge Photo" + shrinkTitle = selfController.presentationData.strings.Conversation_MessageOptionsShrinkImage + enlargeTitle = selfController.presentationData.strings.Conversation_MessageOptionsEnlargeImage } items.append(.action(ContextMenuActionItem(text: linkOptions.largeMedia ? shrinkTitle : enlargeTitle, icon: { _ in @@ -830,13 +805,11 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD items.append(.separator) } - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Apply Changes", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_MessageOptionsApplyChanges, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in f(.default) }))) - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Do Not Preview", textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController, weak chatController] c, f in + items.append(.action(ContextMenuActionItem(text: selfController.presentationData.strings.Conversation_LinkOptionsCancel, textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak selfController, weak chatController] c, f in guard let selfController else { return } @@ -921,10 +894,9 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD } } - //TODO:localize return ContextController.Source( id: AnyHashable(OptionsId.link), - title: "Link", + title: selfController.presentationData.strings.Conversation_MessageOptionsTabLink, source: .controller(ChatContextControllerContentSourceImpl(controller: chatController, sourceNode: sourceNode, passthroughTouches: true)), items: items ) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index ab7577dde6..9fc6b7473c 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -4950,18 +4950,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let self else { return } - //TODO:localize let text: String if let peer = peer as? TelegramChannel { if case .broadcast = peer.info { - text = "This quote is from a private channel" + text = self.presentationData.strings.Chat_ToastQuoteChatUnavailbalePrivateChannel } else { - text = "This quote is from a private group" + text = self.presentationData.strings.Chat_ToastQuoteChatUnavailbalePrivateGroup } } else if peer is TelegramGroup { - text = "This quote is from a private group" + text = self.presentationData.strings.Chat_ToastQuoteChatUnavailbalePrivateGroup } else { - text = "This quote is from a private chat" + text = self.presentationData.strings.Chat_ToastQuoteChatUnavailbalePrivateChat } self.controllerInteraction?.displayUndo(.info(title: nil, text: text, timeout: nil, customUndoText: nil)) }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: self.stickerSettings, presentationContext: ChatPresentationContext(context: context, backgroundNode: self.chatBackgroundNode)) @@ -5294,15 +5293,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if !selectionState.canQuote { return nil } - //TODO:localize - return "You can select a specific part to quote" + return presentationData.strings.Chat_SubtitleQuoteSelectionTip } case let .link(link): subtitleTextSignal = link.options |> map { options -> String? in if options.hasAlternativeLinks { - //TODO:localize - return "Tap on a link to generate its preview" + return presentationData.strings.Chat_SubtitleLinkListTip } else { return nil } @@ -5354,12 +5351,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let peer = peerViewMainPeer(peerView) { if case let .messageOptions(_, _, info) = presentationInterfaceState.subject { if case .reply = info { - //TODO:localize let titleContent: ChatTitleContent if case let .reply(hasQuote) = messageOptionsTitleInfo, hasQuote { - titleContent = .custom("Reply to Quote", subtitleText, false) + titleContent = .custom(presentationInterfaceState.strings.Chat_TitleQuoteSelection, subtitleText, false) } else { - titleContent = .custom("Reply to Message", subtitleText, false) + titleContent = .custom(presentationInterfaceState.strings.Chat_TitleReply, subtitleText, false) } if strongSelf.chatTitleView?.titleContent != titleContent { if strongSelf.chatTitleView?.titleContent != nil { @@ -5368,8 +5364,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.chatTitleView?.titleContent = titleContent } } else if case .link = info { - //TODO:localize - strongSelf.chatTitleView?.titleContent = .custom("Link Preview Settings", subtitleText, false) + strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Chat_TitleLinkOptions, subtitleText, false) } else if displayedCount == 1 { strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_ForwardOptions_ForwardTitleSingle, subtitleText, false) } else { @@ -8033,8 +8028,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if message.text.contains(quote) { hasQuote = true } else { - //TODO:localize - strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(title: nil, text: "Quote not found", timeout: nil, customUndoText: nil), elevatedLayout: false, action: { _ in return true }), in: .current) + strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(title: nil, text: strongSelf.presentationData.strings.Chat_ToastQuoteNotFound, timeout: nil, customUndoText: nil), elevatedLayout: false, action: { _ in return true }), in: .current) } } diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 5f43c18512..417c5e2f8e 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -3401,7 +3401,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { } if !found { - //TODO:localize let authorName: String = (replyMessage.author.flatMap(EnginePeer.init))?.compactDisplayTitle ?? "" let errorTextData = self.chatPresentationInterfaceState.strings.Chat_ErrorQuoteOutdatedText(authorName) let errorText = errorTextData.string diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index 5c5abd156f..f073a2adf6 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -3710,8 +3710,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch var children: [UIAction] = [] - //TODO:localize - children.append(UIAction(title: "Quote", image: nil) { [weak self] (action) in + children.append(UIAction(title: self.strings?.TextFormat_Quote ?? "Quote", image: nil) { [weak self] (action) in if let strongSelf = self { strongSelf.formatAttributesQuote(strongSelf) } diff --git a/submodules/TextSelectionNode/Sources/TextSelectionNode.swift b/submodules/TextSelectionNode/Sources/TextSelectionNode.swift index 90cab9a5af..fd6cf39c1a 100644 --- a/submodules/TextSelectionNode/Sources/TextSelectionNode.swift +++ b/submodules/TextSelectionNode/Sources/TextSelectionNode.swift @@ -740,8 +740,7 @@ public final class TextSelectionNode: ASDisplayNode { let realFullRange = NSRange(location: 0, length: attributedString.length) if range != realFullRange { - //TODO:localize - actions.append(ContextMenuAction(content: .text(title: "Select All", accessibilityLabel: "Select All"), action: { [weak self] in + actions.append(ContextMenuAction(content: .text(title: self.strings.TextSelection_SelectAll, accessibilityLabel: self.strings.TextSelection_SelectAll), action: { [weak self] in guard let self else { return }