refactor: i18n HistoryStrings

This commit is contained in:
2026-06-11 23:34:48 +02:00
parent b053da6a05
commit 868869fd88
11 changed files with 980 additions and 535 deletions
@@ -141,6 +141,225 @@ val EnHomeStrings = AppStrings(
sendVmUnsupportedType = { tag -> "Unsupported type: $tag" },
sendVmPaymentFailedRescan = "Payment failed — could not re-fetch address",
// // ── HistoryScreen ─────────────────────────────────────────────────────────
// historyTitle = "Activity",
// historyClose = "Close",
// historySearchPayments = "Search payments",
// historyFilterPayments = "Filter payments",
// historyRetry = "Retry",
// historyNoPayments = "No payments yet.",
// historySearchPlaceholder = "Search transactions",
// historySearchHelp = "Search help",
// historySearchPaste = "Paste",
// historySearchClear = "Clear search",
// historySearchChip = { tail -> "search: …$tail" },
// historyClearSearch = "Clear search",
// filterDirectionOutgoing = "Outgoing",
// filterDirectionIncoming = "Incoming",
// filterClearDirection = "Clear direction filter",
// filterStatusCompleted = "Completed",
// filterStatusPending = "Pending",
// filterStatusFailed = "Failed",
// filterRemoveStatus = "Remove status filter",
// filterRemoveType = "Remove type filter",
// filterAmountRange = { min, max -> "$min$max sats" },
// filterAmountMin = { min -> "≥ $min sats" },
// filterAmountMax = { max -> "≤ $max sats" },
// filterClearAmount = "Clear amount filter",
// filterDateThisWeek = "This week",
// filterDateThisMonth = "This month",
// filterDateThisYear = "This year",
// filterDateRange = { from, to -> "$from$to" },
// filterDateFrom = { from -> "From $from" },
// filterDateUntil = { until -> "Until $until" },
// filterClearDate = "Clear date filter",
//
// // ── FilterBottomSheet ─────────────────────────────────────────────────────
// filterSheetTitle = "Filter payments",
// filterSectionDirection = "Direction",
// filterDirectionAll = "All",
// filterSectionStatus = "Status",
// filterSectionType = "Type",
// filterSectionAmount = "Amount (sats)",
// filterAmountMin_label = "Min",
// filterAmountMax_label = "Max",
// filterAmountSuffix = "sats",
// filterSectionDate = "Date",
// filterDateFrom_label = "From",
// filterDateTo_label = "To",
// filterDialogOk = "OK",
// filterDialogCancel = "Cancel",
//
// // ── SearchInfoSheet ───────────────────────────────────────────────────────
// searchInfoTitle = "What can I search for?",
// searchInfoSubtitle = "Type any part of the following to find a payment:",
// searchInfoMemoTitle = "Memo",
// searchInfoMemoDesc = "The message or description attached to a payment. " +
// "For example, \"coffee\" or \"rent March\".",
// searchInfoInvoiceTitle = "Invoice",
// searchInfoInvoiceDesc = "The payment request you scanned or pasted to send a payment. " +
// "It usually starts with \"lnbc…\". " +
// "You can paste just the first or last few characters.",
// searchInfoHashTitle = "Hash",
// searchInfoHashDesc = "A unique code that identifies this payment on the " +
// "Lightning Network. Useful if someone asks you to " +
// "confirm a specific transaction.",
// searchInfoPreimageTitle = "Preimage",
// searchInfoPreimageDesc = "A secret code that proves a payment was received. " +
// "Only available after a payment completes successfully.",
// searchInfoNodeAliasTitle = "Node alias",
// searchInfoNodeAliasDesc = "The name of the Lightning node you sent a payment to. " +
// "For example, \"ACINQ\" or \"Wallet of Satoshi\". " +
// "Aliases are resolved automatically for outgoing payments.",
// searchInfoNodeIdTitle = "Node ID (pubkey)",
// searchInfoNodeIdDesc = "The public key of the destination node. " +
// "A 66-character hex string — you can paste just the first few characters.",
// searchInfoFooter = "You can paste a full value or search with just a few characters — " +
// "partial matches work too.",
//
// // ── PaymentDetailScreen ───────────────────────────────────────────────────
// statusSuccess = "Success", // e.g. "Success"
// statusPending = "Pending", // e.g. "Pending"
// statusFailed = "Failed", // e.g. "Failed"
// statusUnknown = "Unknown", // e.g. "Unknown"
// detailOutgoingTitle = "Outgoing payment",
// detailIncomingTitle = "Incoming payment",
// detailBack = "Back",
// detailCouldNotLoad = "Could not load full details",
// detailFeeLabel = { feeSat, fiatPart, ppmPart ->
// "Fee: $feeSat sats$fiatPart$ppmPart"
// },
// detailSectionDetails = "Details",
// detailRowDate = "Date",
// detailRowMemo = "Memo",
// detailRowMemoEmpty = "—",
// detailRowType = "Type",
// detailRowComment = "Comment",
// detailSectionSuccessAction = "Success Action",
// detailSuccessMessage = "Message",
// detailSuccessUrl = "URL",
// detailSuccessDescription = "Description",
// detailSectionTechnical = "Technical",
// detailRowPaymentHash = "Hash",
// detailRowPreimage = "Preimage",
// detailRowDestination = "Destination",
// detailCopyNodeId = "Copy node ID",
// detailRowBolt11 = "BOLT11",
//
// // ── PaymentRow ────────────────────────────────────────────────────────────
// paymentRowSentCD = "Sent",
// paymentRowReceivedCD = "Received",
// paymentRowNoMemo = "No memo",
// paymentRowPending = "Pending",
// paymentRowFailed = "Failed",
onboarding = OnboardingStrings(
back = "Back",
next = "Next",
done = "Done",
title = "Connect to LNbits",
subtitle = "Enter your LNbits server URL and API keys.",
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.",
invalidKeyFormat = "Invalid key format",
connect = "Connect",
notificationsTitle = "Stay in the loop",
notificationsSubtitle = "Get notified instantly when you receive a payment.",
notificationsAlreadyGranted = "You're all set - permissions have been granted.",
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.",
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"
),
receive = ReceiveStrings(
// ── ReceiveScreen — general ───────────────────────────────────────────────
receive = "Receive",
// ── ReceiveScreen — error ─────────────────────────────────────────────────
receiveError = "Error",
// ── ReceiveScreen — QR / share ────────────────────────────────────────────
lightningAddressQrCode = "Lightning address QR code",
lightningAddressLabel = "Lightning Address",
shareLightningAddress = "Share Lightning Address",
lightningInvoiceQrCode = "Lightning invoice QR code",
invoiceLabel = "Invoice",
shareInvoice = "Share Invoice",
// ── ReceiveScreen — amount step ───────────────────────────────────────────
amountInSats = "Amount (sats)",
satsRange = { min, max -> "$min $max sats" },
// ── ReceiveScreen — memo step ─────────────────────────────────────────────
memoOptional = "Memo (optional)",
memoPlaceholder = "What's this for?",
creatingInvoice = "Creating invoice…",
createInvoice = "Create Invoice",
// ── ReceiveScreen — invoice ready ─────────────────────────────────────────
waiting = "Waiting…",
invoiceExpired = "Invoice expired",
newInvoice = "New Invoice",
// ── ReceiveScreen — lnurl withdraw ────────────────────────────────────────
withdrawFrom = "Withdraw from",
minimumSats = { min -> "Minimum is $min sats" },
maximumSats = { max -> "Maximum is $max sats" },
withdrawButton = "Withdraw",
withdrawButtonAmount = { amount -> "Withdraw $amount sats" },
// ── ReceiveScreen — success ───────────────────────────────────────────────
paymentReceived = "Payment Received!",
// ── AmountDisplay ─────────────────────────────────────────────────────────
amountDisplaySats = { amount -> "$amount ${if (amount == 1L) "sat" else "sats"}" },
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
brightnessReduce = "Reduce brightness",
brightnessBoost = "Boost brightness",
qrShare = "Share",
qrCopy = "Copy",
qrNfcStop = "Stop NFC sharing",
qrNfcStart = "Share via NFC",
openInApp = "Open in app",
noAppFound = "No compatible app found",
// ── ReceiveViewModel ──────────────────────────────────────────────────────
receiveVmFailedToCreateInvoice = "Failed to create invoice",
receiveVmWithdrawRejected = "Withdraw service rejected the invoice",
receiveVmWithdrawFailed = "Withdraw failed",
),
history = HistoryStrings(
// ── HistoryScreen ─────────────────────────────────────────────────────────
historyTitle = "Activity",
historyClose = "Close",
@@ -252,111 +471,6 @@ val EnHomeStrings = AppStrings(
paymentRowNoMemo = "No memo",
paymentRowPending = "Pending",
paymentRowFailed = "Failed",
onboarding = OnboardingStrings(
back = "Back",
next = "Next",
done = "Done",
title = "Connect to LNbits",
subtitle = "Enter your LNbits server URL and API keys.",
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.",
invalidKeyFormat = "Invalid key format",
connect = "Connect",
notificationsTitle = "Stay in the loop",
notificationsSubtitle = "Get notified instantly when you receive a payment.",
notificationsAlreadyGranted = "You're all set - permissions have been granted.",
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.",
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"
),
receive = ReceiveStrings(
// ── ReceiveScreen — general ───────────────────────────────────────────────
receive = "Receive",
// ── ReceiveScreen — error ─────────────────────────────────────────────────
receiveError = "Error",
// ── ReceiveScreen — QR / share ────────────────────────────────────────────
lightningAddressQrCode = "Lightning address QR code",
lightningAddressLabel = "Lightning Address",
shareLightningAddress = "Share Lightning Address",
lightningInvoiceQrCode = "Lightning invoice QR code",
invoiceLabel = "Invoice",
shareInvoice = "Share Invoice",
// ── ReceiveScreen — amount step ───────────────────────────────────────────
amountInSats = "Amount (sats)",
satsRange = { min, max -> "$min $max sats" },
// ── ReceiveScreen — memo step ─────────────────────────────────────────────
memoOptional = "Memo (optional)",
memoPlaceholder = "What's this for?",
creatingInvoice = "Creating invoice…",
createInvoice = "Create Invoice",
// ── ReceiveScreen — invoice ready ─────────────────────────────────────────
waiting = "Waiting…",
invoiceExpired = "Invoice expired",
newInvoice = "New Invoice",
// ── ReceiveScreen — lnurl withdraw ────────────────────────────────────────
withdrawFrom = "Withdraw from",
minimumSats = { min -> "Minimum is $min sats" },
maximumSats = { max -> "Maximum is $max sats" },
withdrawButton = "Withdraw",
withdrawButtonAmount = { amount -> "Withdraw $amount sats" },
// ── ReceiveScreen — success ───────────────────────────────────────────────
paymentReceived = "Payment Received!",
// ── AmountDisplay ─────────────────────────────────────────────────────────
amountDisplaySats = { amount -> "$amount ${if (amount == 1L) "sat" else "sats"}" },
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
brightnessReduce = "Reduce brightness",
brightnessBoost = "Boost brightness",
qrShare = "Share",
qrCopy = "Copy",
qrNfcStop = "Stop NFC sharing",
qrNfcStart = "Share via NFC",
openInApp = "Open in app",
noAppFound = "No compatible app found",
// ── ReceiveViewModel ──────────────────────────────────────────────────────
receiveVmFailedToCreateInvoice = "Failed to create invoice",
receiveVmWithdrawRejected = "Withdraw service rejected the invoice",
receiveVmWithdrawFailed = "Withdraw failed",
),
nwc = NwcStrings(
@@ -141,6 +141,226 @@ val EsHomeStrings = AppStrings(
sendVmUnsupportedType = { tag -> "Tipo no compatible: $tag" },
sendVmPaymentFailedRescan = "Pago fallido — no se pudo volver a obtener la dirección",
//// ── HistoryScreen ─────────────────────────────────────────────────────────
// historyTitle = "Historial",
// historyClose = "Cerrar",
// historySearchPayments = "Buscar pagos",
// historyFilterPayments = "Filtrar pagos",
// historyRetry = "Reintentar",
// historyNoPayments = "Aún no hay pagos.",
// historySearchPlaceholder = "Buscar transacciones",
// historySearchHelp = "Ayuda de búsqueda",
// historySearchPaste = "Pegar",
// historySearchClear = "Limpiar búsqueda",
// historySearchChip = { tail -> "búsqueda: …$tail" },
// historyClearSearch = "Limpiar búsqueda",
// filterDirectionOutgoing = "Salientes",
// filterDirectionIncoming = "Entrantes",
// filterClearDirection = "Quitar filtro de dirección",
// filterStatusCompleted = "Completado",
// filterStatusPending = "Pendiente",
// filterStatusFailed = "Fallido",
// filterRemoveStatus = "Quitar filtro de estado",
// filterRemoveType = "Quitar filtro de tipo",
// filterAmountRange = { min, max -> "$min$max sats" },
// filterAmountMin = { min -> "≥ $min sats" },
// filterAmountMax = { max -> "≤ $max sats" },
// filterClearAmount = "Quitar filtro de cantidad",
// filterDateThisWeek = "Esta semana",
// filterDateThisMonth = "Este mes",
// filterDateThisYear = "Este año",
// filterDateRange = { from, to -> "$from$to" },
// filterDateFrom = { from -> "Desde $from" },
// filterDateUntil = { until -> "Hasta $until" },
// filterClearDate = "Quitar filtro de fecha",
//
// // ── FilterBottomSheet ─────────────────────────────────────────────────────
// filterSheetTitle = "Filtrar pagos",
// filterSectionDirection = "Dirección",
// filterDirectionAll = "Todos",
// filterSectionStatus = "Estado",
// filterSectionType = "Tipo",
// filterSectionAmount = "Cantidad (sats)",
// filterAmountMin_label = "Mín.",
// filterAmountMax_label = "Máx.",
// filterAmountSuffix = "sats",
// filterSectionDate = "Fecha",
// filterDateFrom_label = "Desde",
// filterDateTo_label = "Hasta",
// filterDialogOk = "Aceptar",
// filterDialogCancel = "Cancelar",
//
// // ── SearchInfoSheet ───────────────────────────────────────────────────────
// searchInfoTitle = "¿Qué puedo buscar?",
// searchInfoSubtitle = "Escribe cualquier parte de lo siguiente para encontrar un pago:",
// searchInfoMemoTitle = "Nota",
// searchInfoMemoDesc = "El mensaje o descripción adjunto a un pago. " +
// "Por ejemplo, \"café\" o \"alquiler marzo\".",
// searchInfoInvoiceTitle = "Factura",
// searchInfoInvoiceDesc = "La solicitud de pago que escaneaste o pegaste para enviar un pago. " +
// "Normalmente empieza por \"lnbc…\". " +
// "Puedes pegar solo los primeros o últimos caracteres.",
// searchInfoHashTitle = "Hash",
// searchInfoHashDesc = "Un código único que identifica este pago en la " +
// "red Lightning. Útil si alguien te pide que " +
// "confirmes una transacción específica.",
// searchInfoPreimageTitle = "Preimagen",
// searchInfoPreimageDesc = "Un código secreto que demuestra que se recibió un pago. " +
// "Solo disponible después de que un pago se complete correctamente.",
// searchInfoNodeAliasTitle = "Alias del nodo",
// searchInfoNodeAliasDesc = "El nombre del nodo Lightning al que enviaste un pago. " +
// "Por ejemplo, \"ACINQ\" o \"Wallet of Satoshi\". " +
// "Los alias se resuelven automáticamente para pagos salientes.",
// searchInfoNodeIdTitle = "ID del nodo (clave pública)",
// searchInfoNodeIdDesc = "La clave pública del nodo de destino. " +
// "Una cadena hexadecimal de 66 caracteres — puedes pegar solo los primeros.",
// searchInfoFooter = "Puedes pegar un valor completo o buscar con solo unos pocos caracteres — " +
// "las coincidencias parciales también funcionan.",
//
// // ── PaymentDetailScreen ───────────────────────────────────────────────────
// statusSuccess = "Completado",
// statusPending = "Pendiente",
// statusFailed = "Fallido",
// statusUnknown = "Desconocido",
// detailOutgoingTitle = "Pago saliente",
// detailIncomingTitle = "Pago entrante",
// detailBack = "Atrás",
// detailCouldNotLoad = "No se pudieron cargar los detalles completos",
// detailFeeLabel = { feeSat, fiatPart, ppmPart ->
// "Comisión: $feeSat sats$fiatPart$ppmPart"
// },
// detailSectionDetails = "Detalles",
// detailRowDate = "Fecha",
// detailRowMemo = "Nota",
// detailRowMemoEmpty = "—",
// detailRowType = "Tipo",
// detailRowComment = "Comentario",
// detailSectionSuccessAction = "Acción de éxito",
// detailSuccessMessage = "Mensaje",
// detailSuccessUrl = "URL",
// detailSuccessDescription = "Descripción",
// detailSectionTechnical = "Técnico",
// detailRowPaymentHash = "Hash",
// detailRowPreimage = "Preimagen",
// detailRowDestination = "Destino",
// detailCopyNodeId = "Copiar ID del nodo",
// detailRowBolt11 = "BOLT11",
//
// // ── PaymentRow ────────────────────────────────────────────────────────────
// paymentRowSentCD = "Enviado",
// paymentRowReceivedCD = "Recibido",
// paymentRowNoMemo = "Sin nota",
// paymentRowPending = "Pendiente",
// paymentRowFailed = "Fallido",
onboarding = OnboardingStrings(
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 = "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.",
invalidKeyFormat = "Formato de clave no válido",
connect = "Conectar",
notificationsTitle = "Mantente al día",
notificationsSubtitle = "Recibe notificaciones al instante cuando recibas un pago.",
notificationsAlreadyGranted = "Todo listo — los permisos han sido concedidos.",
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"
),
receive = ReceiveStrings(
// ── ReceiveScreen — general ───────────────────────────────────────────────
receive = "Recibir",
// ── ReceiveScreen — error ─────────────────────────────────────────────────
receiveError = "Error",
// ── ReceiveScreen — QR / share ────────────────────────────────────────────
lightningAddressQrCode = "Código QR de dirección Lightning",
lightningAddressLabel = "Dirección Lightning",
shareLightningAddress = "Compartir dirección Lightning",
lightningInvoiceQrCode = "Código QR de factura Lightning",
invoiceLabel = "Factura",
shareInvoice = "Compartir factura",
// ── ReceiveScreen — amount step ───────────────────────────────────────────
amountInSats = "Cantidad (sats)",
satsRange = { min, max -> "$min $max sats" },
// ── ReceiveScreen — memo step ─────────────────────────────────────────────
memoOptional = "Nota (opcional)",
memoPlaceholder = "¿Para qué es esto?",
creatingInvoice = "Creando factura…",
createInvoice = "Crear factura",
// ── ReceiveScreen — invoice ready ─────────────────────────────────────────
waiting = "Esperando…",
invoiceExpired = "Factura expirada",
newInvoice = "Nueva factura",
// ── ReceiveScreen — lnurl withdraw ────────────────────────────────────────
withdrawFrom = "Retirar de",
minimumSats = { min -> "Mínimo es $min sats" },
maximumSats = { max -> "Máximo es $max sats" },
withdrawButton = "Retirar",
withdrawButtonAmount = { amount -> "Retirar $amount sats" },
// ── ReceiveScreen — success ───────────────────────────────────────────────
paymentReceived = "¡Pago recibido!",
// ── AmountDisplay ─────────────────────────────────────────────────────────
amountDisplaySats = { amount -> "$amount ${if (amount == 1L) "sat" else "sats"}" },
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
brightnessReduce = "Reducir brillo",
brightnessBoost = "Aumentar brillo",
qrShare = "Compartir",
qrCopy = "Copiar",
qrNfcStop = "Detener NFC",
qrNfcStart = "Compartir por NFC",
openInApp = "Abrir en app",
noAppFound = "No hay aplicación compatible",
// ── ReceiveViewModel ──────────────────────────────────────────────────────
receiveVmFailedToCreateInvoice = "No se pudo crear la factura",
receiveVmWithdrawRejected = "El servicio de retiro rechazó la factura",
receiveVmWithdrawFailed = "Error al retirar",
),
history = HistoryStrings(
// ── HistoryScreen ─────────────────────────────────────────────────────────
historyTitle = "Historial",
historyClose = "Cerrar",
@@ -252,112 +472,6 @@ val EsHomeStrings = AppStrings(
paymentRowNoMemo = "Sin nota",
paymentRowPending = "Pendiente",
paymentRowFailed = "Fallido",
onboarding = OnboardingStrings(
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 = "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.",
invalidKeyFormat = "Formato de clave no válido",
connect = "Conectar",
notificationsTitle = "Mantente al día",
notificationsSubtitle = "Recibe notificaciones al instante cuando recibas un pago.",
notificationsAlreadyGranted = "Todo listo — los permisos han sido concedidos.",
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"
),
receive = ReceiveStrings(
// ── ReceiveScreen — general ───────────────────────────────────────────────
receive = "Recibir",
// ── ReceiveScreen — error ─────────────────────────────────────────────────
receiveError = "Error",
// ── ReceiveScreen — QR / share ────────────────────────────────────────────
lightningAddressQrCode = "Código QR de dirección Lightning",
lightningAddressLabel = "Dirección Lightning",
shareLightningAddress = "Compartir dirección Lightning",
lightningInvoiceQrCode = "Código QR de factura Lightning",
invoiceLabel = "Factura",
shareInvoice = "Compartir factura",
// ── ReceiveScreen — amount step ───────────────────────────────────────────
amountInSats = "Cantidad (sats)",
satsRange = { min, max -> "$min $max sats" },
// ── ReceiveScreen — memo step ─────────────────────────────────────────────
memoOptional = "Nota (opcional)",
memoPlaceholder = "¿Para qué es esto?",
creatingInvoice = "Creando factura…",
createInvoice = "Crear factura",
// ── ReceiveScreen — invoice ready ─────────────────────────────────────────
waiting = "Esperando…",
invoiceExpired = "Factura expirada",
newInvoice = "Nueva factura",
// ── ReceiveScreen — lnurl withdraw ────────────────────────────────────────
withdrawFrom = "Retirar de",
minimumSats = { min -> "Mínimo es $min sats" },
maximumSats = { max -> "Máximo es $max sats" },
withdrawButton = "Retirar",
withdrawButtonAmount = { amount -> "Retirar $amount sats" },
// ── ReceiveScreen — success ───────────────────────────────────────────────
paymentReceived = "¡Pago recibido!",
// ── AmountDisplay ─────────────────────────────────────────────────────────
amountDisplaySats = { amount -> "$amount ${if (amount == 1L) "sat" else "sats"}" },
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
brightnessReduce = "Reducir brillo",
brightnessBoost = "Aumentar brillo",
qrShare = "Compartir",
qrCopy = "Copiar",
qrNfcStop = "Detener NFC",
qrNfcStart = "Compartir por NFC",
openInApp = "Abrir en app",
noAppFound = "No hay aplicación compatible",
// ── ReceiveViewModel ──────────────────────────────────────────────────────
receiveVmFailedToCreateInvoice = "No se pudo crear la factura",
receiveVmWithdrawRejected = "El servicio de retiro rechazó la factura",
receiveVmWithdrawFailed = "Error al retirar",
),
nwc = NwcStrings(
@@ -141,6 +141,225 @@ val EuStrings = AppStrings(
sendVmUnsupportedType = { tag -> "Mota onartzen ez dena: $tag" },
sendVmPaymentFailedRescan = "Ordainketak huts egin du — ezin izan da helbidea berriro eskuratu",
// // ── HistoryScreen ─────────────────────────────────────────────────────────
// historyTitle = "Historia",
// historyClose = "Itxi",
// historySearchPayments = "Bilatu ordainketak",
// historyFilterPayments = "Iragazi ordainketak",
// historyRetry = "Saiatu berriro",
// historyNoPayments = "Oraindik ez dago ordainketarik.",
// historySearchPlaceholder = "Bilatu transakzioak",
// historySearchHelp = "Bilaketa-laguntza",
// historySearchPaste = "Itsatsi",
// historySearchClear = "Garbitu bilaketa",
// historySearchChip = { tail -> "bilaketa: …$tail" },
// historyClearSearch = "Garbitu bilaketa",
// filterDirectionOutgoing = "Irteerako",
// filterDirectionIncoming = "Sarrerako",
// filterClearDirection = "Garbitu norabide-iragazkia",
// filterStatusCompleted = "Osatuta",
// filterStatusPending = "Zain",
// filterStatusFailed = "Huts eginda",
// filterRemoveStatus = "Kendu egoera-iragazkia",
// filterRemoveType = "Kendu mota-iragazkia",
// filterAmountRange = { min, max -> "$min$max sat" },
// filterAmountMin = { min -> "≥ $min sat" },
// filterAmountMax = { max -> "≤ $max sat" },
// filterClearAmount = "Garbitu zenbateko-iragazkia",
// filterDateThisWeek = "Aste honetan",
// filterDateThisMonth = "Hilabete honetan",
// filterDateThisYear = "Urte honetan",
// filterDateRange = { from, to -> "$from$to" },
// filterDateFrom = { from -> "$from-tik" },
// filterDateUntil = { until -> "$until arte" },
// filterClearDate = "Garbitu data-iragazkia",
//
// // ── FilterBottomSheet ─────────────────────────────────────────────────────
// filterSheetTitle = "Iragazi ordainketak",
// filterSectionDirection = "Norabidea",
// filterDirectionAll = "Guztiak",
// filterSectionStatus = "Egoera",
// filterSectionType = "Mota",
// filterSectionAmount = "Zenbatekoa (sat)",
// filterAmountMin_label = "Gutxienekoa",
// filterAmountMax_label = "Gehienekoa",
// filterAmountSuffix = "sat",
// filterSectionDate = "Data",
// filterDateFrom_label = "Nondik",
// filterDateTo_label = "Nora arte",
// filterDialogOk = "Ados",
// filterDialogCancel = "Utzi",
//
// // ── SearchInfoSheet ───────────────────────────────────────────────────────
// searchInfoTitle = "Zer bila dezaket?",
// searchInfoSubtitle = "Idatzi hurrengoetako edozein zati ordainketa bat aurkitzeko:",
// searchInfoMemoTitle = "Oharra",
// searchInfoMemoDesc = "Ordainketa bati erantsitako mezua edo deskribapena. " +
// "Adibidez, \"kafea\" edo \"martxoko alokairua\".",
// searchInfoInvoiceTitle = "Faktura",
// searchInfoInvoiceDesc = "Ordainketa bat bidaltzeko eskaneatu edo itsatsi zenuen ordainketa-eskaera. " +
// "Normalean \"lnbc…\" hasierarekin dator. " +
// "Lehen edo azken karaktere batzuk bakarrik itsats ditzakezu.",
// searchInfoHashTitle = "Hash",
// searchInfoHashDesc = "Ordainketa hau Lightning Sarean identifikatzen duen kode bakarra. " +
// "Erabilgarria norbaitek transakzio zehatz bat berresteko eskatzen dizunean.",
// searchInfoPreimageTitle = "Aurre-irudia",
// searchInfoPreimageDesc = "Ordainketa bat jaso dela frogatzen duen kode sekretua. " +
// "Ordainketa arrakastaz osatu ondoren bakarrik dago erabilgarri.",
// searchInfoNodeAliasTitle = "Nodo-izengoitia",
// searchInfoNodeAliasDesc = "Ordainketa bidali zenion Lightning nodoaren izena. " +
// "Adibidez, \"ACINQ\" edo \"Wallet of Satoshi\". " +
// "Izengoitiak automatikoki ebazten dira irteerako ordainketetan.",
// searchInfoNodeIdTitle = "Nodo IDa (gako publikoa)",
// searchInfoNodeIdDesc = "Helmuga-nodoaren gako publikoa. " +
// "66 karaktereko hex katea — lehen karaktere batzuk bakarrik itsats ditzakezu.",
// searchInfoFooter = "Balio osoa itsatsi dezakezu edo karaktere gutxi batzuekin bilatu — " +
// "zati-bat datozenak ere funtzionatzen dute.",
//
// // ── PaymentDetailScreen ───────────────────────────────────────────────────
// statusSuccess = "Osatuta",
// statusPending = "Zain",
// statusFailed = "Huts eginda",
// statusUnknown = "Ezezaguna",
// detailOutgoingTitle = "Irteerako ordainketa",
// detailIncomingTitle = "Sarrerako ordainketa",
// detailBack = "Atzera",
// detailCouldNotLoad = "Ezin izan dira xehetasun osoak kargatu",
// detailFeeLabel = { feeSat, fiatPart, ppmPart ->
// "Komisioa: $feeSat sat$fiatPart$ppmPart"
// },
// detailSectionDetails = "Xehetasunak",
// detailRowDate = "Data",
// detailRowMemo = "Oharra",
// detailRowMemoEmpty = "—",
// detailRowType = "Mota",
// detailRowComment = "Iruzkina",
// detailSectionSuccessAction = "Arrakasta-ekintza",
// detailSuccessMessage = "Mezua",
// detailSuccessUrl = "URLa",
// detailSuccessDescription = "Deskribapena",
// detailSectionTechnical = "Teknikoa",
// detailRowPaymentHash = "Hash",
// detailRowPreimage = "Aurre-irudia",
// detailRowDestination = "Helmuga",
// detailCopyNodeId = "Kopiatu nodo IDa",
// detailRowBolt11 = "BOLT11",
//
// // ── PaymentRow ────────────────────────────────────────────────────────────
// paymentRowSentCD = "Bidalita",
// paymentRowReceivedCD = "Jasota",
// paymentRowNoMemo = "Oharrik gabe",
// paymentRowPending = "Zain",
// paymentRowFailed = "Huts eginda",
onboarding = OnboardingStrings(
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 = "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.",
invalidKeyFormat = "Gako formatu baliogabea",
connect = "Konektatu",
notificationsTitle = "Egon eguneratuta",
notificationsSubtitle = "Jaso jakinarazpenak berehala transakzio bat jasotzen duzunean.",
notificationsAlreadyGranted = "Dena prest dago — baimenak emanda daude.",
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"
),
receive = ReceiveStrings(
// ── ReceiveScreen — general ───────────────────────────────────────────────
receive = "Jaso",
// ── ReceiveScreen — error ─────────────────────────────────────────────────
receiveError = "Errorea",
// ── ReceiveScreen — QR / share ────────────────────────────────────────────
lightningAddressQrCode = "Lightning helbidearen QR kodea",
lightningAddressLabel = "Lightning helbidea",
shareLightningAddress = "Partekatu Lightning helbidea",
lightningInvoiceQrCode = "Lightning fakturaren QR kodea",
invoiceLabel = "Faktura",
shareInvoice = "Partekatu faktura",
// ── ReceiveScreen — amount step ───────────────────────────────────────────
amountInSats = "Zenbatekoa (sat)",
satsRange = { min, max -> "$min $max sat" },
// ── ReceiveScreen — memo step ─────────────────────────────────────────────
memoOptional = "Oharra (aukerakoa)",
memoPlaceholder = "Zertarako da hau?",
creatingInvoice = "Faktura sortzen…",
createInvoice = "Sortu faktura",
// ── ReceiveScreen — invoice ready ─────────────────────────────────────────
waiting = "Zain…",
invoiceExpired = "Faktura iraungita",
newInvoice = "Faktura berria",
// ── ReceiveScreen — lnurl withdraw ────────────────────────────────────────
withdrawFrom = "Atera hemendik:",
minimumSats = { min -> "Gutxienekoa $min sat da" },
maximumSats = { max -> "Gehienekoa $max sat da" },
withdrawButton = "Atera",
withdrawButtonAmount = { amount -> "Atera $amount sat" },
// ── ReceiveScreen — success ───────────────────────────────────────────────
paymentReceived = "Ordainketa jasota!",
// ── AmountDisplay ─────────────────────────────────────────────────────────
amountDisplaySats = { amount -> "$amount sat" },
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
brightnessReduce = "Murriztu distira",
brightnessBoost = "Handitu distira",
qrShare = "Partekatu",
qrCopy = "Kopiatu",
qrNfcStop = "Gelditu NFC partekatzea",
qrNfcStart = "Partekatu NFC bidez",
openInApp = "Ireki aplikazioan",
noAppFound = "Ez da aurkitu aplikazio bateragarririk",
// ── ReceiveViewModel ──────────────────────────────────────────────────────
receiveVmFailedToCreateInvoice = "Ezin izan da faktura sortu",
receiveVmWithdrawRejected = "Ateratzeko zerbitzuak faktura baztertu du",
receiveVmWithdrawFailed = "Ateratzeak huts egin du",
),
history = HistoryStrings(
// ── HistoryScreen ─────────────────────────────────────────────────────────
historyTitle = "Historia",
historyClose = "Itxi",
@@ -251,113 +470,8 @@ val EuStrings = AppStrings(
paymentRowNoMemo = "Oharrik gabe",
paymentRowPending = "Zain",
paymentRowFailed = "Huts eginda",
onboarding = OnboardingStrings(
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 = "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.",
invalidKeyFormat = "Gako formatu baliogabea",
connect = "Konektatu",
notificationsTitle = "Egon eguneratuta",
notificationsSubtitle = "Jaso jakinarazpenak berehala transakzio bat jasotzen duzunean.",
notificationsAlreadyGranted = "Dena prest dago — baimenak emanda daude.",
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"
),
receive = ReceiveStrings(
// ── ReceiveScreen — general ───────────────────────────────────────────────
receive = "Jaso",
// ── ReceiveScreen — error ─────────────────────────────────────────────────
receiveError = "Errorea",
// ── ReceiveScreen — QR / share ────────────────────────────────────────────
lightningAddressQrCode = "Lightning helbidearen QR kodea",
lightningAddressLabel = "Lightning helbidea",
shareLightningAddress = "Partekatu Lightning helbidea",
lightningInvoiceQrCode = "Lightning fakturaren QR kodea",
invoiceLabel = "Faktura",
shareInvoice = "Partekatu faktura",
// ── ReceiveScreen — amount step ───────────────────────────────────────────
amountInSats = "Zenbatekoa (sat)",
satsRange = { min, max -> "$min $max sat" },
// ── ReceiveScreen — memo step ─────────────────────────────────────────────
memoOptional = "Oharra (aukerakoa)",
memoPlaceholder = "Zertarako da hau?",
creatingInvoice = "Faktura sortzen…",
createInvoice = "Sortu faktura",
// ── ReceiveScreen — invoice ready ─────────────────────────────────────────
waiting = "Zain…",
invoiceExpired = "Faktura iraungita",
newInvoice = "Faktura berria",
// ── ReceiveScreen — lnurl withdraw ────────────────────────────────────────
withdrawFrom = "Atera hemendik:",
minimumSats = { min -> "Gutxienekoa $min sat da" },
maximumSats = { max -> "Gehienekoa $max sat da" },
withdrawButton = "Atera",
withdrawButtonAmount = { amount -> "Atera $amount sat" },
// ── ReceiveScreen — success ───────────────────────────────────────────────
paymentReceived = "Ordainketa jasota!",
// ── AmountDisplay ─────────────────────────────────────────────────────────
amountDisplaySats = { amount -> "$amount sat" },
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
brightnessReduce = "Murriztu distira",
brightnessBoost = "Handitu distira",
qrShare = "Partekatu",
qrCopy = "Kopiatu",
qrNfcStop = "Gelditu NFC partekatzea",
qrNfcStart = "Partekatu NFC bidez",
openInApp = "Ireki aplikazioan",
noAppFound = "Ez da aurkitu aplikazio bateragarririk",
// ── ReceiveViewModel ──────────────────────────────────────────────────────
receiveVmFailedToCreateInvoice = "Ezin izan da faktura sortu",
receiveVmWithdrawRejected = "Ateratzeko zerbitzuak faktura baztertu du",
receiveVmWithdrawFailed = "Ateratzeak huts egin du",
),
nwc = NwcStrings(
// ── Shared ────────────────────────────────────────────────────────────────
back = "Atzera",
@@ -149,108 +149,109 @@ data class AppStrings(
val sendVmUnsupportedType : (tag: String) -> String,
val sendVmPaymentFailedRescan : String,
// ── HistoryScreen ─────────────────────────────────────────────────────────
val historyTitle : String,
val historyClose : String,
val historySearchPayments : String,
val historyFilterPayments : String,
val historyRetry : String,
val historyNoPayments : String,
val historySearchPlaceholder : String,
val historySearchHelp : String,
val historySearchPaste : String,
val historySearchClear : String,
val historySearchChip : (tail: String) -> String,
val historyClearSearch : String,
val filterDirectionOutgoing : String,
val filterDirectionIncoming : String,
val filterClearDirection : String,
val filterStatusCompleted : String,
val filterStatusPending : String,
val filterStatusFailed : String,
val filterRemoveStatus : String,
val filterRemoveType : String,
val filterAmountRange : (min: Long, max: Long) -> String,
val filterAmountMin : (min: Long) -> String,
val filterAmountMax : (max: Long) -> String,
val filterClearAmount : String,
val filterDateThisWeek : String,
val filterDateThisMonth : String,
val filterDateThisYear : String,
val filterDateRange : (from: String, to: String) -> String,
val filterDateFrom : (from: String) -> String,
val filterDateUntil : (until: String) -> String,
val filterClearDate : String,
// ── FilterBottomSheet ─────────────────────────────────────────────────────
val filterSheetTitle : String,
val filterSectionDirection : String,
val filterDirectionAll : String,
val filterSectionStatus : String,
val filterSectionType : String,
val filterSectionAmount : String,
val filterAmountMin_label : String,
val filterAmountMax_label : String,
val filterAmountSuffix : String,
val filterSectionDate : String,
val filterDateFrom_label : String,
val filterDateTo_label : String,
val filterDialogOk : String,
val filterDialogCancel : String,
// ── SearchInfoSheet ───────────────────────────────────────────────────────
val searchInfoTitle : String,
val searchInfoSubtitle : String,
val searchInfoMemoTitle : String,
val searchInfoMemoDesc : String,
val searchInfoInvoiceTitle : String,
val searchInfoInvoiceDesc : String,
val searchInfoHashTitle : String,
val searchInfoHashDesc : String,
val searchInfoPreimageTitle : String,
val searchInfoPreimageDesc : String,
val searchInfoNodeAliasTitle : String,
val searchInfoNodeAliasDesc : String,
val searchInfoNodeIdTitle : String,
val searchInfoNodeIdDesc : String,
val searchInfoFooter : String,
// ── PaymentDetailScreen ───────────────────────────────────────────────────
val statusSuccess : String, // e.g. "Success"
val statusPending : String, // e.g. "Pending"
val statusFailed : String, // e.g. "Failed"
val statusUnknown : String, // e.g. "Unknown"
val detailOutgoingTitle : String,
val detailIncomingTitle : String,
val detailBack : String,
val detailCouldNotLoad : String,
val detailFeeLabel : (feeSat: Long, fiatPart: String, ppmPart: String) -> String,
val detailSectionDetails : String,
val detailRowDate : String,
val detailRowMemo : String,
val detailRowMemoEmpty : String,
val detailRowType : String,
val detailRowComment : String,
val detailSectionSuccessAction: String,
val detailSuccessMessage : String,
val detailSuccessUrl : String,
val detailSuccessDescription : String,
val detailSectionTechnical : String,
val detailRowPaymentHash : String,
val detailRowPreimage : String,
val detailRowDestination : String,
val detailCopyNodeId : String,
val detailRowBolt11 : String,
// ── PaymentRow ────────────────────────────────────────────────────────────
val paymentRowSentCD : String,
val paymentRowReceivedCD : String,
val paymentRowNoMemo : String,
val paymentRowPending : String,
val paymentRowFailed : String,
// // ── HistoryScreen ─────────────────────────────────────────────────────────
// val historyTitle : String,
// val historyClose : String,
// val historySearchPayments : String,
// val historyFilterPayments : String,
// val historyRetry : String,
// val historyNoPayments : String,
// val historySearchPlaceholder : String,
// val historySearchHelp : String,
// val historySearchPaste : String,
// val historySearchClear : String,
// val historySearchChip : (tail: String) -> String,
// val historyClearSearch : String,
// val filterDirectionOutgoing : String,
// val filterDirectionIncoming : String,
// val filterClearDirection : String,
// val filterStatusCompleted : String,
// val filterStatusPending : String,
// val filterStatusFailed : String,
// val filterRemoveStatus : String,
// val filterRemoveType : String,
// val filterAmountRange : (min: Long, max: Long) -> String,
// val filterAmountMin : (min: Long) -> String,
// val filterAmountMax : (max: Long) -> String,
// val filterClearAmount : String,
// val filterDateThisWeek : String,
// val filterDateThisMonth : String,
// val filterDateThisYear : String,
// val filterDateRange : (from: String, to: String) -> String,
// val filterDateFrom : (from: String) -> String,
// val filterDateUntil : (until: String) -> String,
// val filterClearDate : String,
//
// // ── FilterBottomSheet ─────────────────────────────────────────────────────
// val filterSheetTitle : String,
// val filterSectionDirection : String,
// val filterDirectionAll : String,
// val filterSectionStatus : String,
// val filterSectionType : String,
// val filterSectionAmount : String,
// val filterAmountMin_label : String,
// val filterAmountMax_label : String,
// val filterAmountSuffix : String,
// val filterSectionDate : String,
// val filterDateFrom_label : String,
// val filterDateTo_label : String,
// val filterDialogOk : String,
// val filterDialogCancel : String,
//
// // ── SearchInfoSheet ───────────────────────────────────────────────────────
// val searchInfoTitle : String,
// val searchInfoSubtitle : String,
// val searchInfoMemoTitle : String,
// val searchInfoMemoDesc : String,
// val searchInfoInvoiceTitle : String,
// val searchInfoInvoiceDesc : String,
// val searchInfoHashTitle : String,
// val searchInfoHashDesc : String,
// val searchInfoPreimageTitle : String,
// val searchInfoPreimageDesc : String,
// val searchInfoNodeAliasTitle : String,
// val searchInfoNodeAliasDesc : String,
// val searchInfoNodeIdTitle : String,
// val searchInfoNodeIdDesc : String,
// val searchInfoFooter : String,
//
// // ── PaymentDetailScreen ───────────────────────────────────────────────────
// val statusSuccess : String, // e.g. "Success"
// val statusPending : String, // e.g. "Pending"
// val statusFailed : String, // e.g. "Failed"
// val statusUnknown : String, // e.g. "Unknown"
// val detailOutgoingTitle : String,
// val detailIncomingTitle : String,
// val detailBack : String,
// val detailCouldNotLoad : String,
// val detailFeeLabel : (feeSat: Long, fiatPart: String, ppmPart: String) -> String,
// val detailSectionDetails : String,
// val detailRowDate : String,
// val detailRowMemo : String,
// val detailRowMemoEmpty : String,
// val detailRowType : String,
// val detailRowComment : String,
// val detailSectionSuccessAction: String,
// val detailSuccessMessage : String,
// val detailSuccessUrl : String,
// val detailSuccessDescription : String,
// val detailSectionTechnical : String,
// val detailRowPaymentHash : String,
// val detailRowPreimage : String,
// val detailRowDestination : String,
// val detailCopyNodeId : String,
// val detailRowBolt11 : String,
//
// // ── PaymentRow ────────────────────────────────────────────────────────────
// val paymentRowSentCD : String,
// val paymentRowReceivedCD : String,
// val paymentRowNoMemo : String,
// val paymentRowPending : String,
// val paymentRowFailed : String,
val onboarding: OnboardingStrings,
val receive: ReceiveStrings,
val history: HistoryStrings,
val nwc: NwcStrings
)
@@ -360,6 +361,108 @@ data class ReceiveStrings(
val receiveVmWithdrawFailed : String,
)
data class HistoryStrings(
// ── HistoryScreen ─────────────────────────────────────────────────────────
val historyTitle : String,
val historyClose : String,
val historySearchPayments : String,
val historyFilterPayments : String,
val historyRetry : String,
val historyNoPayments : String,
val historySearchPlaceholder : String,
val historySearchHelp : String,
val historySearchPaste : String,
val historySearchClear : String,
val historySearchChip : (tail: String) -> String,
val historyClearSearch : String,
val filterDirectionOutgoing : String,
val filterDirectionIncoming : String,
val filterClearDirection : String,
val filterStatusCompleted : String,
val filterStatusPending : String,
val filterStatusFailed : String,
val filterRemoveStatus : String,
val filterRemoveType : String,
val filterAmountRange : (min: Long, max: Long) -> String,
val filterAmountMin : (min: Long) -> String,
val filterAmountMax : (max: Long) -> String,
val filterClearAmount : String,
val filterDateThisWeek : String,
val filterDateThisMonth : String,
val filterDateThisYear : String,
val filterDateRange : (from: String, to: String) -> String,
val filterDateFrom : (from: String) -> String,
val filterDateUntil : (until: String) -> String,
val filterClearDate : String,
// ── FilterBottomSheet ─────────────────────────────────────────────────────
val filterSheetTitle : String,
val filterSectionDirection : String,
val filterDirectionAll : String,
val filterSectionStatus : String,
val filterSectionType : String,
val filterSectionAmount : String,
val filterAmountMin_label : String,
val filterAmountMax_label : String,
val filterAmountSuffix : String,
val filterSectionDate : String,
val filterDateFrom_label : String,
val filterDateTo_label : String,
val filterDialogOk : String,
val filterDialogCancel : String,
// ── SearchInfoSheet ───────────────────────────────────────────────────────
val searchInfoTitle : String,
val searchInfoSubtitle : String,
val searchInfoMemoTitle : String,
val searchInfoMemoDesc : String,
val searchInfoInvoiceTitle : String,
val searchInfoInvoiceDesc : String,
val searchInfoHashTitle : String,
val searchInfoHashDesc : String,
val searchInfoPreimageTitle : String,
val searchInfoPreimageDesc : String,
val searchInfoNodeAliasTitle : String,
val searchInfoNodeAliasDesc : String,
val searchInfoNodeIdTitle : String,
val searchInfoNodeIdDesc : String,
val searchInfoFooter : String,
// ── PaymentDetailScreen ───────────────────────────────────────────────────
val statusSuccess : String, // e.g. "Success"
val statusPending : String, // e.g. "Pending"
val statusFailed : String, // e.g. "Failed"
val statusUnknown : String, // e.g. "Unknown"
val detailOutgoingTitle : String,
val detailIncomingTitle : String,
val detailBack : String,
val detailCouldNotLoad : String,
val detailFeeLabel : (feeSat: Long, fiatPart: String, ppmPart: String) -> String,
val detailSectionDetails : String,
val detailRowDate : String,
val detailRowMemo : String,
val detailRowMemoEmpty : String,
val detailRowType : String,
val detailRowComment : String,
val detailSectionSuccessAction: String,
val detailSuccessMessage : String,
val detailSuccessUrl : String,
val detailSuccessDescription : String,
val detailSectionTechnical : String,
val detailRowPaymentHash : String,
val detailRowPreimage : String,
val detailRowDestination : String,
val detailCopyNodeId : String,
val detailRowBolt11 : String,
// ── PaymentRow ────────────────────────────────────────────────────────────
val paymentRowSentCD : String,
val paymentRowReceivedCD : String,
val paymentRowNoMemo : String,
val paymentRowPending : String,
val paymentRowFailed : String,
)
data class NwcStrings(
// ── Shared / navigation ───────────────────────────────────────────────────
@@ -1,8 +1,8 @@
package com.bitcointxoko.gudariwallet.i18n
fun AppStrings.paymentStatusLabel(status: String): String = when (status.lowercase()) {
"success" -> statusSuccess
"pending" -> statusPending
"failed" -> statusFailed
else -> statusUnknown
"success" -> history.statusSuccess
"pending" -> history.statusPending
"failed" -> history.statusFailed
else -> history.statusUnknown
}
@@ -24,18 +24,18 @@ internal fun StatusChip(status: String) {
val style = when (status.lowercase()) {
"success", "complete", "paid" -> ChipStyle(
semantic.successContainer, semantic.onSuccessContainer, strings.statusSuccess
semantic.successContainer, semantic.onSuccessContainer, strings.history.statusSuccess
)
"pending", "in_flight", "inflight" -> ChipStyle(
semantic.warningContainer, semantic.onWarningContainer, strings.statusPending
semantic.warningContainer, semantic.onWarningContainer, strings.history.statusPending
)
"failed", "error", "expired" -> ChipStyle(
semantic.errorContainer, semantic.onErrorContainer, strings.statusFailed
semantic.errorContainer, semantic.onErrorContainer, strings.history.statusFailed
)
else -> ChipStyle(
MaterialTheme.colorScheme.surfaceVariant,
MaterialTheme.colorScheme.onSurfaceVariant,
strings.statusUnknown,
strings.history.statusUnknown,
)
}
@@ -62,14 +62,14 @@ internal fun FilterBottomSheet(
) {
// ── Sheet title ───────────────────────────────────────────────────
Text(
text = strings.filterSheetTitle, // ← "Filter payments"
text = strings.history.filterSheetTitle, // ← "Filter payments"
style = MaterialTheme.typography.titleMedium
)
Spacer(Modifier.height(20.dp))
// ── Direction ─────────────────────────────────────────────────────
Text(
text = strings.filterSectionDirection, // ← "Direction"
text = strings.history.filterSectionDirection, // ← "Direction"
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -77,9 +77,9 @@ internal fun FilterBottomSheet(
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
DirectionFilter.entries.forEach { option ->
val label = when (option) {
DirectionFilter.ALL -> strings.filterDirectionAll // ← "All"
DirectionFilter.OUTGOING -> strings.filterDirectionOutgoing // ← "Outgoing"
DirectionFilter.INCOMING -> strings.filterDirectionIncoming // ← "Incoming"
DirectionFilter.ALL -> strings.history.filterDirectionAll // ← "All"
DirectionFilter.OUTGOING -> strings.history.filterDirectionOutgoing // ← "Outgoing"
DirectionFilter.INCOMING -> strings.history.filterDirectionIncoming // ← "Incoming"
}
FilterChip(
selected = currentFilter.direction == option,
@@ -92,7 +92,7 @@ internal fun FilterBottomSheet(
// ── Status ────────────────────────────────────────────────────────
Text(
text = strings.filterSectionStatus, // ← "Status"
text = strings.history.filterSectionStatus, // ← "Status"
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -105,9 +105,9 @@ internal fun FilterBottomSheet(
label = {
Text(
when (option) {
StatusFilter.COMPLETED -> strings.filterStatusCompleted // ← "Completed"
StatusFilter.PENDING -> strings.filterStatusPending // ← "Pending"
StatusFilter.FAILED -> strings.filterStatusFailed // ← "Failed"
StatusFilter.COMPLETED -> strings.history.filterStatusCompleted // ← "Completed"
StatusFilter.PENDING -> strings.history.filterStatusPending // ← "Pending"
StatusFilter.FAILED -> strings.history.filterStatusFailed // ← "Failed"
}
)
}
@@ -119,7 +119,7 @@ internal fun FilterBottomSheet(
if (availableTypes.isNotEmpty()) {
Spacer(Modifier.height(20.dp))
Text(
text = strings.filterSectionType, // ← "Type"
text = strings.history.filterSectionType, // ← "Type"
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -138,7 +138,7 @@ internal fun FilterBottomSheet(
// ── Amount (sats) ─────────────────────────────────────────────────
Text(
text = strings.filterSectionAmount, // ← "Amount (sats)"
text = strings.history.filterSectionAmount, // ← "Amount (sats)"
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -159,8 +159,8 @@ internal fun FilterBottomSheet(
OutlinedTextField(
value = minText,
onValueChange = { minText = it.filter(Char::isDigit); commitAmount() },
label = { Text(strings.filterAmountMin_label) }, // ← "Min"
suffix = { Text(strings.filterAmountSuffix) }, // ← "sats"
label = { Text(strings.history.filterAmountMin_label) }, // ← "Min"
suffix = { Text(strings.history.filterAmountSuffix) }, // ← "sats"
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier.weight(1f)
@@ -169,8 +169,8 @@ internal fun FilterBottomSheet(
OutlinedTextField(
value = maxText,
onValueChange = { maxText = it.filter(Char::isDigit); commitAmount() },
label = { Text(strings.filterAmountMax_label) }, // ← "Max"
suffix = { Text(strings.filterAmountSuffix) }, // ← "sats"
label = { Text(strings.history.filterAmountMax_label) }, // ← "Max"
suffix = { Text(strings.history.filterAmountSuffix) }, // ← "sats"
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier.weight(1f)
@@ -180,7 +180,7 @@ internal fun FilterBottomSheet(
// ── Date ──────────────────────────────────────────────────────────
Text(
text = strings.filterSectionDate, // ← "Date"
text = strings.history.filterSectionDate, // ← "Date"
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -190,9 +190,9 @@ internal fun FilterBottomSheet(
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
DatePreset.entries.forEach { preset ->
val label = when (preset) {
DatePreset.THIS_WEEK -> strings.filterDateThisWeek // ← "This week"
DatePreset.THIS_MONTH -> strings.filterDateThisMonth // ← "This month"
DatePreset.THIS_YEAR -> strings.filterDateThisYear // ← "This year"
DatePreset.THIS_WEEK -> strings.history.filterDateThisWeek // ← "This week"
DatePreset.THIS_MONTH -> strings.history.filterDateThisMonth // ← "This month"
DatePreset.THIS_YEAR -> strings.history.filterDateThisYear // ← "This year"
}
FilterChip(
selected = currentFilter.datePreset == preset,
@@ -221,7 +221,7 @@ internal fun FilterBottomSheet(
Text(
currentFilter.minCreatedAt
?.let { formatEpochShort(it) }
?: strings.filterDateFrom_label // ← "From"
?: strings.history.filterDateFrom_label // ← "From"
)
}
Text("", style = MaterialTheme.typography.bodyLarge)
@@ -232,7 +232,7 @@ internal fun FilterBottomSheet(
Text(
currentFilter.maxCreatedAt
?.let { formatEpochShort(it) }
?: strings.filterDateTo_label // ← "To"
?: strings.history.filterDateTo_label // ← "To"
)
}
}
@@ -248,11 +248,11 @@ internal fun FilterBottomSheet(
val epochSec = pickerState.selectedDateMillis?.div(1000)
onDateFilterSet(epochSec, currentFilter.maxCreatedAt)
showFromPicker = false
}) { Text(strings.filterDialogOk) } // ← "OK"
}) { Text(strings.history.filterDialogOk) } // ← "OK"
},
dismissButton = {
TextButton(onClick = { showFromPicker = false }) {
Text(strings.filterDialogCancel) // ← "Cancel"
Text(strings.history.filterDialogCancel) // ← "Cancel"
}
}
) { DatePicker(state = pickerState) }
@@ -270,11 +270,11 @@ internal fun FilterBottomSheet(
val epochSec = pickerState.selectedDateMillis?.div(1000)?.let { it + 86399L }
onDateFilterSet(currentFilter.minCreatedAt, epochSec)
showToPicker = false
}) { Text(strings.filterDialogOk) } // ← "OK"
}) { Text(strings.history.filterDialogOk) } // ← "OK"
},
dismissButton = {
TextButton(onClick = { showToPicker = false }) {
Text(strings.filterDialogCancel) // ← "Cancel"
Text(strings.history.filterDialogCancel) // ← "Cancel"
}
}
) { DatePicker(state = pickerState) }
@@ -89,12 +89,12 @@ fun HistoryScreen(
Scaffold(
topBar = {
TopAppBar(
title = { Text(strings.historyTitle) }, // ← "History"
title = { Text(strings.history.historyTitle) }, // ← "History"
navigationIcon = {
IconButton(onClick = onClose) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.historyClose // ← "Close"
contentDescription = strings.history.historyClose // ← "Close"
)
}
},
@@ -108,7 +108,7 @@ fun HistoryScreen(
}) {
Icon(
imageVector = Icons.Default.Search,
contentDescription = strings.historySearchPayments // ← "Search payments"
contentDescription = strings.history.historySearchPayments // ← "Search payments"
)
}
}
@@ -118,7 +118,7 @@ fun HistoryScreen(
IconButton(onClick = { filterSheetVisible = true }) {
Icon(
imageVector = Icons.Default.FilterList,
contentDescription = strings.historyFilterPayments // ← "Filter payments"
contentDescription = strings.history.historyFilterPayments // ← "Filter payments"
)
}
}
@@ -191,7 +191,7 @@ fun HistoryScreen(
)
Spacer(Modifier.height(12.dp))
Button(onClick = { vm.refresh() }) {
Text(strings.historyRetry) // ← "Retry"
Text(strings.history.historyRetry) // ← "Retry"
}
}
}
@@ -210,7 +210,7 @@ fun HistoryScreen(
if (s.payments.isEmpty()) {
Text(
text = strings.historyNoPayments, // ← "No payments yet."
text = strings.history.historyNoPayments, // ← "No payments yet."
modifier = Modifier.align(Alignment.Center),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
@@ -310,13 +310,13 @@ private fun SearchBar(
IconButton(onClick = onInfoClick) {
Icon(
imageVector = Icons.Default.Info,
contentDescription = strings.historySearchHelp // ← "Search help"
contentDescription = strings.history.historySearchHelp // ← "Search help"
)
}
TextField(
value = query,
onValueChange = onQueryChange,
placeholder = { Text(strings.historySearchPlaceholder) }, // ← "Search transactions"
placeholder = { Text(strings.history.historySearchPlaceholder) }, // ← "Search transactions"
singleLine = true,
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
@@ -337,7 +337,7 @@ private fun SearchBar(
}) {
Icon(
imageVector = Icons.Default.ContentPaste,
contentDescription = strings.historySearchPaste // ← "Paste"
contentDescription = strings.history.historySearchPaste // ← "Paste"
)
}
IconButton(
@@ -346,7 +346,7 @@ private fun SearchBar(
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.historySearchClear, // ← "Clear search"
contentDescription = strings.history.historySearchClear, // ← "Clear search"
tint = if (query.isNotEmpty()) LocalContentColor.current
else MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
)
@@ -382,15 +382,15 @@ private fun ActiveFilterChips(
label = {
Text(
when (filter.direction) {
DirectionFilter.OUTGOING -> strings.filterDirectionOutgoing // ← "Outgoing"
else -> strings.filterDirectionIncoming // ← "Incoming"
DirectionFilter.OUTGOING -> strings.history.filterDirectionOutgoing // ← "Outgoing"
else -> strings.history.filterDirectionIncoming // ← "Incoming"
}
)
},
trailingIcon = {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.filterClearDirection, // ← "Clear direction filter"
contentDescription = strings.history.filterClearDirection, // ← "Clear direction filter"
modifier = Modifier.size(16.dp)
)
}
@@ -403,16 +403,16 @@ private fun ActiveFilterChips(
label = {
Text(
when (s) {
StatusFilter.COMPLETED -> strings.filterStatusCompleted // ← "Completed"
StatusFilter.PENDING -> strings.filterStatusPending // ← "Pending"
StatusFilter.FAILED -> strings.filterStatusFailed // ← "Failed"
StatusFilter.COMPLETED -> strings.history.filterStatusCompleted // ← "Completed"
StatusFilter.PENDING -> strings.history.filterStatusPending // ← "Pending"
StatusFilter.FAILED -> strings.history.filterStatusFailed // ← "Failed"
}
)
},
trailingIcon = {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.filterRemoveStatus, // ← "Remove status filter"
contentDescription = strings.history.filterRemoveStatus, // ← "Remove status filter"
modifier = Modifier.size(16.dp)
)
}
@@ -426,7 +426,7 @@ private fun ActiveFilterChips(
trailingIcon = {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.filterRemoveType, // ← "Remove type filter"
contentDescription = strings.history.filterRemoveType, // ← "Remove type filter"
modifier = Modifier.size(16.dp)
)
}
@@ -435,11 +435,11 @@ private fun ActiveFilterChips(
if (filter.minAmountSat != null || filter.maxAmountSat != null) {
val label = when {
filter.minAmountSat != null && filter.maxAmountSat != null ->
strings.filterAmountRange(filter.minAmountSat, filter.maxAmountSat) // ← "XY sats"
strings.history.filterAmountRange(filter.minAmountSat, filter.maxAmountSat) // ← "XY sats"
filter.minAmountSat != null ->
strings.filterAmountMin(filter.minAmountSat) // ← "≥ X sats"
strings.history.filterAmountMin(filter.minAmountSat) // ← "≥ X sats"
else ->
strings.filterAmountMax(filter.maxAmountSat!!) // ← "≤ X sats"
strings.history.filterAmountMax(filter.maxAmountSat!!) // ← "≤ X sats"
}
InputChip(
selected = true,
@@ -448,7 +448,7 @@ private fun ActiveFilterChips(
trailingIcon = {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.filterClearAmount, // ← "Clear amount filter"
contentDescription = strings.history.filterClearAmount, // ← "Clear amount filter"
modifier = Modifier.size(16.dp)
)
}
@@ -458,19 +458,19 @@ private fun ActiveFilterChips(
val maxCreatedAt = filter.maxCreatedAt
if (minCreatedAt != null || maxCreatedAt != null) {
val label = when (filter.datePreset) {
DatePreset.THIS_WEEK -> strings.filterDateThisWeek // ← "This week"
DatePreset.THIS_MONTH -> strings.filterDateThisMonth // ← "This month"
DatePreset.THIS_YEAR -> strings.filterDateThisYear // ← "This year"
DatePreset.THIS_WEEK -> strings.history.filterDateThisWeek // ← "This week"
DatePreset.THIS_MONTH -> strings.history.filterDateThisMonth // ← "This month"
DatePreset.THIS_YEAR -> strings.history.filterDateThisYear // ← "This year"
null -> when {
minCreatedAt != null && maxCreatedAt != null ->
strings.filterDateRange( // ← "XY"
strings.history.filterDateRange( // ← "XY"
formatEpochShort(minCreatedAt),
formatEpochShort(maxCreatedAt)
)
minCreatedAt != null ->
strings.filterDateFrom(formatEpochShort(minCreatedAt)) // ← "From X"
strings.history.filterDateFrom(formatEpochShort(minCreatedAt)) // ← "From X"
else ->
strings.filterDateUntil(formatEpochShort(maxCreatedAt!!)) // ← "Until X"
strings.history.filterDateUntil(formatEpochShort(maxCreatedAt!!)) // ← "Until X"
}
}
InputChip(
@@ -480,7 +480,7 @@ private fun ActiveFilterChips(
trailingIcon = {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.filterClearDate, // ← "Clear date filter"
contentDescription = strings.history.filterClearDate, // ← "Clear date filter"
modifier = Modifier.size(16.dp)
)
}
@@ -490,11 +490,11 @@ private fun ActiveFilterChips(
InputChip(
selected = true,
onClick = onClearSearch,
label = { Text(strings.historySearchChip(filter.searchQuery.takeLast(8))) }, // ← "search: …XXXXXXXX"
label = { Text(strings.history.historySearchChip(filter.searchQuery.takeLast(8))) }, // ← "search: …XXXXXXXX"
trailingIcon = {
Icon(
imageVector = Icons.Default.Close,
contentDescription = strings.historyClearSearch, // ← "Clear search"
contentDescription = strings.history.historyClearSearch, // ← "Clear search"
modifier = Modifier.size(16.dp)
)
}
@@ -92,15 +92,15 @@ fun PaymentDetailScreen(
TopAppBar(
title = {
Text(
if (payment.isOutgoing) strings.detailOutgoingTitle // ← "Outgoing payment"
else strings.detailIncomingTitle // ← "Incoming payment"
if (payment.isOutgoing) strings.history.detailOutgoingTitle // ← "Outgoing payment"
else strings.history.detailIncomingTitle // ← "Incoming payment"
)
},
navigationIcon = {
IconButton(onClick = onBack) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = strings.detailBack // ← "Back"
contentDescription = strings.history.detailBack // ← "Back"
)
}
}
@@ -122,7 +122,7 @@ fun PaymentDetailScreen(
modifier = Modifier.fillMaxWidth()
) {
Text(
text = strings.detailCouldNotLoad, // ← "Could not load full details"
text = strings.history.detailCouldNotLoad, // ← "Could not load full details"
color = MaterialTheme.colorScheme.onErrorContainer,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(12.dp)
@@ -215,7 +215,7 @@ private fun PaymentDetailContent(
// Build the optional parts separately so the lambda stays clean
val fiatPart = if (feeFiat != null) " ($feeFiat)" else ""
val ppmPart = if (ppm != null) " · $ppm ppm" else ""
val feeLabel = strings.detailFeeLabel( // ← "Fee: X sats (fiat) · Y ppm"
val feeLabel = strings.history.detailFeeLabel( // ← "Fee: X sats (fiat) · Y ppm"
payment.feeSat, fiatPart, ppmPart
)
Spacer(Modifier.height(4.dp))
@@ -233,17 +233,17 @@ private fun PaymentDetailContent(
// ── Basic info ───────────────────────────────────────────────────────
item {
DetailSection(title = strings.detailSectionDetails) { // ← "Details"
DetailRow(strings.detailRowDate, formatTimestamp(payment.createdAt, payment.time)) // ← "Date"
DetailSection(title = strings.history.detailSectionDetails) { // ← "Details"
DetailRow(strings.history.detailRowDate, formatTimestamp(payment.createdAt, payment.time)) // ← "Date"
DetailRow(
strings.detailRowMemo, // ← "Memo"
payment.memo?.takeIf { it.isNotBlank() } ?: strings.detailRowMemoEmpty // ← "—"
strings.history.detailRowMemo, // ← "Memo"
payment.memo?.takeIf { it.isNotBlank() } ?: strings.history.detailRowMemoEmpty // ← "—"
)
if (payment.extra?.tag != null) {
DetailRow(strings.detailRowType, payment.extra.tag) // ← "Type"
DetailRow(strings.history.detailRowType, payment.extra.tag) // ← "Type"
}
if (payment.extra?.comment?.isNotBlank() == true) {
DetailRow(strings.detailRowComment, payment.extra.comment) // ← "Comment"
DetailRow(strings.history.detailRowComment, payment.extra.comment) // ← "Comment"
}
}
}
@@ -251,19 +251,19 @@ private fun PaymentDetailContent(
// ── Success action (LNURL) ───────────────────────────────────────────
payment.extra?.successAction?.let { action ->
item {
DetailSection(title = strings.detailSectionSuccessAction) { // ← "Success Action"
action.message?.let { DetailRow(strings.detailSuccessMessage, it) } // ← "Message"
action.url?.let { DetailRow(strings.detailSuccessUrl, it) } // ← "URL"
action.description?.let { DetailRow(strings.detailSuccessDescription, it) } // ← "Description"
DetailSection(title = strings.history.detailSectionSuccessAction) { // ← "Success Action"
action.message?.let { DetailRow(strings.history.detailSuccessMessage, it) } // ← "Message"
action.url?.let { DetailRow(strings.history.detailSuccessUrl, it) } // ← "URL"
action.description?.let { DetailRow(strings.history.detailSuccessDescription, it) } // ← "Description"
}
}
}
// ── Technical ────────────────────────────────────────────────────────
item {
DetailSection(title = strings.detailSectionTechnical) { // ← "Technical"
DetailSection(title = strings.history.detailSectionTechnical) { // ← "Technical"
DetailRow(
label = strings.detailRowPaymentHash, // ← "Payment Hash"
label = strings.history.detailRowPaymentHash, // ← "Payment Hash"
value = payment.paymentHash,
monospace = true,
copyable = true,
@@ -277,7 +277,7 @@ private fun PaymentDetailContent(
)
if (!payment.preimage.isNullOrBlank() && payment.preimage != "0".repeat(64)) {
DetailRow(
label = strings.detailRowPreimage, // ← "Preimage"
label = strings.history.detailRowPreimage, // ← "Preimage"
value = payment.preimage,
monospace = true,
copyable = true,
@@ -294,7 +294,7 @@ private fun PaymentDetailContent(
val ambossUrl = "https://amboss.space/node/$pubkey"
val label = alias ?: "${pubkey.take(8)}${pubkey.takeLast(8)}"
DetailRow(
label = strings.detailRowDestination, // ← "Destination"
label = strings.history.detailRowDestination, // ← "Destination"
value = label,
valueColor = MaterialTheme.colorScheme.primary,
textDecoration = androidx.compose.ui.text.style.TextDecoration.Underline,
@@ -308,7 +308,7 @@ private fun PaymentDetailContent(
}
if (!payment.bolt11.isNullOrBlank()) {
DetailRow(
label = strings.detailRowBolt11, // ← "BOLT11"
label = strings.history.detailRowBolt11, // ← "BOLT11"
value = payment.bolt11,
monospace = true,
copyable = true,
@@ -61,8 +61,8 @@ internal fun PaymentRow(
) {
Icon(
imageVector = icon,
contentDescription = if (payment.isOutgoing) strings.paymentRowSentCD // ← "Sent"
else strings.paymentRowReceivedCD, // ← "Received"
contentDescription = if (payment.isOutgoing) strings.history.paymentRowSentCD // ← "Sent"
else strings.history.paymentRowReceivedCD, // ← "Received"
tint = amountColor,
modifier = Modifier.size(20.dp)
)
@@ -71,7 +71,7 @@ internal fun PaymentRow(
Column(modifier = Modifier.weight(1f)) {
Text(
text = payment.memo?.takeIf { it.isNotBlank() }
?: strings.paymentRowNoMemo, // ← "No memo"
?: strings.history.paymentRowNoMemo, // ← "No memo"
style = MaterialTheme.typography.bodyMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis
@@ -86,8 +86,8 @@ internal fun PaymentRow(
color = MaterialTheme.colorScheme.onSurfaceVariant
)
val statusLabel = when {
isPending -> strings.paymentRowPending
isFailed -> strings.paymentRowFailed
isPending -> strings.history.paymentRowPending
isFailed -> strings.history.paymentRowFailed
else -> null
}
val statusColor = when {
@@ -33,45 +33,45 @@ internal fun SearchInfoSheet(visible: Boolean, onDismiss: () -> Unit) {
.padding(start = 24.dp, end = 24.dp, bottom = 40.dp)
) {
Text(
text = strings.searchInfoTitle, // ← "What can I search for?"
text = strings.history.searchInfoTitle, // ← "What can I search for?"
style = MaterialTheme.typography.titleMedium
)
Spacer(Modifier.height(8.dp))
Text(
text = strings.searchInfoSubtitle, // ← "Type any part of the following…"
text = strings.history.searchInfoSubtitle, // ← "Type any part of the following…"
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(Modifier.height(20.dp))
SearchInfoItem(
title = strings.searchInfoMemoTitle, // ← "Memo"
description = strings.searchInfoMemoDesc
title = strings.history.searchInfoMemoTitle, // ← "Memo"
description = strings.history.searchInfoMemoDesc
)
SearchInfoItem(
title = strings.searchInfoInvoiceTitle, // ← "Invoice"
description = strings.searchInfoInvoiceDesc
title = strings.history.searchInfoInvoiceTitle, // ← "Invoice"
description = strings.history.searchInfoInvoiceDesc
)
SearchInfoItem(
title = strings.searchInfoHashTitle, // ← "Hash"
description = strings.searchInfoHashDesc
title = strings.history.searchInfoHashTitle, // ← "Hash"
description = strings.history.searchInfoHashDesc
)
SearchInfoItem(
title = strings.searchInfoPreimageTitle, // ← "Preimage"
description = strings.searchInfoPreimageDesc
title = strings.history.searchInfoPreimageTitle, // ← "Preimage"
description = strings.history.searchInfoPreimageDesc
)
SearchInfoItem(
title = strings.searchInfoNodeAliasTitle, // ← "Node alias"
description = strings.searchInfoNodeAliasDesc
title = strings.history.searchInfoNodeAliasTitle, // ← "Node alias"
description = strings.history.searchInfoNodeAliasDesc
)
SearchInfoItem(
title = strings.searchInfoNodeIdTitle, // ← "Node ID (pubkey)"
description = strings.searchInfoNodeIdDesc
title = strings.history.searchInfoNodeIdTitle, // ← "Node ID (pubkey)"
description = strings.history.searchInfoNodeIdDesc
)
Spacer(Modifier.height(16.dp))
Text(
text = strings.searchInfoFooter, // ← "You can paste a full value…"
text = strings.history.searchInfoFooter, // ← "You can paste a full value…"
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)