Update localization

This commit is contained in:
Isaac 2025-12-02 22:15:52 +08:00
parent 62d29ee551
commit 3b02aeae9d
9 changed files with 64 additions and 38 deletions

View file

@ -15506,3 +15506,31 @@ Error: %8$@";
"Gift.Auction.Extension" = "+ %1$@ for late bids in top %2$@";
"ChatList.Auctions.UpcomingAuction" = "Upcoming Auction";
"Login.PhoneWithPasskeySubtitle" = "Enter your phone number\nor [log in using Passkey >](passkey)";
"PrivacySettings.Passkey" = "Passkey";
"Attachment.SharedAudio" = "SHARED AUDIO";
"Attachment.FilesSearchPlaceholder" = "Search shared audio";
"Chat.GiftPurchaseOffer.Reject" = "Reject";
"Chat.GiftPurchaseOffer.Accept" = "Accept";
"Passkeys.DeleteAlert.Title" = "Delete Passkey?";
"Passkeys.DeleteAlert.Text" = "Once deleted, this passkey can't be used to log in.\n\nDon't forget to remove it from your password manager too.";
"Passkeys.DeleteAlert.Action" = "Delete";
"Passkeys.Into.Title" = "Protect your account";
"Passkeys.Subtitle" = "Log in safely and keep your account secure.";
"Passkeys.Into.Title0" = "Create a Passkey";
"Passkeys.Into.Text0" = "Make a passkey to sign in easily and safely.";
"Passkeys.Into.Title1" = "Log in with Face ID";
"Passkeys.Into.Text1" = "Use Face ID, Touch ID, or your passcode to sign in.";
"Passkeys.Into.Title2" = "Store Passkey Securely";
"Passkeys.Into.Text2" = "Your passkey is safely kept in your iCloud Keychain.";
"Passkeys.ButtonCreate" = "Create Passkey";
"Passkeys.ButtonSkip" = "Skip";
"Passkeys.Title" = "Passkeys";
"Passkeys.Subtitle" = "Log in safely and keep your account secure.";
"Passkeys.EmptyName" = "Passkey";
"Passkeys.PasskeyCreatedPattern" = "created %@";
"Passkeys.PasskeyCreatedAndUsedPattern" = "created %1$@ • used %2$@";
"Passkeys.AddPasskey" = "Create Passkey";
"Passkeys.ListFooter" = "Your passkeys are stored securely in your password manager.";

View file

@ -576,11 +576,10 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
}
func updateDisplayPasskeyLoginOption() {
//TODO:localize
if self.account == nil {
return
}
let attributedText = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("Enter your phone number\nor [log in using Passkey >](passkey)", attributes: MarkdownAttributes(
let attributedText = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(self.strings.Login_PhoneWithPasskeySubtitle, attributes: MarkdownAttributes(
body: MarkdownAttributeSet(font: Font.regular(17.0), textColor: self.theme.list.itemPrimaryTextColor),
bold: MarkdownAttributeSet(font: Font.semibold(17.0), textColor: self.theme.list.itemPrimaryTextColor),
link: MarkdownAttributeSet(font: Font.regular(17.0), textColor: self.theme.list.itemAccentColor),
@ -607,7 +606,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
let titleInset: CGFloat = layout.size.width > 320.0 ? 18.0 : 0.0
let additionalBottomInset: CGFloat = layout.size.width > 320.0 ? 80.0 : 10.0
self.titleNode.attributedText = NSAttributedString(string: self.account == nil ? strings.Login_NewNumber : strings.Login_PhoneTitle, font: Font.bold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
self.titleNode.attributedText = NSAttributedString(string: self.account == nil ? self.strings.Login_NewNumber : self.strings.Login_PhoneTitle, font: Font.bold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
self.titleActivateAreaNode.accessibilityLabel = self.titleNode.attributedText?.string ?? ""
let inset: CGFloat = 24.0

View file

@ -673,12 +673,11 @@ private func privacyAndSecurityControllerEntries(
entries.append(.twoStepVerification(presentationData.theme, presentationData.strings.PrivacySettings_TwoStepAuth, twoStepAuthString, twoStepAuthData))
if displayPasskeys {
//TODO:localize
var passkeysString = ""
if let hasPasskeys = hasPasskeys {
passkeysString = hasPasskeys ? "On" : "Off"
passkeysString = hasPasskeys ? presentationData.strings.PrivacySettings_PasscodeOn : presentationData.strings.PrivacySettings_PasscodeOff
}
entries.append(.passkeys(presentationData.theme, "Passkey", passkeysString))
entries.append(.passkeys(presentationData.theme, presentationData.strings.PrivacySettings_Passkey, passkeysString))
}
if let privacySettings = privacySettings {

View file

@ -207,8 +207,7 @@ private func attachmentFileControllerEntries(presentationData: PresentationData,
case .recent:
listTitle = presentationData.strings.Attachment_RecentlySentFiles
case .audio:
//TODO:localize
listTitle = "SHARED AUDIO"
listTitle = presentationData.strings.Attachment_SharedAudio
}
if case .audio = mode {

View file

@ -138,7 +138,6 @@ private final class AttachmentFileSearchItemNode: ItemListControllerSearchNode {
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight), size: CGSize(width: layout.size.width, height: layout.size.height - navigationBarHeight)))
self.containerNode.containerLayoutUpdated(layout.withUpdatedSize(CGSize(width: layout.size.width, height: layout.size.height - navigationBarHeight)), navigationBarHeight: 0.0, transition: transition)
//TODO:localize
let searchInputSize = self.searchInput.update(
transition: .immediate,
component: AnyComponent(
@ -147,7 +146,7 @@ private final class AttachmentFileSearchItemNode: ItemListControllerSearchNode {
strings: self.presentationData.strings,
metrics: layout.metrics,
safeInsets: layout.safeInsets,
placeholder: self.mode == .audio ? "Search shared audio" : self.presentationData.strings.Attachment_FilesSearchPlaceholder,
placeholder: self.mode == .audio ? self.presentationData.strings.Attachment_FilesSearchPlaceholder : self.presentationData.strings.Attachment_FilesSearchPlaceholder,
updated: { [weak self] query in
guard let self else {
return

View file

@ -2844,7 +2844,6 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
icon: .suggestedPostApprove
)
]
//TODO:localize
let (minWidth, buttonsLayout) = actionButtonsLayout(
item.context,
item.presentationData.theme,
@ -2854,8 +2853,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
ReplyMarkupMessageAttribute(
rows: [
ReplyMarkupRow(buttons: [
ReplyMarkupButton(title: "Reject", titleWhenForwarded: nil, action: .callback(requiresPassword: false, data: buttonDecline)),
ReplyMarkupButton(title: "Accept", titleWhenForwarded: nil, action: .callback(requiresPassword: false, data: buttonApprove))
ReplyMarkupButton(title: item.presentationData.strings.Chat_GiftPurchaseOffer_Reject, titleWhenForwarded: nil, action: .callback(requiresPassword: false, data: buttonDecline)),
ReplyMarkupButton(title: item.presentationData.strings.Chat_GiftPurchaseOffer_Accept, titleWhenForwarded: nil, action: .callback(requiresPassword: false, data: buttonApprove))
])
],
flags: [],

View file

@ -180,9 +180,8 @@ final class PasskeysScreenComponent: Component {
return
}
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
//TODO:localize
controller.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Delete Passkey?", text: "Once deleted, this passkey can't be used to log in.\n\nDon't forget to remove it from your password manager too.", actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
}), TextAlertAction(type: .destructiveAction, title: "Delete", action: { [weak self] in
controller.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: environment.strings.Passkeys_DeleteAlert_Title, text: environment.strings.Passkeys_DeleteAlert_Text, actions: [TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {
}), TextAlertAction(type: .destructiveAction, title: environment.strings.Passkeys_DeleteAlert_Action, action: { [weak self] in
guard let self else {
return
}
@ -266,6 +265,7 @@ final class PasskeysScreenComponent: Component {
component: AnyComponent(PasskeysScreenIntroComponent(
context: component.context,
theme: environment.theme,
strings: environment.strings,
insets: UIEdgeInsets(top: environment.statusBarHeight + environment.navigationHeight, left: 0.0, bottom: environment.safeInsets.bottom, right: 0.0),
displaySkip: component.displaySkip,
createPasskeyAction: { [weak self] in

View file

@ -13,6 +13,7 @@ import BundleIconComponent
final class PasskeysScreenIntroComponent: Component {
let context: AccountContext
let theme: PresentationTheme
let strings: PresentationStrings
let insets: UIEdgeInsets
let displaySkip: Bool
let createPasskeyAction: () -> Void
@ -21,6 +22,7 @@ final class PasskeysScreenIntroComponent: Component {
init(
context: AccountContext,
theme: PresentationTheme,
strings: PresentationStrings,
insets: UIEdgeInsets,
displaySkip: Bool,
createPasskeyAction: @escaping () -> Void,
@ -28,6 +30,7 @@ final class PasskeysScreenIntroComponent: Component {
) {
self.context = context
self.theme = theme
self.strings = strings
self.insets = insets
self.displaySkip = displaySkip
self.createPasskeyAction = createPasskeyAction
@ -41,6 +44,9 @@ final class PasskeysScreenIntroComponent: Component {
if lhs.theme !== rhs.theme {
return false
}
if lhs.strings !== rhs.strings {
return false
}
if lhs.insets != rhs.insets {
return false
}
@ -120,7 +126,6 @@ final class PasskeysScreenIntroComponent: Component {
var contentHeight: CGFloat = 0.0
//TODO:localize
let iconSize = self.icon.update(
transition: .immediate,
component: AnyComponent(LottieComponent(
@ -145,7 +150,7 @@ final class PasskeysScreenIntroComponent: Component {
let titleSize = self.title.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "Protect your account", font: Font.bold(27.0), textColor: component.theme.list.itemPrimaryTextColor)),
text: .plain(NSAttributedString(string: component.strings.Passkeys_Into_Title, font: Font.bold(27.0), textColor: component.theme.list.itemPrimaryTextColor)),
horizontalAlignment: .center,
maximumNumberOfLines: 0
)),
@ -166,7 +171,7 @@ final class PasskeysScreenIntroComponent: Component {
let subtitleSize = self.subtitle.update(
transition: .immediate,
component: AnyComponent(BalancedTextComponent(
text: .plain(NSAttributedString(string: "Log in safely and keep your account secure.", font: Font.regular(16.0), textColor: component.theme.list.itemPrimaryTextColor)),
text: .plain(NSAttributedString(string: component.strings.Passkeys_Subtitle, font: Font.regular(16.0), textColor: component.theme.list.itemPrimaryTextColor)),
horizontalAlignment: .center,
maximumNumberOfLines: 0,
lineSpacing: 0.2
@ -193,18 +198,18 @@ final class PasskeysScreenIntroComponent: Component {
let itemDescs: [ItemDesc] = [
ItemDesc(
icon: "Settings/Passkeys/Intro1",
title: "Create a Passkey",
text: "Make a passkey to sign in easily and safely."
title: component.strings.Passkeys_Into_Title0,
text: component.strings.Passkeys_Into_Text0
),
ItemDesc(
icon: "Settings/Passkeys/Intro2",
title: "Log in with Face ID",
text: "Use Face ID, Touch ID, or your passcode to sign in."
title: component.strings.Passkeys_Into_Title1,
text: component.strings.Passkeys_Into_Text1
),
ItemDesc(
icon: "Settings/Passkeys/Intro3",
title: "Store Passkey Securely",
text: "Your passkey is safely kept in your iCloud Keychain."
title: component.strings.Passkeys_Into_Title2,
text: component.strings.Passkeys_Into_Text2
)
]
for i in 0 ..< itemDescs.count {
@ -290,7 +295,7 @@ final class PasskeysScreenIntroComponent: Component {
),
content: AnyComponentWithIdentity(
id: AnyHashable(0),
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Create Passkey", font: Font.semibold(17.0), textColor: component.theme.list.itemCheckColors.foregroundColor))))
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: component.strings.Passkeys_ButtonCreate, font: Font.semibold(17.0), textColor: component.theme.list.itemCheckColors.foregroundColor))))
),
action: { [weak self] in
guard let self, let component = self.component else {
@ -312,7 +317,6 @@ final class PasskeysScreenIntroComponent: Component {
skipButton = ComponentView()
self.skipButton = skipButton
}
//TODO:localize
skipButtonSize = skipButton.update(
transition: transition,
component: AnyComponent(ButtonComponent(
@ -325,7 +329,7 @@ final class PasskeysScreenIntroComponent: Component {
),
content: AnyComponentWithIdentity(
id: AnyHashable(0),
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Skip", font: Font.semibold(17.0), textColor: component.theme.list.itemCheckColors.foregroundColor))))
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: component.strings.Passkeys_ButtonSkip, font: Font.semibold(17.0), textColor: component.theme.list.itemCheckColors.foregroundColor))))
),
action: { [weak self] in
guard let self, let component = self.component else {

View file

@ -123,7 +123,6 @@ final class PasskeysScreenListComponent: Component {
contentHeight += component.insets.top
contentHeight += 8.0
//TODO:localize
let iconSize = self.icon.update(
transition: .immediate,
component: AnyComponent(LottieComponent(
@ -148,7 +147,7 @@ final class PasskeysScreenListComponent: Component {
let titleSize = self.title.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "Passkeys", font: Font.bold(27.0), textColor: component.theme.list.itemPrimaryTextColor)),
text: .plain(NSAttributedString(string: component.strings.Passkeys_Title, font: Font.bold(27.0), textColor: component.theme.list.itemPrimaryTextColor)),
horizontalAlignment: .center,
maximumNumberOfLines: 0
)),
@ -169,7 +168,7 @@ final class PasskeysScreenListComponent: Component {
let subtitleSize = self.subtitle.update(
transition: .immediate,
component: AnyComponent(BalancedTextComponent(
text: .plain(NSAttributedString(string: "Log in safely and keep your account secure.", font: Font.regular(16.0), textColor: component.theme.list.itemPrimaryTextColor)),
text: .plain(NSAttributedString(string: component.strings.Passkeys_Subtitle, font: Font.regular(16.0), textColor: component.theme.list.itemPrimaryTextColor)),
horizontalAlignment: .center,
maximumNumberOfLines: 0,
lineSpacing: 0.2
@ -229,11 +228,12 @@ final class PasskeysScreenListComponent: Component {
)
}
//TODO:localize
var subtitleString = "created \(dateString)"
let subtitleString: String
if let lastUsageDate = passkey.lastUsageDate {
let lastUsedDateString = dateFormatter.string(from: Date(timeIntervalSince1970: Double(lastUsageDate)))
subtitleString.append(" • used \(lastUsedDateString)")
subtitleString = component.strings.Passkeys_PasskeyCreatedAndUsedPattern(dateString, lastUsedDateString).string
} else {
subtitleString = component.strings.Passkeys_PasskeyCreatedPattern(dateString).string
}
listSectionItems.append(AnyComponentWithIdentity(id: passkey.id, component: AnyComponent(ListActionItemComponent(
@ -241,7 +241,7 @@ final class PasskeysScreenListComponent: Component {
title: AnyComponent(VStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: passkey.name.isEmpty ? "Passkey" : passkey.name, //TODO:localize
string: passkey.name.isEmpty ? component.strings.Passkeys_EmptyName : passkey.name,
font: Font.regular(17.0),
textColor: component.theme.list.itemPrimaryTextColor
)),
@ -283,7 +283,7 @@ final class PasskeysScreenListComponent: Component {
title: AnyComponent(VStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: "Create Passkey", //TODO:localize
string: component.strings.Passkeys_AddPasskey,
font: Font.regular(17.0),
textColor: component.theme.list.itemAccentColor
)),
@ -305,7 +305,6 @@ final class PasskeysScreenListComponent: Component {
))))
}
//TODO:localize
let listSectionSize = self.listSection.update(
transition: transition,
component: AnyComponent(ListSectionComponent(
@ -314,7 +313,7 @@ final class PasskeysScreenListComponent: Component {
header: nil,
footer: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: "Your passkeys are stored securely in your password manager.",
string: component.strings.Passkeys_ListFooter,
font: Font.regular(13.0),
textColor: component.theme.list.freeTextColor
)),