Fix Localizations (#684)

* Update all `NSLocalizedString` with `L10n.string`

+ combine with `L10n.format`

* Handle Localizations + Swift Package
This commit is contained in:
Islam
2025-09-26 11:09:10 +02:00
committed by GitHub
parent 9abfab3248
commit d01538a2ea
10 changed files with 52 additions and 44 deletions
+1
View File
@@ -72,6 +72,7 @@
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Services/TransportConfig.swift,
Utils/Localization.swift,
);
target = 57CA17A36A2532A6CFF367BB /* bitchatShareExtension */;
};
+4 -4
View File
@@ -77,17 +77,17 @@ final class LocationNotesManager: ObservableObject {
private let dependencies: LocationNotesDependencies
private enum Strings {
static let noRelays = NSLocalizedString(
static let noRelays = L10n.string(
"location_notes.error.no_relays",
comment: "Shown when no geo relays are available near the selected location"
)
static func failedToSend(_ detail: String) -> String {
let format = NSLocalizedString(
L10n.string(
"location_notes.error.failed_to_send",
comment: "Shown when a location note fails to send"
comment: "Shown when a location note fails to send",
detail
)
return String(format: format, detail)
}
}
+14 -5
View File
@@ -1,12 +1,21 @@
import Foundation
enum L10n {
static func string(_ key: String, comment: String) -> String {
NSLocalizedString(key, comment: comment)
static func string(_ key: String, comment: String, _ args: CVarArg...) -> String {
let basic = NSLocalizedString(key, bundle: .localization, comment: comment)
if args.isEmpty {
return basic
}
return String(format: basic, locale: .current, arguments: args)
}
}
static func format(_ key: String, comment: String, _ args: CVarArg...) -> String {
let format = NSLocalizedString(key, comment: comment)
return String(format: format, locale: Locale.current, arguments: args)
private extension Bundle {
static var localization: Bundle {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle.main
#endif
}
}
+6 -6
View File
@@ -2077,7 +2077,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
for (k, v) in nostrKeyMapping where v.lowercased() == hex { nostrKeyMapping.removeValue(forKey: k) }
addSystemMessage(
L10n.format(
L10n.string(
"system.geohash.blocked",
comment: "System message shown when a user is blocked in geohash chats",
displayName
@@ -2088,7 +2088,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
func unblockGeohashUser(pubkeyHexLowercased: String, displayName: String) {
identityManager.setNostrBlocked(pubkeyHexLowercased, isBlocked: false)
addSystemMessage(
L10n.format(
L10n.string(
"system.geohash.unblocked",
comment: "System message shown when a user is unblocked in geohash chats",
displayName
@@ -2278,7 +2278,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
if unifiedPeerService.isBlocked(peerID) {
let nickname = meshService.peerNickname(peerID: peerID) ?? "user"
addSystemMessage(
L10n.format(
L10n.string(
"system.dm.blocked_recipient",
comment: "System message when attempting to message a blocked user",
nickname
@@ -2353,7 +2353,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
)
}
addSystemMessage(
L10n.format(
L10n.string(
"system.dm.unreachable",
comment: "System message when a recipient is unreachable",
recipientNickname ?? L10n.string("system.common.user", comment: "Fallback recipient name")
@@ -2561,7 +2561,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
// Check if the peer is blocked
if unifiedPeerService.isBlocked(peerID) {
addSystemMessage(
L10n.format(
L10n.string(
"system.chat.blocked",
comment: "System message when starting chat fails because peer is blocked",
peerNickname
@@ -2574,7 +2574,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
if let peer = unifiedPeerService.getPeer(by: peerID),
peer.isFavorite && !peer.theyFavoritedUs && !peer.isConnected {
addSystemMessage(
L10n.format(
L10n.string(
"system.chat.requires_favorite",
comment: "System message when mutual favorite requirement blocks chat",
peerNickname
+11 -13
View File
@@ -1225,7 +1225,7 @@ struct ContentView: View {
}
.buttonStyle(.plain)
.accessibilityLabel(
L10n.format(
L10n.string(
"content.accessibility.toggle_bookmark",
comment: "Accessibility label for toggling a geohash bookmark",
ch.geohash
@@ -1271,13 +1271,11 @@ struct ContentView: View {
Image(systemName: "person.2.fill")
.font(.system(size: headerPeerIconSize, weight: .regular))
.accessibilityLabel(
NSString.localizedStringWithFormat(
NSLocalizedString(
"content.accessibility.people_count",
comment: "Accessibility label announcing number of people in header"
) as NSString,
L10n.string(
"content.accessibility.people_count",
comment: "Accessibility label announcing number of people in header",
headerOtherPeersCount
) as String
)
)
Text("\(headerOtherPeersCount)")
.font(.system(size: headerPeerCountFontSize, weight: .regular, design: .monospaced))
@@ -1578,7 +1576,7 @@ struct ContentView: View {
encryptionStatus == .noiseSecured ? textColor :
Color.red)
.accessibilityLabel(
L10n.format(
L10n.string(
"content.accessibility.encryption_status",
comment: "Accessibility label announcing encryption status",
encryptionStatus.accessibilityDescription
@@ -1588,7 +1586,7 @@ struct ContentView: View {
}
}
.accessibilityLabel(
L10n.format(
L10n.string(
"content.accessibility.private_chat_header",
comment: "Accessibility label describing the private chat header",
privatePeerNick
@@ -1751,7 +1749,7 @@ struct DeliveryStatusView: View {
private enum Strings {
static func delivered(to nickname: String) -> String {
L10n.format(
L10n.string(
"content.delivery.delivered_to",
comment: "Tooltip for delivered private messages",
nickname
@@ -1759,7 +1757,7 @@ struct DeliveryStatusView: View {
}
static func read(by nickname: String) -> String {
L10n.format(
L10n.string(
"content.delivery.read_by",
comment: "Tooltip for read private messages",
nickname
@@ -1767,7 +1765,7 @@ struct DeliveryStatusView: View {
}
static func failed(_ reason: String) -> String {
L10n.format(
L10n.string(
"content.delivery.failed",
comment: "Tooltip for failed message delivery",
reason
@@ -1775,7 +1773,7 @@ struct DeliveryStatusView: View {
}
static func deliveredToMembers(_ reached: Int, _ total: Int) -> String {
L10n.format(
L10n.string(
"content.delivery.delivered_members",
comment: "Tooltip for partially delivered messages",
reached,
+1 -1
View File
@@ -32,7 +32,7 @@ struct FingerprintView: View {
static let notVerifiedBadge: LocalizedStringKey = "fingerprint.badge.not_verified"
static let verifiedMessage: LocalizedStringKey = "fingerprint.message.verified"
static func verifyHint(_ nickname: String) -> String {
L10n.format(
L10n.string(
"fingerprint.message.verify_hint",
comment: "Instruction to compare fingerprints with a named peer",
nickname
+5 -5
View File
@@ -54,7 +54,7 @@ struct LocationChannelsSheet: View {
}
static func subtitlePrefix(geohash: String, coverage: String) -> String {
L10n.format(
L10n.string(
"location_channels.subtitle_prefix",
comment: "Subtitle prefix showing geohash and coverage",
geohash,
@@ -64,7 +64,7 @@ struct LocationChannelsSheet: View {
static func subtitle(prefix: String, name: String?) -> String {
guard let name, !name.isEmpty else { return prefix }
return L10n.format(
return L10n.string(
"location_channels.subtitle_with_name",
comment: "Subtitle combining prefix and resolved location name",
prefix,
@@ -73,11 +73,11 @@ struct LocationChannelsSheet: View {
}
private static func rowTitle(label: String, count: Int) -> String {
let format = NSLocalizedString(
L10n.string(
"location_channels.row_title",
comment: "List row title with participant count"
comment: "List row title with participant count",
label, count
)
return NSString.localizedStringWithFormat(format as NSString, label, count) as String
}
}
+3 -3
View File
@@ -145,11 +145,11 @@ struct LocationNotesView: View {
}
private func headerTitle(for count: Int) -> String {
let format = NSLocalizedString(
L10n.string(
"location_notes.header",
comment: "Header displaying the geohash and localized note count"
comment: "Header displaying the geohash and localized note count",
geohash, count
)
return NSString.localizedStringWithFormat(format as NSString, geohash, count) as String
}
private var notesContent: some View {
+1 -1
View File
@@ -120,7 +120,7 @@ struct QRScanView: View {
static let pastePrompt: LocalizedStringKey = "verification.scan.paste_prompt"
static let validate: LocalizedStringKey = "verification.scan.validate"
static func requested(_ nickname: String) -> String {
L10n.format(
L10n.string(
"verification.scan.status.requested",
comment: "Status text when verification is requested for a nickname",
nickname
@@ -16,12 +16,12 @@ final class ShareViewController: UIViewController {
private static let groupID = "group.chat.bitchat"
private enum Strings {
static let nothingToShare = NSLocalizedString("share.status.nothing_to_share", comment: "Shown when the share extension receives no content")
static let noShareableContent = NSLocalizedString("share.status.no_shareable_content", comment: "Shown when provided content cannot be shared")
static let sharedLinkTitleFallback = NSLocalizedString("share.fallback.shared_link_title", comment: "Fallback title when saving a shared link")
static let sharedLinkConfirmation = NSLocalizedString("share.status.shared_link", comment: "Confirmation after successfully sharing a link")
static let sharedTextConfirmation = NSLocalizedString("share.status.shared_text", comment: "Confirmation after successfully sharing text")
static let failedToEncode = NSLocalizedString("share.status.failed_to_encode", comment: "Shown when the share payload cannot be encoded")
static let nothingToShare = L10n.string("share.status.nothing_to_share", comment: "Shown when the share extension receives no content")
static let noShareableContent = L10n.string("share.status.no_shareable_content", comment: "Shown when provided content cannot be shared")
static let sharedLinkTitleFallback = L10n.string("share.fallback.shared_link_title", comment: "Fallback title when saving a shared link")
static let sharedLinkConfirmation = L10n.string("share.status.shared_link", comment: "Confirmation after successfully sharing a link")
static let sharedTextConfirmation = L10n.string("share.status.shared_text", comment: "Confirmation after successfully sharing text")
static let failedToEncode = L10n.string("share.status.failed_to_encode", comment: "Shown when the share payload cannot be encoded")
}
private let statusLabel: UILabel = {