diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/MainActivity.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/MainActivity.kt index 0d64978..7b2787d 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/MainActivity.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/MainActivity.kt @@ -146,7 +146,7 @@ class MainActivity : AppCompatActivity() { OnboardingScreen( secretStore = secretStore, syncStore = syncStore, - onRequestNotificationPermission = { requestNotificationPermissionIfNeeded() }, // ← new + onRequestNotificationPermission = { requestNotificationPermissionIfNeeded() }, onComplete = {} ) } diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EnStrings.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EnStrings.kt index 616c45a..3c44a4a 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EnStrings.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EnStrings.kt @@ -317,7 +317,11 @@ val EnHomeStrings = AppStrings( serverUrl = "Server URL", serverUrlHint = "https://bitcointxoko.org", invoiceKey = "Invoice Key (read-only)", + invoiceKeySubtitle = "Used to generate payment requests.", + pasteInvoiceKey = "Paste invoice key", adminKey = "Admin Key (for sending)", + adminKeySubtitle = "Required to send payments.", + pasteAdminKey = "Paste admin key", hideAdminKey = "Hide", showAdminKey = "Show", fieldsRequired = "All fields are required.", @@ -331,7 +335,22 @@ val EnHomeStrings = AppStrings( batterySubtitle = "Allow Gudari Wallet to run unrestricted so notifications arrive even when the app is closed.", openSettings = "Open Settings", batteryNote = "Tap 'Battery' → 'Unrestricted'. You can skip this and change it later.", - batteryAlreadyUnrestricted = "You're all set — no restrictions detected." + batteryAlreadyUnrestricted = "You're all set — no restrictions detected.", + paymentHistory = "Payment history", + paymentHistorySubtitle = "Download your past payments so they're available offline.", + syncNow = "Sync now", + skipForNow = "Skip for now", + syncScheduled = "Sync scheduled — will run when your device is online. You will get a notification when the sync is done. You can already start using the app.", + continueToApp = "Continue to app →", + connecting = "Connecting...", + paymentsFetchedTotal = { fetched, total -> "$fetched / $total payments" }, + paymentsSynced = { total -> "✓ $total payments synced"}, + syncComplete = "✓ Sync complete", + syncFailed = "Sync failed. You can retry from Settings.", + scheduleForLater = "Schedule for later", + scheduleSync = "Schedule sync", + schedule = "Schedule", + cancel = "Cancel" ) ) diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EsStrings.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EsStrings.kt index a3862d5..6a1e813 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EsStrings.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EsStrings.kt @@ -309,28 +309,47 @@ val EsHomeStrings = AppStrings( onboarding = OnboardingStrings( - back = "Back", - next = "Next", - done = "Done", - title = "Connect to LNbits", - subtitle = "Enter your LNbits server URL and API keys.", - serverUrl = "Server URL", + back = "Atrás", + next = "Siguiente", + done = "Hecho", + title = "Conectar a LNbits", + subtitle = "Introduce la URL de tu servidor LNbits y las claves de API.", + serverUrl = "URL del servidor", serverUrlHint = "https://bitcointxoko.org", - invoiceKey = "Invoice Key (read-only)", - adminKey = "Admin Key (for sending)", - hideAdminKey = "Hide", - showAdminKey = "Show", - fieldsRequired = "All fields are required.", - connect = "Connect", - notificationsTitle = "Stay in the loop", - notificationsSubtitle = "Get notified instantly when you receive a payment.", - allowNotifications = "Allow Notifications", - notificationsNote = "You can change this later in system Settings.", - notificationsAutoGranted = "Notifications are enabled automatically on your device.", - batteryTitle = "Background activity", - batterySubtitle = "Allow Gudari Wallet to run unrestricted so notifications arrive even when the app is closed.", - openSettings = "Open Settings", - batteryNote = "Tap 'Battery' → 'Unrestricted'. You can skip this and change it later.", - batteryAlreadyUnrestricted = "You're all set — no restrictions detected." + invoiceKey = "Clave de factura (solo lectura)", + invoiceKeySubtitle = "Se usa para generar solicitudes de pago.", + pasteInvoiceKey = "Pegar clave de factura", + adminKey = "Clave de administrador (para enviar)", + adminKeySubtitle = "Necesaria para enviar pagos.", + pasteAdminKey = "Pegar clave de administrador", + hideAdminKey = "Ocultar", + showAdminKey = "Mostrar", + fieldsRequired = "Todos los campos son obligatorios.", + connect = "Conectar", + notificationsTitle = "Mantente al día", + notificationsSubtitle = "Recibe notificaciones al instante cuando recibas un pago.", + allowNotifications = "Permitir notificaciones", + notificationsNote = "Puedes cambiar esto más tarde en los Ajustes del sistema.", + notificationsAutoGranted = "Las notificaciones se activan automáticamente en tu dispositivo.", + batteryTitle = "Actividad en segundo plano", + batterySubtitle = "Permite que Gudari Wallet funcione sin restricciones para que las notificaciones lleguen incluso cuando la aplicación esté cerrada.", + openSettings = "Abrir Ajustes", + batteryNote = "Pulsa 'Batería' → 'Sin restricciones'. Puedes omitir esto y cambiarlo más tarde.", + batteryAlreadyUnrestricted = "Todo listo — no se han detectado restricciones.", + paymentHistory = "Historial de transacciones", + paymentHistorySubtitle = "Descarga tus transacciones anteriores para tenerlas disponibles sin conexión.", + syncNow = "Sincronizar ahora", + skipForNow = "Omitir por ahora", + syncScheduled = "Sincronización programada — se ejecutará cuando tu dispositivo esté en línea. Recibirás una notificación cuando la sincronización haya finalizado. Ya puedes empezar a usar la aplicación.", + continueToApp = "Ir a la aplicación →", + connecting = "Conectando...", + paymentsFetchedTotal = { fetched, total -> "$fetched / $total transacciones" }, + paymentsSynced = { total -> "✓ $total transacciones sincronizadas"}, + syncComplete = "✓ Sincronización completada", + syncFailed = "Error en la sincronización. Puedes volver a intentarlo desde Ajustes.", + scheduleForLater = "Programar para más tarde", + scheduleSync = "Programar sincronización", + schedule = "Programar", + cancel = "Cancelar" ) ) diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EuStrings.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EuStrings.kt index 66e31eb..40133ad 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EuStrings.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/EuStrings.kt @@ -309,28 +309,47 @@ val EuStrings = AppStrings( onboarding = OnboardingStrings( - back = "Back", - next = "Next", - done = "Done", - title = "Connect to LNbits", - subtitle = "Enter your LNbits server URL and API keys.", - serverUrl = "Server URL", + back = "Atzera", + next = "Hurrengoa", + done = "Eginda", + title = "Konektatu LNbits-era", + subtitle = "Sartu zure LNbits zerbitzariaren URLa eta API gakoak.", + serverUrl = "Zerbitzariaren URLa", serverUrlHint = "https://bitcointxoko.org", - invoiceKey = "Invoice Key (read-only)", - adminKey = "Admin Key (for sending)", - hideAdminKey = "Hide", - showAdminKey = "Show", - fieldsRequired = "All fields are required.", - connect = "Connect", - notificationsTitle = "Stay in the loop", - notificationsSubtitle = "Get notified instantly when you receive a payment.", - allowNotifications = "Allow Notifications", - notificationsNote = "You can change this later in system Settings.", - notificationsAutoGranted = "Notifications are enabled automatically on your device.", - batteryTitle = "Background activity", - batterySubtitle = "Allow Gudari Wallet to run unrestricted so notifications arrive even when the app is closed.", - openSettings = "Open Settings", - batteryNote = "Tap 'Battery' → 'Unrestricted'. You can skip this and change it later.", - batteryAlreadyUnrestricted = "You're all set — no restrictions detected." + invoiceKey = "Faktura gakoa (irakurtzeko soilik)", + invoiceKeySubtitle = "Ordainketa eskaerak sortzeko erabiltzen da.", + pasteInvoiceKey = "Itsatsi faktura gakoa", + adminKey = "Administrazio gakoa (bidaltzeko)", + adminKeySubtitle = "Beharrezkoa da transakzioak bidaltzeko.", + pasteAdminKey = "Itsatsi administrazio gakoa", + hideAdminKey = "Ezkutatu", + showAdminKey = "Erakutsi", + fieldsRequired = "Eremu guztiak beharrezkoak dira.", + connect = "Konektatu", + notificationsTitle = "Egon eguneratuta", + notificationsSubtitle = "Jaso jakinarazpenak berehala transakzio bat jasotzen duzunean.", + allowNotifications = "Baimendu jakinarazpenak", + notificationsNote = "Hau geroago alda dezakezu sistemaren Ezarpenetan.", + notificationsAutoGranted = "Jakinarazpenak automatikoki gaituta daude zure gailuan.", + batteryTitle = "Atzeko planoko jarduera", + batterySubtitle = "Baimendu Gudari Wallet murrizketarik gabe funtzionatzea, jakinarazpenak aplikazioa itxita dagoenean ere irits daitezen.", + openSettings = "Ireki Ezarpenak", + batteryNote = "Sakatu 'Bateria' → 'Murrizketarik gabe'. Hau saltatu eta geroago alda dezakezu.", + batteryAlreadyUnrestricted = "Dena prest dago — ez da murrizketarik hauteman.", + paymentHistory = "Transakzioen historia", + paymentHistorySubtitle = "Deskargatu iraganeko transakzioak konexiorik gabe erabilgarri izateko.", + syncNow = "Sinkronizatu orain", + skipForNow = "Saltatu oraingoz", + syncScheduled = "Sinkronizazioa programatuta dago — gailua sarean dagoenean exekutatuko da. Sinkronizazioa amaitutakoan jakinarazpen bat jasoko duzu. Dagoeneko has zaitezke aplikazioa erabiltzen.", + continueToApp = "Joan aplikaziora →", + connecting = "Konektatzen...", + paymentsFetchedTotal = { fetched, total -> "$fetched / $total transakzio" }, + paymentsSynced = { total -> "✓ $total transakzio sinkronizatuta"}, + syncComplete = "✓ Sinkronizazioa osatuta", + syncFailed = "Sinkronizazioak huts egin du. Berriro saia zaitezke Ezarpenetatik.", + scheduleForLater = "Programatu geroago", + scheduleSync = "Programatu sinkronizazioa", + schedule = "Programatu", + cancel = "Utzi" ) ) diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/Strings.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/Strings.kt index 4ba2048..4db3d79 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/Strings.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/i18n/Strings.kt @@ -313,7 +313,11 @@ data class OnboardingStrings( val serverUrl: String, val serverUrlHint: String, val invoiceKey: String, + val invoiceKeySubtitle: String, + val pasteInvoiceKey: String, val adminKey: String, + val adminKeySubtitle: String, + val pasteAdminKey: String, val showAdminKey: String, val hideAdminKey: String, val connect: String, @@ -330,5 +334,20 @@ data class OnboardingStrings( val batterySubtitle: String, val openSettings: String, val batteryNote: String, - val batteryAlreadyUnrestricted: String + val batteryAlreadyUnrestricted: String, + val paymentHistory: String, + val paymentHistorySubtitle: String, + val syncNow: String, + val skipForNow: String, + val syncScheduled: String, + val continueToApp: String, + val connecting: String, + val paymentsFetchedTotal: (fetched: Int, total: Int) -> String, + val paymentsSynced: (total: Int) -> String, + val syncComplete: String, + val syncFailed: String, + val scheduleForLater: String, + val scheduleSync: String, + val schedule: String, + val cancel: String ) \ No newline at end of file diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingPages.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingPages.kt index a93dd1d..3171b90 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingPages.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingPages.kt @@ -140,7 +140,7 @@ val scope = rememberCoroutineScope() OnboardingPageScaffold( title = strings.onboarding.invoiceKey, - subtitle = "Used to generate payment requests." + subtitle = strings.onboarding.invoiceKeySubtitle // "Used to generate payment requests." ) { OutlinedTextField( value = invoiceKey, @@ -161,7 +161,7 @@ val scope = rememberCoroutineScope() }) { Icon( imageVector = Icons.Default.ContentPaste, - contentDescription = "Paste invoice key" + contentDescription = strings.onboarding.pasteInvoiceKey // "Paste invoice key" ) } } @@ -185,7 +185,7 @@ internal fun AdminKeyPage( OnboardingPageScaffold( title = strings.onboarding.adminKey, - subtitle = "Required to send payments." + subtitle = strings.onboarding.adminKeySubtitle // "Required to send payments." ) { OutlinedTextField( value = adminKey, @@ -209,7 +209,7 @@ internal fun AdminKeyPage( }) { Icon( imageVector = Icons.Default.ContentPaste, - contentDescription = "Paste admin key" + contentDescription = strings.onboarding.pasteAdminKey // "Paste admin key" ) } IconButton(onClick = onToggleVis) { @@ -333,7 +333,8 @@ fun SyncHistoryPage( syncIsDeferred: Boolean, onSyncNow : () -> Unit, onSchedule : (delayMillis: Long) -> Unit, - onContinue : () -> Unit + onContinue : () -> Unit, + strings : AppStrings ) { // Derive UI state from WorkInfo val state = when { @@ -364,8 +365,8 @@ fun SyncHistoryPage( } OnboardingPageScaffold( - title = "Payment history", - subtitle = "Download your past payments so they're available offline." + title = strings.onboarding.paymentHistory, // ← "Payment history" + subtitle = strings.onboarding.paymentHistorySubtitle // ← "Download your past payments so they're available offline." ) { Icon( imageVector = Icons.Default.History, @@ -387,23 +388,23 @@ fun SyncHistoryPage( onClick = onSyncNow, modifier = Modifier.fillMaxWidth() ) { - Text("Sync now") + Text(strings.onboarding.syncNow) // ← "Sync now" } Spacer(Modifier.height(8.dp)) - ScheduleLaterPicker(onSchedule = onSchedule) + ScheduleLaterPicker(onSchedule, strings) Spacer(Modifier.height(8.dp)) TextButton( onClick = onContinue, modifier = Modifier.fillMaxWidth() ) { - Text("Skip for now") + Text(strings.onboarding.skipForNow) // ← "Skip for now" } } // ── Scheduled (deferred, waiting for delay + network) ───────────── SyncUiState.Scheduled -> { Text( - text = "Sync scheduled — will run when your device is online. You will get a notification when the sync is done. You can already start using the app.", + text = strings.onboarding.syncScheduled, // ← "Sync scheduled — will run when your device is online. You will get a notification when the sync is done. You can already start using the app." style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.Center @@ -413,7 +414,7 @@ fun SyncHistoryPage( onClick = onContinue, modifier = Modifier.fillMaxWidth() ) { - Text("Continue to app →") + Text(strings.onboarding.continueToApp) // ← "Continue to app →" } } @@ -427,7 +428,7 @@ fun SyncHistoryPage( ) Spacer(Modifier.height(8.dp)) Text( - text = "${state.fetched} / ${state.total} payments", + text = strings.onboarding.paymentsFetchedTotal(state.fetched, state.total), // ← "${state.fetched} / ${state.total} payments" style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant ) @@ -436,7 +437,7 @@ fun SyncHistoryPage( LinearProgressIndicator(modifier = Modifier.fillMaxWidth()) // indeterminate Spacer(Modifier.height(8.dp)) Text( - text = "Connecting…", + text = strings.onboarding.connecting, // ← "Connecting…" style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant ) @@ -447,7 +448,7 @@ fun SyncHistoryPage( onClick = onContinue, modifier = Modifier.fillMaxWidth() ) { - Text("Continue to app →") + Text(strings.onboarding.continueToApp) // ← "Continue to app →" } } @@ -455,9 +456,9 @@ fun SyncHistoryPage( is SyncUiState.Done -> { Text( text = if (state.total > 0) - "✓ ${state.total} payments synced" + strings.onboarding.paymentsSynced(state.total) // ← "✓ ${state.total} payments synced" else - "✓ Sync complete", + strings.onboarding.syncComplete, // ← "✓ Sync complete" style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.primary, textAlign = TextAlign.Center @@ -467,14 +468,14 @@ fun SyncHistoryPage( onClick = onContinue, modifier = Modifier.fillMaxWidth() ) { - Text("Continue to app →") + Text(strings.onboarding.continueToApp) // ← "Continue to app →" } } // ── Failed ──────────────────────────────────────────────────────── SyncUiState.Failed -> { Text( - text = "Sync failed. You can retry from Settings.", + text = strings.onboarding.syncFailed, // ← "Sync failed. You can retry from Settings." style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.error, textAlign = TextAlign.Center @@ -484,7 +485,7 @@ fun SyncHistoryPage( onClick = onContinue, modifier = Modifier.fillMaxWidth() ) { - Text("Continue to app →") + Text(strings.onboarding.continueToApp) // ← "Continue to app →" } } } @@ -503,18 +504,18 @@ private sealed interface SyncUiState { // ── "Schedule for later" time picker ───────────────────────────────────────── @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun ScheduleLaterPicker(onSchedule: (delayMillis: Long) -> Unit) { +private fun ScheduleLaterPicker(onSchedule: (delayMillis: Long) -> Unit, strings: AppStrings) { var showPicker by remember { mutableStateOf(false) } TextButton(onClick = { showPicker = true }) { - Text("Schedule for later") + Text(strings.onboarding.scheduleForLater) // ← "Schedule for later" } if (showPicker) { val timePickerState = rememberTimePickerState(is24Hour = true) AlertDialog( onDismissRequest = { showPicker = false }, - title = { Text("Schedule sync") }, + title = { Text(strings.onboarding.scheduleSync) }, // ← Schedule sync text = { Column(horizontalAlignment = Alignment.CenterHorizontally) { TimePicker(state = timePickerState) @@ -525,10 +526,10 @@ private fun ScheduleLaterPicker(onSchedule: (delayMillis: Long) -> Unit) { showPicker = false val delayMs = timePickerState.toDelayMillis() onSchedule(delayMs) - }) { Text("Schedule") } + }) { Text(strings.onboarding.schedule) } // ← "Schedule" }, dismissButton = { - TextButton(onClick = { showPicker = false }) { Text("Cancel") } + TextButton(onClick = { showPicker = false }) { Text(strings.onboarding.cancel) } // ← "Cancel" } ) } diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingScreen.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingScreen.kt index c84d65b..0884494 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingScreen.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/onboarding/OnboardingScreen.kt @@ -130,7 +130,8 @@ fun OnboardingScreen( secretStore.setOnboarded() // moved here from PAGE_BATTERY onComplete() } - } + }, + strings ) } }