@@ -2,13 +2,14 @@ package to.bitkit.ui.screens.transfer
22
33import androidx.compose.foundation.Image
44import androidx.compose.foundation.layout.Arrangement
5+ import androidx.compose.foundation.layout.Box
56import androidx.compose.foundation.layout.Column
67import androidx.compose.foundation.layout.IntrinsicSize
78import androidx.compose.foundation.layout.Row
89import androidx.compose.foundation.layout.fillMaxSize
10+ import androidx.compose.foundation.layout.fillMaxWidth
911import androidx.compose.foundation.layout.height
1012import androidx.compose.foundation.layout.padding
11- import androidx.compose.foundation.layout.size
1213import androidx.compose.foundation.rememberScrollState
1314import androidx.compose.foundation.verticalScroll
1415import androidx.compose.runtime.Composable
@@ -17,7 +18,7 @@ import androidx.compose.runtime.mutableStateOf
1718import androidx.compose.runtime.remember
1819import androidx.compose.runtime.rememberCoroutineScope
1920import androidx.compose.runtime.setValue
20- import androidx.compose.ui.Alignment.Companion.CenterHorizontally
21+ import androidx.compose.ui.Alignment
2122import androidx.compose.ui.Modifier
2223import androidx.compose.ui.layout.ContentScale
2324import androidx.compose.ui.res.painterResource
@@ -102,117 +103,123 @@ private fun Content(
102103 onBackClick = onBackClick,
103104 actions = { CloseNavIcon (onCloseClick) },
104105 )
105- Column (
106- modifier = Modifier
107- .padding(horizontal = 16 .dp)
108- .fillMaxSize()
109- .verticalScroll(rememberScrollState())
110- ) {
111- val clientBalance = order.clientBalanceSat
112- val networkFee = order.networkFeeSat
113- val serviceFee = order.serviceFeeSat
114- val totalFee = order.feeSat
115- val lspBalance = order.lspBalanceSat
116-
117- VerticalSpacer (32 .dp)
118- Display (
119- text = stringResource(R .string.lightning__transfer__confirm)
120- .withAccent(accentColor = Colors .Purple )
121- )
122- VerticalSpacer (8 .dp)
123-
124- Row (
125- horizontalArrangement = Arrangement .spacedBy(16 .dp),
126- modifier = Modifier .height(IntrinsicSize .Min )
127- ) {
128- FeeInfo (
129- label = stringResource(R .string.lightning__spending_confirm__network_fee),
130- amount = networkFee.toLong(),
131- )
132- FeeInfo (
133- label = stringResource(R .string.lightning__spending_confirm__lsp_fee),
134- amount = serviceFee.toLong(),
135- )
136- }
137- Row (
138- horizontalArrangement = Arrangement .spacedBy(16 .dp),
139- modifier = Modifier .height(IntrinsicSize .Min )
140- ) {
141- FeeInfo (
142- label = stringResource(R .string.lightning__spending_confirm__amount),
143- amount = clientBalance.toLong(),
144- )
145- FeeInfo (
146- label = stringResource(R .string.lightning__spending_confirm__total),
147- amount = totalFee.toLong(),
148- )
149- }
150-
151- if (isAdvanced) {
152- VerticalSpacer (16 .dp)
153- LightningChannel (
154- capacity = (clientBalance + lspBalance).toLong(),
155- localBalance = clientBalance.toLong(),
156- remoteBalance = lspBalance.toLong(),
157- status = ChannelStatusUi .OPEN ,
158- showLabels = true ,
159- )
160- }
161-
162- VerticalSpacer (16 .dp)
163- Row (horizontalArrangement = Arrangement .spacedBy(16 .dp)) {
164- PrimaryButton (
165- text = stringResource(R .string.common__learn_more),
166- size = ButtonSize .Small ,
167- fullWidth = false ,
168- onClick = onLearnMoreClick,
169- )
170- PrimaryButton (
171- text = stringResource(
172- if (isAdvanced) R .string.lightning__spending_confirm__default else R .string.common__advanced
173- ),
174- size = ButtonSize .Small ,
175- fullWidth = false ,
176- onClick = {
177- if (isAdvanced) {
178- onUseDefaultLspBalanceClick()
179- } else {
180- onAdvancedClick()
181- }
182- },
183- )
184- }
185- VerticalSpacer (16 .dp)
186-
106+ Box (modifier = Modifier .fillMaxSize()) {
187107 if (! isAdvanced) {
188108 Image (
189109 painter = painterResource(id = R .drawable.coin_stack_x),
190110 contentDescription = null ,
191111 contentScale = ContentScale .Fit ,
192112 modifier = Modifier
193- .size(256 .dp)
194- .align(alignment = CenterHorizontally )
113+ .fillMaxWidth()
114+ .padding(horizontal = 60 .dp)
115+ .align(alignment = Alignment .BottomCenter )
116+ .padding(bottom = 76 .dp)
195117 )
196118 }
197- FillHeight ()
198119
199- var isLoading by remember { mutableStateOf(false ) }
200- SwipeToConfirm (
201- text = stringResource(R .string.lightning__transfer__swipe),
202- loading = isLoading,
203- color = Colors .Purple ,
204- onConfirm = {
205- scope.launch {
206- isLoading = true
207- delay(300 )
208- onTransferToSpendingConfirm(order)
209- onConfirm()
210- }
120+ Column (
121+ modifier = Modifier
122+ .padding(horizontal = 16 .dp)
123+ .fillMaxSize()
124+ .verticalScroll(rememberScrollState())
125+ ) {
126+ val clientBalance = order.clientBalanceSat
127+ val networkFee = order.networkFeeSat
128+ val serviceFee = order.serviceFeeSat
129+ val totalFee = order.feeSat
130+ val lspBalance = order.lspBalanceSat
131+
132+ VerticalSpacer (32 .dp)
133+ Display (
134+ text = stringResource(R .string.lightning__transfer__confirm)
135+ .withAccent(accentColor = Colors .Purple )
136+ )
137+ VerticalSpacer (8 .dp)
138+
139+ Row (
140+ horizontalArrangement = Arrangement .spacedBy(16 .dp),
141+ modifier = Modifier .height(IntrinsicSize .Min )
142+ ) {
143+ FeeInfo (
144+ label = stringResource(R .string.lightning__spending_confirm__network_fee),
145+ amount = networkFee.toLong(),
146+ )
147+ FeeInfo (
148+ label = stringResource(R .string.lightning__spending_confirm__lsp_fee),
149+ amount = serviceFee.toLong(),
150+ )
151+ }
152+ Row (
153+ horizontalArrangement = Arrangement .spacedBy(16 .dp),
154+ modifier = Modifier .height(IntrinsicSize .Min )
155+ ) {
156+ FeeInfo (
157+ label = stringResource(R .string.lightning__spending_confirm__amount),
158+ amount = clientBalance.toLong(),
159+ )
160+ FeeInfo (
161+ label = stringResource(R .string.lightning__spending_confirm__total),
162+ amount = totalFee.toLong(),
163+ )
164+ }
165+
166+ if (isAdvanced) {
167+ VerticalSpacer (16 .dp)
168+ LightningChannel (
169+ capacity = (clientBalance + lspBalance).toLong(),
170+ localBalance = clientBalance.toLong(),
171+ remoteBalance = lspBalance.toLong(),
172+ status = ChannelStatusUi .OPEN ,
173+ showLabels = true ,
174+ )
211175 }
212- )
213- VerticalSpacer (16 .dp)
176+
177+ VerticalSpacer (16 .dp)
178+ Row (horizontalArrangement = Arrangement .spacedBy(16 .dp)) {
179+ PrimaryButton (
180+ text = stringResource(R .string.common__learn_more),
181+ size = ButtonSize .Small ,
182+ fullWidth = false ,
183+ onClick = onLearnMoreClick,
184+ )
185+ PrimaryButton (
186+ text = stringResource(
187+ if (isAdvanced) R .string.lightning__spending_confirm__default else R .string.common__advanced
188+ ),
189+ size = ButtonSize .Small ,
190+ fullWidth = false ,
191+ onClick = {
192+ if (isAdvanced) {
193+ onUseDefaultLspBalanceClick()
194+ } else {
195+ onAdvancedClick()
196+ }
197+ },
198+ )
199+ }
200+ VerticalSpacer (16 .dp)
201+
202+ FillHeight ()
203+
204+ var isLoading by remember { mutableStateOf(false ) }
205+ SwipeToConfirm (
206+ text = stringResource(R .string.lightning__transfer__swipe),
207+ loading = isLoading,
208+ color = Colors .Purple ,
209+ onConfirm = {
210+ scope.launch {
211+ isLoading = true
212+ delay(300 )
213+ onTransferToSpendingConfirm(order)
214+ onConfirm()
215+ }
216+ }
217+ )
218+ VerticalSpacer (16 .dp)
219+ }
214220 }
215221 }
222+
216223}
217224
218225@Preview(showSystemUi = true , showBackground = true )
@@ -290,3 +297,79 @@ private fun Preview() {
290297 )
291298 }
292299}
300+
301+ @Preview(showSystemUi = true , showBackground = true )
302+ @Composable
303+ private fun Preview2 () {
304+ AppThemeSurface {
305+ Content (
306+ onBackClick = {},
307+ onCloseClick = {},
308+ onLearnMoreClick = {},
309+ onAdvancedClick = {},
310+ onConfirm = {},
311+ onUseDefaultLspBalanceClick = {},
312+ onTransferToSpendingConfirm = {},
313+ order = IBtOrder (
314+ id = " order_7e6f3b7c-486a-4f5a-8b1e-2c9d7f0a8b9d" ,
315+ state = BtOrderState .CREATED ,
316+ state2 = BtOrderState2 .CREATED ,
317+ feeSat = 1000UL ,
318+ networkFeeSat = 250UL ,
319+ serviceFeeSat = 750UL ,
320+ lspBalanceSat = 2000000UL ,
321+ clientBalanceSat = 500000UL ,
322+ zeroConf = false ,
323+ zeroReserve = true ,
324+ clientNodeId = null ,
325+ channelExpiryWeeks = 8u ,
326+ channelExpiresAt = " 2025-09-22T08:29:03Z" ,
327+ orderExpiresAt = " 2025-07-29T08:29:03Z" ,
328+ channel = null ,
329+ lspNode = ILspNode (
330+ alias = " Bitkit LSP" ,
331+ pubkey = " 02f12451995802149b1855a7948305763328e9304337b51e45e7f1b637956424e8" ,
332+ connectionStrings
= listOf (
" [email protected] :9735" ),
333+ readonly = null
334+ ),
335+ lnurl = null ,
336+ payment = IBtPayment (
337+ state = BtPaymentState .CREATED ,
338+ state2 = BtPaymentState2 .CREATED ,
339+ paidSat = 0UL ,
340+ bolt11Invoice = IBtBolt11Invoice (
341+ request = " lnmock" ,
342+ state = BtBolt11InvoiceState .PENDING ,
343+ expiresAt = " 2025-07-28T12:00:00Z" ,
344+ updatedAt = " 2025-07-28T08:30:00Z"
345+ ),
346+ onchain = IBtOnchainTransactions (
347+ address = " bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq" ,
348+ confirmedSat = 0UL ,
349+ requiredConfirmations = 1u ,
350+ transactions = listOf (
351+ IBtOnchainTransaction (
352+ amountSat = 50000UL ,
353+ txId = " f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16" ,
354+ vout = 0u ,
355+ blockHeight = null ,
356+ blockConfirmationCount = 0u ,
357+ feeRateSatPerVbyte = 12.5 ,
358+ confirmed = false ,
359+ suspicious0ConfReason = " "
360+ )
361+ )
362+ ),
363+ isManuallyPaid = null ,
364+ manualRefunds = null
365+ ),
366+ couponCode = null ,
367+ source = null ,
368+ discount = null ,
369+ updatedAt = " 2025-07-28T08:29:03Z" ,
370+ createdAt = " 2025-07-28T08:29:03Z"
371+ ),
372+ isAdvanced = true
373+ )
374+ }
375+ }
0 commit comments