Skip to content

Commit

Permalink
feat/#12: signUp 회원가입 화면 baseviewmodel, uiEvent, uiSideEffect, uiStat…
Browse files Browse the repository at this point in the history
…e 사용으로 수정
  • Loading branch information
kangyein9892 committed Dec 17, 2024
1 parent 73964a1 commit 4753dd3
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
Expand All @@ -29,7 +28,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.launch
import org.sopt.and.presentation.R
import org.sopt.and.presentation.component.CloseTopBar
import org.sopt.and.presentation.component.DividerWithText
Expand All @@ -39,7 +37,8 @@ import org.sopt.and.presentation.component.WavveActionTextField
import org.sopt.and.presentation.component.WavveTextField
import org.sopt.and.presentation.delegate.NetworkState
import org.sopt.and.presentation.extension.noRippleClickable
import org.sopt.and.presentation.sign.signup.intent.SignUpSideEffect
import org.sopt.and.presentation.sign.signup.contract.SignUpEvent
import org.sopt.and.presentation.sign.signup.contract.SignUpSideEffect
import org.sopt.and.presentation.sign.signup.viewmodel.SignUpViewModel
import org.sopt.and.presentation.ui.theme.ThirdGrey
import org.sopt.and.presentation.ui.theme.White
Expand All @@ -53,24 +52,17 @@ fun SignUpScreen(
viewModel: SignUpViewModel = hiltViewModel()
) {

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

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

LaunchedEffect(viewModel.intent) {
viewModel.intent.collect { intent ->
when(intent) {
SignUpSideEffect.SignUp -> {
navigationToSignIn(state.id, state.password)
}
is SignUpSideEffect.SnackBar -> {
snackBarHostState.showSnackbar(context.getString(intent.message))
}

is SignUpSideEffect.SnackBarText -> {
snackBarHostState.showSnackbar(intent.message)
}
LaunchedEffect(viewModel.sideEffect) {
viewModel.sideEffect.collect { sideEffect ->
when(sideEffect) {
is SignUpSideEffect.SnackBar -> snackBarHostState.showSnackbar(context.getString(sideEffect.message))
is SignUpSideEffect.SnackBarText -> snackBarHostState.showSnackbar(sideEffect.message)
SignUpSideEffect.NavigateToSignIn -> navigationToSignIn(state.id, state.password)
}
}
}
Expand Down Expand Up @@ -122,7 +114,7 @@ fun SignUpScreen(
WavveTextField(
value = state.id,
hint = stringResource(R.string.signup_login_hint),
onValueChange = { viewModel.updateId(it) },
onValueChange = { viewModel.setEvent(SignUpEvent.OnIdChanged(it)) },
modifier = Modifier.padding(horizontal = 8.dp)
)

Expand All @@ -133,7 +125,7 @@ fun SignUpScreen(
WavveActionTextField(
value = state.password,
hint = stringResource(R.string.signup_password_hint),
onValueChange = { viewModel.updatePassword(it) },
onValueChange = { viewModel.setEvent(SignUpEvent.OnPasswordChanged(it)) },
modifier = Modifier.padding(horizontal = 8.dp),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Next
Expand All @@ -147,7 +139,7 @@ fun SignUpScreen(
WavveTextField(
value = state.hobby,
hint = stringResource(R.string.signup_hobby_hint),
onValueChange = { viewModel.updateHobby(it) },
onValueChange = { viewModel.setEvent(SignUpEvent.OnHobbyChanged(it)) },
modifier = Modifier.padding(horizontal = 8.dp),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.and.presentation.sign.signup.contract

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

sealed class SignUpEvent: UiEvent {
data class OnIdChanged(val id: String) : SignUpEvent()
data class OnPasswordChanged(val password: String) : SignUpEvent()
data class OnHobbyChanged(val hobby: String) : SignUpEvent()
data object OnSignUpButtonClick : SignUpEvent()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.sopt.and.presentation.sign.signup.contract

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

sealed class SignUpSideEffect: UiSideEffect {
data class SnackBar(@StringRes val message: Int) : SignUpSideEffect()
data class SnackBarText(val message: String): SignUpSideEffect()
data object NavigateToSignIn: SignUpSideEffect()
}

Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.sopt.and.presentation.sign.signup.model
package org.sopt.and.presentation.sign.signup.contract

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

data class SignUpState(
val id: String = DEFAULT_STRING,
val password: String = DEFAULT_STRING,
val hobby: String = DEFAULT_STRING
)
): UiState

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,71 +1,74 @@
package org.sopt.and.presentation.sign.signup.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.model.User
import org.sopt.and.domain.repository.UserRepository
import org.sopt.and.presentation.R
import org.sopt.and.presentation.delegate.NetworkDelegate
import org.sopt.and.presentation.sign.signup.intent.SignUpSideEffect
import org.sopt.and.presentation.sign.signup.model.SignUpState
import org.sopt.and.presentation.sign.signup.contract.SignUpEvent
import org.sopt.and.presentation.sign.signup.contract.SignUpSideEffect
import org.sopt.and.presentation.sign.signup.contract.SignUpState
import org.sopt.and.presentation.util.base.BaseViewModel
import javax.inject.Inject

@HiltViewModel
class SignUpViewModel @Inject constructor(
private val userRepository: UserRepository,
private val networkDelegate: NetworkDelegate
): ViewModel() {

private var _state = MutableStateFlow(SignUpState())
val state = _state.asStateFlow()

private var _intent = MutableSharedFlow<SignUpSideEffect>()
val intent = _intent.asSharedFlow()
): BaseViewModel<SignUpState, SignUpEvent, SignUpSideEffect>() {

val networkState get() = networkDelegate.networkState

fun updateId(id: String) = _state.update {
it.copy(id = id)
}

fun updatePassword(password: String) = _state.update {
it.copy(password = password)
}
override fun createInitialState(): SignUpState = SignUpState()

fun updateHobby(hobby: String) = _state.update {
it.copy(hobby = hobby)
override suspend fun handleEvent(event: SignUpEvent) {
when(event) {
is SignUpEvent.OnIdChanged -> {
setState { copy(id = event.id) }
}
is SignUpEvent.OnPasswordChanged -> {
setState { copy(password = event.password) }
}
is SignUpEvent.OnHobbyChanged -> {
setState { copy(hobby = event.hobby) }
}
SignUpEvent.OnSignUpButtonClick -> {
signUp()
}
}
}

fun signUp() = viewModelScope.launch {
val currentState = _state.value
val currentState = uiState.value
val user = User(
username = currentState.id,
password = currentState.password,
hobby = currentState.hobby
)
userRepository.signUp(user).onSuccess {
networkDelegate.handleNetworkSuccess()
navigateToSignIn()
}.onError {
networkDelegate.handleSignUpError(it)
}
}

suspend fun handleSignUpIntentError(message: String) {
_intent.emit(SignUpSideEffect.SnackBarText(message))
private fun navigateToSignIn() = viewModelScope.launch {
delay(100)
setSideEffect(SignUpSideEffect.NavigateToSignIn)
}

fun handleSignUpIntentError(message: String) = viewModelScope.launch {
setSideEffect(SignUpSideEffect.SnackBarText(message))
}

suspend fun handleSignUpIntentSuccess() {
_intent.emit(SignUpSideEffect.SnackBar(R.string.signup_success_text))
_intent.emit(SignUpSideEffect.SignUp)
fun handleSignUpIntentSuccess() = viewModelScope.launch {
setSideEffect(SignUpSideEffect.SnackBar(R.string.signup_success_text))
}

}
Expand Down

0 comments on commit 4753dd3

Please sign in to comment.