Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Migrate :core:datastore to KMP #2306

Open
wants to merge 13 commits into
base: kmp-impl
Choose a base branch
from
30 changes: 17 additions & 13 deletions core/datastore/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
plugins {
alias(libs.plugins.mifos.android.library)
alias(libs.plugins.mifos.android.library.jacoco)
alias(libs.plugins.mifos.android.hilt)
alias(libs.plugins.mifos.kmp.library)
alias(libs.plugins.kotlin.serialization)

}

android {
Expand All @@ -26,15 +26,19 @@ android {
}
}

dependencies {
api(projects.core.model)
api(projects.core.common)

api(libs.converter.gson)
kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.multiplatform.settings)
implementation(libs.multiplatform.settings.serialization)
implementation(libs.multiplatform.settings.coroutines)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.core)
// implementation(projects.core.common)
api(projects.core.model)
api(projects.core.common)

// fineract sdk dependencies
api(libs.mifos.android.sdk.arch)

// sdk client
api(libs.fineract.client)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
@file:OptIn(ExperimentalSerializationApi::class, ExperimentalSettingsApi::class)

package org.mifos.core.datastore

import com.russhwolf.settings.ExperimentalSettingsApi
import com.russhwolf.settings.Settings
import com.russhwolf.settings.serialization.decodeValue
import com.russhwolf.settings.serialization.decodeValueOrNull
import com.russhwolf.settings.serialization.encodeValue
import datastore.model.UserData
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.withContext
import kotlinx.serialization.ExperimentalSerializationApi

private const val USER_DATA = "userData"

class UserPreferencesDataSource(
private val settings: Settings,
private val dispatcher: CoroutineDispatcher,
) {
@OptIn(ExperimentalSerializationApi::class, ExperimentalSettingsApi::class)
private val _userInfo = MutableStateFlow(
settings.decodeValue(
key = USER_DATA,
serializer = UserData.serializer(),
defaultValue = settings.decodeValueOrNull(
key = USER_DATA,
serializer = UserData.serializer(),
) ?: UserData.DEFAULT,
),
)
val userInfo = _userInfo
suspend fun updateUserInfo(user: UserData) {
withContext(dispatcher) {
settings.putUserPreference(user)
_userInfo.value = user
}
}

suspend fun clearInfo() {
withContext(dispatcher) {
settings.clear()
}
}
}

@OptIn(ExperimentalSerializationApi::class, ExperimentalSettingsApi::class)
private fun Settings.putUserPreference(user: UserData) {
encodeValue(
key = USER_DATA,
serializer = UserData.serializer(),
value = user,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package org.mifos.core.datastore

import datastore.model.UserData
import kotlinx.coroutines.flow.Flow

interface UserPreferencesRepository {
val userInfo: Flow<UserData>
suspend fun updateUser(user: UserData): Result<Unit>
suspend fun logOut(): Unit
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package org.mifos.core.datastore

import datastore.model.UserData
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow

class UserPreferencesRepositoryImpl(
private val preferenceManager: UserPreferencesDataSource,
private val ioDispatcher: CoroutineDispatcher,
unconfinedDispatcher: CoroutineDispatcher,
) : UserPreferencesRepository {
private val unconfinedScope = CoroutineScope(unconfinedDispatcher)
override val userInfo: Flow<UserData>
get() = preferenceManager.userInfo

override suspend fun updateUser(user: UserData): Result<Unit> {
return try {
val result = preferenceManager.updateUserInfo(user)
Result.success(result)
} catch (e: Exception) {
Result.failure(e)
}
}

override suspend fun logOut() {
preferenceManager.clearInfo()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2024 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package org.mifos.core.datastore.di

import com.russhwolf.settings.Settings
import org.koin.core.qualifier.named
import org.koin.dsl.module
import org.mifos.core.datastore.UserPreferencesDataSource
import org.mifos.core.datastore.UserPreferencesRepository
import org.mifos.core.datastore.UserPreferencesRepositoryImpl

val PreferencesModule = module {
factory<Settings> { Settings() }
factory {
UserPreferencesDataSource(
settings = get(),
dispatcher = get(named(MifosDispatchers.IO.name)),
)
}
single<UserPreferencesRepository> {
UserPreferencesRepositoryImpl(
preferenceManager = get(),
ioDispatcher = get(named(MifosDispatchers.IO.name)),
unconfinedDispatcher = get(named(MifosDispatchers.Unconfined.name)),
)
}
}

enum class MifosDispatchers {
Default,
IO,
Unconfined,
}
29 changes: 29 additions & 0 deletions core/datastore/src/commonMain/kotlin/datastore/model/UserData.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package datastore.model

import kotlinx.serialization.Serializable

@Serializable
data class UserData(
val userId: Long,
val userName: String,
val clientId: Long,
val isAuthenticated: Boolean,
) {
companion object {
val DEFAULT = UserData(
userId = -1,
userName = "",
clientId = -1,
isAuthenticated = false,
)
}
}

This file was deleted.

Loading