add nostr view model

This commit is contained in:
2026-04-25 08:52:42 +07:00
parent 8c6b70304d
commit 3240382498
11 changed files with 100 additions and 94 deletions
@@ -1,72 +1,53 @@
package su.reya.coop
import android.content.Context
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.preferencesDataStore
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.toRoute
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
private val FIRST_TIME_KEY = booleanPreferencesKey("first_time")
import kotlinx.coroutines.flow.flow
import su.reya.coop.coop.storage.SecretStore
@Composable
fun App() {
fun App(dbPath: String) {
val context = LocalContext.current
val nostr = remember { Nostr() }
val secretStore = remember { SecretStore(context) }
val viewModel: NostrViewModel = viewModel { NostrViewModel(nostr, secretStore) }
LaunchedEffect(Unit) {
viewModel.initAndConnect(dbPath)
}
MaterialTheme {
val context = LocalContext.current
val scope = rememberCoroutineScope()
rememberCoroutineScope()
val navController = rememberNavController()
val isFirstTimeFlow = remember {
context.dataStore.data.map { preferences ->
preferences[FIRST_TIME_KEY] ?: true
// Get user's signer status
val hasSecretFlow = remember {
flow {
emit(secretStore.has("user_signer"))
}
}
val isFirstTime by isFirstTimeFlow.collectAsState(initial = null)
val hasSecret by hasSecretFlow.collectAsState(initial = null)
if (isFirstTime == null) {
if (hasSecret == null) {
// Loading state
return@MaterialTheme
}
NavHost(
navController = navController,
startDestination = if (isFirstTime == true) Screen.Welcome else Screen.Home
startDestination = if (hasSecret == true) Screen.Onboarding else Screen.Home
) {
composable<Screen.Welcome> { backStackEntry ->
WelcomeScreen(onContinue = {
scope.launch {
context.dataStore.edit { settings ->
settings[FIRST_TIME_KEY] = false
}
navController.navigate(Screen.Home) {
popUpTo<Screen.Welcome> { inclusive = true }
}
}
})
}
composable<Screen.Home> { backStackEntry ->
HomeScreen(
onOpenChat = { id -> navController.navigate(Screen.Chat(id)) }
)
}
composable<Screen.Chat> { backStackEntry ->
val chat: Screen.Chat = backStackEntry.toRoute()
ChatScreen(id = chat.id)
}
composable<Screen.Onboarding> { backStackEntry ->
OnboardingScreen(
onOpenImport = { navController.navigate(Screen.Import) },
@@ -79,6 +60,15 @@ fun App() {
composable<Screen.New> { backStackEntry ->
NewScreen()
}
composable<Screen.Home> { backStackEntry ->
HomeScreen(
onOpenChat = { id -> navController.navigate(Screen.Chat(id)) }
)
}
composable<Screen.Chat> { backStackEntry ->
val chat: Screen.Chat = backStackEntry.toRoute()
ChatScreen(id = chat.id)
}
}
}
}