Skip to content

Commit 1cd5c98

Browse files
authored
Merge pull request #58 from synonymdev/feat/handle_payment_method
Split on-chain and lightning descriptions
2 parents 961c90e + 477e5b8 commit 1cd5c98

File tree

3 files changed

+254
-128
lines changed

3 files changed

+254
-128
lines changed

app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAndReviewScreen.kt

Lines changed: 216 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,20 @@ import androidx.compose.ui.Alignment
2424
import androidx.compose.ui.Modifier
2525
import androidx.compose.ui.res.painterResource
2626
import androidx.compose.ui.res.stringResource
27+
import androidx.compose.ui.tooling.preview.Preview
2728
import androidx.compose.ui.unit.dp
2829
import kotlinx.coroutines.delay
2930
import kotlinx.coroutines.launch
3031
import to.bitkit.R
3132
import to.bitkit.ext.DatePattern
3233
import to.bitkit.ext.ellipsisMiddle
3334
import to.bitkit.ext.formatted
34-
import to.bitkit.ext.truncate
3535
import to.bitkit.ui.components.BalanceHeaderView
3636
import to.bitkit.ui.components.BodySSB
3737
import to.bitkit.ui.components.Caption13Up
38-
import to.bitkit.ui.components.Display
38+
import to.bitkit.ui.components.PrimaryButton
3939
import to.bitkit.ui.components.SwipeToConfirm
4040
import to.bitkit.ui.scaffold.SheetTopBar
41-
import to.bitkit.ui.shared.moneyString
42-
import to.bitkit.ui.shared.util.DarkModePreview
4341
import to.bitkit.ui.theme.AppThemeSurface
4442
import to.bitkit.ui.theme.Colors
4543
import to.bitkit.viewmodels.SendEvent
@@ -70,136 +68,33 @@ fun SendAndReviewScreen(
7068
.padding(horizontal = 16.dp)
7169
.fillMaxWidth()
7270
) {
73-
7471
BalanceHeaderView(sats = uiState.amount.toLong(), modifier = Modifier.fillMaxWidth())
7572

7673
Spacer(modifier = Modifier.height(16.dp))
7774

78-
Caption13Up(
79-
text = stringResource(
80-
if (uiState.payMethod == SendMethod.ONCHAIN) R.string.wallet__send_to else R.string.wallet__send_invoice
81-
),
82-
color = Colors.White64,
83-
)
84-
val destination = when (uiState.payMethod) {
85-
SendMethod.ONCHAIN -> uiState.address.ellipsisMiddle(25)
86-
SendMethod.LIGHTNING -> uiState.bolt11?.truncate(100) ?: ""
75+
when (uiState.payMethod) {
76+
SendMethod.ONCHAIN -> OnChainDescription(uiState = uiState, onEvent = onEvent)
77+
SendMethod.LIGHTNING -> LightningDescription(uiState = uiState, onEvent = onEvent)
8778
}
79+
80+
Spacer(modifier = Modifier.height(16.dp))
81+
Caption13Up(text = stringResource(R.string.wallet__tags), color = Colors.White64)
8882
Spacer(modifier = Modifier.height(8.dp))
89-
BodySSB(text = destination)
83+
//TODO DISPLAY TAGS
84+
PrimaryButton(
85+
stringResource(R.string.wallet__tags_add),
86+
onClick = {}, //TODO IMPLEMENT
87+
icon = {
88+
Icon(
89+
painter = painterResource(R.drawable.ic_tag),
90+
contentDescription = null,
91+
tint = Colors.Brand
92+
)
93+
},
94+
fullWidth = false
95+
)
9096
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
9197

92-
Row(
93-
horizontalArrangement = Arrangement.spacedBy(16.dp),
94-
modifier = Modifier.height(IntrinsicSize.Min)
95-
) {
96-
if (uiState.payMethod == SendMethod.ONCHAIN) {
97-
Column(
98-
modifier = Modifier
99-
.fillMaxHeight()
100-
.weight(1f)
101-
.clickable { onEvent(SendEvent.SpeedAndFee) }
102-
.padding(top = 16.dp)
103-
) {
104-
Caption13Up(text = stringResource(R.string.label_speed), color = Colors.White64)
105-
Spacer(modifier = Modifier.height(8.dp))
106-
BodySSB(text = "Todo Normal (₿ 210)")
107-
Spacer(modifier = Modifier.weight(1f))
108-
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
109-
}
110-
Column(
111-
modifier = Modifier
112-
.fillMaxHeight()
113-
.weight(1f)
114-
.clickable { onEvent(SendEvent.SpeedAndFee) }
115-
.padding(top = 16.dp)
116-
) {
117-
Caption13Up(text = stringResource(R.string.label_confirms_in), color = Colors.White64)
118-
Spacer(modifier = Modifier.height(8.dp))
119-
BodySSB(text = "Todo ± 20-60 minutes")
120-
Spacer(modifier = Modifier.weight(1f))
121-
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
122-
}
123-
} else {
124-
Column(
125-
modifier = Modifier
126-
.fillMaxHeight()
127-
.weight(1f)
128-
.padding(top = 16.dp)
129-
) {
130-
Caption13Up(text = stringResource(R.string.label_speed), color = Colors.White64)
131-
Spacer(modifier = Modifier.height(8.dp))
132-
Row(
133-
verticalAlignment = Alignment.CenterVertically,
134-
horizontalArrangement = Arrangement.spacedBy(4.dp),
135-
) {
136-
Icon(
137-
painterResource(R.drawable.ic_speed_normal),
138-
contentDescription = null,
139-
tint = Colors.Brand,
140-
modifier = Modifier.size(16.dp)
141-
) //TODO GET FROM STATE
142-
BodySSB(text = "Instant (±$0.01)") //TODO GET FROM STATE
143-
Icon(
144-
painterResource(R.drawable.ic_pencil_simple),
145-
contentDescription = null,
146-
tint = Colors.White,
147-
modifier = Modifier.size(16.dp)
148-
)
149-
}
150-
Spacer(modifier = Modifier.weight(1f))
151-
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
152-
}
153-
uiState.decodedInvoice?.expirySeconds?.let { expirySeconds ->
154-
Column(
155-
modifier = Modifier
156-
.fillMaxHeight()
157-
.weight(1f)
158-
.padding(top = 16.dp)
159-
) {
160-
val invoiceExpiryTimestamp = expirySeconds.let {
161-
Instant.now().plusSeconds(it.toLong()).formatted(DatePattern.INVOICE_EXPIRY)
162-
}
163-
Caption13Up(
164-
text = stringResource(R.string.label_invoice_expiration),
165-
color = Colors.White64
166-
)
167-
Spacer(modifier = Modifier.height(8.dp))
168-
Row(
169-
verticalAlignment = Alignment.CenterVertically,
170-
horizontalArrangement = Arrangement.spacedBy(4.dp),
171-
) {
172-
Icon(
173-
painterResource(R.drawable.ic_clock),
174-
contentDescription = null,
175-
tint = Colors.Brand,
176-
modifier = Modifier.size(16.dp)
177-
)
178-
BodySSB(text = invoiceExpiryTimestamp)
179-
}
180-
Spacer(modifier = Modifier.weight(1f))
181-
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
182-
}
183-
}
184-
}
185-
}
186-
187-
uiState.decodedInvoice?.description?.let { description ->
188-
Column {
189-
Caption13Up(text = stringResource(R.string.label_note), color = Colors.White64)
190-
Spacer(modifier = Modifier.height(8.dp))
191-
BodySSB(text = description)
192-
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
193-
}
194-
}
195-
196-
Column {
197-
Spacer(modifier = Modifier.height(16.dp))
198-
Caption13Up(text = stringResource(R.string.label_tags), color = Colors.White64)
199-
Spacer(modifier = Modifier.height(8.dp))
200-
BodySSB(text = "Todo")
201-
}
202-
20398
Spacer(modifier = Modifier.weight(1f))
20499
SwipeToConfirm(
205100
text = stringResource(R.string.wallet__send_swipe),
@@ -217,8 +112,172 @@ fun SendAndReviewScreen(
217112
}
218113
}
219114

115+
@Composable
116+
private fun OnChainDescription(
117+
uiState: SendUiState,
118+
onEvent: (SendEvent) -> Unit,
119+
) {
120+
Column(modifier = Modifier.fillMaxWidth()) {
121+
Caption13Up(
122+
text = stringResource(R.string.wallet__send_to),
123+
color = Colors.White64,
124+
)
125+
val destination = uiState.address.ellipsisMiddle(25)
126+
Spacer(modifier = Modifier.height(8.dp))
127+
BodySSB(text = destination)
128+
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
129+
130+
Row(
131+
horizontalArrangement = Arrangement.spacedBy(16.dp),
132+
modifier = Modifier.height(IntrinsicSize.Min)
133+
) {
134+
Column(
135+
modifier = Modifier
136+
.fillMaxHeight()
137+
.weight(1f)
138+
.clickable { onEvent(SendEvent.SpeedAndFee) }
139+
.padding(top = 16.dp)
140+
) {
141+
Caption13Up(text = stringResource(R.string.wallet__send_fee_and_speed), color = Colors.White64)
142+
Spacer(modifier = Modifier.height(8.dp))
143+
Row(
144+
verticalAlignment = Alignment.CenterVertically,
145+
horizontalArrangement = Arrangement.spacedBy(4.dp),
146+
) {
147+
Icon(
148+
painterResource(R.drawable.ic_speed_normal),
149+
contentDescription = null,
150+
tint = Colors.Brand,
151+
modifier = Modifier.size(16.dp)
152+
)
153+
BodySSB(text = "Normal (₿ 210)") //TODO GET FROM STATE
154+
Icon(
155+
painterResource(R.drawable.ic_pencil_simple),
156+
contentDescription = null,
157+
tint = Colors.White,
158+
modifier = Modifier.size(16.dp)
159+
)
160+
}
161+
Spacer(modifier = Modifier.weight(1f))
162+
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
163+
}
164+
Column(
165+
modifier = Modifier
166+
.fillMaxHeight()
167+
.weight(1f)
168+
.clickable { onEvent(SendEvent.SpeedAndFee) }
169+
.padding(top = 16.dp)
170+
) {
171+
Caption13Up(text = stringResource(R.string.wallet__send_confirming_in), color = Colors.White64)
172+
Spacer(modifier = Modifier.height(8.dp))
173+
Row(
174+
verticalAlignment = Alignment.CenterVertically,
175+
horizontalArrangement = Arrangement.spacedBy(4.dp),
176+
) {
177+
Icon(
178+
painterResource(R.drawable.ic_clock),
179+
contentDescription = null,
180+
tint = Colors.Brand,
181+
modifier = Modifier.size(16.dp)
182+
)
183+
BodySSB(text = "± 20-60 minutes") //TODO GET FROM STATE
184+
}
185+
Spacer(modifier = Modifier.weight(1f))
186+
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
187+
}
188+
189+
}
190+
}
191+
}
192+
193+
@Composable
194+
private fun LightningDescription(
195+
uiState: SendUiState,
196+
onEvent: (SendEvent) -> Unit,
197+
) {
198+
Column(modifier = Modifier.fillMaxWidth()) {
199+
Caption13Up(
200+
text = stringResource(R.string.wallet__send_invoice),
201+
color = Colors.White64,
202+
)
203+
val destination = uiState.bolt11?.ellipsisMiddle(25).orEmpty()
204+
Spacer(modifier = Modifier.height(8.dp))
205+
BodySSB(text = destination)
206+
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
207+
208+
Row(
209+
horizontalArrangement = Arrangement.spacedBy(16.dp),
210+
modifier = Modifier.height(IntrinsicSize.Min)
211+
) {
212+
Column(
213+
modifier = Modifier
214+
.fillMaxHeight()
215+
.weight(1f)
216+
.padding(top = 16.dp)
217+
) {
218+
Caption13Up(text = stringResource(R.string.wallet__send_fee_and_speed), color = Colors.White64)
219+
Spacer(modifier = Modifier.height(8.dp))
220+
Row(
221+
verticalAlignment = Alignment.CenterVertically,
222+
horizontalArrangement = Arrangement.spacedBy(4.dp),
223+
) {
224+
Icon(
225+
painterResource(R.drawable.ic_lightning),
226+
contentDescription = null,
227+
tint = Colors.Purple,
228+
modifier = Modifier.size(16.dp)
229+
)
230+
BodySSB(text = "Instant (±$0.01)") //TODO GET FROM STATE
231+
}
232+
Spacer(modifier = Modifier.weight(1f))
233+
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
234+
}
235+
uiState.decodedInvoice?.expirySeconds?.let { expirySeconds ->
236+
Column(
237+
modifier = Modifier
238+
.fillMaxHeight()
239+
.weight(1f)
240+
.padding(top = 16.dp)
241+
) {
242+
Caption13Up(
243+
text = stringResource(R.string.wallet__send_invoice_expiration),
244+
color = Colors.White64
245+
)
246+
Spacer(modifier = Modifier.height(8.dp))
247+
Row(
248+
verticalAlignment = Alignment.CenterVertically,
249+
horizontalArrangement = Arrangement.spacedBy(4.dp),
250+
) {
251+
Icon(
252+
painterResource(R.drawable.ic_timer),
253+
contentDescription = null,
254+
tint = Colors.Purple,
255+
modifier = Modifier.size(16.dp)
256+
)
257+
val invoiceExpiryTimestamp = expirySeconds.let {
258+
Instant.now().plusSeconds(it.toLong()).formatted(DatePattern.INVOICE_EXPIRY)
259+
}
260+
BodySSB(text = invoiceExpiryTimestamp)
261+
}
262+
Spacer(modifier = Modifier.weight(1f))
263+
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
264+
}
265+
}
266+
}
267+
268+
uiState.decodedInvoice?.description?.let { description ->
269+
Column {
270+
Caption13Up(text = stringResource(R.string.wallet__note), color = Colors.White64)
271+
Spacer(modifier = Modifier.height(8.dp))
272+
BodySSB(text = description)
273+
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
274+
}
275+
}
276+
}
277+
}
278+
220279
@Suppress("SpellCheckingInspection")
221-
@DarkModePreview
280+
@Preview(name = "Lightning")
222281
@Composable
223282
private fun SendAndReviewPreview() {
224283
AppThemeSurface {
@@ -231,7 +290,36 @@ private fun SendAndReviewPreview() {
231290
decodedInvoice = LightningInvoice(
232291
bolt11 = "bcrt123",
233292
paymentHash = ByteArray(0),
234-
amountSatoshis = 0uL,
293+
amountSatoshis = 100000uL,
294+
timestampSeconds = 0uL,
295+
expirySeconds = 3600uL,
296+
isExpired = false,
297+
networkType = NetworkType.REGTEST,
298+
payeeNodeId = null,
299+
description = "Some invoice description",
300+
)
301+
),
302+
onBack = {},
303+
onEvent = {},
304+
)
305+
}
306+
}
307+
308+
@Suppress("SpellCheckingInspection")
309+
@Preview(name = "OnChain")
310+
@Composable
311+
private fun SendAndReviewPreview2() {
312+
AppThemeSurface {
313+
SendAndReviewScreen(
314+
uiState = SendUiState(
315+
amount = 1234uL,
316+
address = "bcrt1qkgfgyxyqhvkdqh04sklnzxphmcds6vft6y7h0r",
317+
bolt11 = "lnbcrt1…",
318+
payMethod = SendMethod.ONCHAIN,
319+
decodedInvoice = LightningInvoice(
320+
bolt11 = "bcrt123",
321+
paymentHash = ByteArray(0),
322+
amountSatoshis = 10000uL,
235323
timestampSeconds = 0uL,
236324
expirySeconds = 3600uL,
237325
isExpired = false,

0 commit comments

Comments
 (0)