twoFa -> validation naming; fixes for preview for screens (separating view model from ui); some improvements & fixes

This commit is contained in:
2024-07-13 22:45:49 +03:00
parent dfdc48b682
commit 733627f935
98 changed files with 1611 additions and 1637 deletions
@@ -5,14 +5,18 @@ import com.meloda.app.fast.common.UserConfig
import com.meloda.app.fast.common.VkConstants
import com.meloda.app.fast.common.extensions.listenValue
import com.meloda.app.fast.common.extensions.setValue
import com.meloda.app.fast.data.State
import com.meloda.app.fast.data.api.users.UsersUseCase
import com.meloda.app.fast.data.processState
import com.meloda.app.fast.model.BaseError
import com.meloda.app.fast.network.VkErrorCodes
import com.meloda.app.fast.profile.model.ProfileScreenState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
interface ProfileViewModel {
val screenState: StateFlow<ProfileScreenState>
val baseError: StateFlow<BaseError?>
}
class ProfileViewModelImpl(
@@ -20,6 +24,7 @@ class ProfileViewModelImpl(
) : ViewModel(), ProfileViewModel {
override val screenState = MutableStateFlow(ProfileScreenState.EMPTY)
override val baseError = MutableStateFlow<BaseError?>(null)
init {
getLocalAccountInfo()
@@ -30,6 +35,16 @@ class ProfileViewModelImpl(
.listenValue { state ->
state.processState(
error = { error ->
if (error is State.Error.ApiError) {
when (error.errorCode) {
VkErrorCodes.UserAuthorizationFailed -> {
baseError.setValue { BaseError.SessionExpired }
}
else -> Unit
}
}
screenState.setValue { old ->
old.copy(
avatarUrl = null,
@@ -7,24 +7,24 @@ import com.meloda.app.fast.common.extensions.navigation.sharedViewModel
import com.meloda.app.fast.model.BaseError
import com.meloda.app.fast.profile.ProfileViewModel
import com.meloda.app.fast.profile.ProfileViewModelImpl
import com.meloda.app.fast.profile.presentation.ProfileScreen
import com.meloda.app.fast.profile.presentation.ProfileRoute
import kotlinx.serialization.Serializable
@Serializable
object Profile
fun NavGraphBuilder.profileRoute(
fun NavGraphBuilder.profileScreen(
onError: (BaseError) -> Unit,
onNavigateToSettings: () -> Unit,
onSettingsButtonClicked: () -> Unit,
navController: NavController
) {
composable<Profile> {
val viewModel: ProfileViewModel =
it.sharedViewModel<ProfileViewModelImpl>(navController = navController)
ProfileScreen(
ProfileRoute(
onError = onError,
onNavigateToSettings = onNavigateToSettings,
onSettingsButtonClicked = onSettingsButtonClicked,
viewModel = viewModel
)
}
@@ -1,6 +1,5 @@
package com.meloda.app.fast.profile.presentation
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@@ -38,27 +37,42 @@ import coil.compose.AsyncImage
import com.meloda.app.fast.model.BaseError
import com.meloda.app.fast.profile.ProfileViewModel
import com.meloda.app.fast.profile.ProfileViewModelImpl
import com.meloda.app.fast.profile.model.ProfileScreenState
import org.koin.androidx.compose.koinViewModel
import com.meloda.app.fast.designsystem.R as UiR
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProfileScreen(
fun ProfileRoute(
onError: (BaseError) -> Unit,
onNavigateToSettings: () -> Unit,
onSettingsButtonClicked: () -> Unit,
viewModel: ProfileViewModel = koinViewModel<ProfileViewModelImpl>()
) {
val screenState by viewModel.screenState.collectAsStateWithLifecycle()
val baseError by viewModel.baseError.collectAsStateWithLifecycle()
Log.d("ProfileScreen", "isLoading: ${screenState.isLoading}")
ProfileScreen(
screenState = screenState,
baseError = baseError,
onSettingsButtonClicked = onSettingsButtonClicked
)
}
// TODO: 13/07/2024, Danil Nikolaev: handle expired session
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProfileScreen(
screenState: ProfileScreenState = ProfileScreenState.EMPTY,
baseError: BaseError? = null,
onSettingsButtonClicked: () -> Unit = {},
) {
Scaffold(
topBar = {
TopAppBar(
title = {},
actions = {
IconButton(onClick = onNavigateToSettings) {
IconButton(onClick = onSettingsButtonClicked) {
Icon(
imageVector = Icons.Rounded.Settings,
contentDescription = null