Adds recommended amounts for the Zap the Devs
Block error messages from closing the Zap split payment screen.
This commit is contained in:
@@ -103,7 +103,7 @@ class ZapPaymentHandler(val account: Account) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (account.hasWalletConnectSetup()) {
|
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.
|
onProgress(it * 0.25f + 0.75f) // keeps within range.
|
||||||
}, context) {
|
}, context) {
|
||||||
// onProgress(1f)
|
// onProgress(1f)
|
||||||
@@ -113,9 +113,9 @@ class ZapPaymentHandler(val account: Account) {
|
|||||||
it.map {
|
it.map {
|
||||||
Payable(
|
Payable(
|
||||||
info = it.key.first,
|
info = it.key.first,
|
||||||
user = null,
|
user = it.key.second.user,
|
||||||
amountMilliSats = it.value.first,
|
amountMilliSats = it.value.zapValue,
|
||||||
invoice = it.value.second,
|
invoice = it.value.invoice,
|
||||||
)
|
)
|
||||||
}.toImmutableList(),
|
}.toImmutableList(),
|
||||||
)
|
)
|
||||||
@@ -136,28 +136,33 @@ class ZapPaymentHandler(val account: Account) {
|
|||||||
return roundedZapValue
|
return roundedZapValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SignAllZapRequestsReturn(
|
||||||
|
val zapRequestJson: String,
|
||||||
|
val user: User? = null,
|
||||||
|
)
|
||||||
|
|
||||||
suspend fun signAllZapRequests(
|
suspend fun signAllZapRequests(
|
||||||
note: Note,
|
note: Note,
|
||||||
pollOption: Int?,
|
pollOption: Int?,
|
||||||
message: String,
|
message: String,
|
||||||
zapType: LnZapEvent.ZapType,
|
zapType: LnZapEvent.ZapType,
|
||||||
zapsToSend: List<ZapSplitSetup>,
|
zapsToSend: List<ZapSplitSetup>,
|
||||||
onAllDone: suspend (MutableMap<ZapSplitSetup, String>) -> Unit,
|
onAllDone: suspend (MutableMap<ZapSplitSetup, SignAllZapRequestsReturn>) -> Unit,
|
||||||
) {
|
) {
|
||||||
collectSuccessfulSigningOperations<ZapSplitSetup, String>(
|
collectSuccessfulSigningOperations<ZapSplitSetup, SignAllZapRequestsReturn>(
|
||||||
operationsInput = zapsToSend,
|
operationsInput = zapsToSend,
|
||||||
runRequestFor = { next: ZapSplitSetup, onReady ->
|
runRequestFor = { next: ZapSplitSetup, onReady ->
|
||||||
if (next.isLnAddress) {
|
if (next.isLnAddress) {
|
||||||
prepareZapRequestIfNeeded(note, pollOption, message, zapType) { zapRequestJson ->
|
prepareZapRequestIfNeeded(note, pollOption, message, zapType) { zapRequestJson ->
|
||||||
if (zapRequestJson != null) {
|
if (zapRequestJson != null) {
|
||||||
onReady(zapRequestJson)
|
onReady(SignAllZapRequestsReturn(zapRequestJson))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val user = LocalCache.getUserIfExists(next.lnAddressOrPubKeyHex)
|
val user = LocalCache.getUserIfExists(next.lnAddressOrPubKeyHex)
|
||||||
prepareZapRequestIfNeeded(note, pollOption, message, zapType, user) { zapRequestJson ->
|
prepareZapRequestIfNeeded(note, pollOption, message, zapType, user) { zapRequestJson ->
|
||||||
if (zapRequestJson != null) {
|
if (zapRequestJson != null) {
|
||||||
onReady(zapRequestJson)
|
onReady(SignAllZapRequestsReturn(zapRequestJson, user))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,23 +172,23 @@ class ZapPaymentHandler(val account: Account) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun assembleAllInvoices(
|
suspend fun assembleAllInvoices(
|
||||||
invoices: List<Pair<ZapSplitSetup, String>>,
|
invoices: List<Pair<ZapSplitSetup, SignAllZapRequestsReturn>>,
|
||||||
totalAmountMilliSats: Long,
|
totalAmountMilliSats: Long,
|
||||||
message: String,
|
message: String,
|
||||||
onError: (String, String) -> Unit,
|
onError: (String, String) -> Unit,
|
||||||
onProgress: (percent: Float) -> Unit,
|
onProgress: (percent: Float) -> Unit,
|
||||||
context: Context,
|
context: Context,
|
||||||
onAllDone: suspend (MutableMap<Pair<ZapSplitSetup, String>, Pair<Long, String>>) -> Unit,
|
onAllDone: suspend (MutableMap<Pair<ZapSplitSetup, SignAllZapRequestsReturn>, AssembleInvoiceReturn>) -> Unit,
|
||||||
) {
|
) {
|
||||||
var progressAllPayments = 0.00f
|
var progressAllPayments = 0.00f
|
||||||
val totalWeight = invoices.sumOf { it.first.weight }
|
val totalWeight = invoices.sumOf { it.first.weight }
|
||||||
|
|
||||||
collectSuccessfulSigningOperations<Pair<ZapSplitSetup, String>, Pair<Long, String>>(
|
collectSuccessfulSigningOperations<Pair<ZapSplitSetup, SignAllZapRequestsReturn>, AssembleInvoiceReturn>(
|
||||||
operationsInput = invoices,
|
operationsInput = invoices,
|
||||||
runRequestFor = { splitZapRequestPair: Pair<ZapSplitSetup, String>, onReady ->
|
runRequestFor = { splitZapRequestPair: Pair<ZapSplitSetup, SignAllZapRequestsReturn>, onReady ->
|
||||||
assembleInvoice(
|
assembleInvoice(
|
||||||
splitSetup = splitZapRequestPair.first,
|
splitSetup = splitZapRequestPair.first,
|
||||||
nostrZapRequest = splitZapRequestPair.second,
|
nostrZapRequest = splitZapRequestPair.second.zapRequestJson,
|
||||||
zapValue = calculateZapValue(totalAmountMilliSats, splitZapRequestPair.first.weight, totalWeight),
|
zapValue = calculateZapValue(totalAmountMilliSats, splitZapRequestPair.first.weight, totalWeight),
|
||||||
message = message,
|
message = message,
|
||||||
onError = onError,
|
onError = onError,
|
||||||
@@ -243,6 +248,11 @@ class ZapPaymentHandler(val account: Account) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AssembleInvoiceReturn(
|
||||||
|
val zapValue: Long,
|
||||||
|
val invoice: String,
|
||||||
|
)
|
||||||
|
|
||||||
private fun assembleInvoice(
|
private fun assembleInvoice(
|
||||||
splitSetup: ZapSplitSetup,
|
splitSetup: ZapSplitSetup,
|
||||||
nostrZapRequest: String,
|
nostrZapRequest: String,
|
||||||
@@ -251,7 +261,7 @@ class ZapPaymentHandler(val account: Account) {
|
|||||||
onError: (String, String) -> Unit,
|
onError: (String, String) -> Unit,
|
||||||
onProgressStep: (percent: Float) -> Unit,
|
onProgressStep: (percent: Float) -> Unit,
|
||||||
context: Context,
|
context: Context,
|
||||||
onReady: (Pair<Long, String>) -> Unit,
|
onReady: (AssembleInvoiceReturn) -> Unit,
|
||||||
) {
|
) {
|
||||||
var progressThisPayment = 0.00f
|
var progressThisPayment = 0.00f
|
||||||
|
|
||||||
@@ -280,7 +290,7 @@ class ZapPaymentHandler(val account: Account) {
|
|||||||
context = context,
|
context = context,
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
onProgressStep(1 - progressThisPayment)
|
onProgressStep(1 - progressThisPayment)
|
||||||
onReady(Pair(zapValue, it))
|
onReady(AssembleInvoiceReturn(zapValue, it))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ fun ClickableWithdrawal(withdrawalString: String) {
|
|||||||
|
|
||||||
ClickableText(
|
ClickableText(
|
||||||
text = withdraw,
|
text = withdraw,
|
||||||
onClick = { payViaIntent(withdrawalString, context) { showErrorMessageDialog = it } },
|
onClick = { payViaIntent(withdrawalString, context, { }) { showErrorMessageDialog = it } },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ fun InvoicePreview(
|
|||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 10.dp),
|
.padding(vertical = 10.dp),
|
||||||
onClick = { payViaIntent(lnInvoice, context) { showErrorMessageDialog = it } },
|
onClick = { payViaIntent(lnInvoice, context, { }) { showErrorMessageDialog = it } },
|
||||||
shape = QuoteBorder,
|
shape = QuoteBorder,
|
||||||
colors =
|
colors =
|
||||||
ButtonDefaults.buttonColors(
|
ButtonDefaults.buttonColors(
|
||||||
|
|||||||
@@ -439,6 +439,15 @@ fun ZapVote(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
justShowError = {
|
||||||
|
scope.launch {
|
||||||
|
showErrorMessageDialog =
|
||||||
|
StringToastMsg(
|
||||||
|
context.getString(R.string.error_dialog_zap_error),
|
||||||
|
it,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -985,7 +985,8 @@ fun ZapReaction(
|
|||||||
if (wantsToZap) {
|
if (wantsToZap) {
|
||||||
ZapAmountChoicePopup(
|
ZapAmountChoicePopup(
|
||||||
baseNote = baseNote,
|
baseNote = baseNote,
|
||||||
iconSize = iconSize,
|
zapAmountChoices = accountViewModel.account.zapAmountChoices,
|
||||||
|
popupYOffset = iconSize,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
wantsToZap = false
|
wantsToZap = false
|
||||||
@@ -1042,6 +1043,11 @@ fun ZapReaction(
|
|||||||
showErrorMessageDialog = showErrorMessageDialog + it
|
showErrorMessageDialog = showErrorMessageDialog + it
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
justShowError = {
|
||||||
|
scope.launch {
|
||||||
|
showErrorMessageDialog = showErrorMessageDialog + it
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1430,6 +1436,7 @@ private fun ActionableReactionButton(
|
|||||||
@Composable
|
@Composable
|
||||||
fun ZapAmountChoicePopup(
|
fun ZapAmountChoicePopup(
|
||||||
baseNote: Note,
|
baseNote: Note,
|
||||||
|
zapAmountChoices: List<Long>,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
popupYOffset: Dp,
|
popupYOffset: Dp,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
@@ -1449,7 +1456,7 @@ fun ZapAmountChoicePopup(
|
|||||||
onDismissRequest = { onDismiss() },
|
onDismissRequest = { onDismiss() },
|
||||||
) {
|
) {
|
||||||
FlowRow(horizontalArrangement = Arrangement.Center) {
|
FlowRow(horizontalArrangement = Arrangement.Center) {
|
||||||
accountViewModel.account.zapAmountChoices.forEach { amountInSats ->
|
zapAmountChoices.forEach { amountInSats ->
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.padding(horizontal = 3.dp),
|
modifier = Modifier.padding(horizontal = 3.dp),
|
||||||
onClick = {
|
onClick = {
|
||||||
|
|||||||
@@ -347,12 +347,12 @@ fun PayViaIntentDialog(
|
|||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
onClose: () -> Unit,
|
onClose: () -> Unit,
|
||||||
onError: (String) -> Unit,
|
onError: (String) -> Unit,
|
||||||
|
justShowError: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
if (payingInvoices.size == 1) {
|
if (payingInvoices.size == 1) {
|
||||||
payViaIntent(payingInvoices.first().invoice, context, onError)
|
payViaIntent(payingInvoices.first().invoice, context, onClose, onError)
|
||||||
onClose()
|
|
||||||
} else {
|
} else {
|
||||||
Dialog(
|
Dialog(
|
||||||
onDismissRequest = onClose,
|
onDismissRequest = onClose,
|
||||||
@@ -422,9 +422,7 @@ fun PayViaIntentDialog(
|
|||||||
Spacer(modifier = DoubleHorzSpacer)
|
Spacer(modifier = DoubleHorzSpacer)
|
||||||
|
|
||||||
PayButton(isActive = !paid.value) {
|
PayButton(isActive = !paid.value) {
|
||||||
paid.value = true
|
payViaIntent(it.invoice, context, { paid.value = true }, justShowError)
|
||||||
|
|
||||||
payViaIntent(it.invoice, context, onError)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -437,6 +435,7 @@ fun PayViaIntentDialog(
|
|||||||
fun payViaIntent(
|
fun payViaIntent(
|
||||||
invoice: String,
|
invoice: String,
|
||||||
context: Context,
|
context: Context,
|
||||||
|
onPaid: () -> Unit,
|
||||||
onError: (String) -> Unit,
|
onError: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
@@ -444,6 +443,7 @@ fun payViaIntent(
|
|||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
|
|
||||||
ContextCompat.startActivity(context, intent, null)
|
ContextCompat.startActivity(context, intent, null)
|
||||||
|
onPaid()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (e is CancellationException) throw e
|
if (e is CancellationException) throw e
|
||||||
// don't display ugly error messages
|
// don't display ugly error messages
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.note
|
package com.vitorpamplona.amethyst.ui.note
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -306,7 +307,7 @@ fun ZapDonationButton(
|
|||||||
animationSize: Dp = 14.dp,
|
animationSize: Dp = 14.dp,
|
||||||
nav: (String) -> Unit,
|
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 showErrorMessageDialog by remember { mutableStateOf<String?>(null) }
|
||||||
var wantsToPay by
|
var wantsToPay by
|
||||||
remember(baseNote) {
|
remember(baseNote) {
|
||||||
@@ -323,14 +324,14 @@ fun ZapDonationButton(
|
|||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
zapClick(
|
customZapClick(
|
||||||
baseNote,
|
baseNote,
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
context,
|
context,
|
||||||
onZappingProgress = { progress: Float ->
|
onZappingProgress = { progress: Float ->
|
||||||
scope.launch { zappingProgress = progress }
|
scope.launch { zappingProgress = progress }
|
||||||
},
|
},
|
||||||
onMultipleChoices = { wantsToZap = true },
|
onMultipleChoices = { options -> wantsToZap = options },
|
||||||
onError = { _, message ->
|
onError = { _, message ->
|
||||||
scope.launch {
|
scope.launch {
|
||||||
zappingProgress = 0f
|
zappingProgress = 0f
|
||||||
@@ -342,17 +343,18 @@ fun ZapDonationButton(
|
|||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
) {
|
) {
|
||||||
if (wantsToZap) {
|
if (wantsToZap != null) {
|
||||||
ZapAmountChoicePopup(
|
ZapAmountChoicePopup(
|
||||||
baseNote = baseNote,
|
baseNote = baseNote,
|
||||||
|
zapAmountChoices = wantsToZap ?: accountViewModel.account.zapAmountChoices,
|
||||||
popupYOffset = iconSize,
|
popupYOffset = iconSize,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
wantsToZap = false
|
wantsToZap = null
|
||||||
zappingProgress = 0f
|
zappingProgress = 0f
|
||||||
},
|
},
|
||||||
onChangeAmount = {
|
onChangeAmount = {
|
||||||
wantsToZap = false
|
wantsToZap = null
|
||||||
},
|
},
|
||||||
onError = { _, message ->
|
onError = { _, message ->
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@@ -395,6 +397,11 @@ fun ZapDonationButton(
|
|||||||
showErrorMessageDialog = it
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1193,7 +1193,7 @@ fun DisplayLNAddress(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
payViaIntent(it, context) { showErrorMessageDialog = it }
|
payViaIntent(it, context, { zapExpanded = false }, { showErrorMessageDialog = it })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onClose = { zapExpanded = false },
|
onClose = { zapExpanded = false },
|
||||||
|
|||||||
Reference in New Issue
Block a user