localisation: nwc
This commit is contained in:
@@ -379,6 +379,9 @@ val EnHomeStrings = AppStrings(
|
||||
connectionRowExpires = "Expires",
|
||||
connectionRowPubkey = "Public key",
|
||||
connectionNeverUsed = "Never",
|
||||
lastUsedToday = "Last used today",
|
||||
lastUsedYesterday = "Last used yesterday",
|
||||
lastUsedDate = "Last used %s",
|
||||
connectionNoExpiry = "Never",
|
||||
connectionExpired = { date -> "Expired · $date" },
|
||||
connectionSectionPermissions = "Permissions",
|
||||
@@ -400,6 +403,10 @@ val EnHomeStrings = AppStrings(
|
||||
permSignMessage = "Sign messages",
|
||||
permPay = "Send payments",
|
||||
permInvoice = "Create invoices",
|
||||
permLookup = "Lookup invoice status",
|
||||
permHistory = "Read transaction history",
|
||||
permBalance = "Read wallet balance",
|
||||
permInfo = "Read account info",
|
||||
permLookupHistory = "Lookup status & transaction history",
|
||||
permBalanceInfo = "Read balance & account info",
|
||||
permSendPayments = "Send payments",
|
||||
@@ -412,6 +419,57 @@ val EnHomeStrings = AppStrings(
|
||||
revokeDialogBody = "This will permanently revoke this Nostr Wallet Connect key. Any app using it will lose access.",
|
||||
revokeDialogConfirm = "Revoke",
|
||||
revokeDialogDismiss = "Cancel",
|
||||
)
|
||||
refreshDaily = "Daily",
|
||||
refreshWeekly = "Weekly",
|
||||
refreshMonthly = "Monthly",
|
||||
refreshYearly = "Yearly",
|
||||
refreshNever = "Never",
|
||||
|
||||
newConnection = "New connection",
|
||||
labelHint = "Label (e.g. Amethyst, Bitrefill)",
|
||||
expires = "Expires",
|
||||
pickDate = "Pick date",
|
||||
pickTime = "Pick time",
|
||||
never = "Never",
|
||||
budgets = "Budgets",
|
||||
addBudget = "Add budget",
|
||||
removeBudget = "Remove budget",
|
||||
permissions = "Permissions",
|
||||
unnamed = "Unnamed",
|
||||
creating = "Creating…",
|
||||
createConnection = "Create connection",
|
||||
ok = "OK",
|
||||
sats = "Sats",
|
||||
resets = "Resets",
|
||||
|
||||
deleteConnection = "Delete connection",
|
||||
unnamedConnection = "Unnamed connection",
|
||||
neverUsed = "Never used",
|
||||
expired = "Expired",
|
||||
|
||||
connectionCreated = "Connection created",
|
||||
scanOrCopyHint = "Scan or copy this connection string into your app. It will not be shown again.",
|
||||
nwcPairingQrCode = "NWC pairing QR code",
|
||||
nwcConnectionString = "NWC connection string",
|
||||
shareNwcConnectionString = "Share NWC connection string",
|
||||
openInApp = "Open in app",
|
||||
|
||||
walletConnect = "Wallet Connect",
|
||||
addConnection = "Add connection",
|
||||
noCompatibleAppFound = "No compatible app found",
|
||||
removeConnection = "Remove connection?",
|
||||
removeConnectionDetail = "This will permanently revoke this Nostr Wallet Connect key. Any app using it will lose access.",
|
||||
remove = "Remove",
|
||||
|
||||
noConnectionsYet = "No connections yet",
|
||||
tapToAddHint = "Tap + to connect an app via Nostr Wallet Connect.",
|
||||
somethingWentWrong = "Something went wrong",
|
||||
retry = "Retry",
|
||||
|
||||
failedToLoadConnections = "Failed to load connections",
|
||||
failedToCreateConnection = "Failed to create connection",
|
||||
failedToDeleteConnection = "Failed to delete connection",
|
||||
failedToLoadConnection = "Failed to load connection",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -380,6 +380,9 @@ val EsHomeStrings = AppStrings(
|
||||
connectionRowExpires = "Vence",
|
||||
connectionRowPubkey = "Clave pública",
|
||||
connectionNeverUsed = "Nunca",
|
||||
lastUsedToday = "Usada hoy",
|
||||
lastUsedYesterday = "Usada ayer",
|
||||
lastUsedDate = "Usada %s",
|
||||
connectionNoExpiry = "Sin vencimiento",
|
||||
connectionExpired = { date -> "Vencido · $date" },
|
||||
connectionSectionPermissions = "Permisos",
|
||||
@@ -401,6 +404,10 @@ val EsHomeStrings = AppStrings(
|
||||
permSignMessage = "Firmar mensajes",
|
||||
permPay = "Enviar pagos",
|
||||
permInvoice = "Crear facturas",
|
||||
permLookup = "Consultar estado de facturas",
|
||||
permHistory = "Leer historial de transacciones",
|
||||
permBalance = "Leer saldo del monedero",
|
||||
permInfo = "Leer información de cuenta",
|
||||
permLookupHistory = "Consultar estado e historial de transacciones",
|
||||
permBalanceInfo = "Ver saldo e información de cuenta",
|
||||
permSendPayments = "Enviar pagos",
|
||||
@@ -413,5 +420,56 @@ val EsHomeStrings = AppStrings(
|
||||
revokeDialogBody = "Esto revocará permanentemente esta clave Nostr Wallet Connect. Cualquier app que la use perderá el acceso.",
|
||||
revokeDialogConfirm = "Revocar",
|
||||
revokeDialogDismiss = "Cancelar",
|
||||
refreshDaily = "Diario",
|
||||
refreshWeekly = "Semanal",
|
||||
refreshMonthly = "Mensual",
|
||||
refreshYearly = "Anual",
|
||||
refreshNever = "Nunca",
|
||||
|
||||
newConnection = "Nueva conexión",
|
||||
labelHint = "Etiqueta (p.ej. Amethyst, Bitrefill)",
|
||||
expires = "Caduca",
|
||||
pickDate = "Elegir fecha",
|
||||
pickTime = "Elegir hora",
|
||||
never = "Nunca",
|
||||
budgets = "Presupuestos",
|
||||
addBudget = "Añadir presupuesto",
|
||||
removeBudget = "Eliminar presupuesto",
|
||||
permissions = "Permisos",
|
||||
unnamed = "Sin nombre",
|
||||
creating = "Creando…",
|
||||
createConnection = "Crear conexión",
|
||||
ok = "OK",
|
||||
sats = "Sats",
|
||||
resets = "Se reinicia",
|
||||
|
||||
deleteConnection = "Eliminar conexión",
|
||||
unnamedConnection = "Conexión sin nombre",
|
||||
neverUsed = "Nunca usada",
|
||||
expired = "Caducada",
|
||||
|
||||
connectionCreated = "Conexión creada",
|
||||
scanOrCopyHint = "Escanea o copia esta cadena de conexión en tu app. No se volverá a mostrar.",
|
||||
nwcPairingQrCode = "Código QR de emparejamiento NWC",
|
||||
nwcConnectionString = "Cadena de conexión NWC",
|
||||
shareNwcConnectionString = "Compartir cadena de conexión NWC",
|
||||
openInApp = "Abrir en app",
|
||||
|
||||
walletConnect = "Wallet Connect",
|
||||
addConnection = "Añadir conexión",
|
||||
noCompatibleAppFound = "No se encontró una app compatible",
|
||||
removeConnection = "¿Eliminar conexión?",
|
||||
removeConnectionDetail = "Esto revocará permanentemente esta clave de Nostr Wallet Connect. Cualquier app que la use perderá el acceso.",
|
||||
remove = "Eliminar",
|
||||
|
||||
noConnectionsYet = "Aún no hay conexiones",
|
||||
tapToAddHint = "Toca + para conectar una app vía Nostr Wallet Connect.",
|
||||
somethingWentWrong = "Algo salió mal",
|
||||
retry = "Reintentar",
|
||||
|
||||
failedToLoadConnections = "Error al cargar las conexiones",
|
||||
failedToCreateConnection = "Error al crear la conexión",
|
||||
failedToDeleteConnection = "Error al eliminar la conexión",
|
||||
failedToLoadConnection = "Error al cargar la conexión",
|
||||
)
|
||||
)
|
||||
|
||||
@@ -376,6 +376,9 @@ val EuStrings = AppStrings(
|
||||
connectionSectionDetails = "Xehetasunak",
|
||||
connectionRowCreated = "Konektatuta",
|
||||
connectionRowLastUsed = "Azken erabilera",
|
||||
lastUsedToday = "Duela gutxi erabilia", // "used recently" (idiomatic for today)
|
||||
lastUsedYesterday = "Atzo erabilia", // "used yesterday"
|
||||
lastUsedDate = "Duela %s erabilia", // "used [date] ago"
|
||||
connectionRowExpires = "Iraungitze-data",
|
||||
connectionRowPubkey = "Gako publikoa",
|
||||
connectionNeverUsed = "Inoiz ez",
|
||||
@@ -400,6 +403,10 @@ val EuStrings = AppStrings(
|
||||
permSignMessage = "Mezuak sinatu",
|
||||
permPay = "Ordainketak bidali",
|
||||
permInvoice = "Fakturak sortu",
|
||||
permLookup = "Kontsultatu faktura-egoera",
|
||||
permHistory = "Irakurri transakzio-historiala",
|
||||
permBalance = "Irakurri zorroaren saldoa",
|
||||
permInfo = "Irakurri kontu-informazioa",
|
||||
permLookupHistory = "Egoera eta transakzio-historia kontsultatu",
|
||||
permBalanceInfo = "Saldoa eta kontuaren informazioa ikusi",
|
||||
permSendPayments = "Ordainketak bidali",
|
||||
@@ -412,5 +419,56 @@ val EuStrings = AppStrings(
|
||||
revokeDialogBody = "Honek Nostr Wallet Connect gako hau behin betiko baliogabetuko du. Erabiltzen duen edozein aplikaziok sarbidea galduko du.",
|
||||
revokeDialogConfirm = "Baliogabetu",
|
||||
revokeDialogDismiss = "Utzi",
|
||||
)
|
||||
refreshDaily = "Egunero",
|
||||
refreshWeekly = "Astero",
|
||||
refreshMonthly = "Hilabetero",
|
||||
refreshYearly = "Urtero",
|
||||
refreshNever = "Inoiz ez",
|
||||
|
||||
newConnection = "Konexio berria",
|
||||
labelHint = "Etiketa (adb. Amethyst, Bitrefill)",
|
||||
expires = "Iraungitzen da",
|
||||
pickDate = "Aukeratu data",
|
||||
pickTime = "Aukeratu ordua",
|
||||
never = "Inoiz ez",
|
||||
budgets = "Aurrekontuak",
|
||||
addBudget = "Gehitu aurrekontua",
|
||||
removeBudget = "Kendu aurrekontua",
|
||||
permissions = "Baimenak",
|
||||
unnamed = "Izengabea",
|
||||
creating = "Sortzen…",
|
||||
createConnection = "Sortu konexioa",
|
||||
ok = "Ados",
|
||||
sats = "Sats",
|
||||
resets = "Berrezarri",
|
||||
|
||||
deleteConnection = "Ezabatu konexioa",
|
||||
unnamedConnection = "Izengabeko konexioa",
|
||||
neverUsed = "Inoiz erabili gabea",
|
||||
expired = "Iraungitua",
|
||||
|
||||
connectionCreated = "Konexioa sortuta",
|
||||
scanOrCopyHint = "Eskaneatu edo kopiatu konexio-kate hau zure app-ean. Ez da berriro erakutsiko.",
|
||||
nwcPairingQrCode = "NWC parekatzeko QR kodea",
|
||||
nwcConnectionString = "NWC konexio-katea",
|
||||
shareNwcConnectionString = "Partekatu NWC konexio-katea",
|
||||
openInApp = "Ireki app-ean",
|
||||
|
||||
walletConnect = "Wallet Connect",
|
||||
addConnection = "Gehitu konexioa",
|
||||
noCompatibleAppFound = "Ez da app bateragarririk aurkitu",
|
||||
removeConnection = "Kendu konexioa?",
|
||||
removeConnectionDetail = "Honek Nostr Wallet Connect gako hau behin betiko indargabetuko du. Erabiltzen duen edozein app-ek sarbidea galduko du.",
|
||||
remove = "Kendu",
|
||||
|
||||
noConnectionsYet = "Oraindik konexiorik ez",
|
||||
tapToAddHint = "Sakatu + app bat Nostr Wallet Connect bidez konektatzeko.",
|
||||
somethingWentWrong = "Zerbait gaizki atera da",
|
||||
retry = "Saiatu berriro",
|
||||
|
||||
failedToLoadConnections = "Huts egin du konexioak kargatzean",
|
||||
failedToCreateConnection = "Huts egin du konexioa sortzean",
|
||||
failedToDeleteConnection = "Huts egin du konexioa ezabatzean",
|
||||
failedToLoadConnection = "Huts egin du konexioa kargatzean",
|
||||
)
|
||||
)
|
||||
|
||||
@@ -383,6 +383,9 @@ data class NwcStrings(
|
||||
val connectionRowExpires : String,
|
||||
val connectionRowPubkey : String,
|
||||
val connectionNeverUsed : String,
|
||||
val lastUsedToday : String, // e.g. "Last used today"
|
||||
val lastUsedYesterday : String, // e.g. "Last used yesterday"
|
||||
val lastUsedDate : String, // e.g. "Last used %s" — %s is a formatted date
|
||||
val connectionNoExpiry : String,
|
||||
/** "Expired · {date}" */
|
||||
val connectionExpired : (date: String) -> String,
|
||||
@@ -406,12 +409,16 @@ data class NwcStrings(
|
||||
val permLookupInvoice : String,
|
||||
val permListTransactions : String,
|
||||
val permSignMessage : String,
|
||||
val permPay : String, // "Send payments"
|
||||
val permInvoice : String, // "Create invoices"
|
||||
val permLookupHistory: String, // "Lookup status & transaction history"
|
||||
val permBalanceInfo : String, // "Read balance & account info"
|
||||
val permSendPayments: String,
|
||||
val permCreateInvoices: String,
|
||||
val permPay : String, // "Send payments"
|
||||
val permInvoice : String, // "Create invoices"
|
||||
val permLookup : String,
|
||||
val permHistory : String,
|
||||
val permBalance : String,
|
||||
val permInfo : String,
|
||||
val permLookupHistory : String, // "Lookup status & transaction history"
|
||||
val permBalanceInfo : String, // "Read balance & account info"
|
||||
val permSendPayments : String,
|
||||
val permCreateInvoices : String,
|
||||
val permLookupInvoiceStatus: String,
|
||||
val permReadTransactionHistory: String,
|
||||
val permReadWalletBalance: String,
|
||||
@@ -420,4 +427,56 @@ data class NwcStrings(
|
||||
val revokeDialogBody : String,
|
||||
val revokeDialogConfirm : String,
|
||||
val revokeDialogDismiss : String,
|
||||
)
|
||||
val refreshDaily : String,
|
||||
val refreshWeekly : String,
|
||||
val refreshMonthly : String,
|
||||
val refreshYearly : String,
|
||||
val refreshNever : String,
|
||||
|
||||
// New Connection
|
||||
val newConnection : String,
|
||||
val labelHint : String,
|
||||
val expires : String,
|
||||
val pickDate : String,
|
||||
val pickTime : String,
|
||||
val never : String,
|
||||
val budgets : String,
|
||||
val addBudget : String,
|
||||
val removeBudget : String,
|
||||
val permissions : String,
|
||||
val unnamed : String,
|
||||
val creating : String,
|
||||
val createConnection : String,
|
||||
val ok : String,
|
||||
val sats : String,
|
||||
val resets : String,
|
||||
|
||||
val deleteConnection : String,
|
||||
val unnamedConnection : String,
|
||||
val neverUsed : String,
|
||||
val expired : String,
|
||||
|
||||
val connectionCreated : String,
|
||||
val scanOrCopyHint : String,
|
||||
val nwcPairingQrCode : String,
|
||||
val nwcConnectionString : String,
|
||||
val shareNwcConnectionString : String,
|
||||
val openInApp : String,
|
||||
|
||||
val walletConnect : String,
|
||||
val addConnection : String,
|
||||
val noCompatibleAppFound : String,
|
||||
val removeConnection : String,
|
||||
val removeConnectionDetail: String,
|
||||
val remove : String,
|
||||
|
||||
val noConnectionsYet : String,
|
||||
val tapToAddHint : String,
|
||||
val somethingWentWrong : String,
|
||||
val retry : String,
|
||||
|
||||
val failedToLoadConnections : String,
|
||||
val failedToCreateConnection : String,
|
||||
val failedToDeleteConnection : String,
|
||||
val failedToLoadConnection : String,
|
||||
)
|
||||
@@ -461,7 +461,7 @@ fun WalletScreen(
|
||||
|
||||
val connectionState by nwcVm.connectionDetailState.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(pubkey) { nwcVm.loadConnectionDetail(pubkey) }
|
||||
LaunchedEffect(pubkey) { nwcVm.loadConnectionDetail(pubkey, strings) }
|
||||
DisposableEffect(Unit) { onDispose { nwcVm.clearConnectionDetail() } }
|
||||
|
||||
when (val state = connectionState) {
|
||||
@@ -491,7 +491,7 @@ fun WalletScreen(
|
||||
budgets = state.budgets,
|
||||
onBack = { navController.popBackStack() },
|
||||
onRevoke = {
|
||||
nwcVm.deleteConnection(pubkey)
|
||||
nwcVm.deleteConnection(pubkey, strings)
|
||||
navController.popBackStack()
|
||||
}
|
||||
)
|
||||
|
||||
@@ -16,6 +16,8 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bitcointxoko.gudariwallet.api.NwcNewBudget
|
||||
import com.bitcointxoko.gudariwallet.i18n.AppStrings
|
||||
import com.bitcointxoko.gudariwallet.strings
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
@@ -41,6 +43,16 @@ private class AddConnectionState {
|
||||
expiry.atZone(ZoneId.systemDefault()).toEpochSecond()
|
||||
}
|
||||
|
||||
private fun NwcPermission.displayLabel(strings: AppStrings): String = when (serverKey) {
|
||||
"pay" -> strings.nwc.permPay
|
||||
"invoice" -> strings.nwc.permInvoice
|
||||
"lookup" -> strings.nwc.permLookup
|
||||
"history" -> strings.nwc.permHistory
|
||||
"balance" -> strings.nwc.permBalance
|
||||
"info" -> strings.nwc.permInfo
|
||||
else -> serverKey
|
||||
}
|
||||
|
||||
// ── Sheet ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -58,6 +70,7 @@ internal fun NwcAddConnectionSheet(
|
||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val state = remember { AddConnectionState() }
|
||||
|
||||
|
||||
if (state.showDatePicker) {
|
||||
val initialMillis = state.expiry
|
||||
.atZone(ZoneId.systemDefault())
|
||||
@@ -81,10 +94,10 @@ internal fun NwcAddConnectionSheet(
|
||||
.withDayOfMonth(picked.dayOfMonth)
|
||||
}
|
||||
state.showDatePicker = false
|
||||
}) { Text("OK") }
|
||||
}) { Text(strings.nwc.ok) }
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { state.showDatePicker = false }) { Text("Cancel") }
|
||||
TextButton(onClick = { state.showDatePicker = false }) { Text(strings.nwc.cancel) }
|
||||
}
|
||||
) { DatePicker(state = datePickerState) }
|
||||
}
|
||||
@@ -105,10 +118,10 @@ internal fun NwcAddConnectionSheet(
|
||||
.withSecond(0)
|
||||
.withNano(0)
|
||||
state.showTimePicker = false
|
||||
}) { Text("OK") }
|
||||
}) { Text(strings.nwc.ok) }
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { state.showTimePicker = false }) { Text("Cancel") }
|
||||
TextButton(onClick = { state.showTimePicker = false }) { Text(strings.nwc.cancel) }
|
||||
},
|
||||
text = { TimePicker(state = timePickerState) }
|
||||
)
|
||||
@@ -127,7 +140,7 @@ internal fun NwcAddConnectionSheet(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "New connection",
|
||||
text = strings.nwc.newConnection,
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
|
||||
@@ -135,7 +148,7 @@ internal fun NwcAddConnectionSheet(
|
||||
OutlinedTextField(
|
||||
value = state.description,
|
||||
onValueChange = { state.description = it },
|
||||
label = { Text("Label (e.g. Amethyst, Bitrefill)") },
|
||||
label = { Text(strings.nwc.labelHint) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -145,7 +158,7 @@ internal fun NwcAddConnectionSheet(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(text = "Expires", style = MaterialTheme.typography.bodyMedium)
|
||||
Text(text = strings.nwc.expires, style = MaterialTheme.typography.bodyMedium)
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
if (!state.neverExpires) {
|
||||
@@ -158,7 +171,7 @@ internal fun NwcAddConnectionSheet(
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.CalendarToday,
|
||||
contentDescription = "Pick date",
|
||||
contentDescription = strings.nwc.pickDate,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@@ -173,7 +186,7 @@ internal fun NwcAddConnectionSheet(
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Schedule,
|
||||
contentDescription = "Pick time",
|
||||
contentDescription = strings.nwc.pickTime,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
}
|
||||
@@ -185,7 +198,7 @@ internal fun NwcAddConnectionSheet(
|
||||
checked = state.neverExpires,
|
||||
onCheckedChange = { state.neverExpires = it }
|
||||
)
|
||||
Text(text = "Never", style = MaterialTheme.typography.bodyMedium)
|
||||
Text(text = strings.nwc.never, style = MaterialTheme.typography.bodyMedium)
|
||||
}
|
||||
|
||||
Row(
|
||||
@@ -193,7 +206,7 @@ internal fun NwcAddConnectionSheet(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = "Budgets",
|
||||
text = strings.nwc.budgets,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
@@ -206,11 +219,11 @@ internal fun NwcAddConnectionSheet(
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = "Add budget",
|
||||
contentDescription = strings.nwc.addBudget,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Text("Add budget")
|
||||
Text(strings.nwc.addBudget)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +243,7 @@ internal fun NwcAddConnectionSheet(
|
||||
|
||||
// ── Permissions ──────────────────────────────────────────────────
|
||||
Text(
|
||||
text = "Permissions",
|
||||
text = strings.nwc.permissions,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
@@ -251,11 +264,11 @@ internal fun NwcAddConnectionSheet(
|
||||
}
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text(text = perm.displayLabel, style = MaterialTheme.typography.bodyMedium)
|
||||
Text(text = perm.displayLabel(strings), style = MaterialTheme.typography.bodyMedium)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unnamed = strings.nwc.unnamed
|
||||
// ── Create button ─────────────────────────────────────────────────
|
||||
Button(
|
||||
onClick = {
|
||||
@@ -263,7 +276,7 @@ internal fun NwcAddConnectionSheet(
|
||||
else state.expiryEpochSeconds() // #10
|
||||
val validBudgets = state.budgets.mapNotNull { it.toNwcNewBudget() }
|
||||
onCreate(
|
||||
state.description.trim().ifBlank { "Unnamed" },
|
||||
state.description.trim().ifBlank { unnamed },
|
||||
state.selectedPermissions.toList(),
|
||||
expiresAtSecs,
|
||||
validBudgets
|
||||
@@ -280,7 +293,7 @@ internal fun NwcAddConnectionSheet(
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
}
|
||||
Text(if (isCreating) "Creating…" else "Create connection")
|
||||
Text(if (isCreating) strings.nwc.creating else strings.nwc.createConnection)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,6 +301,15 @@ internal fun NwcAddConnectionSheet(
|
||||
|
||||
// ── Budget row ────────────────────────────────────────────────────────────────
|
||||
|
||||
@Composable
|
||||
fun BudgetRefreshWindow.displayLabel(strings: AppStrings): String = when (this) {
|
||||
BudgetRefreshWindow.DAILY -> strings.nwc.refreshDaily
|
||||
BudgetRefreshWindow.WEEKLY -> strings.nwc.refreshWeekly
|
||||
BudgetRefreshWindow.MONTHLY -> strings.nwc.refreshMonthly
|
||||
BudgetRefreshWindow.YEARLY -> strings.nwc.refreshYearly
|
||||
BudgetRefreshWindow.NEVER -> strings.nwc.refreshNever
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun BudgetRow(
|
||||
@@ -313,7 +335,7 @@ private fun BudgetRow(
|
||||
OutlinedTextField(
|
||||
value = draft.amountSats,
|
||||
onValueChange = { onChange(draft.copy(amountSats = it.filter(Char::isDigit))) },
|
||||
label = { Text("Sats") },
|
||||
label = { Text(strings.nwc.sats) },
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||
modifier = Modifier.weight(1f).height(fieldHeight)
|
||||
@@ -325,10 +347,10 @@ private fun BudgetRow(
|
||||
modifier = Modifier.weight(1f).height(fieldHeight)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = draft.refreshWindow.label,
|
||||
value = draft.refreshWindow.displayLabel(strings),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text("Resets") },
|
||||
label = { Text(strings.nwc.resets) },
|
||||
trailingIcon = {
|
||||
ExposedDropdownMenuDefaults.TrailingIcon(expanded = dropdownExpanded)
|
||||
},
|
||||
@@ -343,7 +365,7 @@ private fun BudgetRow(
|
||||
) {
|
||||
BudgetRefreshWindow.entries.forEach { window ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(window.label) },
|
||||
text = { Text(window.displayLabel(strings)) },
|
||||
onClick = {
|
||||
onChange(draft.copy(refreshWindow = window))
|
||||
dropdownExpanded = false
|
||||
@@ -359,7 +381,7 @@ private fun BudgetRow(
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = "Remove budget",
|
||||
contentDescription = strings.nwc.removeBudget,
|
||||
tint = MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.bitcointxoko.gudariwallet.ui.nwc
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
@@ -17,16 +19,19 @@ import com.bitcointxoko.gudariwallet.api.NwcGetResponse
|
||||
import com.bitcointxoko.gudariwallet.strings
|
||||
import com.bitcointxoko.gudariwallet.ui.theme.semanticColors
|
||||
import com.bitcointxoko.gudariwallet.util.formatEpochShort
|
||||
import com.bitcointxoko.gudariwallet.util.isToday
|
||||
import com.bitcointxoko.gudariwallet.util.isYesterday
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.Instant
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
@Composable
|
||||
internal fun NwcConnectionRow(
|
||||
connection : NwcGetResponse,
|
||||
isDeleting : Boolean,
|
||||
onDeleteConfirm : () -> Unit,
|
||||
connection: NwcGetResponse,
|
||||
isDeleting: Boolean,
|
||||
onDeleteConfirm: () -> Unit,
|
||||
onConnectionClick: () -> Unit,
|
||||
modifier : Modifier = Modifier
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val key = connection.data
|
||||
val expired = key.expires_at > 0 && key.expires_at < Instant.now().epochSecond
|
||||
@@ -85,7 +90,7 @@ internal fun NwcConnectionRow(
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = "Delete connection",
|
||||
contentDescription = strings.nwc.deleteConnection,
|
||||
tint = MaterialTheme.colorScheme.onError.copy(alpha = bgAlpha)
|
||||
)
|
||||
}
|
||||
@@ -111,7 +116,7 @@ internal fun NwcConnectionRow(
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = key.description.ifBlank { "Unnamed connection" },
|
||||
text = key.description.ifBlank { strings.nwc.unnamedConnection },
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
@@ -121,9 +126,15 @@ internal fun NwcConnectionRow(
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Spacer(Modifier.height(2.dp))
|
||||
val lastUsedText = when {
|
||||
key.last_used <= 0L -> strings.nwc.neverUsed
|
||||
isToday(key.last_used) -> strings.nwc.lastUsedToday
|
||||
isYesterday(key.last_used) -> strings.nwc.lastUsedYesterday
|
||||
else -> strings.nwc.lastUsedDate.format(formatEpochShort(key.last_used, strings.today, strings.yesterday))
|
||||
}
|
||||
Text(
|
||||
text = if (key.last_used <= 0L) "Never used"
|
||||
else "Last used ${formatEpochShort(key.last_used, strings.today, strings.yesterday)}",
|
||||
text = if (key.last_used <= 0L) strings.nwc.neverUsed
|
||||
else lastUsedText,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
@@ -135,7 +146,7 @@ internal fun NwcConnectionRow(
|
||||
contentColor = semantic.onErrorContainer
|
||||
) {
|
||||
Text(
|
||||
text = "Expired",
|
||||
text = strings.nwc.expired,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp)
|
||||
)
|
||||
|
||||
@@ -5,17 +5,16 @@ import com.bitcointxoko.gudariwallet.api.NwcNewBudget
|
||||
// ── Available permissions ────────────────────────────────────────────
|
||||
internal data class NwcPermission(
|
||||
val serverKey : String, // what we send in the permissions array
|
||||
val displayLabel : String, // shown in the UI
|
||||
val default : Boolean // pre-checked by default
|
||||
)
|
||||
|
||||
internal val ALL_PERMISSIONS = listOf(
|
||||
NwcPermission("pay", "Send payments", default = true),
|
||||
NwcPermission("invoice", "Create invoices", default = false),
|
||||
NwcPermission("lookup", "Lookup invoice status", default = false),
|
||||
NwcPermission("history", "Read transaction history", default = false),
|
||||
NwcPermission("balance", "Read wallet balance", default = false),
|
||||
NwcPermission("info", "Read account info", default = false)
|
||||
NwcPermission("pay", default = true),
|
||||
NwcPermission("invoice", default = false),
|
||||
NwcPermission("lookup", default = false),
|
||||
NwcPermission("history", default = false),
|
||||
NwcPermission("balance", default = false),
|
||||
NwcPermission("info", default = false)
|
||||
)
|
||||
|
||||
// ── Budget ────────────────────────────────────────────────────────────
|
||||
@@ -24,12 +23,12 @@ internal val ALL_PERMISSIONS = listOf(
|
||||
* Transient UI state for a single budget row in the "Add connection" sheet.
|
||||
* Converted to [NwcNewBudget] on submit.
|
||||
*/
|
||||
enum class BudgetRefreshWindow(val label: String, val seconds: Int) {
|
||||
DAILY ("Daily", 86_400),
|
||||
WEEKLY ("Weekly", 604_800),
|
||||
MONTHLY ("Monthly", 2_592_000),
|
||||
YEARLY ("Yearly", 31_536_000),
|
||||
NEVER ("Never", 0);
|
||||
enum class BudgetRefreshWindow(val seconds: Int) {
|
||||
DAILY (86_400),
|
||||
WEEKLY (604_800),
|
||||
MONTHLY (2_592_000),
|
||||
YEARLY (31_536_000),
|
||||
NEVER (0);
|
||||
}
|
||||
|
||||
data class BudgetDraft(
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
import com.bitcointxoko.gudariwallet.strings
|
||||
import com.bitcointxoko.gudariwallet.ui.common.rememberBrightnessController
|
||||
import com.bitcointxoko.gudariwallet.ui.common.QrDisplayCard
|
||||
|
||||
@@ -29,20 +30,21 @@ internal fun NwcPairingUrlDialog(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text("Connection created") },
|
||||
title = { Text(strings.nwc.connectionCreated) },
|
||||
text = {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
Text(
|
||||
text = "Scan or copy this connection string into your app. It will not be shown again.",
|
||||
text = strings.nwc.scanOrCopyHint,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
val strings = strings
|
||||
QrDisplayCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
content = url,
|
||||
contentDescription = "NWC pairing QR code",
|
||||
clipLabel = "NWC connection string",
|
||||
shareTitle = "Share NWC connection string",
|
||||
contentDescription = strings.nwc.nwcPairingQrCode,
|
||||
clipLabel = strings.nwc.nwcConnectionString,
|
||||
shareTitle = strings.nwc.shareNwcConnectionString,
|
||||
textToCopy = url,
|
||||
brightnessOn = brightness.isOn,
|
||||
onToggleBrightness = brightness.toggle,
|
||||
@@ -52,7 +54,7 @@ internal fun NwcPairingUrlDialog(
|
||||
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
try {
|
||||
context.startActivity(
|
||||
Intent.createChooser(intent, "Open in app")
|
||||
Intent.createChooser(intent, strings.nwc.openInApp)
|
||||
)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
onNoAppFound() // #17: no Toast — caller handles it
|
||||
@@ -63,7 +65,7 @@ internal fun NwcPairingUrlDialog(
|
||||
},
|
||||
confirmButton = {}, // actions live inside QrDisplayCard
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) { Text("Done") }
|
||||
TextButton(onClick = onDismiss) { Text(strings.nwc.done) }
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.bitcointxoko.gudariwallet.ui.nwc
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
@@ -13,8 +15,10 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.bitcointxoko.gudariwallet.LocalAppStrings
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun NwcScreen(
|
||||
@@ -30,8 +34,13 @@ fun NwcScreen(
|
||||
val pendingDeletePubkey by viewModel.pendingDeletePubkey.collectAsStateWithLifecycle()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
val strings = LocalAppStrings.current
|
||||
|
||||
val refresh = { viewModel.loadConnections(includeExpired = true) }
|
||||
val refresh = { viewModel.loadConnections(includeExpired = true, strings) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.loadConnections(includeExpired = true, strings)
|
||||
}
|
||||
|
||||
LaunchedEffect(pairingUrl) {
|
||||
if (pairingUrl != null) {
|
||||
@@ -42,17 +51,17 @@ fun NwcScreen(
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Wallet Connect") },
|
||||
title = { Text(strings.nwc.walletConnect) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
|
||||
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = strings.nwc.back)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(onClick = { viewModel.openAddSheet() }) {
|
||||
Icon(Icons.Default.Add, contentDescription = "Add connection")
|
||||
Icon(Icons.Default.Add, contentDescription = strings.nwc.addConnection)
|
||||
}
|
||||
},
|
||||
snackbarHost = { SnackbarHost(snackbarHostState) }
|
||||
@@ -102,7 +111,7 @@ fun NwcScreen(
|
||||
connection,
|
||||
isDeleting,
|
||||
onDeleteConfirm = { viewModel.requestDelete(connection.data.pubkey) },
|
||||
onConnectionClick = { onConnectionClick(connection.data.pubkey) }
|
||||
{ onConnectionClick(connection.data.pubkey) }
|
||||
)
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
@@ -125,7 +134,8 @@ fun NwcScreen(
|
||||
description = description,
|
||||
permissions = permissions,
|
||||
expiresAt = expiresAt,
|
||||
budgets = budgets
|
||||
budgets = budgets,
|
||||
strings = strings
|
||||
)
|
||||
},
|
||||
onDismiss = { viewModel.closeAddSheet() }
|
||||
@@ -134,12 +144,13 @@ fun NwcScreen(
|
||||
|
||||
// ── Pairing URL dialog ─────────────────────────────────────────────────────
|
||||
pairingUrl?.let { url ->
|
||||
val strings = strings
|
||||
NwcPairingUrlDialog(
|
||||
url = url,
|
||||
onDismiss = { viewModel.clearPairingUrl() },
|
||||
onNoAppFound = {
|
||||
scope.launch {
|
||||
snackbarHostState.showSnackbar("No compatible app found")
|
||||
snackbarHostState.showSnackbar(strings.nwc.noCompatibleAppFound)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -149,15 +160,15 @@ fun NwcScreen(
|
||||
pendingDeletePubkey?.let {
|
||||
AlertDialog(
|
||||
onDismissRequest = { viewModel.cancelDelete() },
|
||||
title = { Text("Remove connection?") },
|
||||
text = { Text("This will permanently revoke this Nostr Wallet Connect key. Any app using it will lose access.") },
|
||||
title = { Text(strings.nwc.removeConnection) },
|
||||
text = { Text(strings.nwc.removeConnectionDetail) },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = { viewModel.confirmDelete() }
|
||||
) { Text("Remove", color = MaterialTheme.colorScheme.error) }
|
||||
onClick = { viewModel.confirmDelete(strings) }
|
||||
) { Text(strings.nwc.remove, color = MaterialTheme.colorScheme.error) }
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { viewModel.cancelDelete() }) { Text("Cancel") }
|
||||
TextButton(onClick = { viewModel.cancelDelete() }) { Text(strings.nwc.cancel) }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bitcointxoko.gudariwallet.strings
|
||||
|
||||
// ── Empty state ──────────────────────────────────────────────────────
|
||||
|
||||
@@ -21,10 +22,10 @@ internal fun NwcEmptyContent(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text("No connections yet", style = MaterialTheme.typography.titleMedium)
|
||||
Text(strings.nwc.noConnectionsYet, style = MaterialTheme.typography.titleMedium)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(
|
||||
"Tap + to connect an app via Nostr Wallet Connect.",
|
||||
strings.nwc.tapToAddHint,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
@@ -32,7 +33,7 @@ internal fun NwcEmptyContent(
|
||||
Button(onClick = onAddNew) {
|
||||
Icon(Icons.Default.Add, contentDescription = null)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text("Add connection")
|
||||
Text(strings.nwc.addConnection)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +52,7 @@ internal fun NwcErrorContent(
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
"Something went wrong",
|
||||
strings.nwc.somethingWentWrong,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
@@ -62,6 +63,6 @@ internal fun NwcErrorContent(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(Modifier.height(24.dp))
|
||||
OutlinedButton(onClick = onRetry) { Text("Retry") }
|
||||
OutlinedButton(onClick = onRetry) { Text(strings.nwc.retry) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,16 @@ package com.bitcointxoko.gudariwallet.ui.nwc
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.bitcointxoko.gudariwallet.LocalAppStrings
|
||||
import com.bitcointxoko.gudariwallet.api.NwcGetResponse
|
||||
import com.bitcointxoko.gudariwallet.api.NwcNewBudget
|
||||
import com.bitcointxoko.gudariwallet.api.NwcRegistrationRequest
|
||||
import com.bitcointxoko.gudariwallet.data.NwcCacheRepository
|
||||
import com.bitcointxoko.gudariwallet.data.WalletRepository
|
||||
import com.bitcointxoko.gudariwallet.data.db.toDomain
|
||||
import com.bitcointxoko.gudariwallet.data.toDomain
|
||||
import com.bitcointxoko.gudariwallet.data.toGetResponse
|
||||
import com.bitcointxoko.gudariwallet.i18n.AppStrings
|
||||
import com.bitcointxoko.gudariwallet.util.NwcKeyGenerator
|
||||
import com.bitcointxoko.gudariwallet.util.NwcKeypair
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -95,18 +97,14 @@ class NwcViewModel(
|
||||
fun requestDelete(pubkey: String) { _pendingDeletePubkey.value = pubkey }
|
||||
fun cancelDelete() { _pendingDeletePubkey.value = null }
|
||||
// confirmDelete() calls the existing deleteConnection() then clears the pending key
|
||||
fun confirmDelete() {
|
||||
_pendingDeletePubkey.value?.let { deleteConnection(it) }
|
||||
fun confirmDelete(strings: AppStrings) {
|
||||
_pendingDeletePubkey.value?.let { deleteConnection(it, strings) }
|
||||
_pendingDeletePubkey.value = null
|
||||
}
|
||||
|
||||
init {
|
||||
loadConnections(includeExpired = true)
|
||||
}
|
||||
|
||||
// ── Load ──────────────────────────────────────────────────────────────────
|
||||
|
||||
fun loadConnections(includeExpired: Boolean = false) {
|
||||
fun loadConnections(includeExpired: Boolean = false, strings: AppStrings) {
|
||||
Timber.d("[$TAG] loadConnections(includeExpired=$includeExpired)")
|
||||
isSyncing = true
|
||||
|
||||
@@ -154,7 +152,7 @@ class NwcViewModel(
|
||||
isSyncing = false
|
||||
if (_uiState.value !is NwcUiState.Success) {
|
||||
_uiState.value = NwcUiState.Error(
|
||||
e.message ?: "Failed to load connections"
|
||||
e.message ?: strings.nwc.failedToLoadConnections
|
||||
)
|
||||
} else {
|
||||
Timber.w("[$TAG] network failed but cache is showing — non-fatal")
|
||||
@@ -172,7 +170,8 @@ class NwcViewModel(
|
||||
description : String,
|
||||
permissions : List<String>,
|
||||
expiresAt : Long = 0L,
|
||||
budgets : List<NwcNewBudget> = emptyList()
|
||||
budgets : List<NwcNewBudget> = emptyList(),
|
||||
strings : AppStrings
|
||||
) {
|
||||
Timber.d("[$TAG] createConnection description='$description' permissions=$permissions")
|
||||
viewModelScope.launch {
|
||||
@@ -213,7 +212,7 @@ class NwcViewModel(
|
||||
}
|
||||
.onFailure { e ->
|
||||
Timber.e(e, "[$TAG] createConnection failed")
|
||||
_uiState.value = NwcUiState.Error(e.message ?: "Failed to create connection")
|
||||
_uiState.value = NwcUiState.Error(e.message ?: strings.nwc.failedToCreateConnection)
|
||||
}
|
||||
} finally {
|
||||
_isCreating.value = false
|
||||
@@ -234,7 +233,7 @@ class NwcViewModel(
|
||||
* and the detail screen (revoke button). Sets [_isDeleting] for the duration
|
||||
* so the list screen can disable row interactions while in flight.
|
||||
*/
|
||||
fun deleteConnection(pubkey: String) {
|
||||
fun deleteConnection(pubkey: String, strings: AppStrings) {
|
||||
Timber.d("[$TAG] deleteConnection pubkey=${pubkey.take(16)}…")
|
||||
viewModelScope.launch {
|
||||
_isDeleting.value = true
|
||||
@@ -254,7 +253,7 @@ class NwcViewModel(
|
||||
.onFailure { e ->
|
||||
Timber.e(e, "[$TAG] failed to delete connection pubkey=${pubkey.take(16)}…")
|
||||
_uiState.value = NwcUiState.Error(
|
||||
e.message ?: "Failed to delete connection"
|
||||
e.message ?: strings.nwc.failedToDeleteConnection
|
||||
)
|
||||
}
|
||||
} finally {
|
||||
@@ -264,7 +263,7 @@ class NwcViewModel(
|
||||
}
|
||||
|
||||
|
||||
fun loadConnectionDetail(pubkey: String) {
|
||||
fun loadConnectionDetail(pubkey: String, strings: AppStrings) {
|
||||
Timber.d("[$TAG] loadConnectionDetail pubkey=${pubkey.take(16)}…")
|
||||
|
||||
// Cancel any subscription from a previous key — prevents stale Flow
|
||||
@@ -303,7 +302,7 @@ class NwcViewModel(
|
||||
Timber.e(e, "[$TAG] failed to load connection detail")
|
||||
if (_connectionDetailState.value !is ConnectionDetailState.Success) {
|
||||
_connectionDetailState.value = ConnectionDetailState.Error(
|
||||
e.message ?: "Failed to load connection"
|
||||
e.message ?: strings.nwc.failedToLoadConnection
|
||||
)
|
||||
} else {
|
||||
Timber.w("[$TAG] detail network refresh failed — cache showing (non-fatal)")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.bitcointxoko.gudariwallet.util
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import timber.log.Timber
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
@@ -98,3 +100,15 @@ fun formatEpoch(epochSeconds: Long, todayLabel: String, yesterdayLabel: String):
|
||||
"—"
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
private fun epochToLocalDate(epochSeconds: Long): LocalDate =
|
||||
LocalDate.ofInstant(Instant.ofEpochSecond(epochSeconds), ZoneId.systemDefault())
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
internal fun isToday(epochSeconds: Long): Boolean =
|
||||
epochToLocalDate(epochSeconds) == LocalDate.now(ZoneId.systemDefault())
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
internal fun isYesterday(epochSeconds: Long): Boolean =
|
||||
epochToLocalDate(epochSeconds) == LocalDate.now(ZoneId.systemDefault()).minusDays(1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user