Skip to content

Commit 11a4e02

Browse files
authored
Merge pull request #166 from synonymdev/feat/settings-general-2
Settings General - Widgets & Tags
2 parents df98c25 + 13fa62e commit 11a4e02

File tree

17 files changed

+199
-63
lines changed

17 files changed

+199
-63
lines changed

app/src/main/java/to/bitkit/data/SettingsStore.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ class SettingsStore @Inject constructor(
3030
store.updateData(transform)
3131
}
3232

33+
suspend fun addLastUsedTag(newTag: String) {
34+
store.updateData { currentSettings ->
35+
val combinedTags = (listOf(newTag) + currentSettings.lastUsedTags).distinct()
36+
val limitedTags = combinedTags.take(10)
37+
currentSettings.copy(lastUsedTags = limitedTags)
38+
}
39+
}
40+
41+
suspend fun deleteLastUsedTag(tag: String) {
42+
store.updateData {
43+
it.copy(lastUsedTags = it.lastUsedTags.filter { it != tag })
44+
}
45+
}
46+
3347
suspend fun reset() {
3448
store.updateData { SettingsData() }
3549
Logger.info("Deleted all user settings data.")
@@ -56,4 +70,7 @@ data class SettingsData(
5670
val isPinOnIdleEnabled: Boolean = false,
5771
val isPinForPaymentsEnabled: Boolean = false,
5872
val isDevModeEnabled: Boolean = false,
73+
val showWidgets: Boolean = false,
74+
val showWidgetTitles: Boolean = false,
75+
val lastUsedTags: List<String> = emptyList(),
5976
)

app/src/main/java/to/bitkit/repositories/WalletRepo.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,13 @@ class WalletRepo @Inject constructor(
298298
return@withContext Result.success(Unit)
299299
}
300300

301-
fun addTagToSelected(newTag: String) {
301+
suspend fun addTagToSelected(newTag: String) {
302302
_walletState.update {
303303
it.copy(
304304
selectedTags = (it.selectedTags + newTag).distinct()
305305
)
306306
}
307+
settingsStore.addLastUsedTag(newTag)
307308
}
308309

309310
fun removeTag(tag: String) {

app/src/main/java/to/bitkit/ui/components/Tag.kt

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@ package to.bitkit.ui.components
33
import androidx.compose.foundation.border
44
import androidx.compose.foundation.layout.Arrangement
55
import androidx.compose.foundation.layout.Column
6-
import androidx.compose.foundation.layout.ExperimentalLayoutApi
76
import androidx.compose.foundation.layout.Row
87
import androidx.compose.foundation.layout.padding
98
import androidx.compose.foundation.layout.size
109
import androidx.compose.foundation.layout.wrapContentWidth
1110
import androidx.compose.material3.Icon
1211
import androidx.compose.material3.MaterialTheme
13-
import androidx.compose.material3.Text
1412
import androidx.compose.runtime.Composable
1513
import androidx.compose.ui.Alignment
1614
import androidx.compose.ui.Modifier
15+
import androidx.compose.ui.graphics.painter.Painter
1716
import androidx.compose.ui.res.painterResource
18-
import androidx.compose.ui.text.font.FontWeight
1917
import androidx.compose.ui.tooling.preview.Preview
2018
import androidx.compose.ui.unit.dp
2119
import to.bitkit.R
@@ -27,10 +25,11 @@ import to.bitkit.ui.theme.Colors
2725
@Composable
2826
fun TagButton(
2927
text: String,
30-
isSelected: Boolean = false,
31-
displayIconClose: Boolean = false,
3228
onClick: () -> Unit,
3329
modifier: Modifier = Modifier,
30+
isSelected: Boolean = false,
31+
displayIconClose: Boolean = false,
32+
icon: Painter = painterResource(R.drawable.ic_x),
3433
) {
3534
val borderColor = if (isSelected) Colors.Brand else Colors.White16
3635
val textColor = if (isSelected) Colors.Brand else MaterialTheme.colorScheme.onSurface
@@ -44,15 +43,14 @@ fun TagButton(
4443
.clickableAlpha { onClick() }
4544
.padding(horizontal = 12.dp, vertical = 8.dp)
4645
) {
47-
Text(
46+
BodySSB(
4847
text = text,
4948
color = textColor,
50-
fontWeight = FontWeight.Medium,
5149
)
5250

5351
if (displayIconClose) {
5452
Icon(
55-
painter = painterResource(R.drawable.ic_x),
53+
painter = icon,
5654
contentDescription = null,
5755
tint = Colors.White64,
5856
modifier = Modifier.size(16.dp)
@@ -61,17 +59,16 @@ fun TagButton(
6159
}
6260
}
6361

64-
65-
@OptIn(ExperimentalLayoutApi::class)
6662
@Preview
6763
@Composable
6864
private fun Preview() {
6965
AppThemeSurface {
7066
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
71-
TagButton("Selected", isSelected = true, onClick = {})
72-
TagButton("Not Selected", isSelected = false, onClick = {})
73-
TagButton("Selected With icon close", displayIconClose = true, isSelected = true, onClick = {})
74-
TagButton("Not Selected With icon close", displayIconClose = true, isSelected = false, onClick = {})
67+
TagButton("Selected", onClick = {}, isSelected = true)
68+
TagButton("Not Selected", onClick = {})
69+
TagButton("Selected With icon close", onClick = {}, isSelected = true, displayIconClose = true)
70+
TagButton("Not Selected With icon close", onClick = {}, displayIconClose = true)
71+
TagButton("Icon trash", onClick = {}, displayIconClose = true, icon = painterResource(R.drawable.ic_trash))
7572
}
7673
}
7774
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ private fun TagSelectorSheetContent(
8585
availableTags.forEach { tag ->
8686
TagButton(
8787
text = tag,
88-
isSelected = selectedTags.contains(tag),
89-
onClick = { onTagClick(tag) }
88+
onClick = { onTagClick(tag) },
89+
isSelected = selectedTags.contains(tag)
9090
)
9191
}
9292
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import androidx.compose.material3.rememberModalBottomSheetState
99
import androidx.compose.runtime.Composable
1010
import androidx.compose.runtime.DisposableEffect
1111
import androidx.compose.runtime.LaunchedEffect
12-
import androidx.compose.runtime.collectAsState
1312
import androidx.compose.runtime.getValue
1413
import androidx.compose.ui.Modifier
1514
import androidx.compose.ui.unit.dp
1615
import androidx.hilt.navigation.compose.hiltViewModel
16+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1717
import to.bitkit.ui.components.ModalBottomSheetHandle
1818
import to.bitkit.ui.screens.wallets.send.AddTagContent
1919
import to.bitkit.ui.shared.util.gradientBackground
@@ -32,7 +32,7 @@ fun ActivityAddTagSheet(
3232
onDismiss: () -> Unit,
3333
) {
3434
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
35-
val uiState by tagsViewModel.uiState.collectAsState()
35+
val uiState by tagsViewModel.uiState.collectAsStateWithLifecycle()
3636

3737
LaunchedEffect(Unit) {
3838
tagsViewModel.loadTagSuggestions()

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ fun EditInvoiceScreen(
9393
val receiveSats = satsString.toULongOrNull()
9494
updateInvoice(receiveSats)
9595

96-
9796
if (receiveSats == null) {
9897
onBack()
9998
return@collect
@@ -328,7 +327,6 @@ fun EditInvoiceContent(
328327
tags.map { tagText ->
329328
TagButton(
330329
text = tagText,
331-
isSelected = false,
332330
displayIconClose = true,
333331
onClick = { onClickTag(tagText) },
334332
)

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ import androidx.compose.material3.Text
1616
import androidx.compose.material3.TextField
1717
import androidx.compose.runtime.Composable
1818
import androidx.compose.runtime.LaunchedEffect
19-
import androidx.compose.runtime.collectAsState
2019
import androidx.compose.runtime.getValue
2120
import androidx.compose.ui.Modifier
2221
import androidx.compose.ui.res.stringResource
2322
import androidx.compose.ui.text.input.ImeAction
2423
import androidx.compose.ui.tooling.preview.Preview
2524
import androidx.compose.ui.unit.dp
2625
import androidx.hilt.navigation.compose.hiltViewModel
26+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
2727
import to.bitkit.R
2828
import to.bitkit.ui.components.Caption13Up
2929
import to.bitkit.ui.components.PrimaryButton
@@ -43,7 +43,7 @@ fun AddTagScreen(
4343
onBack: () -> Unit,
4444
onTagSelected: (String) -> Unit,
4545
) {
46-
val uiState: AddTagUiState by viewModel.uiState.collectAsState()
46+
val uiState: AddTagUiState by viewModel.uiState.collectAsStateWithLifecycle()
4747

4848
LaunchedEffect(Unit) {
4949
viewModel.loadTagSuggestions()
@@ -99,7 +99,6 @@ fun AddTagContent(
9999
uiState.tagsSuggestions.map { tagText ->
100100
TagButton(
101101
tagText,
102-
isSelected = false,
103102
onClick = { onTagSelected(tagText) },
104103
)
105104
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ private fun SendAndReviewContent(
178178
uiState.selectedTags.map { tagText ->
179179
TagButton(
180180
text = tagText,
181-
isSelected = false,
182181
displayIconClose = true,
183182
onClick = { onClickTag(tagText) },
184183
)

app/src/main/java/to/bitkit/ui/settings/general/GeneralSettingsScreen.kt

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.padding
55
import androidx.compose.foundation.rememberScrollState
66
import androidx.compose.foundation.verticalScroll
77
import androidx.compose.runtime.Composable
8+
import androidx.compose.runtime.getValue
89
import androidx.compose.ui.Modifier
910
import androidx.compose.ui.res.stringResource
1011
import androidx.compose.ui.tooling.preview.Preview
@@ -15,7 +16,6 @@ import to.bitkit.R
1516
import to.bitkit.models.PrimaryDisplay
1617
import to.bitkit.models.TransactionSpeed
1718
import to.bitkit.ui.LocalCurrencies
18-
import to.bitkit.ui.appViewModel
1919
import to.bitkit.ui.components.settings.SettingsButtonRow
2020
import to.bitkit.ui.components.settings.SettingsButtonValue
2121
import to.bitkit.ui.navigateToDefaultUnitSettings
@@ -38,12 +38,14 @@ fun GeneralSettingsScreen(
3838
) {
3939
val settings = settingsViewModel ?: return
4040
val currencies = LocalCurrencies.current
41-
val defaultTransactionSpeed = settings.defaultTransactionSpeed.collectAsStateWithLifecycle()
41+
val defaultTransactionSpeed by settings.defaultTransactionSpeed.collectAsStateWithLifecycle()
42+
val lastUsedTags by settings.lastUsedTags.collectAsStateWithLifecycle()
4243

4344
GeneralSettingsContent(
4445
selectedCurrency = currencies.selectedCurrency,
4546
primaryDisplay = currencies.primaryDisplay,
46-
defaultTransactionSpeed = defaultTransactionSpeed.value,
47+
defaultTransactionSpeed = defaultTransactionSpeed,
48+
showTagsButton = lastUsedTags.isNotEmpty(),
4749
onBackClick = { navController.popBackStack() },
4850
onCloseClick = { navController.navigateToHome() },
4951
onLocalCurrencyClick = { navController.navigateToLocalCurrencySettings() },
@@ -60,6 +62,7 @@ private fun GeneralSettingsContent(
6062
selectedCurrency: String,
6163
primaryDisplay: PrimaryDisplay,
6264
defaultTransactionSpeed: TransactionSpeed,
65+
showTagsButton: Boolean = false,
6366
onBackClick: () -> Unit = {},
6467
onCloseClick: () -> Unit = {},
6568
onLocalCurrencyClick: () -> Unit = {},
@@ -108,10 +111,12 @@ private fun GeneralSettingsContent(
108111
title = stringResource(R.string.settings__quickpay__nav_title),
109112
onClick = onQuickPayClick,
110113
)
111-
SettingsButtonRow(
112-
title = stringResource(R.string.settings__general__tags),
113-
onClick = onTagsClick,
114-
)
114+
if (showTagsButton) {
115+
SettingsButtonRow(
116+
title = stringResource(R.string.settings__general__tags),
117+
onClick = onTagsClick,
118+
)
119+
}
115120
}
116121
}
117122
}
@@ -124,6 +129,7 @@ private fun Preview() {
124129
selectedCurrency = "USD",
125130
primaryDisplay = PrimaryDisplay.BITCOIN,
126131
defaultTransactionSpeed = TransactionSpeed.Medium,
132+
showTagsButton = true,
127133
)
128134
}
129135
}
Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,54 @@
11
package to.bitkit.ui.settings.general
22

3-
import androidx.compose.foundation.layout.Box
4-
import androidx.compose.foundation.layout.fillMaxSize
5-
import androidx.compose.material3.Text
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.FlowRow
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.padding
68
import androidx.compose.runtime.Composable
7-
import androidx.compose.ui.Alignment
9+
import androidx.compose.runtime.getValue
810
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.res.painterResource
912
import androidx.compose.ui.res.stringResource
1013
import androidx.compose.ui.tooling.preview.Preview
14+
import androidx.compose.ui.unit.dp
15+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1116
import androidx.navigation.NavController
1217
import to.bitkit.R
18+
import to.bitkit.ui.components.TagButton
19+
import to.bitkit.ui.components.settings.SectionHeader
1320
import to.bitkit.ui.navigateToHome
1421
import to.bitkit.ui.scaffold.AppTopBar
1522
import to.bitkit.ui.scaffold.CloseNavIcon
1623
import to.bitkit.ui.scaffold.ScreenColumn
24+
import to.bitkit.ui.settingsViewModel
1725
import to.bitkit.ui.theme.AppThemeSurface
1826

1927
@Composable
2028
fun TagsSettingsScreen(
2129
navController: NavController,
2230
) {
31+
val settings = settingsViewModel ?: return
32+
33+
val tags by settings.lastUsedTags.collectAsStateWithLifecycle()
34+
2335
TagsSettingsContent(
36+
tags = tags,
37+
onClickTag = { tag ->
38+
settings.deleteLastUsedTag(tag)
39+
if (tags.size == 1) {
40+
navController.popBackStack()
41+
}
42+
},
2443
onBackClick = { navController.popBackStack() },
2544
onCloseClick = { navController.navigateToHome() },
2645
)
2746
}
2847

2948
@Composable
3049
private fun TagsSettingsContent(
50+
tags: List<String>,
51+
onClickTag: (String) -> Unit = {},
3152
onBackClick: () -> Unit = {},
3253
onCloseClick: () -> Unit = {},
3354
) {
@@ -37,8 +58,28 @@ private fun TagsSettingsContent(
3758
onBackClick = onBackClick,
3859
actions = { CloseNavIcon(onCloseClick) },
3960
)
40-
Box(modifier = Modifier.fillMaxSize()) {
41-
Text("TODO: Tags Settings Screen", modifier = Modifier.align(Alignment.Center))
61+
Column(
62+
modifier = Modifier.padding(horizontal = 16.dp),
63+
) {
64+
tags.takeIf { it.isNotEmpty() }?.let {
65+
SectionHeader(stringResource(R.string.settings__general__tags_previously))
66+
67+
FlowRow(
68+
horizontalArrangement = Arrangement.spacedBy(8.dp),
69+
verticalArrangement = Arrangement.spacedBy(8.dp),
70+
modifier = Modifier
71+
.fillMaxWidth()
72+
) {
73+
tags.map { tagText ->
74+
TagButton(
75+
text = tagText,
76+
onClick = { onClickTag(tagText) },
77+
displayIconClose = true,
78+
icon = painterResource(R.drawable.ic_trash),
79+
)
80+
}
81+
}
82+
}
4283
}
4384
}
4485
}
@@ -47,6 +88,8 @@ private fun TagsSettingsContent(
4788
@Composable
4889
private fun Preview() {
4990
AppThemeSurface {
50-
TagsSettingsContent()
91+
TagsSettingsContent(
92+
tags = listOf("tag1", "tag2", "tag3"),
93+
)
5194
}
5295
}

0 commit comments

Comments
 (0)