Skip to content

Commit

Permalink
feat/#14: SignIn MVI 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
boiledEgg-s committed Dec 12, 2024
1 parent 5fedc56 commit 2b47925
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 56 deletions.
36 changes: 24 additions & 12 deletions app/src/main/java/org/sopt/and/presentation/signin/SignInScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ import org.sopt.and.core.extension.showWavveSnackBar
import org.sopt.and.core.extension.toast
import org.sopt.and.core.preference.PreferenceUtil.Companion.LocalPreference
import org.sopt.and.presentation.signin.component.SignInExtraServiceGroup
import org.sopt.and.presentation.signin.state.SignInUiState
import org.sopt.and.presentation.signin.contract.SignInEvent
import org.sopt.and.presentation.signin.contract.SignInSideEffect
import org.sopt.and.presentation.signin.contract.SignInUiState

@Composable
fun SignInRoute(
Expand All @@ -61,14 +63,16 @@ fun SignInRoute(
viewModel.sideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
.collect { sideEffect ->
when (sideEffect) {
is SignInSideEffect.Toast -> context.toast(
context.getString(sideEffect.message)
)
is SignInSideEffect.ShowToast -> {
context.toast(sideEffect.message)
}

is SignInSideEffect.SnackBar -> snackBarHost.showWavveSnackBar(
context = context,
message = sideEffect.message
)
is SignInSideEffect.ShowSnackBar -> {
snackBarHost.showWavveSnackBar(
context = context,
message = sideEffect.message
)
}

is SignInSideEffect.NavigateToHome -> {
with(preference) {
Expand All @@ -88,10 +92,18 @@ fun SignInRoute(
SignInScreen(
uiState = uiState,
snackBarHost = snackBarHost,
onIdChange = viewModel::updateId,
onPasswordChange = viewModel::updatePassword,
onLoginClick = viewModel::onSignInButtonClick,
onSignUpClick = viewModel::onSignUpButtonClick,
onIdChange = { newValue ->
viewModel.setEvent(SignInEvent.OnIdTextFieldChanged(newValue))
},
onPasswordChange = { newValue ->
viewModel.setEvent(SignInEvent.OnPasswordTextFieldChanged(newValue))
},
onLoginClick = {
viewModel.setEvent(SignInEvent.OnSignInButtonClicked)
},
onSignUpClick = {
viewModel.setEvent(SignInEvent.OnSignUpButtonClicked)
},
modifier = modifier
)
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,55 +1,57 @@
package org.sopt.and.presentation.signin

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.launch
import org.sopt.and.core.viewmodel.BaseViewModel
import org.sopt.and.domain.entity.User
import org.sopt.and.domain.usecase.SignInUseCase
import org.sopt.and.presentation.signin.state.SignInUiState
import org.sopt.and.presentation.signin.contract.SignInEvent
import org.sopt.and.presentation.signin.contract.SignInSideEffect
import org.sopt.and.presentation.signin.contract.SignInUiState
import javax.inject.Inject

@HiltViewModel
class SignInViewModel @Inject constructor(
private val signInUseCase: SignInUseCase
) : ViewModel() {
private var _uiState = MutableStateFlow(SignInUiState())
val uiState = _uiState.asStateFlow()
) : BaseViewModel<SignInUiState, SignInSideEffect, SignInEvent>() {

private var _sideEffect = MutableSharedFlow<SignInSideEffect>()
val sideEffect = _sideEffect.asSharedFlow()
override fun createInitialState(): SignInUiState = SignInUiState()

fun updateId(id: String) = _uiState.update { currentState ->
currentState.copy(
id = id
)
}
override suspend fun handleEvent(event: SignInEvent) {
when (event) {
is SignInEvent.OnIdTextFieldChanged -> {
setState { copy(id = event.id) }
}

is SignInEvent.OnPasswordTextFieldChanged -> {
setState { copy(password = event.password) }
}

fun updatePassword(password: String) = _uiState.update { currentState ->
currentState.copy(
password = password
)
SignInEvent.OnSignInButtonClicked -> {
postSignIn()
}

SignInEvent.OnSignUpButtonClicked -> {
navigateToSignUp()
}
}
}

fun onSignUpButtonClick() {
private fun navigateToSignUp() {
viewModelScope.launch {
_sideEffect.emit(SignInSideEffect.NavigateToSignUp)
setSideEffect(SignInSideEffect.NavigateToSignUp)
}
}

fun onSignInButtonClick() = viewModelScope.launch {
val user = with(_uiState.value) { User(id, password, "") }
private fun postSignIn() = viewModelScope.launch {
val user = with(currentState) { User(id, password, "") }
signInUseCase.invoke(user).onSuccess { response ->
response.token?.run {
_sideEffect.emit(SignInSideEffect.NavigateToHome(this))
setSideEffect(SignInSideEffect.NavigateToHome(this))
}
}.onFailure { throwable ->
_sideEffect.emit(SignInSideEffect.SnackBar(throwable.message.orEmpty()))
setSideEffect(SignInSideEffect.ShowSnackBar(throwable.message.orEmpty()))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.and.presentation.signin.contract

import org.sopt.and.core.viewmodel.UiEvent

sealed class SignInEvent: UiEvent {
data class OnIdTextFieldChanged(val id: String): SignInEvent()
data class OnPasswordTextFieldChanged(val password: String): SignInEvent()
data object OnSignInButtonClicked: SignInEvent()
data object OnSignUpButtonClicked: SignInEvent()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.and.presentation.signin.contract

import org.sopt.and.core.viewmodel.UiSideEffect

sealed interface SignInSideEffect: UiSideEffect {
data class ShowToast(val message: String) : SignInSideEffect
data class ShowSnackBar(val message: String) : SignInSideEffect
data class NavigateToHome(val token: String) : SignInSideEffect
data object NavigateToSignUp : SignInSideEffect
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.and.presentation.signin.contract

import org.sopt.and.core.viewmodel.UiState


data class SignInUiState(
val id: String = "",
val password: String = ""
): UiState

This file was deleted.

0 comments on commit 2b47925

Please sign in to comment.