localisation: onboarding
This commit is contained in:
@@ -146,7 +146,7 @@ class MainActivity : AppCompatActivity() {
|
||||
OnboardingScreen(
|
||||
secretStore = secretStore,
|
||||
syncStore = syncStore,
|
||||
onRequestNotificationPermission = { requestNotificationPermissionIfNeeded() }, // ← new
|
||||
onRequestNotificationPermission = { requestNotificationPermissionIfNeeded() },
|
||||
onComplete = {}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -130,7 +130,8 @@ fun OnboardingScreen(
|
||||
secretStore.setOnboarded() // moved here from PAGE_BATTERY
|
||||
onComplete()
|
||||
}
|
||||
}
|
||||
},
|
||||
strings
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user