Adds recommended amounts for the Zap the Devs

Block error messages from closing the Zap split payment screen.
This commit is contained in:
Vitor Pamplona 2024-05-13 13:27:03 -04:00
parent 065ba1c165
commit 58ed27dc75
8 changed files with 119 additions and 31 deletions

View File

@ -103,7 +103,7 @@ class ZapPaymentHandler(val account: Account) {
}
if (account.hasWalletConnectSetup()) {
payViaNWC(it.values.map { it.second }, note, onError, onProgress = {
payViaNWC(it.values.map { it.invoice }, note, onError, onProgress = {
onProgress(it * 0.25f + 0.75f) // keeps within range.
}, context) {
// onProgress(1f)
@ -113,9 +113,9 @@ class ZapPaymentHandler(val account: Account) {
it.map {
Payable(
info = it.key.first,
user = null,
amountMilliSats = it.value.first,
invoice = it.value.second,
user = it.key.second.user,
amountMilliSats = it.value.zapValue,
invoice = it.value.invoice,
)
}.toImmutableList(),
)
@ -136,28 +136,33 @@ class ZapPaymentHandler(val account: Account) {
return roundedZapValue
}
class SignAllZapRequestsReturn(
val zapRequestJson: String,
val user: User? = null,
)
suspend fun signAllZapRequests(
note: Note,
pollOption: Int?,
message: String,
zapType: LnZapEvent.ZapType,
zapsToSend: List<ZapSplitSetup>,
onAllDone: suspend (MutableMap<ZapSplitSetup, String>) -> Unit,
onAllDone: suspend (MutableMap<ZapSplitSetup, SignAllZapRequestsReturn>) -> Unit,
) {
collectSuccessfulSigningOperations<ZapSplitSetup, String>(
collectSuccessfulSigningOperations<ZapSplitSetup, SignAllZapRequestsReturn>(
operationsInput = zapsToSend,
runRequestFor = { next: ZapSplitSetup, onReady ->
if (next.isLnAddress) {
prepareZapRequestIfNeeded(note, pollOption, message, zapType) { zapRequestJson ->
if (zapRequestJson != null) {
onReady(zapRequestJson)
onReady(SignAllZapRequestsReturn(zapRequestJson))
}
}
} else {
val user = LocalCache.getUserIfExists(next.lnAddressOrPubKeyHex)
prepareZapRequestIfNeeded(note, pollOption, message, zapType, user) { zapRequestJson ->
if (zapRequestJson != null) {
onReady(zapRequestJson)
onReady(SignAllZapRequestsReturn(zapRequestJson, user))
}
}
}
@ -167,23 +172,23 @@ class ZapPaymentHandler(val account: Account) {
}
suspend fun assembleAllInvoices(
invoices: List<Pair<ZapSplitSetup, String>>,
invoices: List<Pair<ZapSplitSetup, SignAllZapRequestsReturn>>,
totalAmountMilliSats: Long,
message: String,
onError: (String, String) -> Unit,
onProgress: (percent: Float) -> Unit,
context: Context,
onAllDone: suspend (MutableMap<Pair<ZapSplitSetup, String>, Pair<Long, String>>) -> Unit,
onAllDone: suspend (MutableMap<Pair<ZapSplitSetup, SignAllZapRequestsReturn>, AssembleInvoiceReturn>) -> Unit,
) {
var progressAllPayments = 0.00f
val totalWeight = invoices.sumOf { it.first.weight }
collectSuccessfulSigningOperations<Pair<ZapSplitSetup, String>, Pair<Long, String>>(
collectSuccessfulSigningOperations<Pair<ZapSplitSetup, SignAllZapRequestsReturn>, AssembleInvoiceReturn>(
operationsInput = invoices,
runRequestFor = { splitZapRequestPair: Pair<ZapSplitSetup, String>, onReady ->
runRequestFor = { splitZapRequestPair: Pair<ZapSplitSetup, SignAllZapRequestsReturn>, onReady ->
assembleInvoice(
splitSetup = splitZapRequestPair.first,
nostrZapRequest = splitZapRequestPair.second,
nostrZapRequest = splitZapRequestPair.second.zapRequestJson,
zapValue = calculateZapValue(totalAmountMilliSats, splitZapRequestPair.first.weight, totalWeight),
message = message,
onError = onError,
@ -243,6 +248,11 @@ class ZapPaymentHandler(val account: Account) {
)
}
class AssembleInvoiceReturn(
val zapValue: Long,
val invoice: String,
)
private fun assembleInvoice(
splitSetup: ZapSplitSetup,
nostrZapRequest: String,
@ -251,7 +261,7 @@ class ZapPaymentHandler(val account: Account) {
onError: (String, String) -> Unit,
onProgressStep: (percent: Float) -> Unit,
context: Context,
onReady: (Pair<Long, String>) -> Unit,
onReady: (AssembleInvoiceReturn) -> Unit,
) {
var progressThisPayment = 0.00f
@ -280,7 +290,7 @@ class ZapPaymentHandler(val account: Account) {
context = context,
onSuccess = {
onProgressStep(1 - progressThisPayment)
onReady(Pair(zapValue, it))
onReady(AssembleInvoiceReturn(zapValue, it))
},
)
} else {

View File

@ -79,7 +79,7 @@ fun ClickableWithdrawal(withdrawalString: String) {
ClickableText(
text = withdraw,
onClick = { payViaIntent(withdrawalString, context) { showErrorMessageDialog = it } },
onClick = { payViaIntent(withdrawalString, context, { }) { showErrorMessageDialog = it } },
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
)
}

View File

@ -169,7 +169,7 @@ fun InvoicePreview(
Modifier
.fillMaxWidth()
.padding(vertical = 10.dp),
onClick = { payViaIntent(lnInvoice, context) { showErrorMessageDialog = it } },
onClick = { payViaIntent(lnInvoice, context, { }) { showErrorMessageDialog = it } },
shape = QuoteBorder,
colors =
ButtonDefaults.buttonColors(

View File

@ -439,6 +439,15 @@ fun ZapVote(
)
}
},
justShowError = {
scope.launch {
showErrorMessageDialog =
StringToastMsg(
context.getString(R.string.error_dialog_zap_error),
it,
)
}
},
)
}

View File

@ -985,7 +985,8 @@ fun ZapReaction(
if (wantsToZap) {
ZapAmountChoicePopup(
baseNote = baseNote,
iconSize = iconSize,
zapAmountChoices = accountViewModel.account.zapAmountChoices,
popupYOffset = iconSize,
accountViewModel = accountViewModel,
onDismiss = {
wantsToZap = false
@ -1042,6 +1043,11 @@ fun ZapReaction(
showErrorMessageDialog = showErrorMessageDialog + it
}
},
justShowError = {
scope.launch {
showErrorMessageDialog = showErrorMessageDialog + it
}
},
)
}
@ -1430,6 +1436,7 @@ private fun ActionableReactionButton(
@Composable
fun ZapAmountChoicePopup(
baseNote: Note,
zapAmountChoices: List<Long>,
accountViewModel: AccountViewModel,
popupYOffset: Dp,
onDismiss: () -> Unit,
@ -1449,7 +1456,7 @@ fun ZapAmountChoicePopup(
onDismissRequest = { onDismiss() },
) {
FlowRow(horizontalArrangement = Arrangement.Center) {
accountViewModel.account.zapAmountChoices.forEach { amountInSats ->
zapAmountChoices.forEach { amountInSats ->
Button(
modifier = Modifier.padding(horizontal = 3.dp),
onClick = {

View File

@ -347,12 +347,12 @@ fun PayViaIntentDialog(
accountViewModel: AccountViewModel,
onClose: () -> Unit,
onError: (String) -> Unit,
justShowError: (String) -> Unit,
) {
val context = LocalContext.current
if (payingInvoices.size == 1) {
payViaIntent(payingInvoices.first().invoice, context, onError)
onClose()
payViaIntent(payingInvoices.first().invoice, context, onClose, onError)
} else {
Dialog(
onDismissRequest = onClose,
@ -422,9 +422,7 @@ fun PayViaIntentDialog(
Spacer(modifier = DoubleHorzSpacer)
PayButton(isActive = !paid.value) {
paid.value = true
payViaIntent(it.invoice, context, onError)
payViaIntent(it.invoice, context, { paid.value = true }, justShowError)
}
}
}
@ -437,6 +435,7 @@ fun PayViaIntentDialog(
fun payViaIntent(
invoice: String,
context: Context,
onPaid: () -> Unit,
onError: (String) -> Unit,
) {
try {
@ -444,6 +443,7 @@ fun payViaIntent(
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
ContextCompat.startActivity(context, intent, null)
onPaid()
} catch (e: Exception) {
if (e is CancellationException) throw e
// don't display ugly error messages

View File

@ -20,6 +20,7 @@
*/
package com.vitorpamplona.amethyst.ui.note
import android.content.Context
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.Arrangement
@ -306,7 +307,7 @@ fun ZapDonationButton(
animationSize: Dp = 14.dp,
nav: (String) -> Unit,
) {
var wantsToZap by remember { mutableStateOf(false) }
var wantsToZap by remember { mutableStateOf<List<Long>?>(null) }
var showErrorMessageDialog by remember { mutableStateOf<String?>(null) }
var wantsToPay by
remember(baseNote) {
@ -323,14 +324,14 @@ fun ZapDonationButton(
Button(
onClick = {
zapClick(
customZapClick(
baseNote,
accountViewModel,
context,
onZappingProgress = { progress: Float ->
scope.launch { zappingProgress = progress }
},
onMultipleChoices = { wantsToZap = true },
onMultipleChoices = { options -> wantsToZap = options },
onError = { _, message ->
scope.launch {
zappingProgress = 0f
@ -342,17 +343,18 @@ fun ZapDonationButton(
},
modifier = Modifier.fillMaxWidth(),
) {
if (wantsToZap) {
if (wantsToZap != null) {
ZapAmountChoicePopup(
baseNote = baseNote,
zapAmountChoices = wantsToZap ?: accountViewModel.account.zapAmountChoices,
popupYOffset = iconSize,
accountViewModel = accountViewModel,
onDismiss = {
wantsToZap = false
wantsToZap = null
zappingProgress = 0f
},
onChangeAmount = {
wantsToZap = false
wantsToZap = null
},
onError = { _, message ->
scope.launch {
@ -395,6 +397,11 @@ fun ZapDonationButton(
showErrorMessageDialog = it
}
},
justShowError = {
scope.launch {
showErrorMessageDialog = it
}
},
)
}
@ -448,3 +455,58 @@ fun ZapDonationButton(
}
}
}
fun customZapClick(
baseNote: Note,
accountViewModel: AccountViewModel,
context: Context,
onZappingProgress: (Float) -> Unit,
onMultipleChoices: (List<Long>) -> Unit,
onError: (String, String) -> Unit,
onPayViaIntent: (ImmutableList<ZapPaymentHandler.Payable>) -> Unit,
) {
if (baseNote.isDraft()) {
accountViewModel.toast(
R.string.draft_note,
R.string.it_s_not_possible_to_zap_to_a_draft_note,
)
return
}
if (accountViewModel.account.zapAmountChoices.isEmpty()) {
accountViewModel.toast(
context.getString(R.string.error_dialog_zap_error),
context.getString(R.string.no_zap_amount_setup_long_press_to_change),
)
} else if (!accountViewModel.isWriteable()) {
accountViewModel.toast(
context.getString(R.string.error_dialog_zap_error),
context.getString(R.string.login_with_a_private_key_to_be_able_to_send_zaps),
)
} else if (accountViewModel.account.zapAmountChoices.size == 1) {
val amount = accountViewModel.account.zapAmountChoices.first()
if (amount > 600) {
accountViewModel.zap(
baseNote,
amount * 1000,
null,
"",
context,
onError = onError,
onProgress = { onZappingProgress(it) },
zapType = accountViewModel.account.defaultZapType,
onPayViaIntent = onPayViaIntent,
)
} else {
onMultipleChoices(listOf(1000L, 5_000L, 10_000L))
// recommends amounts for a monthly release.
}
} else if (accountViewModel.account.zapAmountChoices.size > 1) {
if (accountViewModel.account.zapAmountChoices.any { it > 600 }) {
onMultipleChoices(accountViewModel.account.zapAmountChoices)
} else {
onMultipleChoices(listOf(1000L, 5_000L, 10_000L))
}
}
}

View File

@ -1193,7 +1193,7 @@ fun DisplayLNAddress(
}
}
} else {
payViaIntent(it, context) { showErrorMessageDialog = it }
payViaIntent(it, context, { zapExpanded = false }, { showErrorMessageDialog = it })
}
},
onClose = { zapExpanded = false },