Update localization

This commit is contained in:
isaac 2026-04-29 21:23:36 +04:00
parent 53ed837123
commit 301be02a89
9 changed files with 80 additions and 52 deletions

View file

@ -16155,6 +16155,41 @@ Error: %8$@";
"TextProcessing.ResultBadge" = "Result";
"TextProcessing.Translate.LanguageStyle" = "%1$@ (%2$@)";
"TextProcessing.StyleTooltip" = "Select Style";
"TextProcessing.AlertCreatorDeleteStyle.Title" = "Delete Style";
"TextProcessing.AlertCreatorDeleteStyle.Text" = "Are you sure you want to delete this style? It will be removed for everyone who installed it.";
"TextProcessing.AlertDeleteStyle.Title" = "Delete Style";
"TextProcessing.AlertDeleteStyle.Text" = "Are you sure you want to delete this style?";
"TextProcessing.StyleMenu.Edit" = "Edit Style";
"TextProcessing.StyleMenu.Share" = "Share Style";
"TextProcessing.StyleMenu.Delete" = "Delete Style";
"TextProcessing.StyleMenu.ButtonClose" = "Close";
"TextProcessing.StyleMenu.ButtonAdd" = "Add Style";
"TextProcessing.StylePreview.ExampleHeader" = "EXAMPLE";
"TextProcessing.StylePreview.ExampleHeaderRefresh" = "ANOTHER EXAMPLE";
"TextProcessing.StylePreview.Subtitle" = "Add this style to instantly\nrewrite your messages.";
"TextProcessing.StylePreview.Before" = "Before";
"TextProcessing.StylePreview.After" = "After";
"TextProcessing.AlertTooManyStyles.Title" = "Too Many Styles";
"TextProcessing.AlertTooManyStyles.Text" = "Please delete some of your saved styles to create a new one.";
"TextProcessing.ToastStyleCreated.Title" = "%@ style created!";
"TextProcessing.ToastStyleCreated.Text" = "Press and hold a style to edit or share the link.";
"TextProcessing.StyleList.Add" = "Add Style";
"TextProcessing.StyleFooterAuthor" = "Style by [%@]()";
"TextProcessing.StyleFooterUserCount_1" = "Used by 1 person";
"TextProcessing.StyleFooterUserCount_any" = "Used by %d people";
"TextProcessing.StyleFooterCreatedByFormat" = "%1$@. %2$@";
"TextProcessing.StyleFooterCreatedBy" = "Created by [%@]()";
"TextProcessing.StyleFooterCreatedBySimpleFormat" = "%@.";
"TextProcessing.EditStyle.NamePlaceholder" = "Style Name (for example, \"Pirate\")";
"TextProcessing.EditStyle.TextPlaceholder" = "Instructions (for example, \"Write like a swashbuckling pirate. Use arr, ye, matey, and talk about treasure, the sea, and rum\")";
"TextProcessing.EditStyle.TitleCreate" = "New Style";
"TextProcessing.EditStyle.TitleEdit" = "Edit Style";
"TextProcessing.EditStyle.ActionCreate" = "Create";
"TextProcessing.EditStyle.ActionEdit" = "Save";
"TextProcessing.EditStyle.Delete" = "Delete Style";
"TextProcessing.EditStyle.AddLink" = "Add a link to my account";
"TextProcessing.ToastStyleAdded.Title" = "Style Added";
"TextProcessing.ToastStyleAdded.Text" = "Tap 'AI' → '%@' when typing your next long message.";
"Bot.AlertCanNotCreateBots" = "%@ can't manage other bots.";
@ -16256,3 +16291,9 @@ Error: %8$@";
"Settings.ChatAutomation" = "Chat Automation";
"Settings.ChatAutomationInfo" = "Add a bot to reply to messages on your behalf.";
"Settings.ChatAutomationOff" = "Off";
"Chat.SavedMessagesStatusViewAsChats" = "Tap to view as chats";
"Chat.ToastVoiceMessageDeviceMuted" = "Device is muted.";
"VideoChat.StatusPeerJoined" = "%@ joined";
"VideoChat.StatusPeerLeft" = "%@ left";

View file

@ -1911,11 +1911,10 @@ final class VideoChatScreenComponent: Component {
}
}
} else {
//TODO:localized
if event.joined {
self.lastTitleEvent = "\(event.peer.compactDisplayTitle) joined"
self.lastTitleEvent = environment.strings.VideoChat_StatusPeerJoined(event.peer.compactDisplayTitle).string
} else {
self.lastTitleEvent = "\(event.peer.compactDisplayTitle) left"
self.lastTitleEvent = environment.strings.VideoChat_StatusPeerLeft(event.peer.compactDisplayTitle).string
}
if !self.isUpdating {
self.state?.updated(transition: .spring(duration: 0.4))

View file

@ -310,8 +310,8 @@ final class TextProcessingContentComponent: Component {
if style.isCreator {
environment.controller()?.push(textAlertController(
context: component.context,
title: "Delete Style",
text: "Are you sure you want to delete this style? It will be removed for everyone who installed it.",
title: environment.strings.TextProcessing_AlertCreatorDeleteStyle_Title,
text: environment.strings.TextProcessing_AlertCreatorDeleteStyle_Text,
actions: [
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}),
TextAlertAction(type: .destructiveAction, title: environment.strings.Common_Delete, action: { [weak self] in
@ -326,8 +326,8 @@ final class TextProcessingContentComponent: Component {
} else {
environment.controller()?.push(textAlertController(
context: component.context,
title: "Delete Style",
text: "Are you sure you want to delete this style?",
title: environment.strings.TextProcessing_AlertDeleteStyle_Title,
text: environment.strings.TextProcessing_AlertDeleteStyle_Text,
actions: [
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}),
TextAlertAction(type: .destructiveAction, title: environment.strings.Common_Delete, action: { [weak self] in
@ -354,7 +354,7 @@ final class TextProcessingContentComponent: Component {
var items: [ContextMenuItem] = []
if style.isAuthor {
items.append(.action(ContextMenuActionItem(
text: "Edit Style",
text: environment.strings.TextProcessing_StyleMenu_Edit,
icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.contextMenu.primaryColor)
},
@ -369,7 +369,7 @@ final class TextProcessingContentComponent: Component {
))
}
items.append(.action(ContextMenuActionItem(
text: "Share Style", //TODO:localize
text: environment.strings.TextProcessing_StyleMenu_Share,
icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor)
},
@ -383,7 +383,7 @@ final class TextProcessingContentComponent: Component {
})
))
items.append(.action(ContextMenuActionItem(
text: "Delete Style",
text: environment.strings.TextProcessing_StyleMenu_Delete,
textColor: .destructive,
icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
@ -576,7 +576,7 @@ final class TextProcessingContentComponent: Component {
let descriptionSize = previewDescription.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "Add this style to instantly\nrewrite your messages.", font: Font.regular(15.0), textColor: environment.theme.list.itemPrimaryTextColor)),
text: .plain(NSAttributedString(string: environment.strings.TextProcessing_StylePreview_Subtitle, font: Font.regular(15.0), textColor: environment.theme.list.itemPrimaryTextColor)),
horizontalAlignment: .center,
maximumNumberOfLines: 0,
lineSpacing: 0.12
@ -805,7 +805,6 @@ final class TextProcessingContentComponent: Component {
if component.styles.filter({ $0.isAuthor }).count >= maxStyles {
if !hasPremium {
//TODO:localize
let context = component.context
var replaceImpl: ((ViewController) -> Void)?
let controller = context.sharedContext.makePremiumDemoController(context: context, subject: .aiTools, forceDark: false, action: {
@ -824,8 +823,8 @@ final class TextProcessingContentComponent: Component {
} else {
environment.controller()?.push(textAlertController(
context: component.context,
title: "Too Many Styles",
text: "Please delete some of your saved styles to create a new one.",
title: environment.strings.TextProcessing_AlertTooManyStyles_Title,
text: environment.strings.TextProcessing_AlertTooManyStyles_Text,
actions: [
TextAlertAction(type: .defaultAction, title: environment.strings.Common_OK, action: {}),
]
@ -1435,8 +1434,7 @@ private final class TextProcessingSheetComponent: Component {
dismiss(true)
}
case let .preview(style, _, _, isAlreadyAdded, added):
//TODO:localize
actionButtonTitle = isAlreadyAdded ? "Done" : "Add Style"
actionButtonTitle = isAlreadyAdded ? environmentValue.strings.TextProcessing_StyleMenu_ButtonClose : environmentValue.strings.TextProcessing_StyleMenu_ButtonAdd
isMainActionEnabled = !self.isPerformingMainAction
performMainAction = { [weak self] in
guard let self, let component = self.component else {
@ -1797,10 +1795,10 @@ private final class TextProcessingSheetComponent: Component {
)),
content: AnyComponent(VStack([
AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "\(styleCreatedToastData.style.title) style created!", font: Font.semibold(14.0), textColor: .white)),
text: .plain(NSAttributedString(string: environmentValue.strings.TextProcessing_ToastStyleCreated_Title(styleCreatedToastData.style.title).string, font: Font.semibold(14.0), textColor: .white)),
))),
AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
text: .markdown(text: "Press and hold a style to edit or share the link.", attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in nil })),
text: .markdown(text: environmentValue.strings.TextProcessing_ToastStyleCreated_Text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in nil })),
maximumNumberOfLines: 0
)))
], alignment: .left, spacing: 6.0)),

View file

@ -638,11 +638,10 @@ private final class CreateItemComponent: Component {
containerSize: CGSize(width: 100.0, height: 100.0)
)
//TODO:localize
let titleSize = self.title.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "Add Style", font: Font.medium(10.0), textColor: iconTintColor))
text: .plain(NSAttributedString(string: component.strings.TextProcessing_StyleList_Add, font: Font.medium(10.0), textColor: iconTintColor))
)),
environment: {},
containerSize: CGSize(width: availableSize.width, height: 100.0)

View file

@ -382,9 +382,8 @@ final class TextProcessingTranslateContentComponent: Component {
}
toTitle = ""
case .preview:
//TODO:localize
fromFormat = "Before"
toFormat = "After"
fromFormat = component.strings.TextProcessing_StylePreview_Before
toFormat = component.strings.TextProcessing_StylePreview_After
toTitle = ""
}
@ -407,14 +406,12 @@ final class TextProcessingTranslateContentComponent: Component {
}
if case .stylize = component.mode {
//TODO:localize
if case .style = component.externalState.style, let style = component.styles.first(where: { $0.id == component.externalState.style }), let authorPeer = style.authorPeer {
let footerText: String
//TODO:localize
if let addressName = authorPeer.addressName {
footerText = "Style by [@\(addressName)](\(authorPeer.id.toInt64()))"
footerText = component.strings.TextProcessing_StyleFooterAuthor("@" + addressName).string
} else {
footerText = "Style by [\(authorPeer.displayTitle(strings: component.strings, displayOrder: .firstLast))](\(authorPeer.id.toInt64()))"
footerText = component.strings.TextProcessing_StyleFooterAuthor(authorPeer.displayTitle(strings: component.strings, displayOrder: .firstLast)).string
}
component.externalState.sectionFooter = AnyComponentWithIdentity(id: "style_by_\(authorPeer.id.toInt64())", component: AnyComponent(MultilineTextComponent(
text: .markdown(text: footerText, attributes: MarkdownAttributes(
@ -448,7 +445,7 @@ final class TextProcessingTranslateContentComponent: Component {
} else if case let .preview(_, _, authorPeer, userCount, _) = component.mode {
component.externalState.sectionHeader = AnyComponentWithIdentity(id: "preview", component: AnyComponent(HStack([
AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
text: .markdown(text: "EXAMPLE", attributes: MarkdownAttributes(
text: .markdown(text: component.strings.TextProcessing_StylePreview_ExampleHeader, attributes: MarkdownAttributes(
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: component.theme.list.freeTextColor),
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: component.theme.list.freeTextColor),
link: MarkdownAttributeSet(font: Font.regular(13.0), textColor: component.theme.list.itemAccentColor),
@ -464,7 +461,7 @@ final class TextProcessingTranslateContentComponent: Component {
tintColor: component.theme.list.itemAccentColor
))),
AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "ANOTHER EXAMPLE", font: Font.regular(13.0), textColor: component.theme.list.itemAccentColor))
text: .plain(NSAttributedString(string: component.strings.TextProcessing_StylePreview_ExampleHeaderRefresh, font: Font.regular(13.0), textColor: component.theme.list.itemAccentColor))
)))
], spacing: 2.0)),
action: { [weak self] in
@ -478,18 +475,17 @@ final class TextProcessingTranslateContentComponent: Component {
))),
], spacing: 8.0, alignment: .alternatingLeftRight)))
let userCountString = userCount == 1 ? "Used by 1 person" : "Used by \(userCount) people"
let userCountString = component.strings.TextProcessing_StyleFooterUserCount(Int32(userCount))
let footerText: String
//TODO:localize
if let authorPeer {
if let addressName = authorPeer.addressName {
footerText = "\(userCountString). Created by [@\(addressName)](\(authorPeer.id.toInt64()))"
footerText = component.strings.TextProcessing_StyleFooterCreatedByFormat(userCountString, component.strings.TextProcessing_StyleFooterCreatedBy("@" + addressName).string).string
} else {
footerText = "\(userCountString). Created by [\(authorPeer.displayTitle(strings: component.strings, displayOrder: .firstLast))](\(authorPeer.id.toInt64()))"
footerText = component.strings.TextProcessing_StyleFooterCreatedByFormat(userCountString, component.strings.TextProcessing_StyleFooterCreatedBy(authorPeer.displayTitle(strings: component.strings, displayOrder: .firstLast)).string).string
}
} else {
footerText = "\(userCountString)."
footerText = component.strings.TextProcessing_StyleFooterCreatedBySimpleFormat(userCountString).string
}
component.externalState.sectionFooter = AnyComponentWithIdentity(id: "style_by_\(authorPeer?.id.toInt64() ?? 0)", component: AnyComponent(MultilineTextComponent(
text: .markdown(text: footerText, attributes: MarkdownAttributes(

View file

@ -335,7 +335,6 @@ final class TextStyleEditContentComponent: Component {
contentHeight += iconBackgroundSize.height + iconSpacing
//TODO:localize
var titleSectionItems: [AnyComponentWithIdentity<Empty>] = []
titleSectionItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(ListMultilineTextFieldItemComponent(
externalState: component.externalState.titleInputState,
@ -347,7 +346,7 @@ final class TextStyleEditContentComponent: Component {
resetText: resetTitle.flatMap { resetTitle in
return ListMultilineTextFieldItemComponent.ResetText(value: resetTitle)
},
placeholder: "Style Name (for example, \"Pirate\")",
placeholder: environment.strings.TextProcessing_EditStyle_NamePlaceholder,
autocapitalizationType: .sentences,
autocorrectionType: .default,
characterLimit: 12,
@ -379,7 +378,6 @@ final class TextStyleEditContentComponent: Component {
contentHeight += titleSectionSize.height
contentHeight += sectionSpacing
//TODO:localize
var textSectionItems: [AnyComponentWithIdentity<Empty>] = []
textSectionItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(ListMultilineTextFieldItemComponent(
externalState: component.externalState.textInputState,
@ -391,7 +389,7 @@ final class TextStyleEditContentComponent: Component {
resetText: resetText.flatMap { resetText in
return ListMultilineTextFieldItemComponent.ResetText(value: resetText)
},
placeholder: "Instructions (for example, \"Write like a swashbuckling pirate. Use arr, ye, matey, and talk about treasure, the sea, and rum\")",
placeholder: environment.strings.TextProcessing_EditStyle_TextPlaceholder,
placeholderDefinesMinHeight: true,
autocapitalizationType: .sentences,
autocorrectionType: .default,
@ -439,7 +437,7 @@ final class TextStyleEditContentComponent: Component {
title: AnyComponent(VStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: "Delete Style",
string: environment.strings.TextProcessing_EditStyle_Delete,
font: Font.regular(17.0),
textColor: environment.theme.list.itemDestructiveColor
)),
@ -453,8 +451,8 @@ final class TextStyleEditContentComponent: Component {
}
environment.controller()?.push(textAlertController(
context: component.context,
title: "Delete Style",
text: "Are you sure you want to delete this style? It will be removed for everyone who installed it.",
title: environment.strings.TextProcessing_AlertCreatorDeleteStyle_Title,
text: environment.strings.TextProcessing_AlertCreatorDeleteStyle_Text,
actions: [
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {}),
TextAlertAction(type: .destructiveAction, title: environment.strings.Common_Delete, action: { [weak self] in
@ -503,7 +501,7 @@ final class TextStyleEditContentComponent: Component {
selected: component.externalState.isLinkToProfileEnabled
))),
AnyComponentWithIdentity(id: AnyHashable(1), component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "Add a link to my account", font: Font.regular(13.0), textColor: environment.theme.list.freeTextColor))
text: .plain(NSAttributedString(string: environment.strings.TextProcessing_EditStyle_AddLink, font: Font.regular(13.0), textColor: environment.theme.list.freeTextColor))
)))
], spacing: 10.0)),
effectAlignment: .center,
@ -779,11 +777,11 @@ private final class TextStyleEditSheetComponent: Component {
let titleString: String
switch component.mode {
case .create:
titleString = "New Style"
actionButtonTitle = "Create"
titleString = environmentValue.strings.TextProcessing_EditStyle_TitleCreate
actionButtonTitle = environmentValue.strings.TextProcessing_EditStyle_ActionCreate
case .edit:
titleString = "Edit Style"
actionButtonTitle = "Save"
titleString = environmentValue.strings.TextProcessing_EditStyle_TitleEdit
actionButtonTitle = environmentValue.strings.TextProcessing_EditStyle_ActionEdit
}
let sheetSize = self.sheet.update(

View file

@ -609,8 +609,7 @@ extension ChatControllerImpl {
} else {
var customSubtitle: String?
if savedMessagesChatsTip {
//TODO:localize
customSubtitle = "Tap to view as chats"
customSubtitle = strings.Chat_SavedMessagesStatusViewAsChats
}
strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, customSubtitle: customSubtitle, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, hidePeerStatus: false, isEnabled: hasPeerInfo)

View file

@ -330,8 +330,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
} |> take(1) |> timeout(1.0, queue: .mainQueue(), alternate: .single(false)) |> deliverOnMainQueue).startStandalone(next: { value in
if value {
let presentationData = params.context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
let toastController = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: "Device is muted.", timeout: 4.0, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
let toastController = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Chat_ToastVoiceMessageDeviceMuted, timeout: 4.0, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
return true
})
params.present(toastController, nil, .current)

View file

@ -2054,8 +2054,7 @@ func openResolvedUrlImpl(
guard let emojiFileId = style.emojiFileId, let file = await context.engine.stickers.resolveInlineStickers(fileIds: [emojiFileId]).get().first?.value else {
return
}
//TODO:localize
present(UndoOverlayController(presentationData: presentationData, content: .customEmoji(context: context, file: file, loop: false, title: "Style Added", text: "Tap 'AI' → '\(style.title)' when typing your next long message.", undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
present(UndoOverlayController(presentationData: presentationData, content: .customEmoji(context: context, file: file, loop: false, title: presentationData.strings.TextProcessing_ToastStyleAdded_Title, text: presentationData.strings.TextProcessing_ToastStyleAdded_Text(style.title).string, undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
return true
}), nil)
}