feat: Add i18n support for offline reading feature

This commit is contained in:
Ilyas Hallak 2025-12-05 09:19:04 +01:00
parent 05e79d763e
commit c5d804e3f7
5 changed files with 81 additions and 33 deletions

View File

@ -166,3 +166,27 @@
"Your Password" = "Passwort";
"Your Username" = "Benutzername";
/* Offline Reading */
"Enable Offline Reading" = "Offline-Lesen aktivieren";
"Offline Reading" = "Offline-Lesen";
"Automatically download articles for offline use." = "Artikel automatisch für die Offline-Nutzung herunterladen.";
"Maximum Articles" = "Maximale Artikelanzahl";
"Max. Articles Offline" = "Max. Artikel Offline";
"Save Images" = "Bilder speichern";
"Also download images for offline use." = "Bilder auch für die Offline-Nutzung herunterladen.";
"Sync Now" = "Jetzt synchronisieren";
"Last synced: %@" = "Zuletzt synchronisiert: %@";
"Preview Cached Articles" = "Gecachte Artikel ansehen";
"%lld articles (%@)" = "%1$lld Artikel (%2$@)";
"Cached Articles" = "Gecachte Artikel";
"%lld articles cached" = "%lld Artikel gecacht";
"These articles are available offline. You can read them without an internet connection." = "Diese Artikel sind offline verfügbar. Sie können sie ohne Internetverbindung lesen.";
"Loading Cached Articles" = "Gecachte Artikel werden geladen";
"Please wait..." = "Bitte warten...";
"Unable to load cached articles" = "Gecachte Artikel können nicht geladen werden";
"No Cached Articles" = "Keine gecachten Artikel";
"Enable offline reading and sync to cache articles for offline access" = "Aktiviere Offline-Lesen und synchronisiere, um Artikel für den Offline-Zugriff zu cachen";
"Use 'Sync Now' to download articles" = "Verwende 'Jetzt synchronisieren', um Artikel herunterzuladen";
"Simulate Offline Mode" = "Offline-Modus simulieren";
"DEBUG: Toggle network status" = "DEBUG: Netzwerkstatus umschalten";

View File

@ -160,4 +160,28 @@
"Warning" = "Warning";
"Your current server connection and login credentials." = "Your current server connection and login credentials.";
"Your Password" = "Your Password";
"Your Username" = "Your Username";
"Your Username" = "Your Username";
/* Offline Reading */
"Enable Offline Reading" = "Enable Offline Reading";
"Offline Reading" = "Offline Reading";
"Automatically download articles for offline use." = "Automatically download articles for offline use.";
"Maximum Articles" = "Maximum Articles";
"Max. Articles Offline" = "Max. Articles Offline";
"Save Images" = "Save Images";
"Also download images for offline use." = "Also download images for offline use.";
"Sync Now" = "Sync Now";
"Last synced: %@" = "Last synced: %@";
"Preview Cached Articles" = "Preview Cached Articles";
"%lld articles (%@)" = "%1$lld articles (%2$@)";
"Cached Articles" = "Cached Articles";
"%lld articles cached" = "%lld articles cached";
"These articles are available offline. You can read them without an internet connection." = "These articles are available offline. You can read them without an internet connection.";
"Loading Cached Articles" = "Loading Cached Articles";
"Please wait..." = "Please wait...";
"Unable to load cached articles" = "Unable to load cached articles";
"No Cached Articles" = "No Cached Articles";
"Enable offline reading and sync to cache articles for offline access" = "Enable offline reading and sync to cache articles for offline access";
"Use 'Sync Now' to download articles" = "Use 'Sync Now' to download articles";
"Simulate Offline Mode" = "Simulate Offline Mode";
"DEBUG: Toggle network status" = "DEBUG: Toggle network status";

View File

@ -29,7 +29,7 @@ struct CachedArticlesPreviewView: View {
cachedBookmarksList
}
}
.navigationTitle("Cached Articles")
.navigationTitle("Cached Articles".localized)
.navigationBarTitleDisplayMode(.inline)
.navigationDestination(
item: Binding<String?>(
@ -79,14 +79,14 @@ struct CachedArticlesPreviewView: View {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
.font(.caption)
Text("\(viewModel.cachedBookmarks.count) articles cached")
Text(String(format: "%lld articles cached".localized, viewModel.cachedBookmarks.count))
.font(.caption)
.foregroundColor(.secondary)
}
.textCase(nil)
.padding(.bottom, 4)
} footer: {
Text("These articles are available offline. You can read them without an internet connection.")
Text("These articles are available offline. You can read them without an internet connection.".localized)
.font(.caption)
.foregroundColor(.secondary)
}
@ -107,11 +107,11 @@ struct CachedArticlesPreviewView: View {
.tint(.accentColor)
VStack(spacing: 8) {
Text("Loading Cached Articles")
Text("Loading Cached Articles".localized)
.font(.headline)
.foregroundColor(.primary)
Text("Please wait...")
Text("Please wait...".localized)
.font(.subheadline)
.foregroundColor(.secondary)
}
@ -128,7 +128,7 @@ struct CachedArticlesPreviewView: View {
.foregroundColor(.orange)
VStack(spacing: 8) {
Text("Unable to load cached articles")
Text("Unable to load cached articles".localized)
.font(.headline)
.foregroundColor(.primary)
@ -138,7 +138,7 @@ struct CachedArticlesPreviewView: View {
.multilineTextAlignment(.center)
}
Button("Try Again") {
Button("Try Again".localized) {
Task {
await viewModel.loadCachedBookmarks()
}
@ -159,12 +159,12 @@ struct CachedArticlesPreviewView: View {
.foregroundColor(.secondary.opacity(0.5))
VStack(spacing: 8) {
Text("No Cached Articles")
Text("No Cached Articles".localized)
.font(.title2)
.fontWeight(.semibold)
.foregroundColor(.primary)
Text("Enable offline reading and sync to cache articles for offline access")
Text("Enable offline reading and sync to cache articles for offline access".localized)
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
@ -176,7 +176,7 @@ struct CachedArticlesPreviewView: View {
HStack(spacing: 8) {
Image(systemName: "arrow.clockwise")
.font(.caption)
Text("Use 'Sync Now' to download articles")
Text("Use 'Sync Now' to download articles".localized)
.font(.caption)
}
.foregroundColor(.accentColor)

View File

@ -15,14 +15,14 @@ struct OfflineReadingDetailView: View {
List {
Section {
VStack(alignment: .leading, spacing: 4) {
Toggle("Enable Offline Reading", isOn: $viewModel.offlineSettings.enabled)
Toggle("Enable Offline Reading".localized, isOn: $viewModel.offlineSettings.enabled)
.onChange(of: viewModel.offlineSettings.enabled) {
Task {
await viewModel.saveSettings()
}
}
Text("Automatically download articles for offline use.")
Text("Automatically download articles for offline use.".localized)
.font(.caption)
.foregroundColor(.secondary)
.padding(.top, 2)
@ -32,7 +32,7 @@ struct OfflineReadingDetailView: View {
// Max articles slider
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("Maximum Articles")
Text("Maximum Articles".localized)
Spacer()
Text("\(viewModel.offlineSettings.maxUnreadArticlesInt)")
.font(.caption)
@ -44,7 +44,7 @@ struct OfflineReadingDetailView: View {
in: 0...100,
step: 10
) {
Text("Max. Articles Offline")
Text("Max. Articles Offline".localized)
}
.onChange(of: viewModel.offlineSettings.maxUnreadArticles) {
Task {
@ -55,27 +55,27 @@ struct OfflineReadingDetailView: View {
// Save images toggle
VStack(alignment: .leading, spacing: 4) {
Toggle("Save Images", isOn: $viewModel.offlineSettings.saveImages)
Toggle("Save Images".localized, isOn: $viewModel.offlineSettings.saveImages)
.onChange(of: viewModel.offlineSettings.saveImages) {
Task {
await viewModel.saveSettings()
}
}
Text("Also download images for offline use.")
Text("Also download images for offline use.".localized)
.font(.caption)
.foregroundColor(.secondary)
.padding(.top, 2)
}
}
} header: {
Text("Settings")
Text("Settings".localized)
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(.primary)
.textCase(nil)
} footer: {
Text("VPN connections are detected as active internet connections.")
Text("VPN connections are detected as active internet connections.".localized)
.font(.caption)
.foregroundColor(.secondary)
}
@ -98,7 +98,7 @@ struct OfflineReadingDetailView: View {
}
VStack(alignment: .leading, spacing: 2) {
Text("Sync Now")
Text("Sync Now".localized)
.foregroundColor(viewModel.isSyncing ? .secondary : .blue)
if let progress = viewModel.syncProgress {
@ -122,14 +122,14 @@ struct OfflineReadingDetailView: View {
SettingsRowNavigationLink(
icon: "doc.text.magnifyingglass",
iconColor: .green,
title: "Preview Cached Articles",
subtitle: "\(viewModel.cachedArticlesCount) articles (\(viewModel.cacheSize))"
title: "Preview Cached Articles".localized,
subtitle: String(format: "%lld articles (%@)".localized, viewModel.cachedArticlesCount, viewModel.cacheSize)
) {
CachedArticlesPreviewView()
}
}
} header: {
Text("Synchronization")
Text("Synchronization".localized)
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(.primary)
@ -151,9 +151,9 @@ struct OfflineReadingDetailView: View {
.foregroundColor(.orange)
VStack(alignment: .leading, spacing: 2) {
Text("Simulate Offline Mode")
Text("Simulate Offline Mode".localized)
.foregroundColor(.orange)
Text("DEBUG: Toggle network status")
Text("DEBUG: Toggle network status".localized)
.font(.caption)
.foregroundColor(.secondary)
}
@ -161,7 +161,7 @@ struct OfflineReadingDetailView: View {
}
}
} header: {
Text("Debug")
Text("Debug".localized)
.font(.subheadline)
.fontWeight(.semibold)
.foregroundColor(.primary)
@ -171,7 +171,7 @@ struct OfflineReadingDetailView: View {
}
}
.listStyle(.insetGrouped)
.navigationTitle("Offline Reading")
.navigationTitle("Offline Reading".localized)
.navigationBarTitleDisplayMode(.inline)
.task {
await viewModel.loadSettings()

View File

@ -21,7 +21,7 @@ struct SettingsContainerView: View {
AppearanceSettingsView()
Section {
Toggle("Enable Offline Reading", isOn: $offlineViewModel.offlineSettings.enabled)
Toggle("Enable Offline Reading".localized, isOn: $offlineViewModel.offlineSettings.enabled)
.onChange(of: offlineViewModel.offlineSettings.enabled) {
Task {
await offlineViewModel.saveSettings()
@ -44,7 +44,7 @@ struct SettingsContainerView: View {
}
VStack(alignment: .leading, spacing: 2) {
Text("Sync Now")
Text("Sync Now".localized)
.foregroundColor(offlineViewModel.isSyncing ? .secondary : .blue)
if let progress = offlineViewModel.syncProgress {
@ -66,16 +66,16 @@ struct SettingsContainerView: View {
SettingsRowNavigationLink(
icon: "arrow.down.circle.fill",
iconColor: .blue,
title: "Offline Reading",
subtitle: offlineViewModel.cachedArticlesCount > 0 ? "\(offlineViewModel.cachedArticlesCount) articles cached" : nil
title: "Offline Reading".localized,
subtitle: offlineViewModel.cachedArticlesCount > 0 ? String(format: "%lld articles cached".localized, offlineViewModel.cachedArticlesCount) : nil
) {
OfflineReadingDetailView()
}
}
} header: {
Text("Offline Reading")
Text("Offline Reading".localized)
} footer: {
Text("Automatically download articles for offline use. VPN connections are detected as active internet connections.")
Text("Automatically download articles for offline use.".localized + " " + "VPN connections are detected as active internet connections.".localized)
}
CacheSettingsView()