diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/changepassword/ComparePasswordScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/changepassword/ComparePasswordScreen.kt index 7bbf6b0c..713171e4 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/changepassword/ComparePasswordScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/changepassword/ComparePasswordScreen.kt @@ -37,6 +37,7 @@ internal fun ComparePasswordScreen( val context = LocalContext.current val focusManager = LocalFocusManager.current val state by resetPasswordViewModel.collectAsState() + val currentPassword = resetPasswordViewModel.currentPassword resetPasswordViewModel.collectSideEffect { when (it) { @@ -58,7 +59,7 @@ internal fun ComparePasswordScreen( val onPasswordChanged = { password: String -> resetPasswordViewModel.setCurrentPassword(password) - if (state.currentPassword.length != password.length) { + if (currentPassword.length != password.length) { resetPasswordViewModel.setComparePasswordErrorState( comparePasswordErrorState = false, ) @@ -85,7 +86,7 @@ internal fun ComparePasswordScreen( } Spacer(modifier = Modifier.height(28.dp)) JobisBoxTextField( - value = state.currentPassword, + value = currentPassword, onValueChanged = onPasswordChanged, hint = stringResource(id = R.string.hint_original_password), textFieldType = TextFieldType.PASSWORD, @@ -96,7 +97,7 @@ internal fun ComparePasswordScreen( Spacer(modifier = Modifier.weight(1f)) JobisLargeButton( text = stringResource(id = R.string.complete), - enabled = state.currentPassword.isNotEmpty() && !state.comparePasswordErrorState, + enabled = currentPassword.isNotEmpty() && !state.comparePasswordErrorState, onClick = resetPasswordViewModel::comparePassword, ) Spacer(modifier = Modifier.height(32.dp)) diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordScreen.kt index 5d77d0f5..8268a5de 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordScreen.kt @@ -43,8 +43,8 @@ internal fun ResetPasswordScreen( val context = LocalContext.current val state by resetPasswordViewModel.collectAsState() val focusManager = LocalFocusManager.current - val newPassword = state.newPassword - val passwordRepeat = state.passwordRepeat + val newPassword = resetPasswordViewModel.newPassword + val passwordRepeat = resetPasswordViewModel.passwordRepeat val onClick: () -> Unit = { when (getPreviousDestination().toString()) { AuthDestinations.ResetPasswordVerifyEmail -> { diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordVerifyEmailScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordVerifyEmailScreen.kt index c7368ba2..a9345320 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordVerifyEmailScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordVerifyEmailScreen.kt @@ -41,8 +41,8 @@ internal fun ResetPasswordVerifyEmailScreen( val context = LocalContext.current val state by resetPasswordViewModel.collectAsState() val focusManager = LocalFocusManager.current - val email = state.email - val authCode = state.authCode + val email = resetPasswordViewModel.email + val authCode = resetPasswordViewModel.authCode val sendAuthCodeState = state.sendAuthCodeState resetPasswordViewModel.collectSideEffect { diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordViewModel.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordViewModel.kt index 98bf56f6..2746f8f5 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordViewModel.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/resetpassword/ResetPasswordViewModel.kt @@ -1,6 +1,9 @@ package team.retum.jobis_android.feature.auth.resetpassword import androidx.annotation.StringRes +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -40,11 +43,22 @@ internal class ResetPasswordViewModel @Inject constructor( initialState = ResetPasswordState(), ) + var email by mutableStateOf("") + private set + var currentPassword by mutableStateOf("") + private set + var authCode by mutableStateOf("") + private set + var newPassword by mutableStateOf("") + private set + var passwordRepeat by mutableStateOf("") + private set + internal fun sendVerificationCode() = intent { viewModelScope.launch(Dispatchers.IO) { sendVerificationCodeUseCase( sendVerificationCodeParam = SendVerificationCodeParam( - email = state.email, + email = email, authCodeType = AuthCodeType.PASSWORD, ), ).onSuccess { @@ -69,8 +83,8 @@ internal class ResetPasswordViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { verifyEmailUseCase( verifyEmailParam = VerifyEmailParam( - email = state.email, - authCode = state.authCode, + email = email, + authCode = authCode, ), ).onSuccess { postSideEffect(sideEffect = ResetPasswordSideEffect.SuccessVerification) @@ -91,7 +105,7 @@ internal class ResetPasswordViewModel @Inject constructor( internal fun comparePassword() = intent { viewModelScope.launch(Dispatchers.IO) { comparePasswordUseCase( - password = state.currentPassword, + password = currentPassword, ).onSuccess { postSideEffect(sideEffect = ResetPasswordSideEffect.SuccessVerification) }.onFailure { @@ -117,8 +131,8 @@ internal class ResetPasswordViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { changePasswordUseCase( changePasswordParam = ChangePasswordParam( - currentPassword = state.currentPassword, - newPassword = state.newPassword, + currentPassword = currentPassword, + newPassword = newPassword, ), ).onSuccess { postSideEffect(sideEffect = ResetPasswordSideEffect.SuccessChangePassword) @@ -132,8 +146,8 @@ internal class ResetPasswordViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { resetPasswordUseCase( resetPasswordParam = ResetPasswordParam( - email = state.email, - password = state.newPassword, + email = email, + password = newPassword, ), ).onSuccess { postSideEffect(ResetPasswordSideEffect.SuccessResetPassword) @@ -143,64 +157,48 @@ internal class ResetPasswordViewModel @Inject constructor( } } - internal fun setEmail( - email: String, - ) = intent { - reduce { - setEmailErrorState(emailErrorState = false) - state.copy(email = email) - } + internal fun setEmail(email: String) { + this.email = email + setEmailErrorState(emailErrorState = false) } - internal fun setAuthCode( - authCode: String, - ) = intent { + internal fun setAuthCode(authCode: String) { authCode.take(6) + this.authCode = authCode if (authCode.length == 6) { - postSideEffect(ResetPasswordSideEffect.ClearFocus) - } - reduce { - state.copy(authCode = authCode) + intent { + postSideEffect(ResetPasswordSideEffect.ClearFocus) + } } } - internal fun setCurrentPassword( - currentPassword: String, - ) = intent { - reduce { - state.copy( - currentPassword = currentPassword, - ) - } + internal fun setCurrentPassword(currentPassword: String) { + this.currentPassword = currentPassword } - internal fun setNewPassword( - newPassword: String, - ) = intent { - reduce { - with(state) { - copy( - newPassword = newPassword, - passwordFormatErrorState = !Regex(Regex.PASSWORD).matches(newPassword), - passwordRepeatErrorState = newPassword != passwordRepeat && passwordRepeat.isNotBlank(), - ) + internal fun setNewPassword(newPassword: String) { + this.newPassword = newPassword + intent { + reduce { + with(state) { + copy( + passwordFormatErrorState = !Regex(Regex.PASSWORD).matches(newPassword), + passwordRepeatErrorState = newPassword != passwordRepeat && passwordRepeat.isNotBlank(), + ) + } } + setButtonEnabled() } - setButtonEnabled() } - internal fun setPasswordRepeat( - passwordRepeat: String, - ) = intent { - reduce { - with(state) { - copy( - passwordRepeat = passwordRepeat, - passwordRepeatErrorState = newPassword != passwordRepeat, - ) + internal fun setPasswordRepeat(passwordRepeat: String) { + this.passwordRepeat = passwordRepeat + intent { + reduce { + state.copy(passwordRepeatErrorState = newPassword != passwordRepeat) } + setButtonEnabled() } - setButtonEnabled() } private fun setButtonEnabled() = intent { @@ -251,11 +249,6 @@ internal class ResetPasswordViewModel @Inject constructor( } data class ResetPasswordState( - val email: String = "", - val authCode: String = "", - val currentPassword: String = "", - val newPassword: String = "", - val passwordRepeat: String = "", val emailErrorState: Boolean = false, val authCodeErrorState: Boolean = false, val sendAuthCodeState: Boolean = false, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreen.kt index 28fac09a..9cb694fc 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreen.kt @@ -111,8 +111,8 @@ internal fun SignInScreen( } Spacer(modifier = Modifier.height(80.dp)) SignInInputs( - email = state.email, - password = state.password, + email = signInScreenViewModel.email, + password = signInScreenViewModel.password, onEmailChanged = signInScreenViewModel::setEmail, onPasswordChanged = signInScreenViewModel::setPassword, emailError = state.emailError, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreenViewModel.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreenViewModel.kt index f9d04dd3..6c90e60a 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreenViewModel.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signin/SignInScreenViewModel.kt @@ -1,6 +1,9 @@ package team.retum.jobis_android.feature.auth.signin import androidx.annotation.StringRes +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -25,12 +28,17 @@ class SignInScreenViewModel @Inject constructor( override val container = container(SignInState()) + var email by mutableStateOf("") + private set + var password by mutableStateOf("") + private set + internal fun postLogin() = intent { viewModelScope.launch { signInUseCase( param = SignInParam( - accountId = state.email, - password = state.password, + accountId = email, + password = password, isAutoLogin = state.autoSignIn, ), ).onSuccess { @@ -69,23 +77,23 @@ class SignInScreenViewModel @Inject constructor( } } - internal fun setEmail(email: String) = intent { + internal fun setEmail(email: String) { + this.email = email setSignInButtonEnabled() - reduce { - state.copy( - email = email, - emailError = false, - ) + intent { + reduce { + state.copy(emailError = false) + } } } - internal fun setPassword(password: String) = intent { + internal fun setPassword(password: String) { + this.password = password setSignInButtonEnabled() - reduce { - state.copy( - password = password, - passwordError = false, - ) + intent { + reduce { + state.copy(passwordError = false) + } } } @@ -105,8 +113,6 @@ class SignInScreenViewModel @Inject constructor( } data class SignInState( - val email: String = "", - val password: String = "", val autoSignIn: Boolean = false, val emailError: Boolean = false, val passwordError: Boolean = false, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/SignUpViewModel.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/SignUpViewModel.kt index 3dc9bc37..b031582a 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/SignUpViewModel.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/SignUpViewModel.kt @@ -1,6 +1,9 @@ package team.retum.jobis_android.feature.auth.signup import androidx.annotation.StringRes +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -38,7 +41,22 @@ class SignUpViewModel @Inject constructor( override val container = container(SignUpState()) - internal val state = container.stateFlow.value + var email by mutableStateOf("") + private set + var verifyCode by mutableStateOf("") + private set + var password by mutableStateOf("") + private set + var repeatPassword by mutableStateOf("") + private set + var grade by mutableStateOf("") + private set + var name by mutableStateOf("") + private set + var classRoom by mutableStateOf("") + private set + var number by mutableStateOf("") + private set internal fun setGender( gender: Gender, @@ -46,68 +64,60 @@ class SignUpViewModel @Inject constructor( reduce { state.copy(gender = gender) } } - internal fun setName( - name: String, - ) = intent { - reduce { state.copy(name = name.trim()) } + internal fun setName(name: String) { + this.name = name.trim() setSignUpButtonEnabled( checkAvailableValues( name = name, - grade = state.grade, - `class` = state.classRoom, - number = state.number, + grade = grade, + classRoom = classRoom, + number = number, ), ) } - internal fun setGrade( - grade: String, - ) = intent { - reduce { state.copy(grade = grade) } + internal fun setGrade(grade: String) { + this.grade = grade setSignUpButtonEnabled( checkAvailableValues( - name = state.name, - grade = state.grade, - `class` = state.classRoom, - number = state.number, + name = name, + grade = grade, + classRoom = classRoom, + number = number, ), ) } - internal fun setClass( - `class`: String, - ) = intent { - reduce { state.copy(classRoom = `class`) } + internal fun setClass(classRoom: String) { + this.classRoom = classRoom setSignUpButtonEnabled( checkAvailableValues( - name = state.name, - grade = state.grade, - `class` = `class`, - number = state.number, + name = name, + grade = grade, + classRoom = classRoom, + number = number, ), ) } - internal fun setNumber( - number: String, - ) = intent { - reduce { state.copy(number = number) } + internal fun setNumber(number: String) { + this.number = number setSignUpButtonEnabled( checkAvailableValues( - name = state.name, - grade = state.grade, - `class` = state.classRoom, + name = name, + grade = grade, + classRoom = classRoom, number = number, ), ) } - internal fun setEmail( - email: String, - ) = intent { - reduce { state.copy(email = email) } + internal fun setEmail(email: String) { + this.email = email setEmailError(!Pattern.matches(Regex.EMAIL, email) || email.isBlank()) - setSignUpButtonEnabled(email.isNotBlank() && state.verifyCode.isNotBlank() && !state.emailError && !state.verifyCodeError) + intent { + setSignUpButtonEnabled(email.isNotBlank() && verifyCode.isNotBlank() && !state.emailError && !state.verifyCodeError) + } } private fun setEmailError( @@ -117,12 +127,12 @@ class SignUpViewModel @Inject constructor( setSendVerifyCodeButtonEnabled(!emailError) } - internal fun setVerifyCode( - verifyCode: String, - ) = intent { - reduce { state.copy(verifyCode = verifyCode) } + internal fun setVerifyCode(verifyCode: String) { + this.verifyCode = verifyCode setVerifyCodeError(false) - setSignUpButtonEnabled(state.email.isNotBlank() || verifyCode.isNotBlank() || !state.emailError || !state.verifyCodeError) + intent { + setSignUpButtonEnabled(email.isNotBlank() || verifyCode.isNotBlank() || !state.emailError || !state.verifyCodeError) + } } private fun setVerifyCodeError( @@ -132,10 +142,8 @@ class SignUpViewModel @Inject constructor( setSignUpButtonEnabled(!verifyCodeError) } - internal fun setPassword( - password: String, - ) = intent { - reduce { state.copy(password = password) } + internal fun setPassword(password: String) { + this.password = password setPasswordError(!Pattern.matches(Regex.PASSWORD, password)) } @@ -146,11 +154,9 @@ class SignUpViewModel @Inject constructor( setSignUpButtonEnabled(!passwordError) } - internal fun setRepeatPassword( - repeatPassword: String, - ) = intent { - reduce { state.copy(repeatPassword = repeatPassword) } - setRepeatPasswordError(state.password != repeatPassword) + internal fun setRepeatPassword(repeatPassword: String) { + this.repeatPassword = repeatPassword + setRepeatPasswordError(password != repeatPassword) } private fun setRepeatPasswordError( @@ -189,11 +195,11 @@ class SignUpViewModel @Inject constructor( private fun checkAvailableValues( name: String, grade: String, - `class`: String, + classRoom: String, number: String, ): Boolean { setStudentNotFound(false) - return name.isNotBlank() && grade.isNotBlank() && `class`.isNotBlank() && number.isNotBlank() + return name.isNotBlank() && grade.isNotBlank() && classRoom.isNotBlank() && number.isNotBlank() } internal fun checkStudentExists() = intent { @@ -201,11 +207,11 @@ class SignUpViewModel @Inject constructor( checkStudentExistUseCase( checkStudentExistsParam = CheckStudentExistsParam( gcn = returnGcn( - grade = state.grade, - `class` = state.classRoom, - number = state.number, + grade = grade, + `class` = classRoom, + number = number, ), - name = container.stateFlow.value.name, + name = name, ), ).onSuccess { postSideEffect(SignUpSideEffect.StudentInfo.CheckStudentExistsSuccess) @@ -236,7 +242,7 @@ class SignUpViewModel @Inject constructor( viewModelScope.launch { sendVerificationCodeUseCase( sendVerificationCodeParam = SendVerificationCodeParam( - email = state.email, + email = email, authCodeType = AuthCodeType.SIGN_UP, ), ).onSuccess { @@ -266,8 +272,8 @@ class SignUpViewModel @Inject constructor( viewModelScope.launch { verifyEmailUseCase( verifyEmailParam = VerifyEmailParam( - email = state.email, - authCode = state.verifyCode, + email = email, + authCode = verifyCode, ), ).onSuccess { postSideEffect(SignUpSideEffect.VerifyEmail.VerifyEmailSuccess) @@ -301,19 +307,19 @@ class SignUpViewModel @Inject constructor( viewModelScope.launch { if ( !checkPassword( - password = state.password, - repeatPassword = state.repeatPassword, + password = password, + repeatPassword = repeatPassword, ) ) { signUpUseCase( signUpParam = SignUpParam( - email = state.email, - password = state.password, - grade = state.grade.toLong(), - name = state.name, + email = email, + password = password, + grade = grade.toLong(), + name = name, gender = state.gender, - classRoom = state.classRoom.toLong(), - number = state.number.toLong(), + classRoom = classRoom.toLong(), + number = number.toLong(), ), ).onSuccess { postSideEffect( @@ -363,19 +369,11 @@ class SignUpViewModel @Inject constructor( } data class SignUpState( - val email: String = "", val emailError: Boolean = false, - val verifyCode: String = "", val verifyCodeError: Boolean = false, - val password: String = "", val passwordError: Boolean = false, - val repeatPassword: String = "", val repeatPasswordError: Boolean = false, - val grade: String = "", - val name: String = "", val gender: Gender = Gender.MAN, - val classRoom: String = "", - val number: String = "", val studentNotFound: Boolean = false, val sendVerifyCodeButtonEnabled: Boolean = false, val authCodeEnabled: Boolean = false, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/setpassword/SetPasswordScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/setpassword/SetPasswordScreen.kt index 9bb642ca..bb418791 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/setpassword/SetPasswordScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/setpassword/SetPasswordScreen.kt @@ -27,8 +27,8 @@ fun SetPasswordScreen( val focusManager = LocalFocusManager.current PasswordFields( - password = state.password, - repeatPassword = state.repeatPassword, + password = signUpViewModel.password, + repeatPassword = signUpViewModel.repeatPassword, onPasswordChanged = signUpViewModel::setPassword, onRepeatPasswordChanged = signUpViewModel::setRepeatPassword, isPasswordError = state.passwordError, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/studentinfo/StudentInfoScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/studentinfo/StudentInfoScreen.kt index 5388282c..b8ee27b4 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/studentinfo/StudentInfoScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/studentinfo/StudentInfoScreen.kt @@ -46,9 +46,9 @@ internal fun StudentInfoScreen( focusManager.moveFocus(FocusDirection.Next) } } - val onClassChanged: (String) -> Unit = { `class`: String -> - signUpViewModel.setClass(`class` = `class`.take(2)) - if (`class`.length == 1) { + val onClassChanged: (String) -> Unit = { classRoom: String -> + signUpViewModel.setClass(classRoom = classRoom.take(2)) + if (classRoom.length == 1) { focusManager.moveFocus(FocusDirection.Next) } } @@ -60,7 +60,7 @@ internal fun StudentInfoScreen( } LaunchedEffect(Unit) { - with(state) { + with(signUpViewModel) { val signUpValidation = name.isNotBlank() && grade.isNotBlank() && classRoom.isNotBlank() && number.isNotBlank() signUpViewModel.setSignUpButtonEnabled(signUpValidation) @@ -78,10 +78,10 @@ internal fun StudentInfoScreen( ) Spacer(modifier = Modifier.height(28.dp)) InformationFields( - name = state.name, - grade = state.grade, - classRoom = state.classRoom, - number = state.number, + name = signUpViewModel.name, + grade = signUpViewModel.grade, + classRoom = signUpViewModel.classRoom, + number = signUpViewModel.number, studentNotFound = state.studentNotFound, onNameChanged = signUpViewModel::setName, onGradeChanged = onGradeChanged, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/verifyemail/VerifyEmailScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/verifyemail/VerifyEmailScreen.kt index c4ba1e25..db86b24f 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/verifyemail/VerifyEmailScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/auth/signup/verifyemail/VerifyEmailScreen.kt @@ -44,7 +44,7 @@ fun VerifyEmailScreen( JobisBoxTextField( color = JobisTextFieldColor.MainColor, onValueChanged = signUpViewModel::setEmail, - value = state.email, + value = signUpViewModel.email, hint = stringResource(id = R.string.please_enter_email), helperText = stringResource(id = R.string.email_verification_email_hint), errorText = stringResource(id = R.string.email_verification_email_hint), @@ -57,7 +57,7 @@ fun VerifyEmailScreen( JobisBoxTextField( color = JobisTextFieldColor.MainColor, onValueChanged = onVerifyCodeChanged, - value = state.verifyCode, + value = signUpViewModel.verifyCode, hint = stringResource(id = R.string.email_verification_verify_code_hint), keyboardActions = KeyboardActions { focusManager.clearFocus() }, enabled = state.authCodeEnabled, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreen.kt index 122a7b9d..df577380 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreen.kt @@ -111,9 +111,9 @@ internal fun BugReportScreen( Header(text = stringResource(id = R.string.bug_report)) ContentInputs( onTitleChanged = bugReportScreenViewModel::setTitle, - title = bugState.title, + title = bugReportScreenViewModel.title, onContentChanged = bugReportScreenViewModel::setContent, - content = bugState.content, + content = bugReportScreenViewModel.content, titleError = bugState.titleError, contentError = bugState.contentError, ) diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreenViewModel.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreenViewModel.kt index adbc2e14..c00192b2 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreenViewModel.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/bugreport/BugReportScreenViewModel.kt @@ -2,7 +2,10 @@ package team.retum.jobis_android.feature.bugreport import android.net.Uri import androidx.annotation.StringRes +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -38,6 +41,11 @@ internal class BugReportScreenViewModel @Inject constructor( private set private val files: SnapshotStateList = mutableStateListOf() + var title by mutableStateOf("") + private set + var content by mutableStateOf("") + private set + internal fun addFile( file: File, uri: Uri, @@ -54,8 +62,8 @@ internal class BugReportScreenViewModel @Inject constructor( private suspend fun reportBug(attachmentUrls: List) = intent { bugReportUseCase( BugReportParam( - title = state.title, - content = state.content, + title = title, + content = content, developmentArea = state.selectedPosition, attachmentUrls = attachmentUrls, ), @@ -99,22 +107,22 @@ internal class BugReportScreenViewModel @Inject constructor( ) } - internal fun setTitle(title: String) = intent { - reduce { - state.copy( - title = title, - titleError = title.isBlank(), - ) + internal fun setTitle(title: String) { + this.title = title + intent { + reduce { + state.copy(titleError = title.isBlank()) + } } setReportBugButtonState() } - internal fun setContent(content: String) = intent { - reduce { - state.copy( - content = content, - contentError = content.isBlank(), - ) + internal fun setContent(content: String) { + this.content = content + intent { + reduce { + state.copy(contentError = content.isBlank()) + } } setReportBugButtonState() } @@ -139,8 +147,6 @@ internal class BugReportScreenViewModel @Inject constructor( } internal data class BugState( - val title: String = "", - val content: String = "", val titleError: Boolean = false, val contentError: Boolean = false, val selectedPosition: DevelopmentArea = DevelopmentArea.ALL, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreen.kt index 17f9c1a6..6c17be7b 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreen.kt @@ -20,7 +20,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.runtime.snapshotFlow import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment @@ -34,7 +33,6 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import coil.compose.AsyncImage import com.jobis.jobis_android.R -import org.orbitmvi.orbit.compose.collectAsState import team.retum.domain.entity.company.CompanyEntity import team.retum.jobis_android.feature.main.home.ApplyCompaniesItemShape import team.retum.jobis_android.util.compose.animation.skeleton @@ -52,13 +50,15 @@ internal fun CompaniesScreen( navigateToCompanyDetails: (Long) -> Unit, companiesScreenViewModel: CompaniesScreenViewModel = hiltViewModel(), ) { - val state by companiesScreenViewModel.collectAsState() - val searchResultTextAlpha = if (state.name.isNullOrBlank()) 0f else 1f + val searchResultTextAlpha = if (companiesScreenViewModel.name.isNullOrBlank()) 0f else 1f val lazyListState = rememberLazyListState() + val name = companiesScreenViewModel.name LaunchedEffect(Unit) { with(companiesScreenViewModel) { snapshotFlow { lazyListState.layoutInfo.visibleItemsInfo.lastOrNull()?.index }.callNextPageByPosition() + fetchCompanies() + fetchCompanyCount() } } @@ -75,10 +75,10 @@ internal fun CompaniesScreen( Header(text = stringResource(id = R.string.company_list_search_company)) Spacer(modifier = Modifier.height(12.dp)) CompanyInput( - companyName = state.name, + companyName = name, onCompanyNameChanged = companiesScreenViewModel::setName, ) - Animated(!state.name.isNullOrBlank()) { + Animated(!name.isNullOrBlank()) { Caption( modifier = Modifier.alpha(alpha = searchResultTextAlpha), text = stringResource(id = R.string.search_result), @@ -93,7 +93,7 @@ internal fun CompaniesScreen( text = stringResource(id = R.string.search_result), color = JobisColor.Gray600, ) - Caption(text = state.name ?: "") + Caption(text = name ?: "") } } Companies( diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreenViewModel.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreenViewModel.kt index b82a9a14..7bd489c8 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreenViewModel.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/company/CompaniesScreenViewModel.kt @@ -1,6 +1,9 @@ package team.retum.jobis_android.feature.company +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -31,24 +34,20 @@ internal class CompaniesScreenViewModel @Inject constructor( internal var companies: SnapshotStateList = mutableStateListOf() private set - init { - fetchCompanies() - fetchCompanyCount() - } + var name: String? by mutableStateOf(null) + private set - internal fun setName(name: String) = intent { - reduce { - state.copy(name = name) - } + internal fun setName(name: String) { + this.name = name } - private fun fetchCompanies() = intent { + internal fun fetchCompanies() = intent { reduce { state.copy(page = state.page + 1) } viewModelScope.launch(Dispatchers.IO) { fetchCompaniesUseCase( fetchCompaniesParam = FetchCompaniesParam( page = state.page, - name = state.name, + name = name, ), ).onSuccess { response -> companies.addAll( @@ -94,12 +93,12 @@ internal class CompaniesScreenViewModel @Inject constructor( } } - private fun fetchCompanyCount() = intent { + internal fun fetchCompanyCount() = intent { viewModelScope.launch(Dispatchers.IO) { fetchCompanyCountUseCase( fetchCompaniesParam = FetchCompaniesParam( page = state.page, - name = state.name, + name = name, ), ).onSuccess { reduce { state.copy(totalPage = it.totalPageCount) } @@ -110,7 +109,6 @@ internal class CompaniesScreenViewModel @Inject constructor( internal data class CompaniesState( val page: Long = 0, - val name: String? = null, val totalPage: Long = 0, ) : State diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilter.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilter.kt index 40135ea7..8920bd5a 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilter.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilter.kt @@ -151,7 +151,7 @@ internal fun RecruitmentFilter( JobisBoxTextField( color = JobisTextFieldColor.MainColor, onValueChanged = onKeywordChanged, - value = state.keyword ?: "", + value = recruitmentFilterViewModel.keyword ?: "", hint = stringResource(id = R.string.search_tech_code), textFieldType = TextFieldType.SEARCH, ) diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilterViewModel.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilterViewModel.kt index 520e0ccc..ef90099c 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilterViewModel.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentFilterViewModel.kt @@ -1,6 +1,9 @@ package team.retum.jobis_android.feature.recruitment +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.toMutableStateList import androidx.lifecycle.viewModelScope @@ -28,13 +31,16 @@ internal class RecruitmentFilterViewModel @Inject constructor( private val _techs = mutableListOf() + var keyword: String? by mutableStateOf(null) + private set + internal fun fetchCodes() = intent { val type = state.type viewModelScope.launch(Dispatchers.IO) { fetchCodesUseCase( fetchCodesParam = FetchCodesParam( - keyword = state.keyword, + keyword = keyword, type = type, parentCode = state.selectedJobCode, ), @@ -82,14 +88,8 @@ internal class RecruitmentFilterViewModel @Inject constructor( } } - internal fun setKeyword( - keyword: String, - ) = intent { - reduce { - state.copy( - keyword = keyword, - ) - } + internal fun setKeyword(keyword: String) { + this.keyword = keyword searchTechCode(keyword) } @@ -155,7 +155,6 @@ data class CodeState( val techs: SnapshotStateList = mutableStateListOf(), val businessAreas: List = emptyList(), val selectedTechs: SnapshotStateList> = mutableStateListOf(), - val keyword: String? = null, val type: Type = Type.JOB, val selectedJobCode: Long? = null, ) : State diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreen.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreen.kt index cc80d841..840882da 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreen.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreen.kt @@ -86,6 +86,8 @@ internal fun RecruitmentsScreen( with(recruitmentsScreenViewModel) { setWinterIntern(isWinterIntern) snapshotFlow { lazyListState.layoutInfo.visibleItemsInfo.lastOrNull()?.index }.callNextPageByPosition() + fetchRecruitments() + fetchRecruitmentCount() } } @@ -129,7 +131,7 @@ internal fun RecruitmentsScreen( ) Spacer(modifier = Modifier.height(12.dp)) RecruitmentInput( - name = state.name, + name = recruitmentsScreenViewModel.name, jobCode = state.jobCode, techCode = state.techCode, onFilterClicked = onFilterClicked, diff --git a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreenViewModel.kt b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreenViewModel.kt index f23c5722..c5484f21 100644 --- a/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreenViewModel.kt +++ b/presentation/src/main/kotlin/team/retum/jobis_android/feature/recruitment/RecruitmentsScreenViewModel.kt @@ -1,6 +1,9 @@ package team.retum.jobis_android.feature.recruitment +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -37,12 +40,10 @@ class RecruitmentsScreenViewModel @Inject constructor( internal var recruitments: SnapshotStateList = mutableStateListOf() private set - init { - fetchRecruitments() - fetchRecruitmentCount() - } + var name: String? by mutableStateOf(null) + private set - private fun fetchRecruitments( + internal fun fetchRecruitments( jobCode: Long? = null, techCode: String? = null, ) = intent { @@ -51,7 +52,7 @@ class RecruitmentsScreenViewModel @Inject constructor( fetchRecruitmentsUseCase( fetchRecruitmentsParam = FetchRecruitmentsParam( page = state.page, - name = state.name, + name = name, jobCode = jobCode, techCode = techCode, winterIntern = state.isWinterIntern, @@ -67,7 +68,7 @@ class RecruitmentsScreenViewModel @Inject constructor( } } - private fun fetchRecruitmentCount( + internal fun fetchRecruitmentCount( jobCode: Long? = null, techCode: String? = null, ) = intent { @@ -75,7 +76,7 @@ class RecruitmentsScreenViewModel @Inject constructor( fetchRecruitmentCountUseCase( FetchRecruitmentsParam( page = state.page, - name = state.name, + name = name, jobCode = jobCode, techCode = techCode, winterIntern = state.isWinterIntern, @@ -135,8 +136,8 @@ class RecruitmentsScreenViewModel @Inject constructor( reduce { state.copy(isWinterIntern = isWinterIntern) } } - internal fun setName(name: String) = intent { - reduce { state.copy(name = name) } + internal fun setName(name: String) { + this.name = name } internal fun setCodes( @@ -165,7 +166,6 @@ class RecruitmentsScreenViewModel @Inject constructor( data class RecruitmentsState( val page: Long = 0, - val name: String? = null, val jobCode: Long? = null, val techCode: String? = null, val isWinterIntern: Boolean = false,