From 0407f04162eb059dea1352ae03d36ede1b12d2ea Mon Sep 17 00:00:00 2001 From: Roman Pytkov Date: Sat, 23 Nov 2024 13:27:37 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20ViewModelBase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/libs.versions.toml | 4 +-- .../wallenc/presentation/WallencUi.kt | 30 ++++++----------- .../wallenc/presentation/WallencViewModel.kt | 33 +++++++++++++++++++ .../presentation/screens/main/MainScreen.kt | 25 +++++++++----- .../screens/main/MainViewModel.kt | 28 ++++++++++++++-- .../screens/local/vault/LocalVaultScreen.kt | 6 +++- .../local/vault/LocalVaultViewModel.kt | 5 +-- .../screens/remotes/RemoteVaultsViewModel.kt | 5 +-- .../screens/settings/SettingsRoute.kt | 2 +- .../screens/settings/SettingsScreen.kt | 4 +-- .../screens/settings/SettingsScreenState.kt | 3 ++ .../screens/settings/SettingsViewModel.kt | 9 +++++ .../presentation/viewmodel/ViewModelBase.kt | 14 ++++++++ 13 files changed, 127 insertions(+), 41 deletions(-) create mode 100644 presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencViewModel.kt create mode 100644 presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreenState.kt create mode 100644 presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsViewModel.kt create mode 100644 presentation/src/main/java/com/github/nullptroma/wallenc/presentation/viewmodel/ViewModelBase.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 078cfe7..d2782bb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] agp = "8.7.1" -kotlin = "2.0.21" +kotlin = "2.0.10" coreKtx = "1.15.0" junit = "4.13.2" junitVersion = "1.2.1" @@ -15,7 +15,7 @@ navigation = "2.8.3" hiltNavigation = "1.2.0" yandexAuthSdk = "3.1.2" daggerHilt = "2.52" -ksp = "2.0.20-1.0.25" +ksp = "2.0.10-1.0.24" room = "2.6.1" retrofit = "2.11.0" gson = "2.11.0" diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencUi.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencUi.kt index 0605d3a..fe9f386 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencUi.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencUi.kt @@ -18,10 +18,10 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState @@ -30,10 +30,10 @@ import com.github.nullptroma.wallenc.presentation.navigation.NavBarItemData import com.github.nullptroma.wallenc.presentation.navigation.rememberNavigationState import com.github.nullptroma.wallenc.presentation.screens.main.MainRoute import com.github.nullptroma.wallenc.presentation.screens.main.MainScreen -import com.github.nullptroma.wallenc.presentation.screens.main.screens.local.vault.LocalVaultRoute -import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsRoute +import com.github.nullptroma.wallenc.presentation.screens.main.MainViewModel import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsRoute import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsScreen +import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsViewModel import com.github.nullptroma.wallenc.presentation.theme.WallencTheme @@ -48,23 +48,14 @@ fun WallencUi() { @OptIn(ExperimentalMaterial3Api::class) @Composable -fun WallencNavRoot() { +fun WallencNavRoot(viewModel: WallencViewModel = hiltViewModel()) { val navState = rememberNavigationState() - val mainNavState = rememberNavigationState() - val mainScreenRoutes = rememberSaveable { - mutableMapOf( - LocalVaultRoute::class.qualifiedName!! to LocalVaultRoute(), - RemoteVaultsRoute::class.qualifiedName!! to RemoteVaultsRoute() - ) - } - val topLevelRoutes = rememberSaveable { - mutableMapOf( - MainRoute::class.qualifiedName!! to MainRoute(), - SettingsRoute::class.qualifiedName!! to SettingsRoute("Base settings") - ) - } + val mainViewModel: MainViewModel = hiltViewModel() + val settingsViewModel: SettingsViewModel = hiltViewModel() + + val topLevelRoutes = viewModel.routes val topLevelNavBarItems = remember { mapOf( @@ -118,7 +109,7 @@ fun WallencNavRoot() { MainScreen( modifier = Modifier.padding(innerPaddings), navState = mainNavState, - routes = mainScreenRoutes + viewModel = mainViewModel ) } composable(enterTransition = { @@ -126,8 +117,7 @@ fun WallencNavRoot() { }, exitTransition = { fadeOut(tween(200)) }) { - val route: SettingsRoute = it.toRoute() - SettingsScreen(Modifier.padding(innerPaddings), route.text) + SettingsScreen(Modifier.padding(innerPaddings), settingsViewModel) } } } diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencViewModel.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencViewModel.kt new file mode 100644 index 0000000..16fc821 --- /dev/null +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/WallencViewModel.kt @@ -0,0 +1,33 @@ +package com.github.nullptroma.wallenc.presentation + +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi +import androidx.lifecycle.viewmodel.compose.saveable +import com.github.nullptroma.wallenc.presentation.screens.ScreenRoute +import com.github.nullptroma.wallenc.presentation.screens.main.MainRoute +import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsRoute +import com.github.nullptroma.wallenc.presentation.viewmodel.ViewModelBase +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlin.collections.set + +@HiltViewModel +class WallencViewModel @javax.inject.Inject constructor(savedStateHandle: SavedStateHandle) : + ViewModelBase(Unit) { + @OptIn(SavedStateHandleSaveableApi::class) + var routes by savedStateHandle.saveable { + mutableStateOf( + mapOf( + MainRoute::class.qualifiedName!! to MainRoute(), + SettingsRoute::class.qualifiedName!! to SettingsRoute() + ) + ) + } + private set + + fun updateRoute(qualifiedName: String, route: ScreenRoute) { + routes = routes.toMutableMap().apply { + this[qualifiedName] = route + } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainScreen.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainScreen.kt index df17ec2..e91a1e6 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainScreen.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainScreen.kt @@ -16,7 +16,6 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.getValue import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -24,14 +23,17 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.toRoute import com.github.nullptroma.wallenc.presentation.R import com.github.nullptroma.wallenc.presentation.navigation.NavBarItemData import com.github.nullptroma.wallenc.presentation.navigation.NavigationState import com.github.nullptroma.wallenc.presentation.navigation.rememberNavigationState import com.github.nullptroma.wallenc.presentation.screens.main.screens.local.vault.LocalVaultRoute import com.github.nullptroma.wallenc.presentation.screens.main.screens.local.vault.LocalVaultScreen +import com.github.nullptroma.wallenc.presentation.screens.main.screens.local.vault.LocalVaultViewModel import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsRoute import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsScreen +import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsViewModel @OptIn(ExperimentalMaterial3Api::class) @@ -40,13 +42,11 @@ fun MainScreen( modifier: Modifier = Modifier, viewModel: MainViewModel = hiltViewModel(), navState: NavigationState = rememberNavigationState(), - routes: MutableMap = rememberSaveable { - mutableMapOf( - LocalVaultRoute::class.qualifiedName!! to LocalVaultRoute(), - RemoteVaultsRoute::class.qualifiedName!! to RemoteVaultsRoute() - ) - } ) { + val routes = viewModel.routes + val localVaultViewModel: LocalVaultViewModel = hiltViewModel() + val remoteVaultsViewModel: RemoteVaultsViewModel = hiltViewModel() + val topLevelNavBarItems = remember { mapOf( LocalVaultRoute::class.qualifiedName!! to NavBarItemData( @@ -94,14 +94,21 @@ fun MainScreen( }, exitTransition = { fadeOut(tween(200)) }) { - LocalVaultScreen(modifier = Modifier.padding(innerPaddings)) + val route: LocalVaultRoute = it.toRoute() + LocalVaultScreen( + modifier = Modifier.padding(innerPaddings), + viewModel = localVaultViewModel + ) } composable(enterTransition = { fadeIn(tween(200)) }, exitTransition = { fadeOut(tween(200)) }) { - RemoteVaultsScreen(modifier = Modifier.padding(innerPaddings)) + RemoteVaultsScreen( + modifier = Modifier.padding(innerPaddings), + viewModel = remoteVaultsViewModel + ) } } } diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainViewModel.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainViewModel.kt index 2c859e5..40a82df 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainViewModel.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/MainViewModel.kt @@ -1,9 +1,33 @@ package com.github.nullptroma.wallenc.presentation.screens.main -import androidx.lifecycle.ViewModel +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi +import androidx.lifecycle.viewmodel.compose.saveable +import com.github.nullptroma.wallenc.presentation.screens.ScreenRoute +import com.github.nullptroma.wallenc.presentation.screens.main.screens.local.vault.LocalVaultRoute +import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsRoute +import com.github.nullptroma.wallenc.presentation.viewmodel.ViewModelBase import dagger.hilt.android.lifecycle.HiltViewModel @HiltViewModel -class MainViewModel @javax.inject.Inject constructor(): ViewModel() { +class MainViewModel @javax.inject.Inject constructor(savedStateHandle: SavedStateHandle) : + ViewModelBase(MainScreenState("default string")) { + @OptIn(SavedStateHandleSaveableApi::class) + var routes by savedStateHandle.saveable { + mutableStateOf( + mapOf( + LocalVaultRoute::class.qualifiedName!! to LocalVaultRoute(), + RemoteVaultsRoute::class.qualifiedName!! to RemoteVaultsRoute() + ) + ) + } + private set + + fun updateRoute(qualifiedName: String, route: ScreenRoute) { + routes = routes.toMutableMap().apply { + this[qualifiedName] = route + } + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultScreen.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultScreen.kt index 314c719..cc12692 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultScreen.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultScreen.kt @@ -3,13 +3,17 @@ package com.github.nullptroma.wallenc.presentation.screens.main.screens.local.va import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle @OptIn(ExperimentalMaterial3Api::class) @Composable fun LocalVaultScreen(modifier: Modifier = Modifier, viewModel: LocalVaultViewModel = hiltViewModel()) { - Text("Local vault screen") + + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + Text(uiState.value) } \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt index f2922c7..d8f7c1b 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt @@ -1,10 +1,11 @@ package com.github.nullptroma.wallenc.presentation.screens.main.screens.local.vault -import androidx.lifecycle.ViewModel +import com.github.nullptroma.wallenc.presentation.viewmodel.ViewModelBase import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel -class LocalVaultViewModel @Inject constructor(): ViewModel() { +class LocalVaultViewModel @Inject constructor() + : ViewModelBase(LocalVaultScreenState("default")) { } \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/remotes/RemoteVaultsViewModel.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/remotes/RemoteVaultsViewModel.kt index 7700370..abbe5bf 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/remotes/RemoteVaultsViewModel.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/remotes/RemoteVaultsViewModel.kt @@ -1,10 +1,11 @@ package com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes -import androidx.lifecycle.ViewModel +import com.github.nullptroma.wallenc.presentation.viewmodel.ViewModelBase import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel -class RemoteVaultsViewModel @Inject constructor(): ViewModel() { +class RemoteVaultsViewModel @Inject constructor() : + ViewModelBase(RemoteVaultsScreenState("")) { } \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsRoute.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsRoute.kt index 2faaac9..46b9fc9 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsRoute.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsRoute.kt @@ -6,4 +6,4 @@ import kotlinx.serialization.Serializable @Serializable @Parcelize -class SettingsRoute(val text: String): ScreenRoute() +class SettingsRoute: ScreenRoute() diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreen.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreen.kt index fd6855e..cd27458 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreen.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreen.kt @@ -11,9 +11,9 @@ import androidx.compose.ui.res.stringResource import com.github.nullptroma.wallenc.presentation.R @Composable -fun SettingsScreen(modifier: Modifier, text: String) { +fun SettingsScreen(modifier: Modifier, viewModel: SettingsViewModel) { Column (modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { Text(text = stringResource(id = R.string.settings_title)) - Text(text = text) +// Text(text = viewModel) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreenState.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreenState.kt new file mode 100644 index 0000000..38832d1 --- /dev/null +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsScreenState.kt @@ -0,0 +1,3 @@ +package com.github.nullptroma.wallenc.presentation.screens.settings + +data class SettingsScreenState(val value: String) \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsViewModel.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsViewModel.kt new file mode 100644 index 0000000..0cdc3bb --- /dev/null +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/settings/SettingsViewModel.kt @@ -0,0 +1,9 @@ +package com.github.nullptroma.wallenc.presentation.screens.settings + +import com.github.nullptroma.wallenc.presentation.viewmodel.ViewModelBase +import dagger.hilt.android.lifecycle.HiltViewModel + +@HiltViewModel +class SettingsViewModel @javax.inject.Inject constructor() : + ViewModelBase(SettingsScreenState("default string")) { +} \ No newline at end of file diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/viewmodel/ViewModelBase.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/viewmodel/ViewModelBase.kt new file mode 100644 index 0000000..defe203 --- /dev/null +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/viewmodel/ViewModelBase.kt @@ -0,0 +1,14 @@ +package com.github.nullptroma.wallenc.presentation.viewmodel + + +import androidx.lifecycle.ViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +abstract class ViewModelBase(initState: TState) : ViewModel() { + protected val mutableUiState = MutableStateFlow(initState) + + val uiState: StateFlow + get() = mutableUiState.asStateFlow() +} \ No newline at end of file