Skip to content

Commit

Permalink
mod/#12: my 마이 화면 baseviewmodel, uiEvent, uiSideEffect, uiState 사용으로 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
kangyein9892 committed Dec 17, 2024
1 parent 4753dd3 commit 7d6bff0
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 33 deletions.
23 changes: 12 additions & 11 deletions presentation/src/main/java/org/sopt/and/presentation/my/MyScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import org.sopt.and.presentation.component.ContentsView
import org.sopt.and.presentation.component.PairTextView
import org.sopt.and.presentation.delegate.NetworkState
import org.sopt.and.presentation.extension.noRippleClickable
import org.sopt.and.presentation.my.contract.MyEvent
import org.sopt.and.presentation.my.sideeffect.MySideEffect
import org.sopt.and.presentation.my.viewmodel.MyViewModel
import org.sopt.and.presentation.ui.theme.FirstGrey
Expand All @@ -55,33 +56,33 @@ fun MyScreen(
modifier: Modifier = Modifier,
viewModel: MyViewModel = hiltViewModel()
) {
LaunchedEffect(viewModel.state) {
if(viewModel.state.value.hobby == DEFAULT_STRING) viewModel.getMyHobby()
LaunchedEffect(viewModel.uiState) {
if(viewModel.uiState.value.hobby == DEFAULT_STRING) viewModel.getMyHobby()
}

Column(
modifier = modifier.fillMaxSize()
) {

val state by viewModel.state.collectAsStateWithLifecycle()
val state by viewModel.uiState.collectAsStateWithLifecycle()

val lifecycleOwner = LocalLifecycleOwner.current
val context = LocalContext.current
val snackBarHostState = remember { SnackbarHostState() }

LaunchedEffect(viewModel.intent, lifecycleOwner){
viewModel.intent.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
.collect{ intent ->
when(intent) {
MySideEffect.Logout -> {
LaunchedEffect(viewModel.sideEffect, lifecycleOwner){
viewModel.sideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
.collect{ sideEffect ->
when(sideEffect) {
MySideEffect.NavigateToSignIn -> {
viewModel.clearUserPreference()
snackBarHostState.showSnackbar(
message = context.getString(R.string.my_logout_text)
)
onLogout()
}
is MySideEffect.SnackBar -> snackBarHostState.showSnackbar(context.getString(intent.message))
is MySideEffect.SnackBarText -> snackBarHostState.showSnackbar(intent.message)
is MySideEffect.SnackBar -> snackBarHostState.showSnackbar(context.getString(sideEffect.message))
is MySideEffect.SnackBarText -> snackBarHostState.showSnackbar(sideEffect.message)
}
}
}
Expand Down Expand Up @@ -183,7 +184,7 @@ fun MyScreen(
.align(Alignment.CenterHorizontally)
.noRippleClickable(
onClick = {
viewModel.onLogOutButtonClick()
viewModel.setEvent(MyEvent.OnLogoutButtonClick)
}
)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.and.presentation.my.contract

import org.sopt.and.presentation.util.base.UiEvent

sealed class MyEvent: UiEvent {
data class GetMyHobby(val token: String): MyEvent()
data object OnLogoutButtonClick: MyEvent()
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.sopt.and.presentation.my.model

import org.sopt.and.presentation.util.KeyUtil.DEFAULT_STRING
import org.sopt.and.presentation.util.base.UiState

data class MyState(
val hobby: String = DEFAULT_STRING
)
): UiState
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.sopt.and.presentation.my.sideeffect

import androidx.annotation.StringRes
import org.sopt.and.presentation.util.base.UiSideEffect

sealed class MySideEffect {
sealed class MySideEffect: UiSideEffect {
data class SnackBar(@StringRes val message: Int): MySideEffect()
data class SnackBarText(val message: String): MySideEffect()
data object Logout: MySideEffect()
data object NavigateToSignIn: MySideEffect()
}
Original file line number Diff line number Diff line change
@@ -1,59 +1,61 @@
package org.sopt.and.presentation.my.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.sopt.and.domain.exception.onError
import org.sopt.and.domain.exception.onSuccess
import org.sopt.and.domain.repository.UserRepository
import org.sopt.and.presentation.delegate.NetworkDelegate
import org.sopt.and.presentation.my.contract.MyEvent
import org.sopt.and.presentation.my.model.MyState
import org.sopt.and.presentation.my.sideeffect.MySideEffect
import org.sopt.and.presentation.sign.signin.sideeffect.SignInSideEffect
import org.sopt.and.presentation.util.base.BaseViewModel
import javax.inject.Inject

@HiltViewModel
class MyViewModel @Inject constructor(
private val userRepository: UserRepository,
private val networkDelegate: NetworkDelegate
): ViewModel() {
): BaseViewModel<MyState, MyEvent, MySideEffect>() {

private val _state = MutableStateFlow(MyState())
val state = _state.asStateFlow()
override fun createInitialState(): MyState = MyState()

private val _intent = MutableSharedFlow<MySideEffect>()
val intent = _intent.asSharedFlow()
override suspend fun handleEvent(event: MyEvent) {
when(event) {
MyEvent.OnLogoutButtonClick -> {
navigateToSignIn()
}
is MyEvent.GetMyHobby -> {
getMyHobby()
}
}
}

val networkState get() = networkDelegate.networkState

fun getMyHobby() = viewModelScope.launch {
val token = userRepository.getToken()
userRepository.getMyHobby(token).onSuccess { result ->
_state.update {
it.copy(hobby = result.hobby)
}
setState { copy(hobby = result.hobby) }
networkDelegate.handleNetworkSuccess()
}.onError {
networkDelegate.handleGetMyHobbyError(it)
}
}

fun onLogOutButtonClick() = viewModelScope.launch {
_intent.emit(MySideEffect.Logout)
private fun navigateToSignIn() = viewModelScope.launch {
delay(100)
setSideEffect(MySideEffect.NavigateToSignIn)
}

fun clearUserPreference() = viewModelScope.launch {
userRepository.clearUserPreference()
}

suspend fun handleMyIntentError(message: String) {
_intent.emit(MySideEffect.SnackBarText(message))
fun handleMyIntentError(message: String) = viewModelScope.launch {
setSideEffect(MySideEffect.SnackBarText(message))
}

}

0 comments on commit 7d6bff0

Please sign in to comment.