Skip to content

Commit

Permalink
#219 feature:intro 모듈 내 로그인, 회원가입 클래스 새로운 패키지로 이동, 회원가입 시 닉네임 속성 이름 오…
Browse files Browse the repository at this point in the history
…류로 가입이 되지 않는 문제 수정
  • Loading branch information
pknujsp committed Mar 11, 2024
1 parent 221d45c commit 170a2a5
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.android.mediproject.core.data.sign

import com.amazonaws.services.cognitoidentityprovider.model.UserNotConfirmedException
import com.amazonaws.services.cognitoidentityprovider.model.UsernameExistsException
import com.android.mediproject.core.data.session.AccountSessionRepository
import com.android.mediproject.core.datastore.AppDataStore
import com.android.mediproject.core.model.sign.LoginParameter
Expand Down Expand Up @@ -50,7 +51,11 @@ internal class SignRepositoryImpl(
SignUpState.Success
},
onFailure = { exception ->
SignUpState.Failed(exception)
if (exception is UsernameExistsException) {
SignUpState.UserExists
} else {
SignUpState.Failed(exception)
}
},
)

Expand All @@ -72,6 +77,7 @@ sealed interface LoginState {

sealed interface SignUpState {
data object Success : SignUpState
data class Failed(val exception: Throwable) : SignUpState
data object UserExists : SignUpState

data class Failed(val exception: Throwable) : SignUpState
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class LoginDataSourceImpl(
override fun onFailure(exception: Exception) {
continuation.resumeWithException(exception)
// UserNotConfirmedException : 이메일 인증을 하지 않았을 때 발생
// UserExistsException : 이미 가입된 이메일일 때 발생
}

override fun authenticationChallenge(continuation: ChallengeContinuation?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserAttribu
import com.amazonaws.services.cognitoidentityprovider.model.SignUpResult

interface SignupDataSource {
suspend fun signUp(signUpParameter: SignUpRequest): Result<SignUpResponse>
suspend fun signUp(request: SignUpRequest): Result<SignUpResponse>
suspend fun confirmEmail(email: String, code: String): Result<Unit>
suspend fun resendConfirmationCode(cognitoUser: CognitoUser): Result<ConfirmationCodeDeliveryDetails>
}

private const val USER_NAME = "user_name"
private const val USER_NAME = "nickname"

class SignUpRequest(
val email: String,
Expand All @@ -20,7 +20,7 @@ class SignUpRequest(
val passwordString: String get() = password.decodeToString()

val attr = CognitoUserAttributes().apply {
this.addAttribute(USER_NAME, nickName)
addAttribute(USER_NAME, nickName)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SignupDataSourceImpl(

override fun onFailure(exception: Exception) {
continuation.resumeWithException(exception)
// UserExistsException : 이미 가입된 이메일일 때 발생
}
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ object ServerNetwork {

@Provides
@Singleton
fun providesUserPool(@ApplicationContext context: Context) = CognitoUserPool(
fun providesUserPool(@ApplicationContext context: Context): CognitoUserPool = CognitoUserPool(
context, BuildConfig.AWS_USER_POOL, BuildConfig.AWS_USER_CLIENT_ID, BuildConfig.AWS_USER_CLIENT_SECRET,
Regions.US_EAST_2,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.core.net.toUri
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
Expand Down Expand Up @@ -39,6 +40,9 @@ abstract class BaseFragment<T : ViewDataBinding, V : BaseViewModel>(private val

fun toast(str: String) = Toast.makeText(requireContext(), str, Toast.LENGTH_SHORT).show()

fun toast(@StringRes str: Int) = Toast.makeText(requireContext(), str, Toast.LENGTH_SHORT).show()


fun navigateWithUri(deepLinkUri: String) = findNavController().navigate(deepLinkUri.toUri())

fun navigateWithUriNavOptions(deepLinkUri: String, navOptions: NavOptions) = findNavController().navigate(deepLinkUri.toUri(), navOptions)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.android.mediproject.feature.intro
package com.android.mediproject.feature.intro.login


import android.os.Bundle
Expand All @@ -15,6 +15,7 @@ import com.android.mediproject.core.common.viewmodel.repeatOnStarted
import com.android.mediproject.core.model.navargs.TOHOME
import com.android.mediproject.core.model.navargs.TOMYPAGE
import com.android.mediproject.core.ui.base.BaseFragment
import com.android.mediproject.feature.intro.R
import com.android.mediproject.feature.intro.databinding.FragmentLoginBinding
import com.android.mediproject.feature.intro.verification.EmailVerficationDialogFragment
import dagger.hilt.android.AndroidEntryPoint
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.android.mediproject.feature.intro
package com.android.mediproject.feature.intro.login

import androidx.lifecycle.viewModelScope
import com.android.mediproject.core.common.network.Dispatcher
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.android.mediproject.feature.intro
package com.android.mediproject.feature.intro.signup

import android.os.Bundle
import android.view.View
Expand All @@ -14,6 +14,7 @@ import com.android.mediproject.core.common.viewmodel.repeatOnStarted
import com.android.mediproject.core.model.navargs.TOHOME
import com.android.mediproject.core.model.navargs.TOMYPAGE
import com.android.mediproject.core.ui.base.BaseFragment
import com.android.mediproject.feature.intro.R
import com.android.mediproject.feature.intro.databinding.FragmentSignUpBinding
import com.android.mediproject.feature.intro.verification.EmailVerficationDialogFragment
import dagger.hilt.android.AndroidEntryPoint
Expand Down Expand Up @@ -51,7 +52,7 @@ class SignUpFragment : BaseFragment<FragmentSignUpBinding, SignUpViewModel>(Frag
viewModel = fragmentViewModel.apply {
viewLifecycleOwner.apply {
repeatOnStarted { eventFlow.collectLatest { handleEvent(it) } }
repeatOnStarted { signUpState.collectLatest { handleSignUpState(it) } }
repeatOnStarted { signUpUiState.collectLatest { handleSignUpState(it) } }
}
}
setDelayTextWatcher()
Expand All @@ -75,14 +76,14 @@ class SignUpFragment : BaseFragment<FragmentSignUpBinding, SignUpViewModel>(Frag
)
}

private fun handleSignUpState(signUpState: SignUpViewModel.SignUpState) {
when (signUpState) {
is SignUpViewModel.SignUpState.SigningUp -> signingUp()
is SignUpViewModel.SignUpState.SignUpSuccess -> signUpSuccess()
is SignUpViewModel.SignUpState.SignUpFailed -> signUpFailed()
is SignUpViewModel.SignUpState.RegexError -> regexError()
is SignUpViewModel.SignUpState.Initial -> initial()
is SignUpViewModel.SignUpState.PasswordError -> passwordError()
private fun handleSignUpState(signUpUiState: SignUpUiState) {
when (signUpUiState) {
is SignUpUiState.SigningUp -> signingUp()
is SignUpUiState.Success -> signUpSuccess()
is SignUpUiState.Failed -> toast(signUpUiState.message)
is SignUpUiState.RegexError -> toast(signUpUiState.text)
is SignUpUiState.UserExists -> toast(signUpUiState.text)
is SignUpUiState.PasswordError -> toast(signUpUiState.text)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.android.mediproject.feature.intro.signup

import androidx.annotation.StringRes
import com.android.mediproject.feature.intro.R

sealed interface SignUpUiState {
@get:StringRes val text: Int?

data object SigningUp : SignUpUiState {
override val text: Int? = null
}

data object RegexError : SignUpUiState {
override val text: Int = R.string.signInRegexError
}

data object PasswordError : SignUpUiState {
override val text: Int = R.string.signUpPasswordError
}

data object UserExists : SignUpUiState {
override val text: Int = R.string.signUpUserExists
}

data object Success : SignUpUiState {
override val text: Int = R.string.signUpSuccess
}

data class Failed(val message: String) : SignUpUiState {
override val text: Int? = null
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.android.mediproject.feature.intro
package com.android.mediproject.feature.intro.signup

import androidx.lifecycle.viewModelScope
import com.android.mediproject.core.common.network.Dispatcher
Expand All @@ -8,6 +8,7 @@ import com.android.mediproject.core.common.util.isPasswordValid
import com.android.mediproject.core.common.viewmodel.MutableEventFlow
import com.android.mediproject.core.common.viewmodel.asEventFlow
import com.android.mediproject.core.data.sign.SignRepository
import com.android.mediproject.core.data.sign.SignUpState
import com.android.mediproject.core.model.navargs.TOHOME
import com.android.mediproject.core.model.sign.SignUpParameter
import com.android.mediproject.core.ui.base.BaseViewModel
Expand All @@ -24,60 +25,48 @@ class SignUpViewModel @Inject constructor(
private val signUpRepository: SignRepository, @Dispatcher(MediDispatchers.IO) private val ioDispatcher: CoroutineDispatcher,
) : BaseViewModel() {

private val mutableSignUpUiState = MutableEventFlow<SignUpUiState>(replay = 1)
val signUpUiState = mutableSignUpUiState.asEventFlow()

private val _signUpState = MutableStateFlow<SignUpState>(SignUpState.Initial)
val signUpState = _signUpState.asStateFlow()
private val _eventFlow = MutableEventFlow<SignUpEvent>(replay = 1)
val eventFlow = _eventFlow.asEventFlow()

private fun setSignUpState(state: SignUpState) {
_signUpState.value = state
}
private val _callBackMoveFlag = MutableStateFlow(TOHOME)
val callBackMoveFlag = _callBackMoveFlag.asStateFlow()

sealed class SignUpState {
object SigningUp : SignUpState()
object Initial : SignUpState()
object RegexError : SignUpState()
object PasswordError : SignUpState()
object SignUpSuccess : SignUpState()
data class SignUpFailed(val message: String) : SignUpState()
private fun setSignUpState(state: SignUpUiState) {
viewModelScope.launch { mutableSignUpUiState.emit(state) }
}

private val _eventFlow = MutableEventFlow<SignUpEvent>(replay = 1)
val eventFlow = _eventFlow.asEventFlow()

fun event(event: SignUpEvent) = viewModelScope.launch { _eventFlow.emit(event) }

fun signUp() = event(SignUpEvent.SignUp)


sealed class SignUpEvent {
object SignUp : SignUpEvent()
}

private val _callBackMoveFlag = MutableStateFlow(TOHOME)
val callBackMoveFlag get() = _callBackMoveFlag.asStateFlow()

fun setCallBackMoveFlag(flag: Int) {
_callBackMoveFlag.value = flag
}

fun signUpWithCheckRegex(
email: String, password: String, checkPassword: String, nickName: String,
) {
if (!checkEmailPasswordRegex(email, password)) {
signUpFaledWithRegexError()
return
}
viewModelScope.launch {
setSignUpState(SignUpUiState.SigningUp)

if (!password.contentEquals(checkPassword)) {
isNotEqualPasswordCheck()
return
}
if (!checkEmailPasswordRegex(email, password)) {
signUpFaledWithRegexError()
return@launch
}
if (!password.contentEquals(checkPassword)) {
isNotEqualPasswordCheck()
return@launch
}

signUp(email, password, nickName)
signUp(email, password, nickName)
}
}

private fun checkEmailPasswordRegex(email: String, password: String): Boolean {
return checkEmailRegex(email) && checkPasswordRegex(password)
return isEmailValid(email) && isPasswordValid(password)
}

private fun checkEmailRegex(email: String): Boolean {
Expand All @@ -88,30 +77,28 @@ class SignUpViewModel @Inject constructor(
return isPasswordValid(password)
}

private fun signUp(
private suspend fun signUp(
email: String,
password: String,
nickName: String,
) {
viewModelScope.launch {
val pair = initEmailPassword(email, password)
setSignUpState(SignUpState.SigningUp)

withContext(ioDispatcher) {
signUpRepository.signUp(SignUpParameter(pair.first.concatToString(), password.toByteArray(), nickName))
}.onSuccess {
setSignUpState(SignUpState.SignUpSuccess)
}.onFailure {
setSignUpState(SignUpState.SignUpFailed(it.message ?: ""))
}
val pair = initEmailPassword(email, password)
val signUpState = withContext(ioDispatcher) {
signUpRepository.signUp(SignUpParameter(email, pair.second, nickName))
}

when (signUpState) {
is SignUpState.Success -> setSignUpState(SignUpUiState.Success)
is SignUpState.UserExists -> setSignUpState(SignUpUiState.UserExists)
is SignUpState.Failed -> setSignUpState(SignUpUiState.Failed(signUpState.exception.message ?: ""))
}
}

private fun isNotEqualPasswordCheck() {
setSignUpState(SignUpState.PasswordError)
setSignUpState(SignUpUiState.PasswordError)
}

private fun initEmailPassword(email: String, password: String): Pair<CharArray, CharArray> {
private fun initEmailPassword(email: String, password: String): Pair<CharArray, ByteArray> {
return Pair(initEmail(email), initPassword(password))
}

Expand All @@ -123,20 +110,22 @@ class SignUpViewModel @Inject constructor(
return emailCharArray
}

private fun initPassword(password: String): CharArray {
val passwordCharArray = CharArray(password.length)
password.trim().forEachIndexed { index, c ->
passwordCharArray[index] = c
}
return passwordCharArray
private fun initPassword(password: String): ByteArray {
return password.trim().toByteArray()
}

private fun signUpFaledWithRegexError() {
setSignUpState(SignUpState.RegexError)
setSignUpState(SignUpUiState.RegexError)
}

private fun fillEmailPassword(email: CharArray, password: CharArray) {
email.fill('\u0000')
password.fill('\u0000')
}


sealed interface SignUpEvent {
data object SignUp : SignUpEvent
}

}
5 changes: 3 additions & 2 deletions feature/intro/src/main/res/layout/fragment_login.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
xmlns:tools="http://schemas.android.com/tools">

<data>

<variable
name="viewModel"
type="com.android.mediproject.feature.intro.LoginViewModel" />
type="com.android.mediproject.feature.intro.login.LoginViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginFragment">
tools:context=".login.LoginFragment">

<com.android.mediproject.core.ui.base.view.Bar
android:id="@+id/loginBar"
Expand Down
Loading

0 comments on commit 170a2a5

Please sign in to comment.