generated from AND-SOPT-ANDROID/and-sopt-android-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
337 additions
and
181 deletions.
There are no files selected for viewing
2 changes: 1 addition & 1 deletion
2
...ava/org/sopt/and/components/SignButton.kt → ...and/presentation/components/SignButton.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
.../org/sopt/and/components/SignTextField.kt → .../presentation/components/SignTextField.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ava/org/sopt/and/components/SignTopBar.kt → ...and/presentation/components/SignTopBar.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
app/src/main/java/org/sopt/and/presentation/signin/SignInUiState.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.sopt.and.presentation.signin | ||
|
||
data class SignInUiState( | ||
val signInUsername: String = "", | ||
val signInPassword: String = "", | ||
val isSignInPasswordVisible: Boolean = false | ||
) | ||
|
||
sealed class SignInResult { | ||
object Initial : SignInResult() | ||
object Success : SignInResult() | ||
object FailurePasswordLength : SignInResult() | ||
object FailureWrongPassword : SignInResult() | ||
} |
130 changes: 130 additions & 0 deletions
130
app/src/main/java/org/sopt/and/presentation/signin/SignInViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package org.sopt.and.presentation.signin | ||
|
||
import android.content.Context | ||
import androidx.compose.material3.SnackbarHostState | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
import kotlinx.coroutines.launch | ||
import org.sopt.and.R | ||
import org.sopt.and.data.service.AppContext | ||
import org.sopt.and.data.service.TokenManager | ||
import org.sopt.and.domain.model.SignInInformationEntity | ||
import org.sopt.and.domain.model.SignInResponseEntity | ||
import org.sopt.and.domain.usecase.SignInUseCase | ||
import org.sopt.and.presentation.util.Utils.showSnackbar | ||
|
||
class SignInViewModel( | ||
private val signInUseCase: SignInUseCase | ||
) : ViewModel() { | ||
private val tokenManager = TokenManager(AppContext.get()) | ||
|
||
private val _uiState = MutableStateFlow(SignInUiState()) | ||
val uiState: StateFlow<SignInUiState> = _uiState.asStateFlow() | ||
|
||
private val _signInResult = MutableStateFlow<SignInResult>(SignInResult.Initial) | ||
val signInResult: StateFlow<SignInResult> = _signInResult.asStateFlow() | ||
|
||
private fun initSignInResult() { | ||
_signInResult.value = SignInResult.Initial | ||
} | ||
|
||
fun setSignInUsername(signInUsername: String) { | ||
_uiState.value = _uiState.value.copy( | ||
signInUsername = signInUsername | ||
) | ||
} | ||
|
||
fun setSignInPassword(signInPassword: String) { | ||
_uiState.value = _uiState.value.copy( | ||
signInPassword = signInPassword | ||
) | ||
} | ||
|
||
fun changeSignInPasswordVisibility() { | ||
_uiState.value = _uiState.value.copy( | ||
isSignInPasswordVisible = !_uiState.value.isSignInPasswordVisible | ||
) | ||
} | ||
|
||
fun signIn( | ||
signInUsername: String, | ||
signInPassword: String | ||
) { | ||
viewModelScope.launch { | ||
signInUseCase( | ||
request = SignInInformationEntity( | ||
username = signInUsername, | ||
password = signInPassword | ||
) | ||
).onSuccess { signInResponseEntity: SignInResponseEntity -> | ||
if (signInResponseEntity.status == 200) { | ||
_signInResult.value = SignInResult.Success | ||
signInResponseEntity.token?.let { token -> | ||
tokenManager.saveToken(token) | ||
} | ||
} else if (signInResponseEntity.code == SignInFailureCase.FAILURE_LENGTH.errorCode | ||
&& signInResponseEntity.status == SignInFailureCase.FAILURE_LENGTH.statusCode | ||
) { | ||
_signInResult.value = SignInResult.FailurePasswordLength | ||
} else if (signInResponseEntity.code == SignInFailureCase.FAILURE_WRONG_PASSWORD.errorCode | ||
&& signInResponseEntity.status == SignInFailureCase.FAILURE_WRONG_PASSWORD.statusCode | ||
) { | ||
_signInResult.value = SignInResult.FailureWrongPassword | ||
} | ||
} | ||
} | ||
} | ||
|
||
fun confirmLogin( | ||
snackbarHostState: SnackbarHostState, | ||
navigateToMyInfo: () -> Unit, | ||
context: Context, | ||
scope: CoroutineScope | ||
) { | ||
when (signInResult.value) { | ||
is SignInResult.Success -> { | ||
context.showSnackbar( | ||
scope = scope, | ||
snackbarHostState = snackbarHostState, | ||
message = R.string.sign_in_success_message, | ||
) | ||
navigateToMyInfo() | ||
initSignInResult() | ||
} | ||
|
||
is SignInResult.FailurePasswordLength -> { | ||
context.showSnackbar( | ||
scope = scope, | ||
snackbarHostState = snackbarHostState, | ||
message = R.string.sign_in_failed_password_length, | ||
) | ||
initSignInResult() | ||
} | ||
|
||
is SignInResult.FailureWrongPassword -> { | ||
context.showSnackbar( | ||
scope = scope, | ||
snackbarHostState = snackbarHostState, | ||
message = R.string.sign_in_failed_wrong_password, | ||
) | ||
initSignInResult() | ||
} | ||
|
||
else -> {} | ||
} | ||
} | ||
} | ||
|
||
data class SignInFailureCase( | ||
val statusCode: Int, | ||
val errorCode: String | ||
) { | ||
companion object { | ||
val FAILURE_LENGTH = SignInFailureCase(statusCode = 400, errorCode = "01") | ||
val FAILURE_WRONG_PASSWORD = SignInFailureCase(statusCode = 403, errorCode = "01") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package org.sopt.and.presentation.util | ||
|
||
import android.content.Context | ||
import android.widget.Toast | ||
import androidx.annotation.StringRes | ||
import androidx.compose.material3.SnackbarHostState | ||
import androidx.compose.ui.text.input.PasswordVisualTransformation | ||
import androidx.compose.ui.text.input.VisualTransformation | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.launch | ||
import org.sopt.and.R | ||
|
||
object Utils { | ||
const val MIN_PASSWORD_LENGTH = 8 | ||
const val MAX_PASSWORD_LENGTH = 20 | ||
|
||
const val MYINFO_SCREEN_INDEX = 2 | ||
const val SEARCH_SCREEN_INDEX = 1 | ||
const val HOME_SCREEN_INDEX = 0 | ||
|
||
const val GREETING_FIRST_LINE_FOCUS_START_INDEX = 0 | ||
const val GREETING_FIRST_LINE_FOCUS_END_INDEX = 9 | ||
const val GREETING_FIRST_LINE_END_INDEX = 12 | ||
const val GREETING_SECOND_LINE_FOCUS_START_INDEX = 13 | ||
const val GREETING_SECOND_LINE_FOCUS_END_INDEX = 24 | ||
const val GREETING_SECOND_LINE_END_INDEX = 29 | ||
|
||
|
||
fun transformationPasswordVisual(isVisible: Boolean): VisualTransformation = | ||
if (isVisible) VisualTransformation.None else PasswordVisualTransformation() | ||
|
||
fun Context.showToast( | ||
@StringRes message: Int | ||
) = Toast.makeText( | ||
this, | ||
this.getString(message), | ||
Toast.LENGTH_SHORT | ||
).show() | ||
|
||
fun Context.showSnackbar( | ||
scope: CoroutineScope, | ||
snackbarHostState: SnackbarHostState, | ||
@StringRes message: Int | ||
) = scope.launch { | ||
snackbarHostState.showSnackbar(message = getString(message)) | ||
} | ||
} |
Oops, something went wrong.