diff --git a/app/build.gradle b/app/build.gradle index f0da93e..0fe8785 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -70,4 +70,7 @@ dependencies { // define any required OkHttp artifacts without version implementation("com.squareup.okhttp3:okhttp") implementation("com.squareup.okhttp3:logging-interceptor") + + // kotlinx 라이브러리 + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' } \ No newline at end of file diff --git a/app/src/main/java/org/sopt/dosopttemplate/AuthService.kt b/app/src/main/java/org/sopt/dosopttemplate/AuthService.kt index b9efbd1..5e4dc7d 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/AuthService.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/AuthService.kt @@ -9,6 +9,7 @@ import org.sopt.dosopttemplate.data.ResponseMemberCheckDto import org.sopt.dosopttemplate.data.ResponseMemberDto import org.sopt.dosopttemplate.data.ResponseSignUpDto import retrofit2.Call +import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST @@ -16,14 +17,14 @@ import retrofit2.http.Query interface AuthService { @POST("api/v1/members") - fun signup( + suspend fun signup( @Body request: RequestSignUpDto, - ):Call // 응답이 왓을 때 Callback으로 불려질 타입 + ):Response // 응답이 왓을 때 Callback으로 불려질 타입 @POST("api/v1/members/sign-in") - fun login( + suspend fun login( @Body request: RequestLoginDto, - ): Call + ): Response @GET("api/v1/members/{memberId}") fun memberInfo( diff --git a/app/src/main/java/org/sopt/dosopttemplate/AuthViewModel.kt b/app/src/main/java/org/sopt/dosopttemplate/AuthViewModel.kt new file mode 100644 index 0000000..2379602 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/AuthViewModel.kt @@ -0,0 +1,56 @@ +package org.sopt.dosopttemplate + +import android.provider.ContactsContract.CommonDataKinds.Nickname +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import org.sopt.dosopttemplate.ServicePool.authService +import org.sopt.dosopttemplate.data.RequestLoginDto +import org.sopt.dosopttemplate.data.RequestSignUpDto + +class AuthViewModel : ViewModel() { + + // UI State 사용 + private val _loginState = MutableStateFlow(LoginState.Loading) + val loginState: StateFlow = _loginState.asStateFlow() + + private val _signUpState = MutableStateFlow(SignUpState.Loading) + val signUpState: StateFlow = _signUpState.asStateFlow() + + fun login(id: String, password: String) { + viewModelScope.launch { + kotlin.runCatching { + val response = authService.login(RequestLoginDto(id, password)) + response.body() + }.onSuccess { + if(it != null){ + _loginState.value = LoginState.Success(it) + } else{ + _loginState.value = LoginState.Error + } + }.onFailure { + _loginState.value = LoginState.Error + } + } + } + + fun signUp(id: String, password: String, nickname: String){ + viewModelScope.launch { + kotlin.runCatching { + val response = authService.signup(RequestSignUpDto(id, password, nickname)) + response.body() + }.onSuccess { + if(it!=null) { + _signUpState.value = SignUpState.Success(it) + }else{ + _signUpState. value = SignUpState.Error + } + }.onFailure { + _signUpState.value = SignUpState.Error + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/sopt/dosopttemplate/LoginActivity.kt b/app/src/main/java/org/sopt/dosopttemplate/LoginActivity.kt index d199ba4..43578b6 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/LoginActivity.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/LoginActivity.kt @@ -2,19 +2,17 @@ package org.sopt.dosopttemplate import android.content.Intent import android.os.Bundle -import android.util.Log +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity -import org.sopt.dosopttemplate.ServicePool.authService -import org.sopt.dosopttemplate.Utils.UserInfo +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch import org.sopt.dosopttemplate.Utils.showToast -import org.sopt.dosopttemplate.data.RequestLoginDto -import org.sopt.dosopttemplate.data.ResponseLoginDto import org.sopt.dosopttemplate.databinding.ActivityLoginBinding -import retrofit2.Call -import retrofit2.Response class LoginActivity : AppCompatActivity() { private lateinit var binding: ActivityLoginBinding + private val authViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -22,6 +20,7 @@ class LoginActivity : AppCompatActivity() { setContentView(binding.root) signup() + observeLoginResult() login() } @@ -32,7 +31,12 @@ class LoginActivity : AppCompatActivity() { val id = binding.etLoginIdIdHint.text.toString() val pw = binding.etLoginIdPwHint.text.toString() - // Request 요청 : RequestLoginDto body 담아주기 + authViewModel.login( + id = id, + password = pw + ) + + /*// Request 요청 : RequestLoginDto body 담아주기 authService.login(RequestLoginDto(id, pw)) // enqueue : 비동기 방식으로 네트워크 요청 보내고, 결과를 받아 알맞게 처리 // Callback 인터페이스를 구현한 객체를 전달 @@ -67,12 +71,31 @@ class LoginActivity : AppCompatActivity() { showToast("네트워크 오류 발생") } } - ) + )*/ + } + } + + private fun observeLoginResult() { + lifecycleScope.launch { + authViewModel.loginState.collect{ loginState -> + when(loginState){ + is LoginState.Success -> { + showToast("로그인 성공") + startActivity(Intent(this@LoginActivity, HomeActivity::class.java)) + } + is LoginState.Error -> { + showToast("로그인 실패") + } + is LoginState.Loading -> { + showToast("로그인 중") + } + } + } } } // 회원가입 버튼 클릭 시 - private fun signup(){ + private fun signup() { // 회원가입 페이지로 이동 binding.btnLoginIdSignUp.setOnClickListener { // Intent 실행 diff --git a/app/src/main/java/org/sopt/dosopttemplate/LoginState.kt b/app/src/main/java/org/sopt/dosopttemplate/LoginState.kt new file mode 100644 index 0000000..3f813dc --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/LoginState.kt @@ -0,0 +1,9 @@ +package org.sopt.dosopttemplate + +import org.sopt.dosopttemplate.data.ResponseLoginDto + +sealed class LoginState{ + object Loading : LoginState() + data class Success(val data: ResponseLoginDto) : LoginState() + object Error : LoginState() +} diff --git a/app/src/main/java/org/sopt/dosopttemplate/SignUpActivity.kt b/app/src/main/java/org/sopt/dosopttemplate/SignUpActivity.kt index 279ecd2..e1428f7 100644 --- a/app/src/main/java/org/sopt/dosopttemplate/SignUpActivity.kt +++ b/app/src/main/java/org/sopt/dosopttemplate/SignUpActivity.kt @@ -3,9 +3,13 @@ package org.sopt.dosopttemplate import android.content.Intent import android.os.Bundle import android.util.Log +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.snackbar.Snackbar +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch import org.sopt.dosopttemplate.ServicePool.authService import org.sopt.dosopttemplate.Utils.showToast import org.sopt.dosopttemplate.data.RequestSignUpDto @@ -22,6 +26,7 @@ import kotlin.properties.Delegates class SignUpActivity : AppCompatActivity() { lateinit var binding: ActivitySignUpBinding private var available by Delegates.notNull() + private val authViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -30,6 +35,7 @@ class SignUpActivity : AppCompatActivity() { birth() signup() + observeSignUpResult() } // 생일 정보 입력 @@ -116,39 +122,32 @@ class SignUpActivity : AppCompatActivity() { if (available) { showToast("중복된 아이디입니다.") } else if (testResult && !available) { // 조건이 적절하고 중복된 아이디가 아닌 경우 - authService.signup(RequestSignUpDto(id, pw, nickname)) - .enqueue(object : retrofit2.Callback { - override fun onResponse( - call: Call, - response: Response - ) { - when (response.code()) { - 201 -> { - // 회원가입 성공 - showToast("회원가입 성공!") - val intent = - Intent(this@SignUpActivity, LoginActivity::class.java) - startActivity(intent) - } - - 400 -> { - // 회원가입 실패 - showToast("회원가입에 실패했습니다.") - } - - else -> { - showToast("서버 에러 발생") - } - } - } - - override fun onFailure(call: Call, t: Throwable) { - showToast("네트워크 에러 발생") - } - }) + authViewModel.signUp( + id = id, + password = pw, + nickname = nickname + ) } else { showToast("올바른 정보를 입력해주세요.") } } } + + private fun observeSignUpResult(){ + lifecycleScope.launch { + authViewModel.signUpState.collect{ SignUpState -> + when(SignUpState){ + is SignUpState.Success -> { + showToast("회원가입 성공") + } + is SignUpState.Error -> { + showToast("회원가입 실패") + } + is SignUpState.Loading -> { + showToast("회원가입 중") + } + } + } + } + } } diff --git a/app/src/main/java/org/sopt/dosopttemplate/SignUpState.kt b/app/src/main/java/org/sopt/dosopttemplate/SignUpState.kt new file mode 100644 index 0000000..f783532 --- /dev/null +++ b/app/src/main/java/org/sopt/dosopttemplate/SignUpState.kt @@ -0,0 +1,9 @@ +package org.sopt.dosopttemplate + +import org.sopt.dosopttemplate.data.ResponseSignUpDto + +sealed class SignUpState { + object Loading : SignUpState() + data class Success(val data: ResponseSignUpDto) : SignUpState() + object Error : SignUpState() +}