From 34c82ba8f68c8dece3edd1fc27bc771781b76308 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Sat, 9 Mar 2024 19:06:33 -0600 Subject: [PATCH] Add module for managing user preferences. - Navigate to Import Account screen if there is no active account. - Add basic node status placeholder in Import Account screen. --- composeApp/build.gradle.kts | 2 + .../kee/ui/component/nodestatus/NodeStatus.kt | 24 +++++++++++ .../agorise/kee/ui/screen/home/HomeScreen.kt | 6 +++ .../importaccount/ImportAccountScreen.kt | 8 +++- gradle/libs.versions.toml | 10 +++-- settings.gradle.kts | 3 +- shared/preferences/build.gradle.kts | 40 +++++++++++++++++++ .../shared/preferences/KeePreferences.kt | 18 +++++++++ 8 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/net/agorise/kee/ui/component/nodestatus/NodeStatus.kt create mode 100644 shared/preferences/build.gradle.kts create mode 100644 shared/preferences/src/commonMain/kotlin/net/agorise/shared/preferences/KeePreferences.kt diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index d1b62aa..137599c 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -36,6 +36,8 @@ kotlin { implementation(libs.androidx.activity.compose) } commonMain.dependencies { + implementation(projects.shared.preferences) + implementation(compose.components.resources) implementation(compose.components.uiToolingPreview) implementation(compose.foundation) diff --git a/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/component/nodestatus/NodeStatus.kt b/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/component/nodestatus/NodeStatus.kt new file mode 100644 index 0000000..f9966a5 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/component/nodestatus/NodeStatus.kt @@ -0,0 +1,24 @@ +package net.agorise.kee.ui.component.nodestatus + +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import org.jetbrains.compose.ui.tooling.preview.Preview +import ui.theme.KeeTheme + +@Composable +fun NodeStatus() { + Text("Connected to X.X.X.X", color = MaterialTheme.colorScheme.onBackground) +} + +@Preview +@Composable +private fun NodeStatusLightPreview() = KeeTheme(useDarkTheme = false) { + NodeStatus() +} + +@Preview +@Composable +private fun NodeStatusDarkPreview() = KeeTheme(useDarkTheme = true) { + NodeStatus() +} diff --git a/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/home/HomeScreen.kt b/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/home/HomeScreen.kt index 88a388b..bb8d63f 100644 --- a/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/home/HomeScreen.kt +++ b/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/home/HomeScreen.kt @@ -12,6 +12,7 @@ import cafe.adriel.voyager.navigator.LocalNavigator import net.agorise.kee.getPlatform import net.agorise.kee.ui.component.topappbar.KeeTopAppBar import net.agorise.kee.ui.screen.importaccount.ImportAccountScreen +import net.agorise.shared.preferences.KeePreferences import org.jetbrains.compose.ui.tooling.preview.Preview import ui.theme.KeeTheme @@ -27,6 +28,11 @@ class HomeScreen : Screen { private fun HomeScreenContent() { val navigator = LocalNavigator.current + // Navigate to Import Account screen immediately if there is no active account + if (KeePreferences.isAccountActive().not()) { + navigator?.replace(ImportAccountScreen()) + } + Scaffold( topBar = { KeeTopAppBar("Kee Wallet") } ) { innerPadding -> diff --git a/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/importaccount/ImportAccountScreen.kt b/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/importaccount/ImportAccountScreen.kt index 36b5ff7..c88b9b3 100644 --- a/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/importaccount/ImportAccountScreen.kt +++ b/composeApp/src/commonMain/kotlin/net/agorise/kee/ui/screen/importaccount/ImportAccountScreen.kt @@ -11,6 +11,7 @@ import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator import kee.composeapp.generated.resources.Res import kee.composeapp.generated.resources.logo_kee +import net.agorise.kee.ui.component.nodestatus.NodeStatus import net.agorise.kee.ui.component.topappbar.KeeTopAppBar import net.agorise.kee.ui.screen.home.HomeScreen import org.jetbrains.compose.resources.ExperimentalResourceApi @@ -37,7 +38,10 @@ private fun ImportAccountScreenContent() { topBar = { KeeTopAppBar("Import Account") } ) { innerPadding -> Column( - modifier = Modifier.padding(innerPadding).padding(16.dp), + modifier = Modifier + .padding(innerPadding) + .consumeWindowInsets(innerPadding) + .padding(top = 16.dp, start = 16.dp, end = 16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp) ) { @@ -72,6 +76,8 @@ private fun ImportAccountScreenContent() { ) { Text("Import Account") } + Spacer(modifier = Modifier.weight(1f)) + NodeStatus() } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 643f12b..c400245 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,13 +7,15 @@ androidx-activityCompose = "1.8.2" compose = "1.6.2" compose-plugin = "1.6.0" kotlin = "1.9.22" +multiplatform-settings = "1.1.1" voyager = "1.0.0" [libraries] -androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } -compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } -compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" } -voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" } +androidx-activity-compose = { group = "androidx.activity", name ="activity-compose", version.ref = "androidx-activityCompose" } +compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "compose" } +compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview", version.ref = "compose" } +multiplatform-settings = { group="com.russhwolf", name = "multiplatform-settings-no-arg", version.ref = "multiplatform-settings" } +voyager-navigator = { group = "cafe.adriel.voyager", name = "voyager-navigator", version.ref = "voyager" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 443e5d7..17f2519 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -18,4 +18,5 @@ dependencyResolutionManagement { } } -include(":composeApp") \ No newline at end of file +include(":composeApp") +include(":shared:preferences") diff --git a/shared/preferences/build.gradle.kts b/shared/preferences/build.gradle.kts new file mode 100644 index 0000000..c7cf725 --- /dev/null +++ b/shared/preferences/build.gradle.kts @@ -0,0 +1,40 @@ +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.androidLibrary) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + commonMain.dependencies { + implementation(libs.multiplatform.settings) + } + } +} + +android { + namespace = "net.agorise.shared.preferences" + compileSdk = libs.versions.android.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.android.minSdk.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} diff --git a/shared/preferences/src/commonMain/kotlin/net/agorise/shared/preferences/KeePreferences.kt b/shared/preferences/src/commonMain/kotlin/net/agorise/shared/preferences/KeePreferences.kt new file mode 100644 index 0000000..1835212 --- /dev/null +++ b/shared/preferences/src/commonMain/kotlin/net/agorise/shared/preferences/KeePreferences.kt @@ -0,0 +1,18 @@ +package net.agorise.shared.preferences + +import com.russhwolf.settings.Settings + +/** + * Provides methods to access preferences on all supported platforms. + */ +object KeePreferences { + // TODO Use a stronger implementation that allows encryption + private val settings: Settings = Settings() + + // Keys used to store/retrieve preferences + private const val KEY_RECOVERY_WORDS = "key_recovery_words" + + fun isAccountActive(): Boolean { + return settings.hasKey(KEY_RECOVERY_WORDS) + } +}