Skip to content

Commit

Permalink
[FEAT/#7] Activity, ViewModel 로그인 기능 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
chattymin committed Dec 30, 2023
1 parent 95049f1 commit 480aa33
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.going.domain.entity.response

data class AuthTokenModel(
val isResigned: Boolean,
val accessToken: String,
val refreshToken: String,
)
4 changes: 4 additions & 0 deletions presentation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,8 @@ dependencies {
implementation(circularProgressBar)
implementation(circleIndicator)
}

KakaoDependencies.run {
implementation(user)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,63 @@
package com.going.presentation.auth

import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.going.presentation.R
import com.going.presentation.databinding.ActivityLoginBinding
import com.going.ui.base.BaseActivity
import com.going.ui.extension.UiState
import com.going.ui.extension.setOnSingleClickListener
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

class LoginActivity() : BaseActivity<ActivityLoginBinding>(R.layout.activity_login) {
private val viewModel by viewModels<LoginViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initKakaoLoginButtonClickListener()
observeInfo()
}

private fun initKakaoLoginButtonClickListener() {
binding.btnSignIn.setOnSingleClickListener {
viewModel.startKakaoLogIn(this)
}
}

private fun observeInfo() {
observeIsAppLoginAvailable()
observePostChangeTokenState()
}

private fun observeIsAppLoginAvailable() {
viewModel.isAppLoginAvailable.flowWithLifecycle(lifecycle).onEach { canLogin ->
if (!canLogin) viewModel.startKakaoLogIn(this)
}.launchIn(lifecycleScope)
}

private fun observePostChangeTokenState() {
viewModel.postChangeTokenState.flowWithLifecycle(lifecycle).onEach { tokenState ->
when (tokenState) {
is UiState.Success -> {
// 성공 했을 때 로직
}

is UiState.Failure -> {
// 실패 했을 때 로직
}

is UiState.Empty -> {
// 여튼 로직
}

is UiState.Loading -> {
// 로딩 중 로직
}
}
}.launchIn(lifecycleScope)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,81 @@
package com.going.presentation.auth

import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.going.domain.entity.response.AuthTokenModel
import com.going.ui.extension.UiState
import com.kakao.sdk.auth.model.OAuthToken
import com.kakao.sdk.common.model.ClientError
import com.kakao.sdk.common.model.ClientErrorCause
import com.kakao.sdk.user.UserApiClient
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class LoginViewModel : ViewModel()
class LoginViewModel : ViewModel() {
private val _postChangeTokenState = MutableStateFlow<UiState<AuthTokenModel>>(UiState.Empty)
val postChangeTokenState: StateFlow<UiState<AuthTokenModel?>> = _postChangeTokenState

private val _isAppLoginAvailable = MutableStateFlow(true)
val isAppLoginAvailable: StateFlow<Boolean> = _isAppLoginAvailable

private var webLoginCallback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
if (error == null && token != null) {
changeTokenFromServer(
accessToken = token.accessToken,
)
}
}

private var appLoginCallback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
if (error != null) {
// 뒤로가기 경우 예외 처리
if (!(error is ClientError && error.reason == ClientErrorCause.Cancelled)) {
_isAppLoginAvailable.value = false
}
} else if (token != null) {
changeTokenFromServer(
accessToken = token.accessToken,
)
}
}

fun startKakaoLogIn(context: Context) {
if (UserApiClient.instance.isKakaoTalkLoginAvailable(context) && isAppLoginAvailable.value) {
UserApiClient.instance.loginWithKakaoTalk(
context = context,
callback = appLoginCallback,
)
} else {
UserApiClient.instance.loginWithKakaoAccount(
context = context,
callback = webLoginCallback,
)
}
}

// 서버통신 - 카카오 토큰 보내서 서비스 토큰 받아오기
private fun changeTokenFromServer(
accessToken: String,
social: String = KAKAO,
) {
_postChangeTokenState.value = UiState.Loading
viewModelScope.launch {
// 통신 로직

// 성공시 저러케 서버에서 준 정보를 넣음
_postChangeTokenState.value = UiState.Success(
AuthTokenModel(
isResigned = true,
accessToken = "testAccessToekn",
refreshToken = "testRefreshToekn",
),
)
}
}

companion object {
const val KAKAO = "KAKAO"
}
}

0 comments on commit 480aa33

Please sign in to comment.