@@ -8,7 +8,10 @@ package org.bitcoindevkit.devkitwallet.presentation.ui.screens.wallet
8
8
import android.content.Context
9
9
import android.widget.Toast
10
10
import androidx.compose.foundation.background
11
+ import androidx.compose.foundation.border
12
+ import androidx.compose.foundation.clickable
11
13
import androidx.compose.foundation.layout.Arrangement
14
+ import androidx.compose.foundation.layout.Box
12
15
import androidx.compose.foundation.layout.Column
13
16
import androidx.compose.foundation.layout.Row
14
17
import androidx.compose.foundation.layout.Spacer
@@ -27,6 +30,7 @@ import androidx.compose.material3.BottomSheetScaffoldState
27
30
import androidx.compose.material3.Button
28
31
import androidx.compose.material3.ButtonDefaults
29
32
import androidx.compose.material3.ExperimentalMaterial3Api
33
+ import androidx.compose.material3.Icon
30
34
import androidx.compose.material3.OutlinedTextField
31
35
import androidx.compose.material3.OutlinedTextFieldDefaults
32
36
import androidx.compose.material3.Switch
@@ -43,22 +47,27 @@ import androidx.compose.runtime.rememberCoroutineScope
43
47
import androidx.compose.runtime.saveable.rememberSaveable
44
48
import androidx.compose.ui.Alignment
45
49
import androidx.compose.ui.Modifier
50
+ import androidx.compose.ui.draw.clip
46
51
import androidx.compose.ui.draw.shadow
47
52
import androidx.compose.ui.graphics.Color
48
53
import androidx.compose.ui.platform.LocalContext
54
+ import androidx.compose.ui.semantics.Role
49
55
import androidx.compose.ui.text.TextStyle
50
56
import androidx.compose.ui.text.style.TextAlign
51
57
import androidx.compose.ui.unit.dp
52
58
import androidx.compose.ui.unit.sp
53
59
import androidx.constraintlayout.compose.ConstraintLayout
54
60
import androidx.constraintlayout.compose.Dimension
55
61
import androidx.navigation.NavController
62
+ import com.composables.icons.lucide.Lucide
63
+ import com.composables.icons.lucide.UserRoundMinus
64
+ import com.composables.icons.lucide.UserRoundPlus
56
65
import kotlinx.coroutines.CoroutineScope
57
66
import kotlinx.coroutines.launch
58
67
import org.bitcoindevkit.devkitwallet.presentation.navigation.HomeScreen
59
68
import org.bitcoindevkit.devkitwallet.presentation.theme.DevkitWalletColors
60
- import org.bitcoindevkit.devkitwallet.presentation.theme.quattroRegular
61
69
import org.bitcoindevkit.devkitwallet.presentation.theme.standardText
70
+ import org.bitcoindevkit.devkitwallet.presentation.ui.components.NeutralButton
62
71
import org.bitcoindevkit.devkitwallet.presentation.ui.components.SecondaryScreensAppBar
63
72
import org.bitcoindevkit.devkitwallet.presentation.viewmodels.SendViewModel
64
73
import org.bitcoindevkit.devkitwallet.presentation.viewmodels.mvi.Recipient
@@ -79,10 +88,7 @@ internal fun SendScreen(navController: NavController, sendViewModel: SendViewMod
79
88
val recipientList: MutableList <Recipient > = remember { mutableStateListOf(Recipient (address = " " , amount = 0u )) }
80
89
val feeRate: MutableState <String > = rememberSaveable { mutableStateOf(" " ) }
81
90
val (showDialog, setShowDialog) = rememberSaveable { mutableStateOf(false ) }
82
-
83
91
val sendAll: MutableState <Boolean > = remember { mutableStateOf(false ) }
84
- val rbfDisabled: MutableState <Boolean > = remember { mutableStateOf(false ) }
85
- val opReturnMsg: MutableState <String ?> = remember { mutableStateOf(null ) }
86
92
87
93
val bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState()
88
94
@@ -94,7 +100,7 @@ internal fun SendScreen(navController: NavController, sendViewModel: SendViewMod
94
100
)
95
101
},
96
102
sheetShape = RoundedCornerShape (topStart = 16 .dp, topEnd = 16 .dp),
97
- sheetContent = { AdvancedOptions (sendAll, opReturnMsg, recipientList) },
103
+ sheetContent = { AdvancedOptions (sendAll, recipientList) },
98
104
sheetContainerColor = DevkitWalletColors .primaryDark,
99
105
scaffoldState = bottomSheetScaffoldState,
100
106
sheetPeekHeight = 0 .dp,
@@ -124,14 +130,12 @@ internal fun SendScreen(navController: NavController, sendViewModel: SendViewMod
124
130
transactionType = if (sendAll.value) TransactionType .SEND_ALL else TransactionType .STANDARD
125
131
)
126
132
TransactionFeeInput (feeRate = feeRate)
127
- MoreOptions (coroutineScope = coroutineScope, bottomSheetScaffoldState = bottomSheetScaffoldState)
128
133
Dialog (
129
134
recipientList = recipientList,
130
135
feeRate = feeRate,
131
136
showDialog = showDialog,
132
137
setShowDialog = setShowDialog,
133
138
transactionType = if (sendAll.value) TransactionType .SEND_ALL else TransactionType .STANDARD ,
134
- opReturnMsg = opReturnMsg.value,
135
139
context = context,
136
140
onAction = onAction
137
141
)
@@ -144,6 +148,7 @@ internal fun SendScreen(navController: NavController, sendViewModel: SendViewMod
144
148
end.linkTo(parent.end)
145
149
}.padding(bottom = 32 .dp)
146
150
) {
151
+ MoreOptions (coroutineScope = coroutineScope, bottomSheetScaffoldState = bottomSheetScaffoldState)
147
152
Button (
148
153
onClick = { setShowDialog(true ) },
149
154
colors = ButtonDefaults .buttonColors(DevkitWalletColors .accent2),
@@ -155,11 +160,7 @@ internal fun SendScreen(navController: NavController, sendViewModel: SendViewMod
155
160
.shadow(elevation = 4 .dp, shape = RoundedCornerShape (16 .dp))
156
161
) {
157
162
Text (
158
- text = " broadcast transaction" ,
159
- fontSize = 14 .sp,
160
- fontFamily = quattroRegular,
161
- textAlign = TextAlign .Center ,
162
- lineHeight = 28 .sp,
163
+ text = " Broadcast transaction" ,
163
164
)
164
165
}
165
166
}
@@ -170,27 +171,13 @@ internal fun SendScreen(navController: NavController, sendViewModel: SendViewMod
170
171
@Composable
171
172
internal fun AdvancedOptions (
172
173
sendAll : MutableState <Boolean >,
173
- opReturnMsg : MutableState <String ?>,
174
174
recipientList : MutableList <Recipient >,
175
175
) {
176
176
Column (
177
177
modifier = Modifier
178
178
.fillMaxWidth()
179
179
.padding(horizontal = 16 .dp, vertical = 8 .dp)
180
180
) {
181
- Row (
182
- Modifier
183
- .fillMaxWidth()
184
- .padding(bottom = 8 .dp),
185
- horizontalArrangement = Arrangement .Center
186
- ) {
187
- Text (
188
- text = " Advanced Options" ,
189
- color = DevkitWalletColors .white,
190
- fontSize = 18 .sp,
191
- )
192
- }
193
-
194
181
Row (
195
182
verticalAlignment = Alignment .CenterVertically ,
196
183
horizontalArrangement = Arrangement .SpaceBetween ,
@@ -221,77 +208,72 @@ internal fun AdvancedOptions(
221
208
)
222
209
}
223
210
224
- Row (verticalAlignment = Alignment .CenterVertically ) {
225
- OutlinedTextField (
226
- modifier = Modifier
227
- .padding(vertical = 8 .dp)
228
- .weight(0.5f ),
229
- value = opReturnMsg.value ? : " " ,
230
- onValueChange = {
231
- opReturnMsg.value = it
232
- },
233
- label = {
234
- Text (
235
- text = " Optional OP_RETURN message" ,
236
- color = DevkitWalletColors .white,
237
- )
238
- },
239
- singleLine = true ,
240
- textStyle = TextStyle (color = DevkitWalletColors .white),
241
- colors = OutlinedTextFieldDefaults .colors(
242
- cursorColor = DevkitWalletColors .accent1,
243
- focusedBorderColor = DevkitWalletColors .accent1,
244
- unfocusedBorderColor = DevkitWalletColors .white
245
- ),
246
- )
247
- }
248
-
249
211
Row (
250
- Modifier
251
- .fillMaxWidth()
252
- .padding(vertical = 4 .dp),
253
- horizontalArrangement = Arrangement .Center
212
+ Modifier .fillMaxWidth(),
213
+ horizontalArrangement = Arrangement .SpaceBetween ,
214
+ verticalAlignment = Alignment .CenterVertically
254
215
) {
255
216
Text (
256
217
text = " Number of Recipients" ,
257
218
style = standardText
258
219
)
259
- }
260
-
261
- Row (
262
- Modifier .fillMaxWidth(),
263
- horizontalArrangement = Arrangement .SpaceBetween ,
264
- verticalAlignment = Alignment .CenterVertically
265
- ) {
266
- Button (
267
- onClick = {
268
- if (recipientList.size > 1 ) {
269
- recipientList.removeLast()
270
- }
271
- },
272
- enabled = ! sendAll.value,
273
- colors = ButtonDefaults .buttonColors(DevkitWalletColors .accent2),
274
- shape = RoundedCornerShape (16 .dp),
275
- modifier = Modifier .width(70 .dp)
276
- ) {
277
- Text (text = " -" )
278
- }
279
-
280
220
Text (
281
221
text = " ${recipientList.size} " ,
282
- color = DevkitWalletColors .white,
283
- fontSize = 18 .sp,
222
+ style = standardText
284
223
)
285
224
286
- Button (
287
- onClick = { recipientList.add(Recipient (" " , 0u )) },
288
- enabled = ! sendAll.value,
289
- colors = ButtonDefaults .buttonColors(DevkitWalletColors .accent1),
290
- shape = RoundedCornerShape (16 .dp),
291
- modifier = Modifier .width(70 .dp)
225
+ Row (
226
+ verticalAlignment = Alignment .CenterVertically ,
227
+ horizontalArrangement = Arrangement .spacedBy((- 1 ).dp),
228
+ modifier = Modifier .padding(top = 4 .dp)
292
229
) {
293
- Text (text = " +" )
230
+ val startShape = RoundedCornerShape (topStart = 6 .dp, bottomStart = 6 .dp)
231
+ val endShape = RoundedCornerShape (topEnd = 6 .dp, bottomEnd = 6 .dp)
232
+ Box (
233
+ Modifier
234
+ .clip(startShape)
235
+ .border(2 .dp, Color .White , startShape)
236
+ .clickable(role = Role .Button ) {
237
+ recipientList.add(Recipient (" " , 0u ))
238
+ }.padding(horizontal = 12 .dp, vertical = 10 .dp)
239
+ ) {
240
+ Icon (Lucide .UserRoundPlus , tint = DevkitWalletColors .white, contentDescription = null )
241
+ }
242
+ Box (
243
+ Modifier
244
+ .clip(endShape)
245
+ .border(2 .dp, Color .White , endShape)
246
+ .clickable(role = Role .Button ) {
247
+ if (recipientList.size > 1 ) {
248
+ recipientList.removeLast()
249
+ }
250
+ }.padding(horizontal = 12 .dp, vertical = 10 .dp)
251
+ ) {
252
+ Icon (Lucide .UserRoundMinus , tint = DevkitWalletColors .white, contentDescription = null )
253
+ }
294
254
}
255
+ // Button(
256
+ // onClick = {
257
+ // if (recipientList.size > 1) {
258
+ // recipientList.removeLast()
259
+ // }
260
+ // },
261
+ // enabled = !sendAll.value,
262
+ // colors = ButtonDefaults.buttonColors(DevkitWalletColors.accent2),
263
+ // shape = RoundedCornerShape(16.dp),
264
+ // modifier = Modifier.width(70.dp)
265
+ // ) {
266
+ // Text(text = "-")
267
+ // }
268
+ // Button(
269
+ // onClick = { recipientList.add(Recipient("", 0u)) },
270
+ // enabled = !sendAll.value,
271
+ // colors = ButtonDefaults.buttonColors(DevkitWalletColors.accent1),
272
+ // shape = RoundedCornerShape(16.dp),
273
+ // modifier = Modifier.width(70.dp)
274
+ // ) {
275
+ // Text(text = "+")
276
+ // }
295
277
}
296
278
297
279
Spacer (modifier = Modifier .height(32 .dp))
@@ -447,29 +429,15 @@ private fun TransactionFeeInput(feeRate: MutableState<String>) {
447
429
fun MoreOptions (coroutineScope : CoroutineScope , bottomSheetScaffoldState : BottomSheetScaffoldState ) {
448
430
Column (
449
431
horizontalAlignment = Alignment .CenterHorizontally ,
450
- modifier = Modifier
451
- .padding(vertical = 8 .dp)
452
- .background(DevkitWalletColors .secondary)
453
432
) {
454
- Button (
433
+ NeutralButton (
434
+ text = " Advanced options" ,
455
435
onClick = {
456
436
coroutineScope.launch {
457
437
bottomSheetScaffoldState.bottomSheetState.expand()
458
438
}
459
439
},
460
- colors = ButtonDefaults .buttonColors(Color .Transparent ),
461
- modifier = Modifier
462
- .height(60 .dp)
463
- .fillMaxWidth(fraction = 0.9f )
464
- .padding(vertical = 8 .dp)
465
- ) {
466
- Text (
467
- text = " advanced options" ,
468
- style = standardText,
469
- textAlign = TextAlign .Center ,
470
- lineHeight = 28 .sp,
471
- )
472
- }
440
+ )
473
441
}
474
442
}
475
443
@@ -480,7 +448,6 @@ private fun Dialog(
480
448
showDialog : Boolean ,
481
449
setShowDialog : (Boolean ) -> Unit ,
482
450
transactionType : TransactionType ,
483
- opReturnMsg : String? ,
484
451
context : Context ,
485
452
onAction : (SendScreenAction ) -> Unit ,
486
453
) {
@@ -490,9 +457,6 @@ private fun Dialog(
490
457
if (feeRate.value.isNotEmpty()) {
491
458
confirmationText + = " Fee Rate : ${feeRate.value.toULong()} "
492
459
}
493
- if (! opReturnMsg.isNullOrEmpty()) {
494
- confirmationText + = " OP_RETURN Message : $opReturnMsg "
495
- }
496
460
AlertDialog (
497
461
containerColor = DevkitWalletColors .primaryLight,
498
462
onDismissRequest = {},
@@ -517,7 +481,6 @@ private fun Dialog(
517
481
recipients = recipientList,
518
482
feeRate = feeRate.value.toULong(),
519
483
transactionType = transactionType,
520
- opReturnMsg = opReturnMsg
521
484
)
522
485
onAction(SendScreenAction .Broadcast (txDataBundle))
523
486
setShowDialog(false )
0 commit comments