chore: refactor the internal storage layer #40
@@ -14,6 +14,8 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import su.reya.coop.nostr.NostrManager
|
||||
import su.reya.coop.storage.SecretStore
|
||||
import su.reya.coop.storage.SettingStorage
|
||||
import su.reya.coop.storage.settingsDataStore
|
||||
import su.reya.coop.viewmodel.AuthViewModel
|
||||
import su.reya.coop.viewmodel.ChatViewModel
|
||||
import su.reya.coop.viewmodel.NostrViewModel
|
||||
@@ -29,12 +31,13 @@ class MainActivity : ComponentActivity() {
|
||||
private val androidSigner =
|
||||
AndroidExternalSigner(this@MainActivity, externalSignerLauncher)
|
||||
private val secretStore = SecretStore(this@MainActivity)
|
||||
private val settingStorage = SettingStorage(this@MainActivity.settingsDataStore)
|
||||
private val nostrViewModel =
|
||||
NostrViewModel(NostrManager.instance)
|
||||
private val chatViewModel =
|
||||
ChatViewModel(NostrManager.instance)
|
||||
private val authViewModel =
|
||||
AuthViewModel(NostrManager.instance, secretStore, androidSigner)
|
||||
AuthViewModel(NostrManager.instance, secretStore, settingStorage, androidSigner)
|
||||
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return when {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package su.reya.coop.storage
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
|
||||
val Context.settingsDataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
|
||||
@@ -33,6 +33,8 @@ kotlin {
|
||||
implementation(libs.ktor.serialization.kotlinx.json)
|
||||
implementation(libs.androidx.lifecycle.viewmodelCompose)
|
||||
implementation(libs.androidx.lifecycle.runtimeCompose)
|
||||
implementation(libs.androidx.datastore.preferences)
|
||||
implementation(libs.androidx.datastore)
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0")
|
||||
implementation("su.reya:nostr-sdk-kmp:0.3.2")
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package su.reya.coop.storage
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface KeyValueStorage {
|
||||
suspend fun get(key: String): String?
|
||||
fun getFlow(key: String): Flow<String?>
|
||||
suspend fun set(key: String, value: String)
|
||||
suspend fun clear(key: String)
|
||||
suspend fun has(key: String): Boolean
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package su.reya.coop.storage
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class SettingStorage(
|
||||
private val dataStore: DataStore<Preferences>
|
||||
) : KeyValueStorage {
|
||||
override suspend fun get(key: String): String? {
|
||||
return dataStore.data.map { it[stringPreferencesKey(key)] }.first()
|
||||
}
|
||||
|
||||
override fun getFlow(key: String): Flow<String?> {
|
||||
return dataStore.data.map { it[stringPreferencesKey(key)] }
|
||||
}
|
||||
|
||||
override suspend fun set(key: String, value: String) {
|
||||
dataStore.edit { it[stringPreferencesKey(key)] = value }
|
||||
}
|
||||
|
||||
override suspend fun clear(key: String) {
|
||||
dataStore.edit { it.remove(stringPreferencesKey(key)) }
|
||||
}
|
||||
|
||||
override suspend fun has(key: String): Boolean {
|
||||
return dataStore.data.map { it.contains(stringPreferencesKey(key)) }.first()
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import su.reya.coop.nostr.ExternalSignerProxy
|
||||
import su.reya.coop.nostr.Nostr
|
||||
import su.reya.coop.nostr.SignerPermissions
|
||||
import su.reya.coop.repository.MediaRepository
|
||||
import su.reya.coop.storage.KeyValueStorage
|
||||
import su.reya.coop.storage.SecretStorage
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@@ -28,6 +29,7 @@ data class AuthState(
|
||||
class AuthViewModel(
|
||||
private val nostr: Nostr,
|
||||
private val secretStore: SecretStorage,
|
||||
private val settingStorage: KeyValueStorage,
|
||||
private val externalSignerHandler: ExternalSignerHandler? = null,
|
||||
) : BaseViewModel() {
|
||||
private val mediaRepository = MediaRepository()
|
||||
@@ -51,7 +53,7 @@ class AuthViewModel(
|
||||
|
||||
private fun checkNotificationBannerDismissedStatus() {
|
||||
viewModelScope.launch {
|
||||
val dismissed = secretStore.get(KEY_BANNER_DISMISSED) == "true"
|
||||
val dismissed = settingStorage.get(KEY_BANNER_DISMISSED) == "true"
|
||||
_state.update { it.copy(isNotificationBannerDismissed = dismissed) }
|
||||
}
|
||||
}
|
||||
@@ -95,7 +97,7 @@ class AuthViewModel(
|
||||
} finally {
|
||||
// Clear credentials from persistent storage
|
||||
secretStore.clear(KEY_USER_SIGNER)
|
||||
secretStore.clear(KEY_BANNER_DISMISSED)
|
||||
settingStorage.clear(KEY_BANNER_DISMISSED)
|
||||
// Call cleanup callback (e.g. to reset other ViewModels)
|
||||
onLogout()
|
||||
// Reset local states
|
||||
@@ -106,7 +108,7 @@ class AuthViewModel(
|
||||
|
||||
fun dismissNotificationBanner() {
|
||||
viewModelScope.launch {
|
||||
secretStore.set(KEY_BANNER_DISMISSED, "true")
|
||||
settingStorage.set(KEY_BANNER_DISMISSED, "true")
|
||||
_state.update { it.copy(isNotificationBannerDismissed = true) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user