diff --git a/FloconAndroid/datastores-no-op/.gitignore b/FloconAndroid/datastores-no-op/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/FloconAndroid/datastores-no-op/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts new file mode 100644 index 00000000..31aafa27 --- /dev/null +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -0,0 +1,88 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + id("com.vanniktech.maven.publish") version "0.34.0" +} + +android { + namespace = "io.github.openflocon.flocon.datastores" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } +} + +dependencies { + + implementation(project(":flocon-base")) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.jetbrains.kotlinx.coroutines.core) + + implementation(libs.androidx.datastore.preferences) +} + + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-datastores-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Datastores Integration No Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} \ No newline at end of file diff --git a/FloconAndroid/datastores-no-op/consumer-rules.pro b/FloconAndroid/datastores-no-op/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/FloconAndroid/datastores-no-op/proguard-rules.pro b/FloconAndroid/datastores-no-op/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/FloconAndroid/datastores-no-op/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/FloconAndroid/datastores-no-op/src/main/AndroidManifest.xml b/FloconAndroid/datastores-no-op/src/main/AndroidManifest.xml new file mode 100644 index 00000000..74b7379f --- /dev/null +++ b/FloconAndroid/datastores-no-op/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt b/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt new file mode 100644 index 00000000..855d25c2 --- /dev/null +++ b/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt @@ -0,0 +1,37 @@ +package io.github.openflocon.flocon.preferences.datastores.model + +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.doublePreferencesKey +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.floatPreferencesKey +import androidx.datastore.preferences.core.intPreferencesKey +import androidx.datastore.preferences.core.longPreferencesKey +import androidx.datastore.preferences.core.stringPreferencesKey +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreferenceValue +import kotlinx.coroutines.flow.first + +class FloconDatastorePreference( + override val name: String, + val dataStore: DataStore, +) : FloconPreference { + + override suspend fun set( + columnName: String, + value: FloconPreferenceValue + ) { + // no op + } + + override suspend fun columns(): List { + return emptyList() // no op + } + + override suspend fun get(columnName: String): FloconPreferenceValue? { + return null // no op + } + +} \ No newline at end of file diff --git a/FloconAndroid/datastores/.gitignore b/FloconAndroid/datastores/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/FloconAndroid/datastores/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts new file mode 100644 index 00000000..47a353b6 --- /dev/null +++ b/FloconAndroid/datastores/build.gradle.kts @@ -0,0 +1,89 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + id("com.vanniktech.maven.publish") version "0.34.0" +} + +android { + namespace = "io.github.openflocon.flocon.datastores" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } +} + +dependencies { + + implementation(project(":flocon-base")) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.jetbrains.kotlinx.coroutines.core) + implementation(libs.jetbrains.kotlinx.coroutines.android) + + implementation(libs.androidx.datastore.preferences) +} + + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-datastores", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Datastores Integration" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} \ No newline at end of file diff --git a/FloconAndroid/datastores/consumer-rules.pro b/FloconAndroid/datastores/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/FloconAndroid/datastores/proguard-rules.pro b/FloconAndroid/datastores/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/FloconAndroid/datastores/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/FloconAndroid/datastores/src/main/AndroidManifest.xml b/FloconAndroid/datastores/src/main/AndroidManifest.xml new file mode 100644 index 00000000..74b7379f --- /dev/null +++ b/FloconAndroid/datastores/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt b/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt new file mode 100644 index 00000000..3332e668 --- /dev/null +++ b/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt @@ -0,0 +1,80 @@ +package io.github.openflocon.flocon.preferences.datastores.model + +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.doublePreferencesKey +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.floatPreferencesKey +import androidx.datastore.preferences.core.intPreferencesKey +import androidx.datastore.preferences.core.longPreferencesKey +import androidx.datastore.preferences.core.stringPreferencesKey +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreferenceValue +import kotlinx.coroutines.flow.first + +class FloconDatastorePreference( + override val name: String, + private val dataStore: DataStore, +) : FloconPreference { + + override suspend fun set( + columnName: String, + value: FloconPreferenceValue + ) { + try { + val data = dataStore.data.first().asMap() + val key = data.keys.find { it.name == columnName } ?: return + + dataStore.edit { + try { + when (it[key]) { + is String -> it[stringPreferencesKey(columnName)] = value.stringValue!! + is Int -> it[intPreferencesKey(columnName)] = value.intValue!! + is Boolean -> it[booleanPreferencesKey(columnName)] = value.booleanValue!! + is Float -> it[floatPreferencesKey(columnName)] = value.floatValue!! + is Long -> it[longPreferencesKey(columnName)] = value.longValue!! + is Double -> it[doublePreferencesKey(columnName)] = + value.floatValue!!.toDouble() + } + } catch (t: Throwable) { + FloconLogger.logError("cannot update datastore preference", t) + } + } + } catch (t: Throwable) { + FloconLogger.logError(t.message ?: "cannot edit datastore preference columns", t) + } + } + + override suspend fun columns(): List { + return try { + dataStore.data.first().asMap().map { it.key.name } + } catch (t: Throwable) { + FloconLogger.logError(t.message ?: "cannot get datastore preference columns", t) + emptyList() + } + } + + override suspend fun get(columnName: String): FloconPreferenceValue? { + return try { + val data = dataStore.data.first().asMap() + val key = data.keys.find { it.name == columnName } ?: return null + val value = data[key] ?: return null + + return when (value) { + is String -> FloconPreferenceValue(stringValue = value) + is Int -> FloconPreferenceValue(intValue = value) + is Float -> FloconPreferenceValue(floatValue = value) + is Double -> FloconPreferenceValue(floatValue = value.toFloat()) + is Boolean -> FloconPreferenceValue(booleanValue = value) + is Long -> FloconPreferenceValue(longValue = value) + else -> null + } + } catch (t: Throwable) { + FloconLogger.logError(t.message ?: "cannot get datastore preference value", t) + null + } + } + +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreference.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreference.kt index 3e15ebe3..5a3810f9 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreference.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreference.kt @@ -4,7 +4,7 @@ interface FloconPreference { val name: String suspend fun set( - rowName: String, + columnName: String, value: FloconPreferenceValue, ) diff --git a/FloconAndroid/flocon-no-op/build.gradle.kts b/FloconAndroid/flocon-no-op/build.gradle.kts index ee80a3e2..dedd7d82 100644 --- a/FloconAndroid/flocon-no-op/build.gradle.kts +++ b/FloconAndroid/flocon-no-op/build.gradle.kts @@ -91,7 +91,7 @@ mavenPublishing { ) pom { - name = "Flocon" + name = "Flocon No Op" description = project.property("floconDescription") as String inceptionYear = "2025" url = "https://github.com/openflocon/Flocon" diff --git a/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/sharedprefs/FloconSharedPreference.kt b/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt similarity index 88% rename from FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/sharedprefs/FloconSharedPreference.kt rename to FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt index a6bfc75f..d5be3322 100644 --- a/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/sharedprefs/FloconSharedPreference.kt +++ b/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.sharedprefs +package io.github.openflocon.flocon.plugins.sharedprefs import android.content.SharedPreferences import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference @@ -10,7 +10,7 @@ data class FloconSharedPreference( ) : FloconPreference { override suspend fun set( - rowName: String, + columnName: String, value: FloconPreferenceValue ) { // no op diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt index 84daf290..1bbe8d4a 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt @@ -10,22 +10,22 @@ data class FloconSharedPreference( ) : FloconPreference { override suspend fun set( - rowName: String, + columnName: String, value: FloconPreferenceValue ) { - val originalValue: Any? = sharedPreferences.all[rowName] + val originalValue: Any? = sharedPreferences.all[columnName] val editor = sharedPreferences.edit() if (originalValue is Boolean && value.booleanValue != null) { - editor.putBoolean(rowName, value.booleanValue!!) + editor.putBoolean(columnName, value.booleanValue!!) } else if (originalValue is Long && value.longValue != null) { - editor.putLong(rowName, value.longValue!!) + editor.putLong(columnName, value.longValue!!) } else if (originalValue is Int && value.intValue != null) { - editor.putInt(rowName, value.intValue!!) + editor.putInt(columnName, value.intValue!!) } else if (originalValue is Float && value.floatValue != null) { - editor.putFloat(rowName, value.floatValue!!) + editor.putFloat(columnName, value.floatValue!!) } else if (originalValue is String && value.stringValue != null) { - editor.putString(rowName, value.stringValue!!) + editor.putString(columnName, value.stringValue!!) } else { // do nothin } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index aa615747..e1818d43 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -67,7 +67,7 @@ internal class FloconPreferencesPluginImpl( scope.launch { try { preference.set( - rowName = toDeviceMessage.key, + columnName = toDeviceMessage.key, value = FloconPreferenceValue( stringValue = toDeviceMessage.stringValue, booleanValue = toDeviceMessage.booleanValue, diff --git a/FloconAndroid/gradle/libs.versions.toml b/FloconAndroid/gradle/libs.versions.toml index 84ea62e6..1e4a3182 100644 --- a/FloconAndroid/gradle/libs.versions.toml +++ b/FloconAndroid/gradle/libs.versions.toml @@ -3,6 +3,7 @@ agp = "8.11.0-rc02" apollo = "4.0.0" coilCompose = "3.2.0" compose = "1.9.0" +datastorePreferences = "1.1.7" kotlin = "2.1.0" mavenPublish = "0.34.0" coreKtx = "1.16.0" @@ -33,6 +34,7 @@ buildconfig = "5.6.8" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } diff --git a/FloconAndroid/publishLocal.sh b/FloconAndroid/publishLocal.sh index 4021b891..5e62f35c 100755 --- a/FloconAndroid/publishLocal.sh +++ b/FloconAndroid/publishLocal.sh @@ -8,7 +8,9 @@ :okhttp-interceptor:assembleRelease \ :okhttp-interceptor-no-op:assembleRelease \ :ktor-interceptor:assembleRelease \ - :ktor-interceptor-no-op:assembleRelease + :ktor-interceptor-no-op:assembleRelease \ + :datastores:assembleRelease \ + :datastores-no-op:assembleRelease ./gradlew \ :flocon-base:publishToMavenLocal \ @@ -21,4 +23,6 @@ :okhttp-interceptor-no-op:publishToMavenLocal \ :ktor-interceptor:publishToMavenLocal \ :ktor-interceptor-no-op:publishToMavenLocal \ + :datastores:publishToMavenLocal \ + :datastores-no-op:publishToMavenLocal \ -Psigning.required=false \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index b83ca7ed..1d056d1c 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -84,6 +84,8 @@ dependencies { implementation(project(":grpc:grpc-interceptor-lite")) debugImplementation(project(":ktor-interceptor")) releaseImplementation(project(":ktor-interceptor-no-op")) + debugImplementation(project(":datastores")) + releaseImplementation(project(":datastores-no-op")) } @@ -135,6 +137,10 @@ dependencies { implementation(libs.ktor.client.okhttp) implementation(libs.ktor.client.core) //endregion + + // region datastore + implementation(libs.androidx.datastore.preferences) + // endregion } apollo { diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index 2974317d..b35249fb 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -26,6 +26,7 @@ import io.github.openflocon.flocon.myapplication.deeplinks.initializeDeeplinks import io.github.openflocon.flocon.myapplication.graphql.GraphQlTester import io.github.openflocon.flocon.myapplication.grpc.GrpcController import io.github.openflocon.flocon.myapplication.images.initializeImages +import io.github.openflocon.flocon.myapplication.sharedpreferences.initializeDatastores import io.github.openflocon.flocon.myapplication.sharedpreferences.initializeSharedPreferences import io.github.openflocon.flocon.myapplication.sharedpreferences.initializeSharedPreferencesAfterInit import io.github.openflocon.flocon.myapplication.table.initializeTable @@ -68,6 +69,7 @@ class MainActivity : ComponentActivity() { initializeDeeplinks() initializeSharedPreferencesAfterInit(applicationContext) + initializeDatastores(applicationContext) val dummyHttpCaller = DummyHttpCaller(client = okHttpClient) val dummyWebsocketCaller = DummyWebsocketCaller(client = okHttpClient) diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/Datastores.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/Datastores.kt new file mode 100644 index 00000000..4b5fab96 --- /dev/null +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/Datastores.kt @@ -0,0 +1,47 @@ +package io.github.openflocon.flocon.myapplication.sharedpreferences + +import android.content.Context +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.intPreferencesKey +import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.preferences.preferencesDataStore +import io.github.openflocon.flocon.plugins.sharedprefs.floconRegisterPreference +import io.github.openflocon.flocon.preferences.datastores.model.FloconDatastorePreference +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch + +private val Context.dataStore by preferencesDataStore(name = "datastore") + +private val USER_NAME = stringPreferencesKey("username") +private val USER_AGE = intPreferencesKey("user.age") + +fun initializeDatastores(context: Context) { + Datastores(context) +} + +class Datastores(private val context: Context) { + suspend fun saveUsername(username: String) { + val value = context.dataStore.data.first()[USER_NAME] + println("Datastore Local Value : $value") + if (value == null) { + context.dataStore.edit { prefs -> + prefs[USER_NAME] = username + } + } + } + + suspend fun saveUserAge(age: Int) { + context.dataStore.edit { prefs -> + prefs[USER_AGE] = age + } + } + + init { + floconRegisterPreference(FloconDatastorePreference("datastore", context.dataStore)) + GlobalScope.launch { + saveUsername("John Doe") + saveUserAge(30) + } + } +} diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 30721c32..511b0712 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -27,3 +27,5 @@ include(":grpc:grpc-interceptor-base") include(":grpc:grpc-interceptor-lite") include(":ktor-interceptor") include(":ktor-interceptor-no-op") +include(":datastores") +include(":datastores-no-op")