refactor: move biometric prompt trigger to UI
This commit is contained in:
@@ -10,7 +10,6 @@ import com.bitcointxoko.gudariwallet.data.WalletRepository
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.bitcointxoko.gudariwallet.data.BalancePrefsStore
|
||||
import com.bitcointxoko.gudariwallet.data.LightningAddressStore
|
||||
import com.bitcointxoko.gudariwallet.ui.balance.BalanceViewModel
|
||||
@@ -103,12 +102,9 @@ class WalletViewModel(
|
||||
fun payLnurlInvoice(state: SendState.LnurlInvoiceReady, strings: SendStrings) =
|
||||
sendVm.payLnurlInvoice(state, strings)
|
||||
|
||||
fun requestPayment(
|
||||
activity : FragmentActivity,
|
||||
subtitle : String,
|
||||
strings : SendStrings,
|
||||
pay : () -> Unit,
|
||||
) = sendVm.requestPayment(activity, subtitle, strings, pay)
|
||||
fun onAuthFailed(message: String, strings: SendStrings) {
|
||||
sendVm.onAuthFailed(message, strings)
|
||||
}
|
||||
fun resetSendState() = sendVm.resetSendState()
|
||||
|
||||
val sendEvents: SharedFlow<SendEvent> = sendVm.events
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.bitcointxoko.gudariwallet.ui.SendState
|
||||
import com.bitcointxoko.gudariwallet.ui.WalletViewModel
|
||||
import com.bitcointxoko.gudariwallet.ui.components.CopyIconButton
|
||||
import com.bitcointxoko.gudariwallet.ui.components.DetailRow
|
||||
import com.bitcointxoko.gudariwallet.util.BiometricHelper
|
||||
import com.bitcointxoko.gudariwallet.util.fiatLabel
|
||||
import com.bitcointxoko.gudariwallet.util.payingToLabel
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -52,13 +53,13 @@ internal fun Bolt11ConfirmCard(
|
||||
title = strings.invoiceDetails, // ← "Invoice Details"
|
||||
invoice = state,
|
||||
fiatLabel = fiatLbl,
|
||||
onPay = {
|
||||
vm.requestPayment(
|
||||
activity,
|
||||
strings.sendBiometricPrompt(state.amountSats),
|
||||
strings = sendStrings, // ← "Send X sats"
|
||||
) { vm.payBolt11(state.bolt11, sendStrings) }
|
||||
},
|
||||
onPay = rememberBiometricPay(
|
||||
activity = activity,
|
||||
subtitle = strings.sendBiometricPrompt(state.amountSats),
|
||||
strings = sendStrings,
|
||||
vm = vm,
|
||||
pay = { vm.payBolt11(state.bolt11, sendStrings) }
|
||||
),
|
||||
onCancel = { vm.resetSendState() }
|
||||
)
|
||||
}
|
||||
@@ -79,13 +80,13 @@ internal fun LnurlInvoiceConfirmCard(
|
||||
title = strings.payingTo(label), // ← "Paying to X"
|
||||
invoice = state,
|
||||
fiatLabel = fiatLbl,
|
||||
onPay = {
|
||||
vm.requestPayment(
|
||||
activity,
|
||||
strings.sendBiometricPromptTo(state.amountSats, label),
|
||||
strings = sendStrings, // ← "Send X sats to Y"
|
||||
) { vm.payLnurlInvoice(state, sendStrings) }
|
||||
},
|
||||
onPay = rememberBiometricPay(
|
||||
activity = activity,
|
||||
subtitle = strings.sendBiometricPromptTo(state.amountSats, label),
|
||||
strings = sendStrings,
|
||||
vm = vm,
|
||||
pay = { vm.payLnurlInvoice(state, sendStrings) }
|
||||
),
|
||||
onCancel = { vm.resetSendState() }
|
||||
)
|
||||
}
|
||||
@@ -270,3 +271,25 @@ private fun PayCancelButton(onCancel: () -> Unit) {
|
||||
Text(strings.cancel) // ← "Cancel"
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberBiometricPay(
|
||||
activity : FragmentActivity,
|
||||
subtitle : String,
|
||||
strings : SendStrings,
|
||||
vm : WalletViewModel,
|
||||
pay : () -> Unit,
|
||||
): () -> Unit = remember(subtitle) {
|
||||
{
|
||||
if (BiometricHelper.canAuthenticate(activity)) {
|
||||
BiometricHelper.prompt(
|
||||
activity = activity,
|
||||
subtitle = subtitle,
|
||||
onSuccess = pay,
|
||||
onError = { _, msg -> vm.onAuthFailed(msg.toString(), strings) }
|
||||
)
|
||||
} else {
|
||||
pay()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,10 @@ class SendViewModel(
|
||||
private val _sendState = MutableStateFlow<SendState>(SendState.Idle)
|
||||
val sendState: StateFlow<SendState> = _sendState
|
||||
|
||||
fun onAuthFailed(message: String, strings: SendStrings) {
|
||||
_sendState.value = SendState.Error(strings.authFailed(message))
|
||||
}
|
||||
|
||||
// ── Entry point ──────────────────────────────────────────────────────────
|
||||
|
||||
fun scan(rawInput: String, strings: SendStrings) {
|
||||
@@ -321,31 +325,6 @@ class SendViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Biometric gate. Shows prompt if device supports it; calls [pay] directly if not.
|
||||
*/
|
||||
fun requestPayment(
|
||||
activity : FragmentActivity,
|
||||
subtitle : String,
|
||||
strings : SendStrings,
|
||||
pay : () -> Unit
|
||||
) {
|
||||
if (!BiometricHelper.canAuthenticate(activity)) {
|
||||
pay()
|
||||
return
|
||||
}
|
||||
BiometricHelper.prompt(
|
||||
activity = activity,
|
||||
subtitle = subtitle,
|
||||
onSuccess = pay,
|
||||
onError = { _, msg ->
|
||||
_sendState.value = SendState.Error(
|
||||
strings.authFailed(msg.toString()) // ← "Authentication failed: $msg"
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun resetSendState() { _sendState.value = SendState.Idle }
|
||||
|
||||
// ── Scan handlers ────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user