Skip to content

Commit f436d03

Browse files
committed
Merge branch 'master' into refactor/transfer-flows
2 parents bb0ba10 + c452864 commit f436d03

File tree

7 files changed

+294
-37
lines changed

7 files changed

+294
-37
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package to.bitkit.ui.components
2+
3+
import androidx.compose.foundation.border
4+
import androidx.compose.foundation.clickable
5+
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.foundation.layout.wrapContentWidth
7+
import androidx.compose.foundation.shape.RoundedCornerShape
8+
import androidx.compose.material3.MaterialTheme
9+
import androidx.compose.material3.Text
10+
import androidx.compose.runtime.Composable
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.text.font.FontWeight
13+
import androidx.compose.ui.unit.dp
14+
import to.bitkit.ui.theme.Colors
15+
16+
@Composable
17+
fun TagButton(
18+
text: String,
19+
isSelected: Boolean,
20+
onClick: () -> Unit,
21+
modifier: Modifier = Modifier,
22+
) {
23+
val borderColor = if (isSelected) Colors.Brand else Colors.White16
24+
val textColor = if (isSelected) Colors.Brand else MaterialTheme.colorScheme.onSurface
25+
26+
Text(
27+
text = text,
28+
color = textColor,
29+
fontWeight = FontWeight.Medium,
30+
modifier = modifier
31+
.wrapContentWidth()
32+
.border(
33+
width = 1.dp,
34+
color = borderColor,
35+
shape = RoundedCornerShape(8.dp)
36+
)
37+
.clickable { onClick() }
38+
.padding(horizontal = 12.dp, vertical = 8.dp)
39+
)
40+
}

app/src/main/java/to/bitkit/ui/screens/wallets/activity/TagSelectorSheet.kt

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package to.bitkit.ui.screens.wallets.activity
22

3-
import androidx.compose.foundation.border
4-
import androidx.compose.foundation.clickable
53
import androidx.compose.foundation.layout.Arrangement
64
import androidx.compose.foundation.layout.Column
75
import androidx.compose.foundation.layout.ExperimentalLayoutApi
@@ -12,23 +10,18 @@ import androidx.compose.foundation.layout.fillMaxHeight
1210
import androidx.compose.foundation.layout.fillMaxWidth
1311
import androidx.compose.foundation.layout.padding
1412
import androidx.compose.foundation.layout.wrapContentHeight
15-
import androidx.compose.foundation.layout.wrapContentWidth
16-
import androidx.compose.foundation.shape.RoundedCornerShape
17-
import androidx.compose.material3.MaterialTheme
18-
import androidx.compose.material3.Text
1913
import androidx.compose.runtime.Composable
2014
import androidx.compose.runtime.collectAsState
2115
import androidx.compose.runtime.getValue
2216
import androidx.compose.ui.Alignment
2317
import androidx.compose.ui.Modifier
2418
import androidx.compose.ui.res.stringResource
25-
import androidx.compose.ui.text.font.FontWeight
2619
import androidx.compose.ui.unit.dp
2720
import to.bitkit.R
2821
import to.bitkit.ui.components.PrimaryButton
2922
import to.bitkit.ui.components.SecondaryButton
23+
import to.bitkit.ui.components.TagButton
3024
import to.bitkit.ui.scaffold.SheetTopBar
31-
import to.bitkit.ui.theme.Colors
3225
import to.bitkit.viewmodels.ActivityListViewModel
3326

3427
@OptIn(ExperimentalLayoutApi::class)
@@ -86,29 +79,3 @@ fun TagSelectorSheet(
8679
}
8780

8881
}
89-
90-
@Composable
91-
fun TagButton(
92-
text: String,
93-
isSelected: Boolean,
94-
onClick: () -> Unit,
95-
modifier: Modifier = Modifier,
96-
) {
97-
val borderColor = if (isSelected) Colors.Brand else Colors.White16
98-
val textColor = if (isSelected) Colors.Brand else MaterialTheme.colorScheme.onSurface
99-
100-
Text(
101-
text = text,
102-
color = textColor,
103-
fontWeight = FontWeight.Medium,
104-
modifier = modifier
105-
.wrapContentWidth()
106-
.border(
107-
width = 1.dp,
108-
color = borderColor,
109-
shape = RoundedCornerShape(8.dp)
110-
)
111-
.clickable { onClick() }
112-
.padding(horizontal = 12.dp, vertical = 8.dp)
113-
)
114-
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package to.bitkit.ui.screens.wallets.send
2+
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.ExperimentalLayoutApi
6+
import androidx.compose.foundation.layout.FlowRow
7+
import androidx.compose.foundation.layout.Spacer
8+
import androidx.compose.foundation.layout.fillMaxSize
9+
import androidx.compose.foundation.layout.fillMaxWidth
10+
import androidx.compose.foundation.layout.height
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.text.KeyboardActions
13+
import androidx.compose.foundation.text.KeyboardOptions
14+
import androidx.compose.material3.MaterialTheme
15+
import androidx.compose.material3.Text
16+
import androidx.compose.material3.TextField
17+
import androidx.compose.runtime.Composable
18+
import androidx.compose.runtime.collectAsState
19+
import androidx.compose.runtime.getValue
20+
import androidx.compose.ui.Modifier
21+
import androidx.compose.ui.res.stringResource
22+
import androidx.compose.ui.text.input.ImeAction
23+
import androidx.compose.ui.tooling.preview.Preview
24+
import androidx.compose.ui.unit.dp
25+
import androidx.hilt.navigation.compose.hiltViewModel
26+
import to.bitkit.R
27+
import to.bitkit.ui.components.Caption13Up
28+
import to.bitkit.ui.components.TagButton
29+
import to.bitkit.ui.scaffold.SheetTopBar
30+
import to.bitkit.ui.theme.AppTextFieldDefaults
31+
import to.bitkit.ui.theme.AppThemeSurface
32+
import to.bitkit.ui.theme.Colors
33+
import to.bitkit.viewmodels.AddTagUiState
34+
import to.bitkit.viewmodels.TagsViewModel
35+
36+
37+
@Composable
38+
fun AddTagScreen(
39+
viewModel: TagsViewModel = hiltViewModel(),
40+
onBack: () -> Unit,
41+
onTagSelected: (String) -> Unit,
42+
) {
43+
val uiState: AddTagUiState by viewModel.uiState.collectAsState()
44+
45+
AddTagContent(
46+
uiState = uiState,
47+
onTagSelected = onTagSelected,
48+
onTagConfirmed = { tag ->
49+
onTagSelected(tag)
50+
},
51+
onInputUpdated = { newText -> viewModel.onInputUpdated(newText) },
52+
onBack = onBack
53+
)
54+
}
55+
56+
@OptIn(ExperimentalLayoutApi::class)
57+
@Composable
58+
fun AddTagContent(
59+
uiState: AddTagUiState,
60+
onTagSelected: (String) -> Unit,
61+
onTagConfirmed: (String) -> Unit,
62+
onInputUpdated: (String) -> Unit,
63+
onBack: () -> Unit,
64+
) {
65+
Column(
66+
modifier = Modifier.fillMaxSize()
67+
) {
68+
69+
SheetTopBar(stringResource(R.string.wallet__tags_add)) {
70+
onBack()
71+
}
72+
73+
Column(
74+
modifier = Modifier
75+
.padding(horizontal = 16.dp)
76+
.fillMaxWidth()
77+
) {
78+
if (uiState.tagsSuggestions.isNotEmpty()) {
79+
Spacer(modifier = Modifier.height(16.dp))
80+
Caption13Up(text = stringResource(R.string.wallet__tags_previously), color = Colors.White64)
81+
Spacer(modifier = Modifier.height(16.dp))
82+
FlowRow(
83+
horizontalArrangement = Arrangement.spacedBy(8.dp),
84+
verticalArrangement = Arrangement.spacedBy(8.dp),
85+
modifier = Modifier
86+
.fillMaxWidth()
87+
.padding(bottom = 16.dp)
88+
) {
89+
uiState.tagsSuggestions.map { tagText ->
90+
TagButton(
91+
tagText,
92+
isSelected = false,
93+
onClick = { onTagSelected(tagText) },
94+
)
95+
}
96+
}
97+
}
98+
Spacer(modifier = Modifier.height(16.dp))
99+
Caption13Up(text = stringResource(R.string.wallet__tags_new), color = Colors.White64)
100+
Spacer(modifier = Modifier.height(16.dp))
101+
TextField(
102+
placeholder = { Text(stringResource(R.string.wallet__tags_new_enter)) },
103+
value = uiState.tagInput,
104+
onValueChange = onInputUpdated,
105+
maxLines = 1,
106+
singleLine = true,
107+
colors = AppTextFieldDefaults.noIndicatorColors,
108+
shape = MaterialTheme.shapes.small,
109+
keyboardOptions = KeyboardOptions(
110+
imeAction = ImeAction.Done
111+
),
112+
keyboardActions = KeyboardActions(onDone = {
113+
onTagConfirmed(uiState.tagInput)
114+
}),
115+
modifier = Modifier.fillMaxWidth()
116+
)
117+
}
118+
}
119+
}
120+
121+
@Preview(showSystemUi = true, showBackground = true)
122+
@Composable
123+
private fun Preview() {
124+
AppThemeSurface {
125+
AddTagContent(
126+
uiState = AddTagUiState(
127+
tagsSuggestions = listOf("Lunch", "Mom", "Dad", "Dinner", "Tip", "Gift")
128+
),
129+
onTagSelected = {},
130+
onInputUpdated = {},
131+
onTagConfirmed = {},
132+
onBack = {}
133+
)
134+
}
135+
}
136+
137+
@Preview(showSystemUi = true, showBackground = true, name = "No tags")
138+
@Composable
139+
private fun Preview2() {
140+
AppThemeSurface {
141+
AddTagContent(
142+
uiState = AddTagUiState(),
143+
onTagSelected = {},
144+
onInputUpdated = {},
145+
onTagConfirmed = {},
146+
onBack = {}
147+
)
148+
}
149+
}

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package to.bitkit.ui.screens.wallets.send
33
import androidx.compose.foundation.clickable
44
import androidx.compose.foundation.layout.Arrangement
55
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.ExperimentalLayoutApi
7+
import androidx.compose.foundation.layout.FlowRow
68
import androidx.compose.foundation.layout.IntrinsicSize
79
import androidx.compose.foundation.layout.Row
810
import androidx.compose.foundation.layout.Spacer
@@ -34,9 +36,11 @@ import to.bitkit.ext.ellipsisMiddle
3436
import to.bitkit.ext.formatted
3537
import to.bitkit.ui.components.BalanceHeaderView
3638
import to.bitkit.ui.components.BodySSB
39+
import to.bitkit.ui.components.ButtonSize
3740
import to.bitkit.ui.components.Caption13Up
3841
import to.bitkit.ui.components.PrimaryButton
3942
import to.bitkit.ui.components.SwipeToConfirm
43+
import to.bitkit.ui.components.TagButton
4044
import to.bitkit.ui.scaffold.SheetTopBar
4145
import to.bitkit.ui.theme.AppThemeSurface
4246
import to.bitkit.ui.theme.Colors
@@ -47,11 +51,13 @@ import uniffi.bitkitcore.LightningInvoice
4751
import uniffi.bitkitcore.NetworkType
4852
import java.time.Instant
4953

54+
@OptIn(ExperimentalLayoutApi::class)
5055
@Composable
5156
fun SendAndReviewScreen(
5257
uiState: SendUiState,
5358
onBack: () -> Unit,
5459
onEvent: (SendEvent) -> Unit,
60+
onClickAddTag: () -> Unit,
5561
) {
5662
Column(
5763
modifier = Modifier.fillMaxSize()
@@ -80,10 +86,25 @@ fun SendAndReviewScreen(
8086
Spacer(modifier = Modifier.height(16.dp))
8187
Caption13Up(text = stringResource(R.string.wallet__tags), color = Colors.White64)
8288
Spacer(modifier = Modifier.height(8.dp))
83-
//TODO DISPLAY TAGS
89+
FlowRow(
90+
horizontalArrangement = Arrangement.spacedBy(8.dp),
91+
verticalArrangement = Arrangement.spacedBy(8.dp),
92+
modifier = Modifier
93+
.fillMaxWidth()
94+
.padding(bottom = 16.dp)
95+
) {
96+
uiState.selectedTags.map { tagText ->
97+
TagButton(
98+
text = tagText,
99+
isSelected = false,
100+
onClick = { }, //TODO IMPLEMENT IN OTHER PR
101+
)
102+
}
103+
}
84104
PrimaryButton(
85-
stringResource(R.string.wallet__tags_add),
86-
onClick = {}, //TODO IMPLEMENT
105+
text = stringResource(R.string.wallet__tags_add),
106+
size = ButtonSize.Small,
107+
onClick = { onClickAddTag() },
87108
icon = {
88109
Icon(
89110
painter = painterResource(R.drawable.ic_tag),
@@ -301,6 +322,7 @@ private fun SendAndReviewPreview() {
301322
),
302323
onBack = {},
303324
onEvent = {},
325+
onClickAddTag = {},
304326
)
305327
}
306328
}
@@ -330,6 +352,7 @@ private fun SendAndReviewPreview2() {
330352
),
331353
onBack = {},
332354
onEvent = {},
355+
onClickAddTag = {},
333356
)
334357
}
335358
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ fun SendOptionsView(
106106
uiState = uiState,
107107
onBack = { navController.popBackStack() },
108108
onEvent = { appViewModel.setSendEvent(it) },
109+
onClickAddTag = { navController.navigate(SendRoute.AddTag) }
110+
)
111+
}
112+
composable<SendRoute.AddTag> {
113+
AddTagScreen(
114+
onBack = { navController.popBackStack() },
115+
onTagSelected = { tag ->
116+
appViewModel.addTagToSelected(tag)
117+
navController.popBackStack()
118+
},
109119
)
110120
}
111121
}
@@ -228,4 +238,7 @@ interface SendRoute {
228238

229239
@Serializable
230240
data object ReviewAndSend : SendRoute
241+
242+
@Serializable
243+
data object AddTag : SendRoute
231244
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ class AppViewModel @Inject constructor(
9696
}
9797
}
9898

99+
fun addTagToSelected(newTag: String) {
100+
_sendUiState.update {
101+
it.copy(
102+
selectedTags = (it.selectedTags + newTag).distinct()
103+
)
104+
}
105+
}
106+
99107
private var scan: Scanner? = null
100108

101109
init {
@@ -641,6 +649,7 @@ data class SendUiState(
641649
val description: String = "",
642650
val isUnified: Boolean = false,
643651
val payMethod: SendMethod = SendMethod.ONCHAIN,
652+
val selectedTags: List<String> = listOf(), //TODO save tags in other PR
644653
val decodedInvoice: LightningInvoice? = null,
645654
)
646655

0 commit comments

Comments
 (0)