Skip to content

Commit 5f04d97

Browse files
committed
(android) Improve Lightning receive screen
Specifically, brought back the popup help messages when tapping the QR code headers. The type (bolt11 or 12) of the LN invoice selected is also displayed in the control switch.
1 parent 45cd22f commit 5f04d97

File tree

14 files changed

+146
-31
lines changed

14 files changed

+146
-31
lines changed

phoenix-android/src/main/kotlin/fr/acinq/phoenix/android/components/buttons/AnimatedSegmentedButton.kt

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import androidx.compose.animation.ExperimentalSharedTransitionApi
44
import androidx.compose.animation.animateBounds
55
import androidx.compose.foundation.BorderStroke
66
import androidx.compose.foundation.background
7+
import androidx.compose.foundation.layout.Arrangement
78
import androidx.compose.foundation.layout.Box
9+
import androidx.compose.foundation.layout.Column
810
import androidx.compose.foundation.layout.IntrinsicSize
911
import androidx.compose.foundation.layout.height
1012
import androidx.compose.foundation.layout.padding
@@ -13,7 +15,6 @@ import androidx.compose.foundation.selection.selectableGroup
1315
import androidx.compose.foundation.shape.RoundedCornerShape
1416
import androidx.compose.material.MaterialTheme
1517
import androidx.compose.material.Surface
16-
import androidx.compose.material.Text
1718
import androidx.compose.runtime.Composable
1819
import androidx.compose.ui.Alignment
1920
import androidx.compose.ui.Modifier
@@ -24,8 +25,6 @@ import androidx.compose.ui.graphics.Shape
2425
import androidx.compose.ui.layout.Layout
2526
import androidx.compose.ui.layout.LookaheadScope
2627
import androidx.compose.ui.layout.layoutId
27-
import androidx.compose.ui.text.style.TextAlign
28-
import androidx.compose.ui.text.style.TextOverflow
2928
import androidx.compose.ui.unit.dp
3029
import fr.acinq.phoenix.android.utils.mutedTextColor
3130

@@ -102,44 +101,37 @@ fun SegmentedControl(
102101
}
103102
}
104103

105-
/**
106-
* A button used as a child of [SegmentedControl].
107-
*/
104+
/** A button used as a child of [SegmentedControl]. */
108105
@Composable
109106
fun SegmentedControlButton(
110107
onClick: () -> Unit,
111-
text: String,
112108
selected: Boolean,
113109
modifier: Modifier = Modifier,
114110
buttonShape: Shape = RoundedCornerShape(16.dp),
111+
content: @Composable () -> Unit,
115112
) {
116-
Box(
113+
Column(
117114
modifier = modifier
118115
.then(if (selected) Modifier.layoutId(SelectedButtonId) else Modifier)
119116
.clip(buttonShape)
120-
.selectable(selected = selected, onClick = onClick),
121-
contentAlignment = Alignment.Center,
117+
.selectable(selected = selected, onClick = onClick)
118+
.padding(horizontal = 4.dp, vertical = 10.dp)
119+
.alpha(if (selected) 1f else 0.3f),
120+
verticalArrangement = Arrangement.Center,
121+
horizontalAlignment = Alignment.CenterHorizontally,
122122
) {
123-
Text(
124-
modifier = Modifier.padding(12.dp).alpha(if (selected) 1f else 0.3f),
125-
text = text,
126-
maxLines = 1,
127-
overflow = TextOverflow.Ellipsis,
128-
textAlign = TextAlign.Center,
129-
)
123+
content()
130124
}
131125
}
132126

133-
/**
134-
* The animated button background that displays behind the currently selected button.
135-
*/
127+
/** The animated button background that displays behind the currently selected button. */
136128
@Composable
137129
private fun SelectedBackground(modifier: Modifier = Modifier, buttonShape: Shape) {
138130
Surface(
139131
modifier = modifier.layoutId(SelectedBackgroundId),
140132
color = MaterialTheme.colors.surface,
141133
shape = buttonShape,
142-
border = BorderStroke(width = 1.dp, color = MaterialTheme.colors.primary),
134+
border = BorderStroke(width = 1.dp, color = mutedTextColor.copy(alpha = .4f)),
143135
) {}
144136
}
145137

phoenix-android/src/main/kotlin/fr/acinq/phoenix/android/components/dialogs/Popup.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,21 @@ package fr.acinq.phoenix.android.components.dialogs
1818

1919
import androidx.compose.foundation.BorderStroke
2020
import androidx.compose.foundation.interaction.MutableInteractionSource
21+
import androidx.compose.foundation.layout.Box
2122
import androidx.compose.foundation.layout.Column
2223
import androidx.compose.foundation.layout.PaddingValues
24+
import androidx.compose.foundation.layout.Row
2325
import androidx.compose.foundation.layout.RowScope
2426
import androidx.compose.foundation.layout.Spacer
2527
import androidx.compose.foundation.layout.fillMaxWidth
2628
import androidx.compose.foundation.layout.height
2729
import androidx.compose.foundation.layout.padding
2830
import androidx.compose.foundation.layout.requiredSize
2931
import androidx.compose.foundation.layout.requiredWidth
32+
import androidx.compose.foundation.layout.size
33+
import androidx.compose.foundation.layout.width
3034
import androidx.compose.foundation.layout.widthIn
35+
import androidx.compose.foundation.shape.CircleShape
3136
import androidx.compose.foundation.shape.RoundedCornerShape
3237
import androidx.compose.material.MaterialTheme
3338
import androidx.compose.material.Surface
@@ -40,16 +45,59 @@ import androidx.compose.runtime.setValue
4045
import androidx.compose.ui.Alignment
4146
import androidx.compose.ui.Modifier
4247
import androidx.compose.ui.graphics.Color
48+
import androidx.compose.ui.text.TextStyle
49+
import androidx.compose.ui.text.style.TextOverflow
4350
import androidx.compose.ui.unit.Dp
4451
import androidx.compose.ui.unit.IntOffset
4552
import androidx.compose.ui.unit.dp
4653
import androidx.compose.ui.unit.sp
4754
import androidx.compose.ui.window.Popup
4855
import fr.acinq.phoenix.android.R
4956
import fr.acinq.phoenix.android.components.BorderButton
57+
import fr.acinq.phoenix.android.components.Clickable
58+
import fr.acinq.phoenix.android.components.PhoenixIcon
5059
import fr.acinq.phoenix.android.components.WebLink
5160
import fr.acinq.phoenix.android.utils.mutedTextColor
5261

62+
63+
@Composable
64+
fun IconTextPopup(
65+
text: String,
66+
icon: Int,
67+
iconTint: Color = MaterialTheme.colors.primary,
68+
iconSize: Dp = 16.dp,
69+
iconPadding: Dp = 5.dp,
70+
textStyle: TextStyle,
71+
popupMessage: String,
72+
popupLink: Pair<String, String>? = null,
73+
) {
74+
var showPopup by remember { mutableStateOf(false) }
75+
Clickable(
76+
onClick = { showPopup = true },
77+
shape = RoundedCornerShape(16.dp),
78+
) {
79+
Row(modifier = Modifier.padding(4.dp), verticalAlignment = Alignment.CenterVertically) {
80+
Surface(
81+
shape = CircleShape,
82+
color = if (showPopup) MaterialTheme.colors.primary else MaterialTheme.colors.surface,
83+
border = BorderStroke(width = 1.dp, color = if (showPopup) MaterialTheme.colors.primary else iconTint)
84+
) {
85+
Box(modifier = Modifier.padding(iconPadding)) {
86+
PhoenixIcon(icon, modifier = Modifier.size(iconSize), tint = if (showPopup) MaterialTheme.colors.onPrimary else iconTint)
87+
}
88+
}
89+
Spacer(Modifier.width(6.dp))
90+
Text(text = text, style = textStyle, maxLines = 1, overflow = TextOverflow.Ellipsis)
91+
92+
if (showPopup) {
93+
PopupDialog(onDismiss = { showPopup = false }, message = popupMessage, button = popupLink?.let { (text, link) ->
94+
{ WebLink(text = text, url = link, fontSize = 14.sp, modifier = Modifier.fillMaxWidth(), padding = PaddingValues(horizontal = 10.dp, vertical = 8.dp)) }
95+
})
96+
}
97+
}
98+
}
99+
}
100+
53101
@Composable
54102
fun RowScope.IconPopup(
55103
modifier: Modifier = Modifier,

phoenix-android/src/main/kotlin/fr/acinq/phoenix/android/payments/receive/ReceiveBaseView.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import fr.acinq.phoenix.android.R
6262
import fr.acinq.phoenix.android.business
6363
import fr.acinq.phoenix.android.components.*
6464
import fr.acinq.phoenix.android.components.dialogs.FullScreenDialog
65+
import fr.acinq.phoenix.android.components.dialogs.IconTextPopup
6566
import fr.acinq.phoenix.android.userPrefs
6667
import fr.acinq.phoenix.android.utils.images.QRCodeHelper
6768
import fr.acinq.phoenix.android.utils.copyToClipboard
@@ -157,14 +158,15 @@ private fun ReceiveViewPages(
157158
fun InvoiceHeader(
158159
text: String,
159160
icon: Int,
161+
helpMessage: String,
160162
) {
161-
TextWithIcon(
163+
IconTextPopup(
162164
text = text,
163165
icon = icon,
164-
textStyle = MaterialTheme.typography.caption.copy(fontSize = 16.sp), maxLines = 1,
165-
iconTint = MaterialTheme.typography.caption.color,
166+
textStyle = MaterialTheme.typography.body1.copy(fontSize = 16.sp),
167+
popupMessage = helpMessage,
166168
)
167-
Spacer(Modifier.height(16.dp))
169+
Spacer(Modifier.height(8.dp))
168170
}
169171

170172
@Composable
@@ -286,9 +288,9 @@ fun CopyShareButtons(
286288
onShare: () -> Unit,
287289
) {
288290
Row(modifier = Modifier.padding(horizontal = 4.dp, vertical = 16.dp)) {
289-
BorderButton(text = stringResource(R.string.btn_copy), icon = R.drawable.ic_copy, onClick = onCopy, shape = RoundedCornerShape(16.dp))
290-
Spacer(modifier = Modifier.width(12.dp))
291-
BorderButton(text = stringResource(R.string.btn_share), icon = R.drawable.ic_share, onClick = onShare, shape = RoundedCornerShape(16.dp))
291+
BorderButton(icon = R.drawable.ic_copy, onClick = onCopy)
292+
Spacer(modifier = Modifier.width(16.dp))
293+
BorderButton(icon = R.drawable.ic_share, onClick = onShare)
292294
}
293295
}
294296

phoenix-android/src/main/kotlin/fr/acinq/phoenix/android/payments/receive/ReceiveLightningView.kt

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,46 @@ fun ColumnScope.LightningInvoiceView(
126126
}
127127

128128
InvoiceHeader(
129-
text = stringResource(if (isReusable) R.string.receive_label_bolt12 else R.string.receive_label_bolt11),
129+
text = stringResource(R.string.receive_label_lightning),
130130
icon = R.drawable.ic_zap,
131+
helpMessage = stringResource(R.string.receive_label_lightning_help),
131132
)
132133

133134
Column(horizontalAlignment = Alignment.CenterHorizontally) {
134135
QRCodeView(bitmap = vm.lightningQRBitmap, data = invoiceData, width = columnWidth, loadingLabel = stringResource(id = R.string.receive_lightning_generating))
135136

136137
Spacer(modifier = Modifier.height(16.dp))
137138
SegmentedControl(modifier = Modifier.width(columnWidth)) {
138-
SegmentedControlButton(onClick = { isReusable = false }, text = stringResource(R.string.receive_lightning_switch_bolt11), selected = !isReusable)
139-
SegmentedControlButton(onClick = { isReusable = true }, text = stringResource(R.string.receive_lightning_switch_bolt12), selected = isReusable)
139+
SegmentedControlButton(onClick = { isReusable = false }, selected = !isReusable) {
140+
Text(
141+
text = stringResource(R.string.receive_lightning_switch_bolt11),
142+
fontSize = 16.sp,
143+
maxLines = 1,
144+
overflow = TextOverflow.Ellipsis,
145+
textAlign = TextAlign.Center,
146+
)
147+
Spacer(Modifier.height(1.dp))
148+
Text(
149+
text = stringResource(R.string.receive_lightning_switch_bolt11_desc),
150+
textAlign = TextAlign.Center,
151+
fontSize = 11.sp,
152+
)
153+
}
154+
SegmentedControlButton(onClick = { isReusable = true }, selected = isReusable) {
155+
Text(
156+
text = stringResource(R.string.receive_lightning_switch_bolt12),
157+
fontSize = 16.sp,
158+
maxLines = 1,
159+
overflow = TextOverflow.Ellipsis,
160+
textAlign = TextAlign.Center,
161+
)
162+
Spacer(Modifier.height(1.dp))
163+
Text(
164+
text = stringResource(R.string.receive_lightning_switch_bolt12_desc),
165+
textAlign = TextAlign.Center,
166+
fontSize = 11.sp,
167+
)
168+
}
140169
}
141170

142171
Spacer(modifier = Modifier.height(8.dp))

phoenix-android/src/main/kotlin/fr/acinq/phoenix/android/payments/receive/ReceiveOnChainView.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ fun ColumnScope.BitcoinAddressView(
4848
InvoiceHeader(
4949
text = stringResource(id = R.string.receive_label_bitcoin),
5050
icon = R.drawable.ic_chain,
51+
helpMessage = stringResource(R.string.receive_label_bitcoin_help)
5152
)
5253

5354
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.width(columnWidth)) {

phoenix-android/src/main/res/values-b+es+419/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@
9292
<string name="receive_bitcoin_share_title">Dirección de Bitcoin</string>
9393
<string name="receive_bitcoin_share_subject">Compartir esta dirección de Bitcoin con…</string>
9494

95+
<string name="receive_label_bitcoin_help">Este código QR es una dirección clásica de Bitcoin.\n\nCasi cualquier servicio o billetera de Bitcoin puede leerlo, pero los pagos tardarán más en llegar.</string>
96+
<string name="receive_label_lightning_help">Este código QR es una factura de Lightning.\n\nLos pagos mediante Lightning son muy rápidos y normalmente más baratos, pero es posible que aún no sean compatibles con algunas billeteras y servicios.\n\nEn ese caso, desliza el dedo hacia la izquierda para obtener una dirección normal de Bitcoin.</string>
97+
9598
<string name="receive_lightning_generating">Generando…</string>
99+
<string name="receive_lightning_switch_bolt11">Un solo uso</string>
100+
<string name="receive_lightning_switch_bolt12">Reutilizable</string>
96101
<string name="receive_lightning_amount_label">Importe</string>
97102
<string name="receive_lightning_desc_label">Desc</string>
98103
<string name="receive_lightning_error">No se pudo generar la factura</string>

phoenix-android/src/main/res/values-cs/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@
7373
<string name="receive_bitcoin_share_title">Bitcoinová adresa</string>
7474
<string name="receive_bitcoin_share_subject">Sdílet tuto Bitcoinovou adresu s…</string>
7575

76+
<string name="receive_label_bitcoin_help">Tento QR kód je klasická Bitcoinová adresa. \n\nDokáže jej přečíst skoro každá Bitcoinová služba/peněženka, ale procházení plateb bude trvat déle.</string>
77+
<string name="receive_label_lightning_help">Tento QR kód je Lightningová faktura.\n\nLightningové platby jsou velmi rychlé a obvykle levnější, ale některé peněženky a služby je nemusí zatím podporovat.\n\nV takovém případě přejeďte prstem doleva a získáte běžnou Bitcoinovou adresu.</string>
78+
7679
<string name="receive_lightning_generating">Vytváření…</string>
80+
<string name="receive_lightning_switch_bolt11">Použijte jednou</string>
81+
<string name="receive_lightning_switch_bolt12">Opakované použití</string>
7782
<string name="receive_lightning_amount_label">Částka</string>
7883
<string name="receive_lightning_desc_label">Popis</string>
7984
<string name="receive_lightning_error">Nepodařilo se vygenerovat fakturu</string>

phoenix-android/src/main/res/values-de/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@
9494
<string name="receive_bitcoin_share_title">Bitcoin-Adresse</string>
9595
<string name="receive_bitcoin_share_subject">Teile diese Bitcoin-Adresse mit…</string>
9696

97+
<string name="receive_label_bitcoin_help">Dieser QR-Code ist eine klassische Bitcoin-Adresse.\n\nEr kann von fast allen Bitcoin-Wallets gelesen werden, allerdings werden die Zahlungen langsamer sein.</string>
98+
<string name="receive_label_lightning_help">Dieser QR-Code ist eine Lightning-Rechnung.\n\nLightning-Zahlungen sind sehr schnell und normalerweise günstiger, werden aber von manchen Wallets nicht unterstützt.\n\nIn diesem Fall bitte nach links wischen, um eine klassische Bitcoin-Adresse zu verwenden.</string>
99+
97100
<string name="receive_lightning_generating">Wird erstellt…</string>
101+
<string name="receive_lightning_switch_bolt11">Einmal verwendbar</string>
102+
<string name="receive_lightning_switch_bolt12">Wiederverwendbar</string>
98103
<string name="receive_lightning_amount_label">Betrag</string>
99104
<string name="receive_lightning_desc_label">Desc</string>
100105
<string name="receive_lightning_error">Rechnung konnte nicht erstellt werden</string>

phoenix-android/src/main/res/values-fr/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,12 @@
9090
<string name="receive_bitcoin_share_title">Adresse Bitcoin</string>
9191
<string name="receive_bitcoin_share_subject">Partagez cette adresse Bitcoin avec…</string>
9292

93+
<string name="receive_label_bitcoin_help">Ce QR code représente une adresse Bitcoin classique.\n\nCelle-ci est compréhensible par presque tous les services et wallets Bitcoin, mais les paiements seront plus lents à arriver.</string>
94+
<string name="receive_label_lightning_help">Ce QR code est une requête de paiement Lightning.\n\nLes paiements Lightning sont très rapides et habituellement moins cher, mais certains wallets et services ne les comprennent pas encore.\n\nDans ce cas, passez sur l\'écran de droite pour afficher une adresse Bitcoin classique.</string>
95+
9396
<string name="receive_lightning_generating">Création d\'une requête de paiement…</string>
97+
<string name="receive_lightning_switch_bolt11">Usage unique</string>
98+
<string name="receive_lightning_switch_bolt12">Réutilisable</string>
9499
<string name="receive_lightning_amount_label">Montant</string>
95100
<string name="receive_lightning_desc_label">Desc</string>
96101
<string name="receive_lightning_error">Échec de la création de la requête</string>

phoenix-android/src/main/res/values-pt-rBR/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@
9191
<string name="receive_bitcoin_share_title">Endereço Bitcoin</string>
9292
<string name="receive_bitcoin_share_subject">Compartilhe este endereço Bitcoin com…</string>
9393

94+
<string name="receive_label_bitcoin_help">Este código QR é um endereço Bitcoin clássico.\n\nQuase qualquer serviço ou carteira Bitcoin pode lê-lo, mas os pagamentos levarão mais tempo para chegar.</string>
95+
<string name="receive_label_lightning_help">Este código QR é uma fatura Lightning.\n\nOs pagamentos Lightning são muito rápidos e geralmente mais baratos, mas podem ainda não ser suportados por algumas carteiras e serviços.\n\nNesse caso, deslize para a esquerda para obter um endereço Bitcoin normal.</string>
96+
9497
<string name="receive_lightning_generating">Gerando…</string>
98+
<string name="receive_lightning_switch_bolt11">Use uma vez</string>
99+
<string name="receive_lightning_switch_bolt12">Reutilizável</string>
95100
<string name="receive_lightning_amount_label">Valor</string>
96101
<string name="receive_lightning_desc_label">Desc</string>
97102
<string name="receive_lightning_error">Não foi possível gerar a fatura</string>

0 commit comments

Comments
 (0)