Skip to content

Commit

Permalink
[feat]: 카카오톡 자동 로그인 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
kangyuri1114 committed Jan 13, 2024
1 parent 1b87cc6 commit c9de466
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import javax.inject.Singleton

@Singleton
class DefaultHMHNetworkPreference @Inject constructor(
private val preferences: SharedPreferences
private val preferences: SharedPreferences,
) : HMHNetworkPreference {
override var accessToken: String
get() = preferences.getString("access_token", "").orEmpty()
Expand All @@ -30,11 +30,11 @@ class DefaultHMHNetworkPreference @Inject constructor(
putString("user_name", value)
}
}
override var userId: String
get() = preferences.getString("user_id", "").orEmpty()
override var userId: Int
get() = preferences.getInt("user_id", -1)
set(value) {
preferences.edit(commit = true) {
putString("user_id", value)
putInt("user_id", value)
}
}
override var autoLoginConfigured: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ interface HMHNetworkPreference {
var accessToken: String
var refreshToken: String
var userName: String
var userId: String
var userId: Int
var autoLoginConfigured: Boolean
fun clear()
}
1 change: 1 addition & 0 deletions feature/login/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ dependencies {
implementation(libs.dot.indicator)
implementation(projects.core.designsystem)
implementation(project(":feature:onboarding"))
implementation(project(":core:network"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,26 @@ class LoginActivity : AppCompatActivity() {
}
setLoginViewPager()
handleKakaoLoginSuccess()
handleAutoLoginSuccess()
}

private fun handleAutoLoginSuccess() {
viewModel.loginState.flowWithLifecycle(lifecycle).onEach { state ->
if (state.autoLogin) {
moveToMainActivity()
}
}.launchIn(lifecycleScope)
}

private fun handleKakaoLoginSuccess() {
viewModel.kakaoLoginEvent.flowWithLifecycle(lifecycle).onEach { state ->

when (state) {
is LoginEffect.LoginSuccess -> moveToMainActivity()

is LoginEffect.LoginFail -> toast(getString(R.string.fail_kakao_login))
is LoginEffect.RequireSignUp -> moveToOnBoardingActivity(state.token)
else -> Unit
}
}.launchIn(lifecycleScope)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package com.hmh.hamyeonham.feature.login
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.hmh.hamyeonham.core.network.auth.datastore.HMHNetworkPreference
import com.hmh.hamyeonham.login.repository.LoginRepository
import com.kakao.sdk.common.model.ClientError
import com.kakao.sdk.common.model.ClientErrorCause
import com.kakao.sdk.user.UserApiClient
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import retrofit2.HttpException
import javax.inject.Inject
Expand All @@ -20,14 +23,29 @@ sealed interface LoginEffect {
data class RequireSignUp(val token: String) : LoginEffect
}

data class LoginState(
val autoLogin: Boolean = false,
)

@HiltViewModel
class LoginViewModel @Inject constructor(
private val loginRepository: LoginRepository,
private val hmhNetworkPreference: HMHNetworkPreference,
) : ViewModel() {

private val _kakaoLoginEvent = MutableSharedFlow<LoginEffect>()
val kakaoLoginEvent = _kakaoLoginEvent.asSharedFlow()

private val _loginState = MutableStateFlow(LoginState())
val loginState = _loginState.asStateFlow()

init {
val currentState = loginState.value
_loginState.value = currentState.copy(
autoLogin = hmhNetworkPreference.autoLoginConfigured,
)
}

fun loginWithKakaoApp(context: Context) {
if (UserApiClient.instance.isKakaoTalkLoginAvailable(context)) {
UserApiClient.instance.loginWithKakaoTalk(context) { token, error ->
Expand All @@ -40,6 +58,10 @@ class LoginViewModel @Inject constructor(
viewModelScope.launch {
loginRepository.login(token.accessToken).onSuccess {
_kakaoLoginEvent.emit(LoginEffect.LoginSuccess)
hmhNetworkPreference.accessToken = token.accessToken
hmhNetworkPreference.refreshToken = token.refreshToken
hmhNetworkPreference.userId = it.userId
hmhNetworkPreference.autoLoginConfigured = true
}.onFailure {
if (it is HttpException && it.code() == 403) {
_kakaoLoginEvent.emit(LoginEffect.RequireSignUp(token.accessToken))
Expand All @@ -63,6 +85,10 @@ class LoginViewModel @Inject constructor(
viewModelScope.launch {
loginRepository.login(token.accessToken).onSuccess {
_kakaoLoginEvent.emit(LoginEffect.LoginSuccess)
hmhNetworkPreference.accessToken = token.accessToken
hmhNetworkPreference.refreshToken = token.refreshToken
hmhNetworkPreference.userId = it.userId
hmhNetworkPreference.autoLoginConfigured = true
}.onFailure {
if (it is HttpException && it.code() == 403) {
_kakaoLoginEvent.emit(LoginEffect.RequireSignUp(token.accessToken))
Expand Down

This file was deleted.

1 change: 1 addition & 0 deletions feature/onboarding/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ dependencies {
implementation(projects.domain.login)

implementation(projects.feature.main)
implementation(project(":core:network"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.hmh.hamyeonham.feature.onboarding.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.hmh.hamyeonham.core.network.auth.datastore.HMHNetworkPreference
import com.hmh.hamyeonham.feature.onboarding.model.OnboardingAnswer
import com.hmh.hamyeonham.feature.onboarding.model.OnboardingPageInfo
import com.hmh.hamyeonham.feature.onboarding.model.toSignUpRequest
Expand All @@ -28,7 +29,8 @@ data class OnBoardingState(

@HiltViewModel
class OnBoardingViewModel @Inject constructor(
private val signUpRepository: SignUpRepository
private val signUpRepository: SignUpRepository,
private val hmhNetworkPreference: HMHNetworkPreference,
) : ViewModel() {
private val _onBoardingState = MutableStateFlow(OnBoardingState())
val onBoardingState = _onBoardingState.asStateFlow()
Expand Down Expand Up @@ -72,7 +74,14 @@ class OnBoardingViewModel @Inject constructor(
val request = onBoardingState.value.onBoardingAnswer
runCatching {
signUpRepository.signUp(token, request.toSignUpRequest())
}.onSuccess {
}.onSuccess { result ->
val signUpUser = result.getOrNull()
signUpUser?.let {
hmhNetworkPreference.accessToken = it.accessToken
hmhNetworkPreference.refreshToken = it.refreshToken
hmhNetworkPreference.userId = it.userId
hmhNetworkPreference.autoLoginConfigured = true
}
setEffect(OnBoardingEffect.SignUpSuccess)
}.onFailure {
setEffect(OnBoardingEffect.SignUpFail)
Expand Down

0 comments on commit c9de466

Please sign in to comment.