feat: tighten the zap UI

ReactionsRow zap popup
- Merge the Lightning and on-chain chips into a single FlowRow so all
  amounts wrap together instead of stacking on two lines.
- Drop the on-chain row's own Tune (settings) button; the Lightning
  row's Tune is the single entry point to the settings screen.

UpdateZapAmountDialog
- Reorder sections: Quick Zap Amounts, Zap Privacy, Quick On-chain Zap
  Amounts, Nostr Wallet Connect — privacy now sits next to the
  Lightning amounts it actually applies to, and on-chain (which has no
  privacy concept) is grouped further down.

OnchainZapSendDialog
- Move the preset amount chips above the sats text field in
  AmountSection so the user sees the quick picks first and the
  free-form input second.

Defaults
- DefaultOnchainZapAmounts is now [10_000] (just one chip) so a fresh
  install / first-upgrade shows 4 chips total in the popup (3
  Lightning defaults + 1 on-chain default), not 6. kotlinx
  serialization defaults handle the back-compat for existing users
  who never set their on-chain choices explicitly.
This commit is contained in:
Claude
2026-05-20 22:26:34 +00:00
parent f6db678249
commit 55e536dfd0
4 changed files with 80 additions and 106 deletions
@@ -38,7 +38,7 @@ val DefaultReactions =
)
val DefaultZapAmounts = listOf(100L, 500L, 1000L)
val DefaultOnchainZapAmounts = listOf(10_000L, 50_000L, 250_000L)
val DefaultOnchainZapAmounts = listOf(10_000L)
val DefaultReportWarningThreshold = 5
@Serializable
@@ -1976,66 +1976,40 @@ fun ZapAmountChoicePopupContent(
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp),
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant),
) {
Column {
FlowRow(
modifier = Modifier.padding(horizontal = 5.dp, vertical = 5.dp),
horizontalArrangement = Arrangement.Center,
verticalArrangement = Arrangement.Center,
itemVerticalAlignment = CenterVertically,
) {
zapAmountChoices.forEach { amountInSats ->
ZapAmountChip(
amountInSats = amountInSats,
onClick = { onZap(amountInSats) },
onLongClick = onChangeAmount,
)
}
ClickableBox(
modifier =
Modifier
.padding(horizontal = 4.dp, vertical = 6.dp)
.size(32.dp)
.padding(7.dp),
onClick = onChangeAmount,
) {
Icon(
symbol = MaterialSymbols.Tune,
contentDescription = stringRes(R.string.quick_zap_amounts),
modifier = Size18Modifier,
tint = MaterialTheme.colorScheme.placeholderText,
)
}
FlowRow(
modifier = Modifier.padding(horizontal = 5.dp, vertical = 5.dp),
horizontalArrangement = Arrangement.Center,
verticalArrangement = Arrangement.Center,
itemVerticalAlignment = CenterVertically,
) {
zapAmountChoices.forEach { amountInSats ->
ZapAmountChip(
amountInSats = amountInSats,
onClick = { onZap(amountInSats) },
onLongClick = onChangeAmount,
)
}
if (onchainZapAmountChoices.isNotEmpty()) {
FlowRow(
modifier = Modifier.padding(horizontal = 5.dp, vertical = 5.dp),
horizontalArrangement = Arrangement.Center,
verticalArrangement = Arrangement.Center,
itemVerticalAlignment = CenterVertically,
) {
onchainZapAmountChoices.forEach { amountInSats ->
OnchainZapAmountChip(
amountInSats = amountInSats,
onClick = { onOnchainAmount(amountInSats) },
onLongClick = onChangeAmount,
)
}
ClickableBox(
modifier =
Modifier
.padding(horizontal = 4.dp, vertical = 6.dp)
.size(32.dp)
.padding(7.dp),
onClick = { onOnchainAmount(null) },
) {
Icon(
symbol = MaterialSymbols.Tune,
contentDescription = stringRes(R.string.quick_zap_amounts_onchain),
modifier = Size18Modifier,
tint = MaterialTheme.colorScheme.placeholderText,
)
}
}
onchainZapAmountChoices.forEach { amountInSats ->
OnchainZapAmountChip(
amountInSats = amountInSats,
onClick = { onOnchainAmount(amountInSats) },
onLongClick = onChangeAmount,
)
}
ClickableBox(
modifier =
Modifier
.padding(horizontal = 4.dp, vertical = 6.dp)
.size(32.dp)
.padding(7.dp),
onClick = onChangeAmount,
) {
Icon(
symbol = MaterialSymbols.Tune,
contentDescription = stringRes(R.string.quick_zap_amounts),
modifier = Size18Modifier,
tint = MaterialTheme.colorScheme.placeholderText,
)
}
}
}
@@ -306,7 +306,40 @@ fun UpdateZapAmountContent(
)
}
// ── Section 2: Quick On-chain Zap Amounts ─────────────────────────────
// ── Section 2: Zap Privacy ────────────────────────────────────────────
Text(
text = stringRes(R.string.zap_privacy_section),
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.titleSmall,
modifier = SettingsCategorySpacingModifier,
)
Text(
text = stringRes(R.string.zap_type_section_explainer),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.padding(bottom = 8.dp),
)
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
TextSpinner(
label = stringRes(id = R.string.zap_type_explainer),
placeholder =
zapTypes
.firstOrNull { it.first == accountViewModel.defaultZapType() }
?.second
?: zapTypes.firstOrNull()?.second
?: "",
options = zapOptions,
onSelect = { postViewModel.selectedZapType = zapTypes[it].first },
modifier = Modifier.fillMaxWidth(),
)
}
// ── Section 3: Quick On-chain Zap Amounts ─────────────────────────────
Text(
text = stringRes(R.string.quick_zap_amounts_onchain),
@@ -395,40 +428,7 @@ fun UpdateZapAmountContent(
)
}
// ── Section 3: Zap Privacy ────────────────────────────────────────────
Text(
text = stringRes(R.string.zap_privacy_section),
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.titleSmall,
modifier = SettingsCategorySpacingModifier,
)
Text(
text = stringRes(R.string.zap_type_section_explainer),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.padding(bottom = 8.dp),
)
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
TextSpinner(
label = stringRes(id = R.string.zap_type_explainer),
placeholder =
zapTypes
.firstOrNull { it.first == accountViewModel.defaultZapType() }
?.second
?: zapTypes.firstOrNull()?.second
?: "",
options = zapOptions,
onSelect = { postViewModel.selectedZapType = zapTypes[it].first },
modifier = Modifier.fillMaxWidth(),
)
}
// ── Section 3: Nostr Wallet Connect ───────────────────────────────────
// ── Section 4: Nostr Wallet Connect ───────────────────────────────────
HorizontalDivider(
modifier = Modifier.padding(vertical = 16.dp),
@@ -608,18 +608,7 @@ private fun AmountSection(
) {
SectionLabel("Amount")
OutlinedTextField(
value = amountInput,
onValueChange = { onAmountChange(it.filter(Char::isDigit)) },
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
placeholder = { Text("0") },
suffix = { Text("sats", color = MaterialTheme.colorScheme.onSurfaceVariant) },
modifier = Modifier.fillMaxWidth(),
)
if (presetAmounts.isNotEmpty()) {
Spacer(Modifier.height(8.dp))
FlowRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
@@ -632,7 +621,18 @@ private fun AmountSection(
)
}
}
Spacer(Modifier.height(8.dp))
}
OutlinedTextField(
value = amountInput,
onValueChange = { onAmountChange(it.filter(Char::isDigit)) },
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
placeholder = { Text("0") },
suffix = { Text("sats", color = MaterialTheme.colorScheme.onSurfaceVariant) },
modifier = Modifier.fillMaxWidth(),
)
}
@OptIn(ExperimentalMaterial3Api::class)