diff --git a/core/datastore/build.gradle.kts b/core/datastore/build.gradle.kts index ff3f90dec..c6cf6bdac 100644 --- a/core/datastore/build.gradle.kts +++ b/core/datastore/build.gradle.kts @@ -38,6 +38,7 @@ kotlin { implementation(libs.multiplatform.settings) implementation(libs.multiplatform.settings.serialization) implementation(libs.multiplatform.settings.coroutines) + implementation(libs.kotlinx.coroutines.core) implementation(projects.core.model) implementation(projects.core.common) } @@ -45,5 +46,10 @@ kotlin { implementation(libs.kotlin.test) implementation(libs.kotlinx.coroutines.test) } + androidMain.dependencies { + implementation(libs.androidx.datastore.core) + implementation(libs.androidx.datastore.preferences) + implementation(libs.multiplatform.settings.datastore) + } } } diff --git a/core/datastore/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreComponent.kt b/core/datastore/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreComponent.kt new file mode 100644 index 000000000..6ac6bcd41 --- /dev/null +++ b/core/datastore/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreComponent.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.datastore.di + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.core.DataStoreFactory +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.preferencesDataStore +import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.Provides + +@Component +abstract class DataStoreComponent { + + private val Context.dataStore by preferencesDataStore("user_preferences") + + @Provides + fun providesDataStore(context: Context): DataStore { + return context.dataStore + } +} \ No newline at end of file diff --git a/core/datastore/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/SettingsComponent.kt b/core/datastore/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/SettingsComponent.kt new file mode 100644 index 000000000..0ef09c647 --- /dev/null +++ b/core/datastore/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/SettingsComponent.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.datastore.di + +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import com.russhwolf.settings.ExperimentalSettingsApi +import com.russhwolf.settings.coroutines.FlowSettings +import com.russhwolf.settings.datastore.DataStoreSettings +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.Provides + +@Component +actual abstract class SettingsComponent { + @OptIn(ExperimentalSettingsApi::class) + @Provides + actual fun providesFlowSettings( + dataStore: DataStore + ): FlowSettings { + return DataStoreSettings() + } +} \ No newline at end of file diff --git a/core/datastore/src/main/AndroidManifest.xml b/core/datastore/src/commonMain/AndroidManifest.xml similarity index 100% rename from core/datastore/src/main/AndroidManifest.xml rename to core/datastore/src/commonMain/AndroidManifest.xml diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt similarity index 100% rename from core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt rename to core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt similarity index 100% rename from core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt rename to core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt similarity index 100% rename from core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt rename to core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt similarity index 94% rename from core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt rename to core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt index 9a76a75a1..e68e19468 100644 --- a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt +++ b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt @@ -21,14 +21,22 @@ import androidx.datastore.core.DataStore import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand import com.google.samples.apps.nowinandroid.core.model.data.UserData +import com.russhwolf.settings.ExperimentalSettingsApi +import com.russhwolf.settings.ObservableSettings +import com.russhwolf.settings.Settings +import com.russhwolf.settings.coroutines.FlowSettings +import com.russhwolf.settings.coroutines.toFlowSettings +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.map import java.io.IOException import javax.inject.Inject -class NiaPreferencesDataSource @Inject constructor( - private val userPreferences: DataStore, +@OptIn(ExperimentalSettingsApi::class) +class NiaPreferencesDataSource constructor( + private val settings: FlowSettings, ) { + val userData = userPreferences.data .map { UserData( diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt similarity index 100% rename from core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt rename to core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt diff --git a/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/SettingsComponent.kt b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/SettingsComponent.kt new file mode 100644 index 000000000..86bca8793 --- /dev/null +++ b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/SettingsComponent.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.datastore.di + +import com.russhwolf.settings.ExperimentalSettingsApi +import com.russhwolf.settings.coroutines.FlowSettings +import me.tatarka.inject.annotations.Provides + +expect abstract class SettingsComponent { + @OptIn(ExperimentalSettingsApi::class) + @Provides + fun providesFlowSettings(): FlowSettings +} \ No newline at end of file diff --git a/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt b/core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt similarity index 100% rename from core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt rename to core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt diff --git a/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt b/core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt similarity index 100% rename from core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt rename to core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt diff --git a/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt b/core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt similarity index 100% rename from core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt rename to core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt diff --git a/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt b/core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt similarity index 100% rename from core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt rename to core/datastore/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt deleted file mode 100644 index e54760ead..000000000 --- a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.samples.apps.nowinandroid.core.datastore.di - -import android.content.Context -import androidx.datastore.core.DataStore -import androidx.datastore.core.DataStoreFactory -import androidx.datastore.dataStoreFile -import com.google.samples.apps.nowinandroid.core.datastore.IntToStringIdsMigration -import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences -import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer -import com.google.samples.apps.nowinandroid.core.di.ApplicationScope -import com.google.samples.apps.nowinandroid.core.network.Dispatcher -import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineScope -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -object DataStoreModule { - - @Provides - @Singleton - internal fun providesUserPreferencesDataStore( - @ApplicationContext context: Context, - @Dispatcher(IO) ioDispatcher: CoroutineDispatcher, - @ApplicationScope scope: CoroutineScope, - userPreferencesSerializer: UserPreferencesSerializer, - ): DataStore = - DataStoreFactory.create( - serializer = userPreferencesSerializer, - scope = CoroutineScope(scope.coroutineContext + ioDispatcher), - migrations = listOf( - IntToStringIdsMigration, - ), - ) { - context.dataStoreFile("user_preferences.pb") - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cff75f95c..081621dab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -96,7 +96,8 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCore" } androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "androidxCoreSplashscreen" } -androidx-dataStore-core = { group = "androidx.datastore", name = "datastore", version.ref = "androidxDataStore" } +androidx-datastore-core = { group = "androidx.datastore", name = "datastore-preferences-core", version.ref = "androidxDataStore" } +androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "androidxDataStore" } androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHiltNavigationCompose" } androidx-lifecycle-runtimeCompose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" } androidx-lifecycle-runtimeTesting = { group = "androidx.lifecycle", name = "lifecycle-runtime-testing", version.ref = "androidxLifecycle" } @@ -170,6 +171,7 @@ sqldelight-primitive-adapters = { group = "app.cash.sqldelight", name = "primiti kotlin-inject-compiler-ksp = { group = "me.tatarka.inject", name = "kotlin-inject-compiler-ksp", version.ref = "kotlinInject" } kotlin-inject-runtime = { group = "me.tatarka.inject", name = "kotlin-inject-runtime", version.ref = "kotlinInject" } multiplatform-settings = { group = "com.russhwolf", name = "multiplatform-settings", version.ref = "multiplatform-settings" } +multiplatform-settings-datastore = { group = "com.russhwolf", name = "multiplatform-settings-datastore", version.ref = "multiplatform-settings" } multiplatform-settings-serialization = { group = "com.russhwolf", name = "multiplatform-settings-serialization", version.ref = "multiplatform-settings" } multiplatform-settings-coroutines = { group = "com.russhwolf", name = "multiplatform-settings-coroutines", version.ref = "multiplatform-settings" }