refactor: i18n ReceiveStrings

This commit is contained in:
2026-06-11 23:25:54 +02:00
parent 78eb034327
commit b053da6a05
11 changed files with 311 additions and 297 deletions
@@ -56,63 +56,6 @@ val EnHomeStrings = AppStrings(
enterValidAmount = "Enter a valid amount", enterValidAmount = "Enter a valid amount",
satsUnit = { sats -> "$sats sats" }, 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!",
// ── 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",
// ── SendScreen — general ────────────────────────────────────────────────── // ── SendScreen — general ──────────────────────────────────────────────────
send = "Send", send = "Send",
paste = "Paste", paste = "Paste",
@@ -327,6 +270,7 @@ val EnHomeStrings = AppStrings(
hideAdminKey = "Hide", hideAdminKey = "Hide",
showAdminKey = "Show", showAdminKey = "Show",
fieldsRequired = "All fields are required.", fieldsRequired = "All fields are required.",
invalidKeyFormat = "Invalid key format",
connect = "Connect", connect = "Connect",
notificationsTitle = "Stay in the loop", notificationsTitle = "Stay in the loop",
notificationsSubtitle = "Get notified instantly when you receive a payment.", notificationsSubtitle = "Get notified instantly when you receive a payment.",
@@ -356,6 +300,65 @@ val EnHomeStrings = AppStrings(
cancel = "Cancel" 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( nwc = NwcStrings(
back = "Back", back = "Back",
next = "Next", next = "Next",
@@ -56,63 +56,6 @@ val EsHomeStrings = AppStrings(
enterValidAmount = "Introduce una cantidad válida", enterValidAmount = "Introduce una cantidad válida",
satsUnit = { sats -> "$sats sats" }, 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!",
// ── 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",
// ── SendScreen — general ────────────────────────────────────────────────── // ── SendScreen — general ──────────────────────────────────────────────────
send = "Enviar", send = "Enviar",
paste = "Pegar", paste = "Pegar",
@@ -328,6 +271,7 @@ val EsHomeStrings = AppStrings(
hideAdminKey = "Ocultar", hideAdminKey = "Ocultar",
showAdminKey = "Mostrar", showAdminKey = "Mostrar",
fieldsRequired = "Todos los campos son obligatorios.", fieldsRequired = "Todos los campos son obligatorios.",
invalidKeyFormat = "Formato de clave no válido",
connect = "Conectar", connect = "Conectar",
notificationsTitle = "Mantente al día", notificationsTitle = "Mantente al día",
notificationsSubtitle = "Recibe notificaciones al instante cuando recibas un pago.", notificationsSubtitle = "Recibe notificaciones al instante cuando recibas un pago.",
@@ -357,6 +301,65 @@ val EsHomeStrings = AppStrings(
cancel = "Cancelar" 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( nwc = NwcStrings(
// ── Shared ──────────────────────────────────────────────────────────────── // ── Shared ────────────────────────────────────────────────────────────────
back = "Atrás", back = "Atrás",
@@ -55,63 +55,6 @@ val EuStrings = AppStrings(
enterValidAmount = "Sartu zenbateko baliogarri bat", enterValidAmount = "Sartu zenbateko baliogarri bat",
satsUnit = { sats -> "$sats sat" }, satsUnit = { sats -> "$sats sat" },
// ── 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",
// ── SendScreen — general ────────────────────────────────────────────────── // ── SendScreen — general ──────────────────────────────────────────────────
send = "Bidali", send = "Bidali",
paste = "Itsatsi", paste = "Itsatsi",
@@ -327,6 +270,7 @@ val EuStrings = AppStrings(
hideAdminKey = "Ezkutatu", hideAdminKey = "Ezkutatu",
showAdminKey = "Erakutsi", showAdminKey = "Erakutsi",
fieldsRequired = "Eremu guztiak beharrezkoak dira.", fieldsRequired = "Eremu guztiak beharrezkoak dira.",
invalidKeyFormat = "Gako formatu baliogabea",
connect = "Konektatu", connect = "Konektatu",
notificationsTitle = "Egon eguneratuta", notificationsTitle = "Egon eguneratuta",
notificationsSubtitle = "Jaso jakinarazpenak berehala transakzio bat jasotzen duzunean.", notificationsSubtitle = "Jaso jakinarazpenak berehala transakzio bat jasotzen duzunean.",
@@ -355,6 +299,65 @@ val EuStrings = AppStrings(
schedule = "Programatu", schedule = "Programatu",
cancel = "Utzi" 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( nwc = NwcStrings(
// ── Shared ──────────────────────────────────────────────────────────────── // ── Shared ────────────────────────────────────────────────────────────────
back = "Atzera", back = "Atzera",
@@ -64,63 +64,6 @@ data class AppStrings(
val enterValidAmount : String, val enterValidAmount : String,
val satsUnit : (sats: Long) -> 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,
// ── AmountDisplay ─────────────────────────────────────────────────────────
val amountDisplaySats : (amount: Long) -> String,
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
val brightnessReduce : String,
val brightnessBoost : String,
val qrShare : String,
val qrCopy : String,
val qrNfcStop : String,
val qrNfcStart : String,
val openInApp : String,
val noAppFound : String,
// ── ReceiveViewModel ──────────────────────────────────────────────────────
val receiveVmFailedToCreateInvoice : String,
val receiveVmWithdrawRejected : String,
val receiveVmWithdrawFailed : String,
// ── SendScreen — general ────────────────────────────────────────────────── // ── SendScreen — general ──────────────────────────────────────────────────
val send : String, val send : String,
val paste : String, val paste : String,
@@ -307,6 +250,7 @@ data class AppStrings(
val paymentRowFailed : String, val paymentRowFailed : String,
val onboarding: OnboardingStrings, val onboarding: OnboardingStrings,
val receive: ReceiveStrings,
val nwc: NwcStrings val nwc: NwcStrings
) )
@@ -325,6 +269,7 @@ data class OnboardingStrings(
val hideAdminKey: String, val hideAdminKey: String,
val connect: String, val connect: String,
val fieldsRequired: String, val fieldsRequired: String,
val invalidKeyFormat: String,
val back: String, val back: String,
val next: String, val next: String,
val done: String, val done: String,
@@ -356,6 +301,65 @@ data class OnboardingStrings(
val cancel: String val cancel: String
) )
data class ReceiveStrings(
// ── 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,
// ── AmountDisplay ─────────────────────────────────────────────────────────
val amountDisplaySats : (amount: Long) -> String,
// ── BrightnessToggleButton & QrDisplayCard ────────────────────────────────
val brightnessReduce : String,
val brightnessBoost : String,
val qrShare : String,
val qrCopy : String,
val qrNfcStop : String,
val qrNfcStart : String,
val openInApp : String,
val noAppFound : String,
// ── ReceiveViewModel ──────────────────────────────────────────────────────
val receiveVmFailedToCreateInvoice : String,
val receiveVmWithdrawRejected : String,
val receiveVmWithdrawFailed : String,
)
data class NwcStrings( data class NwcStrings(
// ── Shared / navigation ─────────────────────────────────────────────────── // ── Shared / navigation ───────────────────────────────────────────────────
@@ -121,7 +121,7 @@ internal fun QrDisplayCard(
) { ) {
Icon( Icon(
imageVector = Icons.Filled.Share, imageVector = Icons.Filled.Share,
contentDescription = strings.qrShare, contentDescription = strings.receive.qrShare,
tint = MaterialTheme.colorScheme.onSurfaceVariant tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
@@ -138,7 +138,7 @@ internal fun QrDisplayCard(
) { ) {
Icon( Icon(
imageVector = Icons.Filled.ContentCopy, imageVector = Icons.Filled.ContentCopy,
contentDescription = strings.qrCopy, contentDescription = strings.receive.qrCopy,
tint = MaterialTheme.colorScheme.onSurfaceVariant tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
@@ -147,8 +147,8 @@ internal fun QrDisplayCard(
FilledTonalIconButton(onClick = onToggleBrightness) { FilledTonalIconButton(onClick = onToggleBrightness) {
Icon( Icon(
imageVector = Icons.Filled.WbSunny, imageVector = Icons.Filled.WbSunny,
contentDescription = if (brightnessOn) strings.brightnessReduce contentDescription = if (brightnessOn) strings.receive.brightnessReduce
else strings.brightnessBoost, else strings.receive.brightnessBoost,
tint = if (brightnessOn) MaterialTheme.colorScheme.primary tint = if (brightnessOn) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.onSurfaceVariant else MaterialTheme.colorScheme.onSurfaceVariant
) )
@@ -163,8 +163,8 @@ internal fun QrDisplayCard(
Icon( Icon(
imageVector = if (isNfcEmulating) Icons.Filled.Nfc imageVector = if (isNfcEmulating) Icons.Filled.Nfc
else Icons.Outlined.Nfc, else Icons.Outlined.Nfc,
contentDescription = if (isNfcEmulating) strings.qrNfcStop contentDescription = if (isNfcEmulating) strings.receive.qrNfcStop
else strings.qrNfcStart, else strings.receive.qrNfcStart,
tint = if (isNfcEmulating) MaterialTheme.colorScheme.primary tint = if (isNfcEmulating) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.onSurfaceVariant else MaterialTheme.colorScheme.onSurfaceVariant
) )
@@ -176,7 +176,7 @@ internal fun QrDisplayCard(
IconButton(onClick = onOpenUri) { IconButton(onClick = onOpenUri) {
Icon( Icon(
imageVector = Icons.AutoMirrored.Filled.OpenInNew, imageVector = Icons.AutoMirrored.Filled.OpenInNew,
contentDescription = strings.openInApp, contentDescription = strings.receive.openInApp,
tint = MaterialTheme.colorScheme.onSurfaceVariant tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
@@ -27,13 +27,13 @@ private const val PAGE_INVOICE = 2
private const val PAGE_ADMIN = 3 private const val PAGE_ADMIN = 3
private const val PAGE_NOTIFICATIONS = 4 private const val PAGE_NOTIFICATIONS = 4
private const val PAGE_BATTERY = 5 private const val PAGE_BATTERY = 5
private const val PAGE_SYNC = 6 // ← new private const val PAGE_SYNC = 6
private const val PAGE_COUNT = 7 // ← was 6 private const val PAGE_COUNT = 7
@Composable @Composable
fun OnboardingScreen( fun OnboardingScreen(
secretStore : SecretStore, secretStore : SecretStore,
syncStore : HistoricalSyncStore, // ← new syncStore : HistoricalSyncStore,
onRequestNotificationPermission: () -> Unit, onRequestNotificationPermission: () -> Unit,
onComplete : () -> Unit onComplete : () -> Unit
) { ) {
@@ -46,12 +46,11 @@ fun OnboardingScreen(
var adminKey by remember { mutableStateOf("") } var adminKey by remember { mutableStateOf("") }
var adminVisible by remember { mutableStateOf(false) } var adminVisible by remember { mutableStateOf(false) }
var error by remember { mutableStateOf<String?>(null) } var error by remember { mutableStateOf<String?>(null) }
var credentialsSaved by remember { mutableStateOf(false) } // var credentialsSaved by remember { mutableStateOf(false) }
// ── Sync state ──────────────────────────────────────────────────────────── // ── Sync state ────────────────────────────────────────────────────────────
val vm: OnboardingViewModel = viewModel( val vm: OnboardingViewModel = viewModel(
factory = OnboardingViewModelFactory( factory = OnboardingViewModelFactory(
// LocalContext.current.applicationContext cast to Application
app = androidx.compose.ui.platform.LocalContext.current app = androidx.compose.ui.platform.LocalContext.current
.applicationContext as android.app.Application, .applicationContext as android.app.Application,
secretStore = secretStore, secretStore = secretStore,
@@ -65,31 +64,33 @@ fun OnboardingScreen(
LaunchedEffect(pagerState.currentPage) { error = null } LaunchedEffect(pagerState.currentPage) { error = null }
// var previousPage by remember { mutableIntStateOf(0) } val hexKeyRegex = Regex("^[0-9a-f]{32}$")
// LaunchedEffect(pagerState.currentPage) {
// val current = pagerState.currentPage
// if (current > previousPage) {
// // User moved forward — save whatever the previous page owned
// when (previousPage) {
// PAGE_SERVER_URL -> secretStore.saveBaseUrl(baseUrl)
// PAGE_INVOICE -> secretStore.saveInvoiceKey(invoiceKey)
// PAGE_ADMIN -> secretStore.saveAdminKey(adminKey)
// else -> Unit
// }
// }
// previousPage = current
// }
fun validateCurrentPage(): Boolean { fun validateCurrentPage(): Boolean {
error = when (pagerState.currentPage) { error = when (pagerState.currentPage) {
PAGE_SERVER_URL -> if (baseUrl.isBlank()) strings.onboarding.fieldsRequired else null PAGE_SERVER_URL -> when {
PAGE_INVOICE -> if (invoiceKey.isBlank()) strings.onboarding.fieldsRequired else null baseUrl.isBlank() -> strings.onboarding.fieldsRequired
PAGE_ADMIN -> if (adminKey.isBlank()) strings.onboarding.fieldsRequired else null else -> null
}
PAGE_INVOICE -> when {
invoiceKey.isBlank() -> strings.onboarding.fieldsRequired
!hexKeyRegex.matches(invoiceKey) -> strings.onboarding.invalidKeyFormat
else -> null
}
PAGE_ADMIN -> when {
adminKey.isBlank() -> strings.onboarding.fieldsRequired
!hexKeyRegex.matches(adminKey) -> strings.onboarding.invalidKeyFormat
else -> null
}
else -> null else -> null
} }
return error == null return error == null
} }
Scaffold { innerPadding -> Scaffold { innerPadding ->
Column( Column(
modifier = Modifier modifier = Modifier
@@ -128,7 +129,7 @@ fun OnboardingScreen(
onSchedule = { delayMs -> vm.enqueueHistoricalSync(delayMillis = delayMs) }, onSchedule = { delayMs -> vm.enqueueHistoricalSync(delayMillis = delayMs) },
onContinue = { onContinue = {
scope.launch { scope.launch {
secretStore.setOnboarded() // moved here from PAGE_BATTERY secretStore.setOnboarded()
onComplete() onComplete()
} }
}, },
@@ -168,7 +169,7 @@ fun OnboardingScreen(
Spacer(Modifier.width(1.dp)) Spacer(Modifier.width(1.dp))
} }
val isLastPage = pagerState.currentPage == PAGE_BATTERY // val isLastPage = pagerState.currentPage == PAGE_BATTERY
Button(onClick = { Button(onClick = {
if (!validateCurrentPage()) return@Button if (!validateCurrentPage()) return@Button
@@ -25,7 +25,7 @@ internal fun AmountDisplay(
val strings = LocalAppStrings.current val strings = LocalAppStrings.current
Text( Text(
text = strings.amountDisplaySats(amountSats), // ← "1 sat" or "X sats" text = strings.receive.amountDisplaySats(amountSats), // ← "1 sat" or "X sats"
style = style, style = style,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
@@ -20,8 +20,8 @@ internal fun BrightnessToggleButton(
Icon( Icon(
imageVector = if (isOn) Icons.Filled.BrightnessHigh imageVector = if (isOn) Icons.Filled.BrightnessHigh
else Icons.Filled.BrightnessLow, else Icons.Filled.BrightnessLow,
contentDescription = if (isOn) strings.brightnessReduce // ← "Reduce brightness" contentDescription = if (isOn) strings.receive.brightnessReduce // ← "Reduce brightness"
else strings.brightnessBoost, // ← "Boost brightness" else strings.receive.brightnessBoost, // ← "Boost brightness"
tint = if (isOn) MaterialTheme.colorScheme.primary tint = if (isOn) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.onSurfaceVariant else MaterialTheme.colorScheme.onSurfaceVariant
) )
@@ -130,7 +130,7 @@ fun ReceiveScreen(
vm.createInvoice( vm.createInvoice(
amountSats, amountSats,
memo, memo,
failedToCreateInvoice = strings.receiveVmFailedToCreateInvoice failedToCreateInvoice = strings.receive.receiveVmFailedToCreateInvoice
) )
} }
) )
@@ -145,9 +145,9 @@ fun ReceiveScreen(
callback = state.callback, callback = state.callback,
amountSats = amountSats, amountSats = amountSats,
memo = state.defaultDescription, memo = state.defaultDescription,
failedToCreateInvoice = strings.receiveVmFailedToCreateInvoice, failedToCreateInvoice = strings.receive.receiveVmFailedToCreateInvoice,
withdrawRejected = strings.receiveVmWithdrawRejected, withdrawRejected = strings.receive.receiveVmWithdrawRejected,
withdrawFailed = strings.receiveVmWithdrawFailed, withdrawFailed = strings.receive.receiveVmWithdrawFailed,
) )
}, },
onDismiss = { vm.resetReceiveState() } onDismiss = { vm.resetReceiveState() }
@@ -172,7 +172,7 @@ fun ReceiveScreen(
modifier = Modifier.padding(24.dp) modifier = Modifier.padding(24.dp)
) { ) {
Text( Text(
text = strings.receiveError, // ← "Error" text = strings.receive.receiveError, // ← "Error"
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.error color = MaterialTheme.colorScheme.error
) )
@@ -225,8 +225,8 @@ private fun LnurlWithdrawSheet(
val parsed = amountText.trim().toLongOrNull() val parsed = amountText.trim().toLongOrNull()
return when { return when {
parsed == null || parsed <= 0 -> { amountError = strings.enterValidAmount; null } // ← "Enter a valid amount" parsed == null || parsed <= 0 -> { amountError = strings.enterValidAmount; null } // ← "Enter a valid amount"
parsed < state.minSats -> { amountError = strings.minimumSats(state.minSats); null } // ← "Minimum is X sats" parsed < state.minSats -> { amountError = strings.receive.minimumSats(state.minSats); null } // ← "Minimum is X sats"
parsed > state.maxSats -> { amountError = strings.maximumSats(state.maxSats); null } // ← "Maximum is X sats" parsed > state.maxSats -> { amountError = strings.receive.maximumSats(state.maxSats); null } // ← "Maximum is X sats"
else -> { amountError = null; parsed } else -> { amountError = null; parsed }
} }
} }
@@ -247,7 +247,7 @@ private fun LnurlWithdrawSheet(
Spacer(Modifier.size(12.dp)) Spacer(Modifier.size(12.dp))
Column { Column {
Text( Text(
text = strings.withdrawFrom, // ← "Withdraw from" text = strings.receive.withdrawFrom, // ← "Withdraw from"
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
@@ -286,7 +286,7 @@ private fun LnurlWithdrawSheet(
color = MaterialTheme.colorScheme.onSecondaryContainer color = MaterialTheme.colorScheme.onSecondaryContainer
) )
Text( Text(
text = strings.withdrawButtonAmount(state.maxSats), // ← "X sats" text = strings.receive.withdrawButtonAmount(state.maxSats), // ← "X sats"
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSecondaryContainer color = MaterialTheme.colorScheme.onSecondaryContainer
@@ -297,12 +297,12 @@ private fun LnurlWithdrawSheet(
OutlinedTextField( OutlinedTextField(
value = amountText, value = amountText,
onValueChange = { amountText = it; amountError = null }, onValueChange = { amountText = it; amountError = null },
label = { Text(strings.amountInSats) }, // ← "Amount (sats)" label = { Text(strings.receive.amountInSats) }, // ← "Amount (sats)"
supportingText = { supportingText = {
if (amountError != null) if (amountError != null)
Text(amountError!!, color = MaterialTheme.colorScheme.error) Text(amountError!!, color = MaterialTheme.colorScheme.error)
else else
Text(strings.satsRange(state.minSats, state.maxSats)) // ← "X Y sats" Text(strings.receive.satsRange(state.minSats, state.maxSats)) // ← "X Y sats"
}, },
isError = amountError != null, isError = amountError != null,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
@@ -321,8 +321,8 @@ private fun LnurlWithdrawSheet(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text( Text(
if (fixedAmount) strings.withdrawButtonAmount(state.maxSats) // ← "Withdraw X sats" if (fixedAmount) strings.receive.withdrawButtonAmount(state.maxSats) // ← "Withdraw X sats"
else strings.withdrawButton // ← "Withdraw" else strings.receive.withdrawButton // ← "Withdraw"
) )
} }
@@ -379,7 +379,7 @@ private fun ReceiveIdleContent(
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
Text( Text(
text = strings.receive, // ← "Receive" text = strings.receive.receive, // ← "Receive"
style = MaterialTheme.typography.headlineSmall style = MaterialTheme.typography.headlineSmall
) )
if (lightningAddress != null) { if (lightningAddress != null) {
@@ -421,9 +421,9 @@ private fun ReceiveIdleContent(
QrDisplayCard( QrDisplayCard(
content = lightningAddress, content = lightningAddress,
contentDescription = strings.lightningAddressQrCode, // ← "Lightning address QR code" contentDescription = strings.receive.lightningAddressQrCode, // ← "Lightning address QR code"
clipLabel = strings.lightningAddressLabel, // ← "Lightning Address" clipLabel = strings.receive.lightningAddressLabel, // ← "Lightning Address"
shareTitle = strings.shareLightningAddress, // ← "Share Lightning Address" shareTitle = strings.receive.shareLightningAddress, // ← "Share Lightning Address"
textToCopy = lightningAddress, textToCopy = lightningAddress,
brightnessOn = brightnessOn, brightnessOn = brightnessOn,
onToggleBrightness = onToggleBrightness onToggleBrightness = onToggleBrightness
@@ -587,8 +587,8 @@ private fun MemoStepContent(
OutlinedTextField( OutlinedTextField(
value = memo, value = memo,
onValueChange = { memo = it }, onValueChange = { memo = it },
label = { Text(strings.memoOptional) }, // ← "Memo (optional)" label = { Text(strings.receive.memoOptional) }, // ← "Memo (optional)"
placeholder = { Text(strings.memoPlaceholder) }, // ← "What's this for?" placeholder = { Text(strings.receive.memoPlaceholder) }, // ← "What's this for?"
singleLine = true, singleLine = true,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@@ -603,8 +603,8 @@ private fun MemoStepContent(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text( Text(
if (isLoading) strings.creatingInvoice // ← "Creating invoice…" if (isLoading) strings.receive.creatingInvoice // ← "Creating invoice…"
else strings.createInvoice // ← "Create Invoice" else strings.receive.createInvoice // ← "Create Invoice"
) )
} }
@@ -665,9 +665,9 @@ private fun ReceiveInvoiceContent(
QrDisplayCard( QrDisplayCard(
content = state.bolt11.uppercase(), content = state.bolt11.uppercase(),
contentDescription = strings.lightningInvoiceQrCode, // ← "Lightning invoice QR code" contentDescription = strings.receive.lightningInvoiceQrCode, // ← "Lightning invoice QR code"
clipLabel = strings.invoiceLabel, // ← "Invoice" clipLabel = strings.receive.invoiceLabel, // ← "Invoice"
shareTitle = strings.shareInvoice, // ← "Share Invoice" shareTitle = strings.receive.shareInvoice, // ← "Share Invoice"
textToCopy = state.bolt11, textToCopy = state.bolt11,
brightnessOn = brightnessOn, brightnessOn = brightnessOn,
onToggleBrightness = onToggleBrightness, onToggleBrightness = onToggleBrightness,
@@ -693,7 +693,7 @@ private fun ReceiveInvoiceContent(
if (!isExpired) { if (!isExpired) {
CircularProgressIndicator(modifier = Modifier.size(16.dp), strokeWidth = 2.dp) CircularProgressIndicator(modifier = Modifier.size(16.dp), strokeWidth = 2.dp)
Text( Text(
text = strings.waiting, // ← "Waiting…" text = strings.receive.waiting, // ← "Waiting…"
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
@@ -704,7 +704,7 @@ private fun ReceiveInvoiceContent(
) )
} else { } else {
Text( Text(
text = strings.invoiceExpired, // ← "Invoice expired" text = strings.receive.invoiceExpired, // ← "Invoice expired"
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error color = MaterialTheme.colorScheme.error
) )
@@ -716,7 +716,7 @@ private fun ReceiveInvoiceContent(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text( Text(
if (isExpired) strings.newInvoice // ← "New Invoice" if (isExpired) strings.receive.newInvoice // ← "New Invoice"
else strings.cancel // ← "Cancel" else strings.cancel // ← "Cancel"
) )
} }
@@ -750,7 +750,7 @@ private fun ReceiveSuccessContent(
) )
Spacer(Modifier.height(16.dp)) Spacer(Modifier.height(16.dp))
Text( Text(
text = strings.paymentReceived, // ← "Payment Received!" text = strings.receive.paymentReceived, // ← "Payment Received!"
style = MaterialTheme.typography.headlineSmall style = MaterialTheme.typography.headlineSmall
) )
Spacer(Modifier.height(8.dp)) Spacer(Modifier.height(8.dp))
@@ -44,7 +44,7 @@ class ReceiveViewModel(
// ── Invoice creation ────────────────────────────────────────────────────── // ── Invoice creation ──────────────────────────────────────────────────────
/** /**
* @param failedToCreateInvoice Localised error string from the call site, * @param failedToCreateInvoice Localised error string from the call site,
* e.g. `strings.receiveVmFailedToCreateInvoice` * e.g. `strings.receive.receiveVmFailedToCreateInvoice`
*/ */
fun createInvoice( fun createInvoice(
amountSats : Long, amountSats : Long,
@@ -104,9 +104,9 @@ class ReceiveViewModel(
} }
/** /**
* @param failedToCreateInvoice `strings.receiveVmFailedToCreateInvoice` * @param failedToCreateInvoice `strings.receive.receiveVmFailedToCreateInvoice`
* @param withdrawRejected `strings.receiveVmWithdrawRejected` * @param withdrawRejected `strings.receive.receiveVmWithdrawRejected`
* @param withdrawFailed `strings.receiveVmWithdrawFailed` * @param withdrawFailed `strings.receive.receiveVmWithdrawFailed`
*/ */
fun executeWithdraw( fun executeWithdraw(
k1 : String, k1 : String,
@@ -59,7 +59,7 @@ internal fun LnurlPayForm(
OutlinedTextField( OutlinedTextField(
value = amount, value = amount,
onValueChange = { if (it.all(Char::isDigit)) amount = it }, onValueChange = { if (it.all(Char::isDigit)) amount = it },
label = { Text(strings.amountInSats) }, // ← "Amount (sats)" label = { Text(strings.receive.amountInSats) }, // ← "Amount (sats)"
isError = amount.isNotBlank() && !isAmountValid, isError = amount.isNotBlank() && !isAmountValid,
supportingText = { supportingText = {
when { when {
@@ -88,7 +88,7 @@ internal fun LnurlPayForm(
) )
} }
// Sats-only range when no fiat rate // Sats-only range when no fiat rate
!isFixed -> Text(strings.satsRange(state.minSats, state.maxSats)) // ← "X Y sats" !isFixed -> Text(strings.receive.satsRange(state.minSats, state.maxSats)) // ← "X Y sats"
else -> {} else -> {}
} }
}, },