refactor: simplify Profile feature state management and update ViewModel
This commit is contained in:
@@ -210,7 +210,6 @@ fun MainScreen(
|
||||
)
|
||||
profileScreen(
|
||||
activity = activity,
|
||||
onError = onError,
|
||||
onSettingsButtonClicked = onSettingsButtonClicked,
|
||||
onPhotoClicked = onPhotoClicked
|
||||
)
|
||||
|
||||
@@ -5,49 +5,33 @@ import androidx.lifecycle.viewModelScope
|
||||
import dev.meloda.fast.common.VkConstants
|
||||
import dev.meloda.fast.common.extensions.listenValue
|
||||
import dev.meloda.fast.common.extensions.setValue
|
||||
import dev.meloda.fast.data.State
|
||||
import dev.meloda.fast.data.UserConfig
|
||||
import dev.meloda.fast.data.processState
|
||||
import dev.meloda.fast.domain.GetLocalUserByIdUseCase
|
||||
import dev.meloda.fast.domain.LoadUserByIdUseCase
|
||||
import dev.meloda.fast.model.BaseError
|
||||
import dev.meloda.fast.network.VkErrorCode
|
||||
import dev.meloda.fast.profile.model.ProfileScreenState
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
interface ProfileViewModel {
|
||||
val screenState: StateFlow<ProfileScreenState>
|
||||
val baseError: StateFlow<BaseError?>
|
||||
}
|
||||
|
||||
class ProfileViewModelImpl(
|
||||
class ProfileViewModel(
|
||||
private val getLocalUserByIdUseCase: GetLocalUserByIdUseCase,
|
||||
private val loadUserByIdUseCase: LoadUserByIdUseCase
|
||||
) : ViewModel(), ProfileViewModel {
|
||||
) : ViewModel() {
|
||||
|
||||
override val screenState = MutableStateFlow(ProfileScreenState.EMPTY)
|
||||
override val baseError = MutableStateFlow<BaseError?>(null)
|
||||
private val screenState = MutableStateFlow(ProfileScreenState.EMPTY)
|
||||
|
||||
init {
|
||||
getLocalAccountInfo()
|
||||
}
|
||||
|
||||
fun screenStateFlow(): StateFlow<ProfileScreenState> = screenState.asStateFlow()
|
||||
|
||||
private fun getLocalAccountInfo() {
|
||||
getLocalUserByIdUseCase(UserConfig.userId)
|
||||
.listenValue(viewModelScope) { state ->
|
||||
state.processState(
|
||||
error = { error ->
|
||||
if (error is State.Error.ApiError) {
|
||||
when (error.errorCode) {
|
||||
VkErrorCode.USER_AUTHORIZATION_FAILED -> {
|
||||
baseError.setValue { BaseError.SessionExpired }
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
error = {
|
||||
screenState.setValue { old ->
|
||||
old.copy(
|
||||
avatarUrl = null,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package dev.meloda.fast.profile.di
|
||||
|
||||
import dev.meloda.fast.profile.ProfileViewModelImpl
|
||||
import dev.meloda.fast.profile.ProfileViewModel
|
||||
import org.koin.core.module.dsl.viewModelOf
|
||||
import org.koin.dsl.module
|
||||
|
||||
val profileModule = module {
|
||||
viewModelOf(::ProfileViewModelImpl)
|
||||
viewModelOf(::ProfileViewModel)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.meloda.fast.profile.navigation
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.compose.composable
|
||||
import dev.meloda.fast.model.BaseError
|
||||
import dev.meloda.fast.profile.ProfileViewModel
|
||||
import dev.meloda.fast.profile.ProfileViewModelImpl
|
||||
import dev.meloda.fast.profile.presentation.ProfileRoute
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.koin.androidx.viewmodel.ext.android.getViewModel
|
||||
@@ -15,19 +15,18 @@ object Profile
|
||||
|
||||
fun NavGraphBuilder.profileScreen(
|
||||
activity: AppCompatActivity,
|
||||
onError: (BaseError) -> Unit,
|
||||
onSettingsButtonClicked: () -> Unit,
|
||||
onPhotoClicked: (url: String) -> Unit
|
||||
) {
|
||||
val viewModel: ProfileViewModel = with(activity) {
|
||||
getViewModel<ProfileViewModelImpl>()
|
||||
}
|
||||
val viewModel: ProfileViewModel = with(activity) { getViewModel() }
|
||||
|
||||
composable<Profile> {
|
||||
val screenState by viewModel.screenStateFlow().collectAsStateWithLifecycle()
|
||||
|
||||
ProfileRoute(
|
||||
onError = onError,
|
||||
screenState = screenState,
|
||||
onSettingsButtonClicked = onSettingsButtonClicked,
|
||||
onPhotoClicked = onPhotoClicked,
|
||||
viewModel = viewModel
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-13
@@ -20,7 +20,6 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
@@ -29,31 +28,21 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import coil.compose.AsyncImage
|
||||
import dev.meloda.fast.model.BaseError
|
||||
import dev.meloda.fast.profile.ProfileViewModel
|
||||
import dev.meloda.fast.profile.ProfileViewModelImpl
|
||||
import dev.meloda.fast.profile.model.ProfileScreenState
|
||||
import dev.meloda.fast.ui.R
|
||||
import dev.meloda.fast.ui.components.SegmentedButtonItem
|
||||
import dev.meloda.fast.ui.components.SegmentedButtonsRow
|
||||
import dev.meloda.fast.ui.util.buildImmutableList
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@Composable
|
||||
fun ProfileRoute(
|
||||
onError: (BaseError) -> Unit,
|
||||
screenState: ProfileScreenState,
|
||||
onSettingsButtonClicked: () -> Unit,
|
||||
onPhotoClicked: (url: String) -> Unit,
|
||||
viewModel: ProfileViewModel = koinViewModel<ProfileViewModelImpl>()
|
||||
) {
|
||||
val screenState by viewModel.screenState.collectAsStateWithLifecycle()
|
||||
val baseError by viewModel.baseError.collectAsStateWithLifecycle()
|
||||
|
||||
ProfileScreen(
|
||||
screenState = screenState,
|
||||
baseError = baseError,
|
||||
onSettingsButtonClicked = onSettingsButtonClicked,
|
||||
onPhotoClicked = onPhotoClicked
|
||||
)
|
||||
@@ -64,7 +53,6 @@ fun ProfileRoute(
|
||||
@Composable
|
||||
fun ProfileScreen(
|
||||
screenState: ProfileScreenState = ProfileScreenState.EMPTY,
|
||||
baseError: BaseError? = null,
|
||||
onSettingsButtonClicked: () -> Unit = {},
|
||||
onPhotoClicked: (url: String) -> Unit = {}
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user