Skip to content

Commit 7e3961a

Browse files
authored
Merge pull request #182 from synonymdev/feat/restore-settings-screen
feat: Reset and Restore settings
2 parents 135509f + 453f347 commit 7e3961a

File tree

23 files changed

+342
-188
lines changed

23 files changed

+342
-188
lines changed

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

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,23 @@ import android.content.Context
44
import android.content.SharedPreferences
55
import androidx.core.content.edit
66
import dagger.hilt.android.qualifiers.ApplicationContext
7-
import kotlinx.coroutines.flow.Flow
8-
import kotlinx.coroutines.flow.MutableStateFlow
9-
import kotlinx.coroutines.flow.asStateFlow
107
import to.bitkit.di.json
118
import to.bitkit.models.BalanceState
12-
import to.bitkit.models.Suggestion
139
import to.bitkit.utils.Logger
1410
import javax.inject.Inject
1511
import javax.inject.Singleton
1612
import kotlin.reflect.KProperty
1713

1814
const val APP_PREFS = "bitkit_prefs"
1915

20-
// TODO use dataStore
16+
// TODO refactor to dataStore (named 'CacheStore'?!)
2117
@Singleton
2218
class AppStorage @Inject constructor(
2319
@ApplicationContext private val appContext: Context,
2420
) {
2521
val sharedPreferences: SharedPreferences
2622
get() = appContext.getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE)
2723

28-
private val _removedSuggestionsFlow = MutableStateFlow<List<String>>(emptyList())
29-
val removedSuggestionsFlow: Flow<List<String>> = _removedSuggestionsFlow.asStateFlow()
30-
31-
init {
32-
_removedSuggestionsFlow.value = getRemovedSuggestionList()
33-
}
34-
3524
var onchainAddress: String by SharedPrefDelegate(Key.ONCHAIN_ADDRESS)
3625
var bolt11: String by SharedPrefDelegate(Key.BOLT11)
3726
var bip21: String by SharedPrefDelegate(Key.BIP21)
@@ -57,34 +46,15 @@ class AppStorage @Inject constructor(
5746
}
5847
}
5948

60-
fun addSuggestionToRemovedList(suggestion: Suggestion) {
61-
val removedSuggestions =
62-
sharedPreferences.getStringSet(Key.REMOVED_SUGGESTION.name, setOf<String>()).orEmpty().toMutableList()
63-
if (removedSuggestions.contains(suggestion.name)) return
64-
65-
removedSuggestions.add(suggestion.name)
66-
67-
sharedPreferences.edit {
68-
putStringSet(Key.REMOVED_SUGGESTION.name, removedSuggestions.toSet())
69-
}
70-
71-
_removedSuggestionsFlow.value = removedSuggestions
72-
}
73-
74-
private fun getRemovedSuggestionList() =
75-
sharedPreferences.getStringSet(Key.REMOVED_SUGGESTION.name, setOf<String>()).orEmpty().toList()
76-
7749
enum class Key {
7850
ONCHAIN_ADDRESS,
7951
BOLT11,
8052
BIP21,
8153
BALANCE,
82-
REMOVED_SUGGESTION
8354
}
8455

8556
fun clear() {
8657
sharedPreferences.edit { clear() }
87-
_removedSuggestionsFlow.value = emptyList()
8858
}
8959
}
9060

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import kotlinx.serialization.Serializable
1010
import to.bitkit.data.serializers.SettingsSerializer
1111
import to.bitkit.models.BitcoinDisplayUnit
1212
import to.bitkit.models.PrimaryDisplay
13+
import to.bitkit.models.Suggestion
1314
import to.bitkit.models.TransactionSpeed
1415
import to.bitkit.utils.Logger
1516
import javax.inject.Inject
@@ -44,6 +45,13 @@ class SettingsStore @Inject constructor(
4445
}
4546
}
4647

48+
suspend fun addDismissedSuggestion(suggestion: Suggestion) {
49+
store.updateData { currentSettings ->
50+
val updatedDismissedSuggestions = (currentSettings.dismissedSuggestions + suggestion.name).distinct()
51+
currentSettings.copy(dismissedSuggestions = updatedDismissedSuggestions)
52+
}
53+
}
54+
4755
suspend fun reset() {
4856
store.updateData { SettingsData() }
4957
Logger.info("Deleted all user settings data.")
@@ -82,4 +90,5 @@ data class SettingsData(
8290
val enableAutoReadClipboard: Boolean = false,
8391
val enableSendAmountWarning: Boolean = false,
8492
val backupVerified: Boolean = false,
93+
val dismissedSuggestions: List<String> = emptyList(),
8594
)

app/src/main/java/to/bitkit/data/serializers/SettingsSerializer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object SettingsSerializer : Serializer<SettingsData> {
1515
return try {
1616
json.decodeFromString(input.readBytes().decodeToString())
1717
} catch (e: SerializationException) {
18-
Logger.error("Failed to deserialize settings: $e")
18+
Logger.error("Failed to deserialize: $e")
1919
defaultValue
2020
}
2121
}

app/src/main/java/to/bitkit/data/serializers/WidgetsSerializer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object WidgetsSerializer : Serializer<WidgetsData> {
1616
return try {
1717
json.decodeFromString(input.readBytes().decodeToString())
1818
} catch (e: SerializationException) {
19-
Logger.error("Failed to deserialize settings: $e")
19+
Logger.error("Failed to deserialize: $e")
2020
defaultValue
2121
}
2222
}

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import kotlinx.coroutines.withContext
1010
import kotlinx.datetime.Clock
1111
import org.lightningdevkit.ldknode.BalanceDetails
1212
import org.lightningdevkit.ldknode.Event
13-
import org.lightningdevkit.ldknode.Network
1413
import org.lightningdevkit.ldknode.Txid
1514
import to.bitkit.data.AppDb
1615
import to.bitkit.data.AppStorage
@@ -47,7 +46,6 @@ class WalletRepo @Inject constructor(
4746
private val settingsStore: SettingsStore,
4847
private val addressChecker: AddressChecker,
4948
private val lightningRepo: LightningRepo,
50-
private val network: Network
5149
) {
5250

5351
private val _walletState = MutableStateFlow(
@@ -198,10 +196,6 @@ class WalletRepo @Inject constructor(
198196
}
199197

200198
suspend fun wipeWallet(walletIndex: Int = 0): Result<Unit> = withContext(bgDispatcher) {
201-
if (network != Network.REGTEST) {
202-
return@withContext Result.failure(Exception("Can only wipe on regtest."))
203-
}
204-
205199
try { //TODO CLEAN ACTIVITY'S AND UPDATE STATE. CHECK ActivityListViewModel.removeAllActivities
206200
keychain.wipe()
207201
appStorage.clear()

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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import androidx.navigation.compose.NavHost
2525
import androidx.navigation.compose.composable
2626
import androidx.navigation.compose.navigation
2727
import androidx.navigation.compose.rememberNavController
28-
import androidx.navigation.navOptions
2928
import androidx.navigation.toRoute
3029
import kotlinx.coroutines.CoroutineScope
3130
import kotlinx.coroutines.delay
@@ -99,7 +98,7 @@ import to.bitkit.ui.settings.SecuritySettingsScreen
9998
import to.bitkit.ui.settings.SettingsScreen
10099
import to.bitkit.ui.settings.backups.BackupNavigationSheet
101100
import to.bitkit.ui.settings.backups.BackupSheet
102-
import to.bitkit.ui.settings.backups.RestoreWalletScreen
101+
import to.bitkit.ui.settings.backups.ResetAndRestoreScreen
103102
import to.bitkit.ui.settings.general.DefaultUnitSettingsScreen
104103
import to.bitkit.ui.settings.general.GeneralSettingsScreen
105104
import to.bitkit.ui.settings.general.LocalCurrencySettingsScreen
@@ -379,7 +378,7 @@ private fun RootNavHost(
379378
defaultUnitSettings(currencyViewModel, navController)
380379
localCurrencySettings(currencyViewModel, navController)
381380
backupSettings(navController)
382-
restoreWalletSettings(navController)
381+
resetAndRestoreSettings(navController)
383382
channelOrdersSettings(navController)
384383
orderDetailSettings(navController)
385384
cjitDetailSettings(navController)
@@ -780,11 +779,11 @@ private fun NavGraphBuilder.backupSettings(
780779
}
781780
}
782781

783-
private fun NavGraphBuilder.restoreWalletSettings(
782+
private fun NavGraphBuilder.resetAndRestoreSettings(
784783
navController: NavHostController,
785784
) {
786-
composableWithDefaultTransitions<Routes.RestoreWalletSettings> {
787-
RestoreWalletScreen(navController)
785+
composableWithDefaultTransitions<Routes.ResetAndRestoreSettings> {
786+
ResetAndRestoreScreen(navController)
788787
}
789788
}
790789

@@ -1082,10 +1081,15 @@ private fun NavGraphBuilder.widgets(
10821081
// endregion
10831082

10841083
// region events
1085-
fun NavController.navigateToHome() = navigate(
1086-
route = Routes.Home,
1087-
navOptions = navOptions { popUpTo(Routes.Home) }
1088-
)
1084+
fun NavController.navigateToHome() {
1085+
val popped = popBackStack<Routes.Home>(inclusive = false)
1086+
if (!popped) {
1087+
navigate(Routes.Home) {
1088+
popUpTo(graph.startDestinationId)
1089+
launchSingleTop = true
1090+
}
1091+
}
1092+
}
10891093

10901094
fun NavController.navigateToSettings() = navigate(
10911095
route = Routes.Settings,
@@ -1151,10 +1155,6 @@ fun NavController.navigateToBackupSettings() = navigate(
11511155
route = Routes.BackupSettings,
11521156
)
11531157

1154-
fun NavController.navigateToRestoreWalletSettings() = navigate(
1155-
route = Routes.RestoreWalletSettings,
1156-
)
1157-
11581158
fun NavController.navigateToChannelOrdersSettings() = navigate(
11591159
route = Routes.ChannelOrdersSettings,
11601160
)
@@ -1319,7 +1319,7 @@ object Routes {
13191319
data object BackupSettings
13201320

13211321
@Serializable
1322-
data object RestoreWalletSettings
1322+
data object ResetAndRestoreSettings
13231323

13241324
@Serializable
13251325
data object ChannelOrdersSettings

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ val LocalSettingsViewModel = staticCompositionLocalOf<SettingsViewModel?> { null
2828

2929
val appViewModel: AppViewModel?
3030
@Composable get() = LocalAppViewModel.current
31-
@Deprecated("Prefer inject the repositories in a specific viewmodel so you don't need to handle a nullable viewmodel")
31+
3232
val walletViewModel: WalletViewModel?
3333
@Composable get() = LocalWalletViewModel.current
3434

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,14 @@ class MainActivity : FragmentActivity() {
220220
if (showForgotPinSheet) {
221221
ForgotPinSheet(
222222
onDismiss = { appViewModel.setShowForgotPin(false) },
223-
onResetClick = { walletViewModel.wipeStorage() },
223+
onResetClick = { walletViewModel.wipeWallet() },
224224
)
225225
}
226226

227227
LaunchedEffect(appViewModel) {
228228
appViewModel.mainScreenEffect.collect {
229229
when (it) {
230-
MainScreenEffect.WipeStorage -> walletViewModel.wipeStorage()
230+
MainScreenEffect.WipeWallet -> walletViewModel.wipeWallet()
231231
else -> Unit
232232
}
233233
}

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.getValue
55
import androidx.lifecycle.compose.collectAsStateWithLifecycle
66
import androidx.navigation.NavController
7+
import androidx.navigation.navOptions
78
import to.bitkit.ui.Routes
89
import to.bitkit.ui.appViewModel
910
import to.bitkit.ui.settingsViewModel
@@ -31,26 +32,36 @@ fun AuthCheckScreen(
3132
when (route.onSuccessActionId) {
3233
AuthCheckAction.TOGGLE_BIOMETRICS -> {
3334
settings.setIsBiometricEnabled(!isBiometricEnabled)
35+
navController.popBackStack()
3436
}
3537

3638
AuthCheckAction.TOGGLE_PIN_ON_LAUNCH -> {
3739
settings.setIsPinOnLaunchEnabled(!isPinOnLaunchEnabled)
40+
navController.popBackStack()
3841
}
3942

4043
AuthCheckAction.TOGGLE_PIN_ON_IDLE -> {
4144
settings.setIsPinOnIdleEnabled(!isPinOnIdleEnabled)
45+
navController.popBackStack()
4246
}
4347

4448
AuthCheckAction.TOGGLE_PIN_FOR_PAYMENTS -> {
4549
settings.setIsPinForPaymentsEnabled(!isPinForPaymentsEnabled)
50+
navController.popBackStack()
4651
}
4752

4853
AuthCheckAction.DISABLE_PIN -> {
4954
app.removePin()
55+
navController.popBackStack()
5056
}
51-
}
5257

53-
navController.popBackStack()
58+
AuthCheckAction.NAV_TO_RESET -> {
59+
navController.navigate(
60+
route = Routes.ResetAndRestoreSettings,
61+
navOptions = navOptions { popUpTo(Routes.BackupSettings) }
62+
)
63+
}
64+
}
5465
},
5566
onBack = { navController.popBackStack() },
5667
)
@@ -62,4 +73,5 @@ object AuthCheckAction {
6273
const val TOGGLE_PIN_ON_IDLE = "TOGGLE_PIN_ON_IDLE"
6374
const val TOGGLE_PIN_FOR_PAYMENTS = "TOGGLE_PIN_FOR_PAYMENTS"
6475
const val DISABLE_PIN = "DISABLE_PIN"
76+
const val NAV_TO_RESET = "NAV_TO_RESET"
6577
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package to.bitkit.ui.components
22

3+
import androidx.activity.compose.BackHandler
34
import androidx.compose.animation.core.animateFloatAsState
45
import androidx.compose.animation.core.tween
56
import androidx.compose.foundation.background
@@ -88,6 +89,15 @@ fun SheetHost(
8889
) {
8990
content()
9091

92+
// Dismiss on back
93+
BackHandler(enabled = scaffoldState.bottomSheetState.isVisible) {
94+
println("SheetHost: BackHandler - trigger")
95+
scope.launch {
96+
scaffoldState.bottomSheetState.hide()
97+
onDismiss()
98+
}
99+
}
100+
91101
Scrim(scaffoldState.bottomSheetState) {
92102
scope.launch {
93103
scaffoldState.bottomSheetState.hide()

0 commit comments

Comments
 (0)