Добавлена ViewModelBase

This commit is contained in:
Roman Pytkov
2024-11-23 13:27:37 +03:00
parent bd0183da79
commit 0407f04162
13 changed files with 127 additions and 41 deletions

View File

@@ -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<SettingsRoute>(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)
}
}
}

View File

@@ -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>(Unit) {
@OptIn(SavedStateHandleSaveableApi::class)
var routes by savedStateHandle.saveable {
mutableStateOf(
mapOf<String, ScreenRoute>(
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
}
}
}

View File

@@ -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<String, MainRoute> = 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<RemoteVaultsRoute>(enterTransition = {
fadeIn(tween(200))
}, exitTransition = {
fadeOut(tween(200))
}) {
RemoteVaultsScreen(modifier = Modifier.padding(innerPaddings))
RemoteVaultsScreen(
modifier = Modifier.padding(innerPaddings),
viewModel = remoteVaultsViewModel
)
}
}
}

View File

@@ -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>(MainScreenState("default string")) {
@OptIn(SavedStateHandleSaveableApi::class)
var routes by savedStateHandle.saveable {
mutableStateOf(
mapOf<String, ScreenRoute>(
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
}
}
}

View File

@@ -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)
}

View File

@@ -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>(LocalVaultScreenState("default")) {
}

View File

@@ -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>(RemoteVaultsScreenState("")) {
}

View File

@@ -6,4 +6,4 @@ import kotlinx.serialization.Serializable
@Serializable
@Parcelize
class SettingsRoute(val text: String): ScreenRoute()
class SettingsRoute: ScreenRoute()

View File

@@ -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)
}
}

View File

@@ -0,0 +1,3 @@
package com.github.nullptroma.wallenc.presentation.screens.settings
data class SettingsScreenState(val value: String)

View File

@@ -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>(SettingsScreenState("default string")) {
}

View File

@@ -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<TState>(initState: TState) : ViewModel() {
protected val mutableUiState = MutableStateFlow<TState>(initState)
val uiState: StateFlow<TState>
get() = mutableUiState.asStateFlow()
}