feat: localisation with lyricist

This commit is contained in:
2026-06-05 23:57:05 +02:00
parent 890dd0004a
commit 5af1dc32ca
3 changed files with 441 additions and 0 deletions
@@ -0,0 +1,144 @@
package com.bitcointxoko.gudariwallet.i18n
import cafe.adriel.lyricist.LyricistStrings
@LyricistStrings(languageTag = "en", default = true)
val EnHomeStrings = AppStrings(
// ── HomeTab ───────────────────────────────────────────────────────────────
loadingBalance = "Loading balance…",
sats = "sats",
hideBalance = "Hide balance",
revealBalance = "Reveal balance",
changeCurrency = "Change currency",
showFiat = "+ Show fiat",
updatedAt = { label -> "Updated $label" },
justNow = "just now",
minAgo = {min -> "$min ago"},
atTime = {time -> "at $time"},
viewHistory = "View History",
selectCurrency = "Select currency",
currencyNone = "None",
hideFiatEquivalent = "Hide fiat equivalent",
selected = "Selected",
search = "Search…",
noCurrenciesAvailable = "No currencies available",
noCurrenciesMatch = { query -> "No currencies match \"$query\"" },
couldNotRefresh = "Could not refresh — pull down to try again",
couldNotLoadBalance = "Could not load balance — pull down to try again",
// ── Shared ────────────────────────────────────────────────────────────────
cancel = "Cancel",
tryAgain = "Try Again",
amount = "Amount",
next = "Next",
back = "← Back",
done = "Done",
details = "Details",
enterValidAmount = "Enter a valid amount",
satsUnit = { sats -> "$sats sats" },
// ── 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!",
// ── SendScreen — general ──────────────────────────────────────────────────
send = "Send",
paste = "Paste",
continueButton = "Continue",
clear = "Clear",
sendAnother = "Send Another",
// ── SendScreen — input field ──────────────────────────────────────────────
sendInputLabel = "Invoice, LNURL, or Lightning Address",
sendInputPlaceholder = "lnbc… / lnurl1… / user@domain.com",
tapNfcHint = "Tap NFC device to receive invoice",
// ── SendScreen — states ───────────────────────────────────────────────────
resolving = "Resolving…",
sendingPayment = "Sending payment…",
// ── SendScreen — payment sent ─────────────────────────────────────────────
paymentSent = "Payment sent!",
amountSats = { sats -> "$sats sats" },
fiatEquivalent = { fiatStr -> "$fiatStr" },
noFees = "No fees",
routingFee = { sats, ppmSuffix -> "Routing fee: $sats sat${if (sats == 1L) "" else "s"}$ppmSuffix" },
// ── ConfirmCard ───────────────────────────────────────────────────────────
invoiceDetails = "Invoice Details",
payingTo = { label -> "Paying to $label" },
confirmAmount = { sats -> "$sats sats" },
confirmAmountWithFiat = { sats, fiat -> "$sats sats · $fiat" },
memo = "Memo",
destination = "Destination",
created = "Created",
expiresIn = "Expires in",
hash = "Hash",
invoice = "Invoice",
expiryExpired = "Expired",
expirySeconds = { s -> "${s}s" },
expiryMinutes = { m, s -> "${m}m ${s}s" },
expiryHours = { h, m -> "${h}h ${m}m" },
createdToday = { time -> "Today, $time" },
createdYesterday = { time -> "Yesterday, $time" },
payButton = { sats -> "Pay $sats sats" },
payButtonWithFiat = { sats, fiat -> "Pay $sats sats · $fiat" },
sendBiometricPrompt = { sats -> "Send $sats sats" },
sendBiometricPromptTo = { sats, label -> "Send $sats sats to $label" },
// ── LnurlPayForm ─────────────────────────────────────────────────────────
lnurlAmountError = { min, max -> "Enter an amount between $min and $max sats" },
lnurlFiatRange = { minFiat, maxFiat -> "$minFiat $maxFiat" },
lnurlSatsAndFiatRange = { min, max, minFiat, maxFiat -> "$min $max sats · $minFiat $maxFiat" },
commentOptional = { max -> "Comment (optional, max $max chars)" },
commentCounter = { current, max -> "$current/$max" },
lnurlPayButton = { sats -> "Pay $sats sats" },
lnurlPayButtonWithFiat = { sats, fiat -> "Pay $sats sats · $fiat" },
// ── RouteHintWarning ──────────────────────────────────────────────────────
routeHintHighFees = "High routing fees in invoice",
routeHintElevatedFees = "Elevated routing fees in invoice",
routeHintForcedChannel = { node -> "This invoice forces payment through a private channel operated by $node." },
routeHintFeeRate = { effectivePpm, worstPpm -> "Effective fee rate: $effectivePpm ppm ($worstPpm ppm)" },
routeHintFeeRateBase = { effectivePpm, worstPpm, baseLabel -> "Effective fee rate: $effectivePpm ppm ($worstPpm ppm + $baseLabel base)" },
routeHintEstimatedFee = { sats -> "Estimated extra fee on this payment: ~$sats sat${if (sats == 1L) "" else "s"}" },
routeHintShowDetails = "See details ▾",
routeHintHideDetails = "Hide details ▴",
routeHintHopsHeader = "Private route hint hops",
routeHintHopFees = { ppm, baseLabel -> "$ppm ppm · $baseLabel base" },
)
@@ -0,0 +1,144 @@
package com.bitcointxoko.gudariwallet.i18n
import cafe.adriel.lyricist.LyricistStrings
@LyricistStrings(languageTag = "es")
val EsHomeStrings = AppStrings(
// ── HomeTab ───────────────────────────────────────────────────────────────
loadingBalance = "Cargando saldo…",
sats = "sats",
hideBalance = "Ocultar saldo",
revealBalance = "Mostrar saldo",
changeCurrency = "Cambiar moneda",
showFiat = "+ Mostrar fiat",
updatedAt = { label -> "Actualizado $label" },
justNow = "justo ahora",
minAgo = {min -> "hace $min min"},
atTime = {time -> "a las $time"},
viewHistory = "Ver historial",
selectCurrency = "Seleccionar moneda",
currencyNone = "Ninguna",
hideFiatEquivalent = "Ocultar equivalente fiat",
selected = "Seleccionado",
search = "Buscar…",
noCurrenciesAvailable = "No hay monedas disponibles",
noCurrenciesMatch = { query -> "Ninguna moneda coincide con \"$query\"" },
couldNotRefresh = "No se pudo actualizar — desliza hacia abajo para reintentar",
couldNotLoadBalance = "No se pudo cargar el saldo — desliza hacia abajo para reintentar",
// ── Shared ────────────────────────────────────────────────────────────────
cancel = "Cancelar",
tryAgain = "Reintentar",
amount = "Cantidad",
next = "Siguiente",
back = "← Atrás",
done = "Hecho",
details = "Detalles",
enterValidAmount = "Introduce una cantidad válida",
satsUnit = { sats -> "$sats sats" },
// ── 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!",
// ── SendScreen — general ──────────────────────────────────────────────────
send = "Enviar",
paste = "Pegar",
continueButton = "Continuar",
clear = "Limpiar",
sendAnother = "Enviar otro",
// ── SendScreen — input field ──────────────────────────────────────────────
sendInputLabel = "Factura, LNURL o dirección Lightning",
sendInputPlaceholder = "lnbc… / lnurl1… / usuario@dominio.com",
tapNfcHint = "Acerca un dispositivo NFC para recibir la factura",
// ── SendScreen — states ───────────────────────────────────────────────────
resolving = "Resolviendo…",
sendingPayment = "Enviando pago…",
// ── SendScreen — payment sent ─────────────────────────────────────────────
paymentSent = "¡Pago enviado!",
amountSats = { sats -> "$sats sats" },
fiatEquivalent = { fiatStr -> "$fiatStr" },
noFees = "Sin comisiones",
routingFee = { sats, ppmSuffix -> "Comisión de enrutamiento: $sats sat${if (sats == 1L) "" else "s"}$ppmSuffix" },
// ── ConfirmCard ───────────────────────────────────────────────────────────
invoiceDetails = "Detalles de la factura",
payingTo = { label -> "Pagando a $label" },
confirmAmount = { sats -> "$sats sats" },
confirmAmountWithFiat = { sats, fiat -> "$sats sats · $fiat" },
memo = "Nota",
destination = "Destino",
created = "Creado",
expiresIn = "Expira en",
hash = "Hash",
invoice = "Factura",
expiryExpired = "Expirado",
expirySeconds = { s -> "${s}s" },
expiryMinutes = { m, s -> "${m}m ${s}s" },
expiryHours = { h, m -> "${h}h ${m}m" },
createdToday = { time -> "Hoy, $time" },
createdYesterday = { time -> "Ayer, $time" },
payButton = { sats -> "Pagar $sats sats" },
payButtonWithFiat = { sats, fiat -> "Pagar $sats sats · $fiat" },
sendBiometricPrompt = { sats -> "Enviar $sats sats" },
sendBiometricPromptTo = { sats, label -> "Enviar $sats sats a $label" },
// ── LnurlPayForm ─────────────────────────────────────────────────────────
lnurlAmountError = { min, max -> "Introduce una cantidad entre $min y $max sats" },
lnurlFiatRange = { minFiat, maxFiat -> "$minFiat $maxFiat" },
lnurlSatsAndFiatRange = { min, max, minFiat, maxFiat -> "$min $max sats · $minFiat $maxFiat" },
commentOptional = { max -> "Comentario (opcional, máx. $max caracteres)" },
commentCounter = { current, max -> "$current/$max" },
lnurlPayButton = { sats -> "Pagar $sats sats" },
lnurlPayButtonWithFiat = { sats, fiat -> "Pagar $sats sats · $fiat" },
// ── RouteHintWarning ──────────────────────────────────────────────────────
routeHintHighFees = "Comisiones de enrutamiento altas en la factura",
routeHintElevatedFees = "Comisiones de enrutamiento elevadas en la factura",
routeHintForcedChannel = { node -> "Esta factura obliga a pagar a través de un canal privado operado por $node." },
routeHintFeeRate = { effectivePpm, worstPpm -> "Tasa de comisión efectiva: $effectivePpm ppm ($worstPpm ppm)" },
routeHintFeeRateBase = { effectivePpm, worstPpm, baseLabel -> "Tasa de comisión efectiva: $effectivePpm ppm ($worstPpm ppm + $baseLabel base)" },
routeHintEstimatedFee = { sats -> "Comisión extra estimada en este pago: ~$sats sat${if (sats == 1L) "" else "s"}" },
routeHintShowDetails = "Ver detalles ▾",
routeHintHideDetails = "Ocultar detalles ▴",
routeHintHopsHeader = "Saltos de ruta privada",
routeHintHopFees = { ppm, baseLabel -> "$ppm ppm · $baseLabel base" },
)
@@ -0,0 +1,153 @@
package com.bitcointxoko.gudariwallet.i18n
data class AppStrings(
// ── Loading state ──────────────────────────────────────────────────────────
val loadingBalance: String,
// ── Balance display ────────────────────────────────────────────────────────
val sats: String,
val hideBalance: String, // accessibility click label
val revealBalance: String, // accessibility long-click label
// ── Fiat / currency ────────────────────────────────────────────────────────
val changeCurrency: String, // click label + icon contentDescription
val showFiat: String, // ghost prompt when no currency selected
val updatedAt: (label: String) -> String, // e.g. "Updated just now"
val justNow: String,
val minAgo: (label: Int) -> String,
val atTime: (label: String) -> String,
// ── History button ─────────────────────────────────────────────────────────
val viewHistory: String,
// ── Currency picker sheet ──────────────────────────────────────────────────
val selectCurrency: String, // sheet header
val currencyNone: String, // "None" list item
val hideFiatEquivalent: String, // supporting text under "None"
val selected: String, // check-icon contentDescription
val search: String, // search field placeholder
// ── Currency picker empty states ───────────────────────────────────────────
val noCurrenciesAvailable: String,
val noCurrenciesMatch: (query: String) -> String,
// ── Error state ────────────────────────────────────────────────────────────
val couldNotRefresh: String,
val couldNotLoadBalance: String,
// ── Shared ────────────────────────────────────────────────────────────────
val cancel : String,
val tryAgain : String,
val amount : String,
val next : String,
val back : String,
val done : String,
val details : String,
val enterValidAmount : String,
val satsUnit : (sats: Long) -> String,
// ── ReceiveScreen — general ───────────────────────────────────────────────
val receive : String,
// ── ReceiveScreen — error ─────────────────────────────────────────────────
val receiveError : String,
// ── ReceiveScreen — QR / share ────────────────────────────────────────────
val lightningAddressQrCode : String,
val lightningAddressLabel : String,
val shareLightningAddress : String,
val lightningInvoiceQrCode : String,
val invoiceLabel : String,
val shareInvoice : String,
// ── ReceiveScreen — amount step ───────────────────────────────────────────
val amountInSats : String, // text field label
val satsRange : (min: Long, max: Long) -> String,
// ── ReceiveScreen — memo step ─────────────────────────────────────────────
val memoOptional : String,
val memoPlaceholder : String,
val creatingInvoice : String,
val createInvoice : String,
// ── ReceiveScreen — invoice ready ─────────────────────────────────────────
val waiting : String,
val invoiceExpired : String,
val newInvoice : String,
// ── ReceiveScreen — lnurl withdraw ────────────────────────────────────────
val withdrawFrom : String,
val minimumSats : (min: Long) -> String,
val maximumSats : (max: Long) -> String,
val withdrawButton : String, // no fixed amount
val withdrawButtonAmount : (amountSats: Long) -> String, // fixed amount
// ── ReceiveScreen — success ───────────────────────────────────────────────
val paymentReceived : String,
// ── SendScreen — general ──────────────────────────────────────────────────
val send : String,
val paste : String,
val continueButton : String,
val clear : String,
val sendAnother : String,
// ── SendScreen — input field ──────────────────────────────────────────────
val sendInputLabel : String,
val sendInputPlaceholder : String,
val tapNfcHint : String,
// ── SendScreen — states ───────────────────────────────────────────────────
val resolving : String,
val sendingPayment : String,
// ── SendScreen — payment sent ─────────────────────────────────────────────
val paymentSent : String,
val amountSats : (sats: Long) -> String,
val fiatEquivalent : (fiatStr: String) -> String,
val noFees : String,
val routingFee : (sats: Long, ppmSuffix: String) -> String,
// ── ConfirmCard ───────────────────────────────────────────────────────────
val invoiceDetails : String,
val payingTo : (label: String) -> String,
val confirmAmount : (sats: Long) -> String,
val confirmAmountWithFiat : (sats: Long, fiat: String) -> String,
val memo : String,
val destination : String,
val created : String,
val expiresIn : String,
val hash : String,
val invoice : String,
val expiryExpired : String,
val expirySeconds : (s: Long) -> String,
val expiryMinutes : (m: Long, s: Long) -> String,
val expiryHours : (h: Long, m: Long) -> String,
val createdToday : (time: String) -> String,
val createdYesterday : (time: String) -> String,
val payButton : (sats: Long) -> String,
val payButtonWithFiat : (sats: Long, fiat: String) -> String,
val sendBiometricPrompt : (sats: Long) -> String,
val sendBiometricPromptTo : (sats: Long, label: String) -> String,
// ── LnurlPayForm ─────────────────────────────────────────────────────────
val lnurlAmountError : (min: Long, max: Long) -> String,
val lnurlFiatRange : (minFiat: String, maxFiat: String) -> String,
val lnurlSatsAndFiatRange : (min: Long, max: Long, minFiat: String, maxFiat: String) -> String,
val commentOptional : (max: Int) -> String,
val commentCounter : (current: Int, max: Int) -> String,
val lnurlPayButton : (sats: String) -> String,
val lnurlPayButtonWithFiat: (sats: String, fiat: String) -> String,
// ── RouteHintWarning ──────────────────────────────────────────────────────
val routeHintHighFees : String,
val routeHintElevatedFees : String,
val routeHintForcedChannel: (node: String) -> String,
val routeHintFeeRate : (effectivePpm: Long, worstPpm: Long) -> String,
val routeHintFeeRateBase : (effectivePpm: Long, worstPpm: Long, baseLabel: String) -> String,
val routeHintEstimatedFee : (sats: Long) -> String,
val routeHintShowDetails : String,
val routeHintHideDetails : String,
val routeHintHopsHeader : String,
val routeHintHopFees : (ppm: Long, baseLabel: String) -> String,
)