Skip to content

Commit

Permalink
[Ref]#11 MyPage MVI패턴 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
angryPodo committed Dec 16, 2024
1 parent 0724052 commit 7027144
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.and.presentation.mypage

sealed interface MyPageEffect {
data class ShowError(val message: String) : MyPageEffect
data object NavigateToPurchase : MyPageEffect
data object NavigateToNotifications : MyPageEffect
data object NavigateToSettings : MyPageEffect
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.and.presentation.mypage

sealed interface MyPageIntent {
data object LoadMyHobby : MyPageIntent
data object RefreshData : MyPageIntent
data object OnPurchaseClick : MyPageIntent
}
36 changes: 22 additions & 14 deletions app/src/main/java/org/sopt/and/presentation/mypage/MyPageScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,26 @@ fun MyPageScreen(
viewModel: MyPageViewModel = hiltViewModel(),
modifier: Modifier = Modifier
) {
val uiState by viewModel.uiState.collectAsState()
val state by viewModel.state.collectAsState()
val snackBarHostState = remember { SnackbarHostState() }

LaunchedEffect(uiState.errorMessage) {
uiState.errorMessage?.let { message ->
snackBarHostState.showSnackbar(message)
// Effect handling
LaunchedEffect(Unit) {
viewModel.effect.collect { effect ->
when (effect) {
is MyPageEffect.ShowError -> {
snackBarHostState.showSnackbar(effect.message)
}
MyPageEffect.NavigateToPurchase -> {
// Handle navigation to purchase
}
MyPageEffect.NavigateToNotifications -> {
// Handle navigation to notifications
}
MyPageEffect.NavigateToSettings -> {
// Handle navigation to settings
}
}
}
}

Expand All @@ -43,22 +57,22 @@ fun MyPageScreen(
.background(Color.Black)
) {
MyPageTopBar(
hobby = uiState.hobby,
isLoading = uiState.isLoading
hobby = state.hobby,
isLoading = state.isLoading,
)

Spacer(modifier = Modifier.height(1.dp))

PurchaseText(
title = "첫 결재 시 첫 달 100원!",
onClick = { }
onClick = { viewModel.processIntent(MyPageIntent.OnPurchaseClick) }
)

Spacer(modifier = Modifier.height(1.dp))

PurchaseText(
title = "현재 보유하신 이용권이 없습니다.",
onClick = { }
onClick = { viewModel.processIntent(MyPageIntent.OnPurchaseClick) }
)

MyMenuSection(text = "전체 시청내역")
Expand All @@ -79,9 +93,3 @@ fun MyPageScreen(
modifier = Modifier.padding(16.dp)
)
}

@Preview(showBackground = true)
@Composable
private fun MyPageScreenPreview() {
MyPageScreen()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.and.presentation.mypage

data class MyPageState(
val hobby: String = "",
val isLoading: Boolean = false,
val hasTicket: Boolean = false
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package org.sopt.and.presentation.mypage
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.sopt.and.domain.usecase.auth.GetMyHobbyUseCase
Expand All @@ -15,30 +17,44 @@ import javax.inject.Inject
class MyPageViewModel @Inject constructor(
private val getMyHobbyUseCase: GetMyHobbyUseCase
) : ViewModel() {
private val _uiState = MutableStateFlow(MyPageUiState())
val uiState: StateFlow<MyPageUiState> = _uiState.asStateFlow()
private val _state = MutableStateFlow(MyPageState())
val state = _state.asStateFlow()

data class MyPageUiState(
val hobby: String = "",
val isLoading: Boolean = false,
val errorMessage: String? = null
)
private val _effect = Channel<MyPageEffect>()
val effect = _effect.receiveAsFlow()

init {
fetchMyHobby()
processIntent(MyPageIntent.LoadMyHobby)
}

fun processIntent(intent: MyPageIntent) {
when (intent) {
MyPageIntent.LoadMyHobby -> fetchMyHobby()
MyPageIntent.RefreshData -> fetchMyHobby()
MyPageIntent.OnPurchaseClick -> handlePurchaseClick()
}
}

private fun fetchMyHobby() {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true) }
_state.update { it.copy(isLoading = true) }

getMyHobbyUseCase()
.onSuccess { hobby ->
_uiState.update { it.copy(hobby = hobby) }
_state.update { it.copy(hobby = hobby) }
}
.onFailure { exception ->
_uiState.update { it.copy(errorMessage = exception.message) }
_effect.send(MyPageEffect.ShowError(exception.message ?: "Unknown error"))
}
_uiState.update { it.copy(isLoading = false) }

_state.update { it.copy(isLoading = false) }
}
}

private fun handlePurchaseClick() {
viewModelScope.launch {
_effect.send(MyPageEffect.NavigateToPurchase)
}
}

}

0 comments on commit 7027144

Please sign in to comment.