Skip to content

Commit 405dd52

Browse files
committed
feat: fee settings screen
1 parent 3221132 commit 405dd52

File tree

4 files changed

+148
-2
lines changed

4 files changed

+148
-2
lines changed

app/src/main/java/to/bitkit/ui/ContentView.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import to.bitkit.ui.onboarding.InitializingWalletView
4040
import to.bitkit.ui.onboarding.WalletInitResult
4141
import to.bitkit.ui.onboarding.WalletInitResultView
4242
import to.bitkit.ui.screens.settings.DevSettingsScreen
43+
import to.bitkit.ui.screens.settings.FeeSettingsScreen
4344
import to.bitkit.ui.screens.profile.CreateProfileScreen
4445
import to.bitkit.ui.screens.profile.ProfileIntroScreen
4546
import to.bitkit.ui.screens.scanner.QrScanningScreen
@@ -674,6 +675,9 @@ private fun NavGraphBuilder.settings(
674675
composableWithDefaultTransitions<Routes.DevSettings> {
675676
DevSettingsScreen(navController)
676677
}
678+
composableWithDefaultTransitions<Routes.FeeSettings> {
679+
FeeSettingsScreen(navController)
680+
}
677681
composableWithDefaultTransitions<Routes.RegtestSettings> {
678682
BlocktankRegtestScreen(navController)
679683
}
@@ -1475,6 +1479,9 @@ sealed interface Routes {
14751479
@Serializable
14761480
data object DevSettings : Routes
14771481

1482+
@Serializable
1483+
data object FeeSettings : Routes
1484+
14781485
@Serializable
14791486
data object RegtestSettings : Routes
14801487

app/src/main/java/to/bitkit/ui/screens/settings/DevSettingsScreen.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,17 @@ fun DevSettingsScreen(
5050
.padding(horizontal = 16.dp)
5151
.verticalScroll(rememberScrollState())
5252
) {
53+
SettingsButtonRow("Fee Settings") { navController.navigate(Routes.FeeSettings) }
54+
SettingsButtonRow("Channel Orders") { navController.navigate(Routes.ChannelOrdersSettings) }
55+
56+
SectionHeader("LOGS")
57+
SettingsButtonRow("Logs") { navController.navigate(Routes.Logs) }
5358
SettingsTextButtonRow(
5459
title = "Export Logs",
5560
onClick = {
5661
viewModel.zipLogsForSharing { uri -> context.shareZipFile(uri) }
5762
}
5863
)
59-
SettingsButtonRow("Logs") { navController.navigate(Routes.Logs) }
60-
SettingsButtonRow("Channel Orders") { navController.navigate(Routes.ChannelOrdersSettings) }
6164

6265
if (Env.network == Network.REGTEST) {
6366
SectionHeader("REGTEST")
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package to.bitkit.ui.screens.settings
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.padding
5+
import androidx.compose.foundation.rememberScrollState
6+
import androidx.compose.foundation.verticalScroll
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.runtime.LaunchedEffect
9+
import androidx.compose.runtime.getValue
10+
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.res.stringResource
12+
import androidx.compose.ui.tooling.preview.Preview
13+
import androidx.compose.ui.unit.dp
14+
import androidx.hilt.navigation.compose.hiltViewModel
15+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
16+
import androidx.navigation.NavController
17+
import com.synonym.bitkitcore.FeeRates
18+
import to.bitkit.R
19+
import to.bitkit.ui.components.settings.SectionHeader
20+
import to.bitkit.ui.components.settings.SettingsTextButtonRow
21+
import to.bitkit.ui.navigateToHome
22+
import to.bitkit.ui.scaffold.AppTopBar
23+
import to.bitkit.ui.scaffold.CloseNavIcon
24+
import to.bitkit.ui.scaffold.ScreenColumn
25+
import to.bitkit.ui.theme.AppThemeSurface
26+
import to.bitkit.viewmodels.FeeSettingsUiState
27+
import to.bitkit.viewmodels.FeeSettingsViewModel
28+
29+
@Composable
30+
fun FeeSettingsScreen(
31+
navController: NavController,
32+
viewModel: FeeSettingsViewModel = hiltViewModel(),
33+
) {
34+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
35+
36+
LaunchedEffect(Unit) {
37+
viewModel.refreshFeeRates()
38+
}
39+
40+
Content(
41+
uiState = uiState,
42+
onBack = { navController.popBackStack() },
43+
onClose = { navController.navigateToHome() },
44+
)
45+
}
46+
47+
@Composable
48+
private fun Content(
49+
uiState: FeeSettingsUiState,
50+
onBack: () -> Unit = {},
51+
onClose: () -> Unit = {},
52+
) {
53+
ScreenColumn {
54+
AppTopBar(
55+
titleText = "Fee Settings",
56+
onBackClick = onBack,
57+
actions = { CloseNavIcon(onClick = onClose) },
58+
)
59+
60+
Column(
61+
modifier = Modifier
62+
.padding(horizontal = 16.dp)
63+
.verticalScroll(rememberScrollState())
64+
) {
65+
uiState.feeRates?.let { rates ->
66+
SectionHeader("FEE RATES")
67+
68+
SettingsTextButtonRow(
69+
title = stringResource(R.string.fee__minimum__title),
70+
value = "${rates.slow}",
71+
)
72+
SettingsTextButtonRow(
73+
title = stringResource(R.string.fee__normal__title),
74+
value = "${rates.mid}",
75+
)
76+
SettingsTextButtonRow(
77+
title = stringResource(R.string.fee__fast__title),
78+
value = "${rates.fast}",
79+
)
80+
}
81+
}
82+
}
83+
}
84+
85+
@Preview(showSystemUi = true)
86+
@Composable
87+
private fun Preview() {
88+
AppThemeSurface {
89+
Content(
90+
uiState = FeeSettingsUiState(
91+
feeRates = FeeRates(fast = 10u, mid = 5u, slow = 2u)
92+
),
93+
)
94+
}
95+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package to.bitkit.viewmodels
2+
3+
import androidx.lifecycle.ViewModel
4+
import androidx.lifecycle.viewModelScope
5+
import com.synonym.bitkitcore.FeeRates
6+
import dagger.hilt.android.lifecycle.HiltViewModel
7+
import kotlinx.coroutines.flow.SharingStarted
8+
import kotlinx.coroutines.flow.StateFlow
9+
import kotlinx.coroutines.flow.map
10+
import kotlinx.coroutines.flow.stateIn
11+
import kotlinx.coroutines.launch
12+
import to.bitkit.repositories.BlocktankRepo
13+
import javax.inject.Inject
14+
15+
@HiltViewModel
16+
class FeeSettingsViewModel @Inject constructor(
17+
private val blocktankRepo: BlocktankRepo,
18+
) : ViewModel() {
19+
20+
val uiState: StateFlow<FeeSettingsUiState> = blocktankRepo.blocktankState
21+
.map { blocktankState ->
22+
FeeSettingsUiState(
23+
feeRates = blocktankState.info?.onchain?.feeRates,
24+
)
25+
}
26+
.stateIn(
27+
scope = viewModelScope,
28+
started = SharingStarted.WhileSubscribed(5000),
29+
initialValue = FeeSettingsUiState(),
30+
)
31+
32+
fun refreshFeeRates() {
33+
viewModelScope.launch {
34+
blocktankRepo.refreshInfo()
35+
}
36+
}
37+
}
38+
39+
data class FeeSettingsUiState(
40+
val feeRates: FeeRates? = null,
41+
)

0 commit comments

Comments
 (0)