Skip to content

Commit d3ef778

Browse files
authored
Merge pull request #111 from synonymdev/feat/display-node-initializing-warning
LN node initializing message and switches
2 parents e9bac4e + b5b4e50 commit d3ef778

File tree

3 files changed

+82
-23
lines changed

3 files changed

+82
-23
lines changed

app/src/main/java/to/bitkit/models/NodeLifecycleState.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ sealed class NodeLifecycleState {
1010

1111
fun isStoppedOrStopping() = this is Stopped || this is Stopping
1212
fun isRunningOrStarting() = this is Running || this is Starting
13+
fun isStarting() = this is Starting
14+
fun isRunning() = this is Running
1315

1416
val displayState: String
1517
get() = when (this) {

app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package to.bitkit.ui.screens.wallets.receive
22

3+
import androidx.compose.animation.AnimatedVisibility
34
import androidx.compose.foundation.layout.Arrangement
45
import androidx.compose.foundation.layout.Column
56
import androidx.compose.foundation.layout.Row
@@ -42,6 +43,7 @@ import kotlinx.coroutines.coroutineScope
4243
import kotlinx.coroutines.launch
4344
import to.bitkit.R
4445
import to.bitkit.ext.truncate
46+
import to.bitkit.models.NodeLifecycleState
4547
import to.bitkit.models.NodeLifecycleState.Running
4648
import to.bitkit.ui.appViewModel
4749
import to.bitkit.ui.blocktankViewModel
@@ -124,7 +126,8 @@ fun ReceiveQrSheet(
124126
navController.navigate(ReceiveRoutes.AMOUNT)
125127
}
126128
},
127-
onClickEditInvoice = { navController.navigate(ReceiveRoutes.EDIT_INVOICE) }
129+
onClickEditInvoice = { navController.navigate(ReceiveRoutes.EDIT_INVOICE) },
130+
onClickReceiveOnSpending = { wallet.updateReceiveOnSpending() }
128131
)
129132
}
130133
composable(ReceiveRoutes.AMOUNT) {
@@ -177,7 +180,8 @@ private fun ReceiveQrScreen(
177180
cjitActive: MutableState<Boolean>,
178181
walletState: MainUiState,
179182
onCjitToggle: (Boolean) -> Unit,
180-
onClickEditInvoice: () -> Unit
183+
onClickEditInvoice: () -> Unit,
184+
onClickReceiveOnSpending: () -> Unit,
181185
) {
182186
val qrLogoImageRes by remember(walletState, cjitInvoice.value) {
183187
val resId = when {
@@ -222,18 +226,50 @@ private fun ReceiveQrScreen(
222226
onchainAddress = onchainAddress,
223227
bolt11 = walletState.bolt11,
224228
cjitInvoice = cjitInvoice.value,
229+
receiveOnSpendingBalance = walletState.receiveOnSpendingBalance
225230
)
226231
}
227232
}
228233
}
229234
Spacer(modifier = Modifier.height(24.dp))
230-
if (walletState.nodeLifecycleState.isRunningOrStarting() && walletState.channels.isEmpty()) {
235+
AnimatedVisibility(walletState.nodeLifecycleState.isRunning() && walletState.channels.isEmpty()) {
231236
ReceiveLightningFunds(
232237
cjitInvoice = cjitInvoice,
233238
cjitActive = cjitActive,
234239
onCjitToggle = onCjitToggle,
235240
)
236241
}
242+
AnimatedVisibility(walletState.nodeLifecycleState.isRunning() && walletState.channels.isNotEmpty()) {
243+
Column {
244+
AnimatedVisibility (!walletState.receiveOnSpendingBalance) {
245+
Headline(
246+
text = stringResource(R.string.wallet__receive_text_lnfunds).withAccent(accentColor = Colors.Purple)
247+
)
248+
}
249+
Row(verticalAlignment = Alignment.CenterVertically) {
250+
BodyM(text = stringResource(R.string.wallet__receive_spending))
251+
Spacer(modifier = Modifier.weight(1f))
252+
AnimatedVisibility(!walletState.receiveOnSpendingBalance) {
253+
Icon(
254+
painter = painterResource(R.drawable.empty_state_arrow_horizontal),
255+
contentDescription = null,
256+
tint = Colors.White64,
257+
modifier = Modifier
258+
.rotate(17.33f)
259+
.padding(start = 7.65.dp, end = 13.19.dp)
260+
)
261+
}
262+
Switch(
263+
checked = walletState.receiveOnSpendingBalance,
264+
onCheckedChange = { onClickReceiveOnSpending() },
265+
colors = AppSwitchDefaults.colorsPurple,
266+
)
267+
}
268+
}
269+
}
270+
AnimatedVisibility(walletState.nodeLifecycleState.isStarting()) {
271+
BodyM(text = stringResource(R.string.wallet__receive_ldk_init))
272+
}
237273
Spacer(modifier = Modifier.height(24.dp))
238274
}
239275
}
@@ -246,22 +282,24 @@ private fun ReceiveLightningFunds(
246282
onCjitToggle: (Boolean) -> Unit,
247283
) {
248284
Column {
249-
if (cjitInvoice.value == null) {
285+
AnimatedVisibility (!cjitActive.value && cjitInvoice.value == null) {
250286
Headline(
251287
text = stringResource(R.string.wallet__receive_text_lnfunds).withAccent(accentColor = Colors.Purple)
252288
)
253289
}
254290
Row(verticalAlignment = Alignment.CenterVertically) {
255291
BodyM(text = stringResource(R.string.wallet__receive_spending))
256292
Spacer(modifier = Modifier.weight(1f))
257-
Icon(
258-
painter = painterResource(R.drawable.empty_state_arrow_horizontal),
259-
contentDescription = null,
260-
tint = Colors.White64,
261-
modifier = Modifier
262-
.rotate(17.33f)
263-
.padding(start = 7.65.dp, end = 13.19.dp)
264-
)
293+
AnimatedVisibility(!cjitActive.value && cjitInvoice.value == null) {
294+
Icon(
295+
painter = painterResource(R.drawable.empty_state_arrow_horizontal),
296+
contentDescription = null,
297+
tint = Colors.White64,
298+
modifier = Modifier
299+
.rotate(17.33f)
300+
.padding(start = 7.65.dp, end = 13.19.dp)
301+
)
302+
}
265303
Switch(
266304
checked = cjitActive.value,
267305
onCheckedChange = onCjitToggle,
@@ -351,20 +389,21 @@ private fun CopyValuesSlide(
351389
onchainAddress: String,
352390
bolt11: String,
353391
cjitInvoice: String?,
392+
receiveOnSpendingBalance: Boolean
354393
) {
355394
Card(
356395
colors = CardDefaults.cardColors(containerColor = Colors.White10),
357396
shape = AppShapes.small,
358397
) {
359398
Column {
360-
if (onchainAddress.isNotEmpty()) {
399+
if (onchainAddress.isNotEmpty() && cjitInvoice == null) {
361400
CopyAddressCard(
362401
title = stringResource(R.string.wallet__receive_bitcoin_invoice),
363402
address = onchainAddress,
364403
type = CopyAddressType.ONCHAIN,
365404
)
366405
}
367-
if (bolt11.isNotEmpty()) {
406+
if (bolt11.isNotEmpty() && receiveOnSpendingBalance) {
368407
CopyAddressCard(
369408
title = stringResource(R.string.wallet__receive_lightning_invoice),
370409
address = bolt11,
@@ -401,7 +440,7 @@ private fun CopyAddressCard(
401440

402441
Spacer(modifier = Modifier.width(3.dp))
403442

404-
val iconRes = if (type == CopyAddressType.ONCHAIN) R.drawable.ic_bitcoin else R.drawable.ic_lightning_alt
443+
val iconRes = if (type == CopyAddressType.ONCHAIN) R.drawable.ic_bitcoin else R.drawable.ic_lightning_alt
405444
Icon(painter = painterResource(iconRes), contentDescription = null, tint = Colors.White64)
406445
}
407446
Spacer(modifier = Modifier.height(16.dp))
@@ -455,7 +494,8 @@ private fun ReceiveQrScreenPreview() {
455494
nodeLifecycleState = Running,
456495
),
457496
onCjitToggle = { },
458-
onClickEditInvoice = {}
497+
onClickEditInvoice = {},
498+
onClickReceiveOnSpending = {},
459499
)
460500
}
461501
}
@@ -471,7 +511,8 @@ private fun ReceiveQrScreenPreviewSmallScreen() {
471511
nodeLifecycleState = Running,
472512
),
473513
onCjitToggle = { },
474-
onClickEditInvoice = {}
514+
onClickEditInvoice = {},
515+
onClickReceiveOnSpending = {},
475516
)
476517
}
477518
}
@@ -484,10 +525,11 @@ private fun ReceiveQrScreenPreviewTablet() {
484525
cjitInvoice = remember { mutableStateOf(null) },
485526
cjitActive = remember { mutableStateOf(false) },
486527
walletState = MainUiState(
487-
nodeLifecycleState = Running,
528+
nodeLifecycleState = NodeLifecycleState.Starting,
488529
),
489530
onCjitToggle = { },
490-
onClickEditInvoice = {}
531+
onClickEditInvoice = {},
532+
onClickReceiveOnSpending = {},
491533
)
492534
}
493535
}
@@ -506,6 +548,7 @@ private fun CopyValuesSlidePreview() {
506548
onchainAddress = "bcrt1qfserxgtuesul4m9zva56wzk849yf9l8rk4qy0l",
507549
bolt11 = "lnbcrt500u1pn7umn7pp5x0s9lt9fwrff6rp70pz3guwnjgw97sjuv79...",
508550
cjitInvoice = null,
551+
true
509552
)
510553
}
511554
}

app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,20 +307,23 @@ class WalletViewModel @Inject constructor(
307307

308308
fun updateBip21Invoice(
309309
amountSats: ULong? = null,
310-
description: String = ""
310+
description: String = "",
311+
generateBolt11IfAvailable: Boolean = true
311312
) {
312313
viewModelScope.launch(Dispatchers.IO) {
314+
_uiState.update { it.copy(bip21AmountSats = amountSats, bip21Description = description) }
315+
313316
val hasChannels = lightningService.channels.hasChannels()
314317

315-
_bolt11 = if (hasChannels) {
316-
createInvoice(amountSats = amountSats, description = description)
318+
_bolt11 = if (hasChannels && generateBolt11IfAvailable) {
319+
createInvoice(amountSats = _uiState.value.bip21AmountSats, description = _uiState.value.bip21Description)
317320
} else {
318321
""
319322
}
320323

321324
val newBip21 = Bip21Utils.buildBip21Url(
322325
bitcoinAddress = _onchainAddress,
323-
amountSats = amountSats,
326+
amountSats = _uiState.value.bip21AmountSats,
324327
message = description.ifBlank { DEFAULT_INVOICE_MESSAGE },
325328
lightningInvoice = _bolt11
326329
)
@@ -330,6 +333,14 @@ class WalletViewModel @Inject constructor(
330333
}
331334
}
332335

336+
fun updateReceiveOnSpending() {
337+
_uiState.update { it.copy(receiveOnSpendingBalance = !it.receiveOnSpendingBalance) }
338+
updateBip21Invoice(
339+
amountSats = _uiState.value.bip21AmountSats,
340+
description = _uiState.value.bip21Description,
341+
generateBolt11IfAvailable = _uiState.value.receiveOnSpendingBalance
342+
)
343+
}
333344

334345
suspend fun createInvoice(
335346
amountSats: ULong? = null,
@@ -535,6 +546,9 @@ data class MainUiState(
535546
val peers: List<LnPeer> = emptyList(),
536547
val channels: List<ChannelDetails> = emptyList(),
537548
val isRefreshing: Boolean = false,
549+
val receiveOnSpendingBalance: Boolean = true,
550+
val bip21AmountSats: ULong? = null,
551+
val bip21Description: String = ""
538552
)
539553

540554
// endregion

0 commit comments

Comments
 (0)