Skip to content

Commit 912cdd2

Browse files
authored
Merge pull request #461 from synonymdev/feat/backup-polish
feat: polish backup & restore
2 parents 2ac0777 + 0573515 commit 912cdd2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2355
-1031
lines changed

app/build.gradle.kts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
2+
import io.gitlab.arturbosch.detekt.Detekt
13
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
24
import org.gradle.api.tasks.testing.logging.TestLogEvent
35
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag
@@ -34,6 +36,8 @@ val keystoreProperties by lazy {
3436
keystoreProperties
3537
}
3638

39+
val locales = listOf("en", "ar", "ca", "cs", "de", "el", "es", "fr", "it", "nl", "pl", "pt", "ru")
40+
3741
android {
3842
namespace = "to.bitkit"
3943
compileSdk = 35
@@ -49,6 +53,7 @@ android {
4953
}
5054
buildConfigField("boolean", "E2E", System.getenv("E2E")?.toBoolean()?.toString() ?: "false")
5155
buildConfigField("boolean", "GEO", System.getenv("GEO")?.toBoolean()?.toString() ?: "true")
56+
buildConfigField("String", "LOCALES", "\"${locales.joinToString(",")}\"")
5257
}
5358

5459
flavorDimensions += "network"
@@ -131,7 +136,7 @@ android {
131136
}
132137
androidResources {
133138
@Suppress("UnstableApiUsage")
134-
localeFilters.addAll(listOf("en", "ar", "ca", "cs", "de", "el", "es", "fr", "it", "nl", "pl", "pt", "ru"))
139+
localeFilters.addAll(locales)
135140
@Suppress("UnstableApiUsage")
136141
generateLocaleConfig = true
137142
}
@@ -153,7 +158,7 @@ android {
153158
applicationVariants.all {
154159
val variant = this
155160
outputs
156-
.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
161+
.map { it as BaseVariantOutputImpl }
157162
.forEach { output ->
158163
val apkName = "bitkit-android-${defaultConfig.versionCode}-${variant.name}.apk"
159164
output.outputFileName = apkName
@@ -169,17 +174,6 @@ composeCompiler {
169174
reportsDestination = layout.buildDirectory.dir("compose_compiler")
170175
}
171176

172-
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
173-
ignoreFailures = true
174-
reports {
175-
html.required.set(true)
176-
sarif.required.set(true)
177-
md.required.set(false)
178-
txt.required.set(false)
179-
xml.required.set(false)
180-
}
181-
}
182-
183177
dependencies {
184178
implementation(fileTree("libs") { include("*.aar") })
185179
implementation(libs.jna) { artifact { type = "aar" } }
@@ -281,6 +275,19 @@ room {
281275
schemaDirectory("$projectDir/schemas")
282276
}
283277

278+
// region Tasks
279+
280+
tasks.withType<Detekt>().configureEach {
281+
ignoreFailures = true
282+
reports {
283+
html.required.set(true)
284+
sarif.required.set(true)
285+
md.required.set(false)
286+
txt.required.set(false)
287+
xml.required.set(false)
288+
}
289+
}
290+
284291
tasks.withType<Test> {
285292
testLogging {
286293
events(
@@ -297,3 +304,12 @@ tasks.withType<Test> {
297304
showStackTraces = true
298305
}
299306
}
307+
308+
// JDK 21+ prints warnings when ByteBuddy loads a dynamic Java agent during tests.
309+
// Our test stack triggers this automatically.
310+
// Explicitly enabling dynamic agent loading silences the warning without altering behavior.
311+
tasks.withType<Test>().configureEach {
312+
jvmArgs("-XX:+EnableDynamicAgentLoading")
313+
}
314+
315+
// endregion

app/detekt-baseline.xml

Lines changed: 0 additions & 47 deletions
Large diffs are not rendered by default.

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import to.bitkit.env.Env
1111
import to.bitkit.models.BitcoinDisplayUnit
1212
import to.bitkit.models.CoinSelectionPreference
1313
import to.bitkit.models.PrimaryDisplay
14+
import to.bitkit.models.SettingsBackupV1
1415
import to.bitkit.models.Suggestion
1516
import to.bitkit.models.TransactionSpeed
1617
import to.bitkit.utils.Logger
@@ -30,6 +31,14 @@ class SettingsStore @Inject constructor(
3031

3132
val data: Flow<SettingsData> = store.data
3233

34+
suspend fun restoreFromBackup(payload: SettingsBackupV1) =
35+
runCatching {
36+
val data = payload.settings.resetPin()
37+
store.updateData { data }
38+
}.onSuccess {
39+
Logger.debug("Restored settings", TAG)
40+
}
41+
3342
suspend fun update(transform: (SettingsData) -> SettingsData) {
3443
store.updateData(transform)
3544
}
@@ -61,6 +70,7 @@ class SettingsStore @Inject constructor(
6170
}
6271

6372
companion object {
73+
private const val TAG = "SettingsStore"
6474
private const val MAX_LAST_USED_TAGS = 10
6575
}
6676
}

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import to.bitkit.data.dto.price.PriceDTO
1515
import to.bitkit.data.serializers.WidgetsSerializer
1616
import to.bitkit.models.WidgetType
1717
import to.bitkit.models.WidgetWithPosition
18+
import to.bitkit.models.WidgetsBackupV1
1819
import to.bitkit.models.widget.BlocksPreferences
1920
import to.bitkit.models.widget.CalculatorValues
2021
import to.bitkit.models.widget.FactsPreferences
@@ -43,9 +44,13 @@ class WidgetsStore @Inject constructor(
4344
val weatherFlow: Flow<WeatherDTO?> = data.map { it.weather }
4445
val priceFlow: Flow<PriceDTO?> = data.map { it.price }
4546

46-
suspend fun update(transform: (WidgetsData) -> WidgetsData) {
47-
store.updateData(transform)
48-
}
47+
suspend fun restoreFromBackup(payload: WidgetsBackupV1) =
48+
runCatching {
49+
val data = payload.widgets
50+
store.updateData { data }
51+
}.onSuccess {
52+
Logger.debug("Restored widgets", TAG)
53+
}
4954

5055
suspend fun updateCalculatorValues(calculatorValues: CalculatorValues) {
5156
store.updateData {
@@ -127,16 +132,16 @@ class WidgetsStore @Inject constructor(
127132
suspend fun addWidget(type: WidgetType) {
128133
if (store.data.first().widgets.map { it.type }.contains(type)) return
129134

130-
store.updateData {
131-
it.copy(widgets = (it.widgets + WidgetWithPosition(type = type)).sortedBy { it.position })
135+
store.updateData { data ->
136+
data.copy(widgets = (data.widgets + WidgetWithPosition(type = type)).sortedBy { it.position })
132137
}
133138
}
134139

135140
suspend fun deleteWidget(type: WidgetType) {
136141
if (!store.data.first().widgets.map { it.type }.contains(type)) return
137142

138-
store.updateData {
139-
it.copy(widgets = it.widgets.filterNot { it.type == type })
143+
store.updateData { data ->
144+
data.copy(widgets = data.widgets.filterNot { it.type == type })
140145
}
141146
}
142147

@@ -145,6 +150,10 @@ class WidgetsStore @Inject constructor(
145150
it.copy(widgets = widgets)
146151
}
147152
}
153+
154+
companion object {
155+
private const val TAG = "WidgetsStore"
156+
}
148157
}
149158

150159
@Serializable

app/src/main/java/to/bitkit/env/Env.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ internal object Env {
1818
const val isE2eTest = BuildConfig.E2E
1919
const val isGeoblockingEnabled = BuildConfig.GEO
2020
val network = Network.valueOf(BuildConfig.NETWORK)
21+
val locales = BuildConfig.LOCALES.split(",")
2122
val walletSyncIntervalSecs = 10_uL // TODO review
2223
val platform = "Android ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})"
2324
const val version = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})"
@@ -116,10 +117,10 @@ internal object Env {
116117
Logger.info("App storage path: $path")
117118
}
118119

119-
val logDir: String
120+
val logDir: File
120121
get() {
121122
require(::appStoragePath.isInitialized)
122-
return File(appStoragePath).resolve("logs").ensureDir().path
123+
return File(appStoragePath).resolve("logs").ensureDir()
123124
}
124125

125126
fun ldkStoragePath(walletIndex: Int) = storagePathOf(walletIndex, network.name.lowercase(), "ldk")

app/src/main/java/to/bitkit/ext/Activities.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ fun Activity.rawId(): String = when (this) {
99
is Activity.Onchain -> v1.id
1010
}
1111

12+
fun Activity.txType(): PaymentType = when (this) {
13+
is Activity.Lightning -> v1.txType
14+
is Activity.Onchain -> v1.txType
15+
}
16+
1217
/**
1318
* Calculates the total value of an activity based on its type.
1419
*

0 commit comments

Comments
 (0)