diff --git a/data/src/main/kotlin/ac/dnd/bookkeeping/android/data/di/RepositoryModule.kt b/data/src/main/kotlin/ac/dnd/bookkeeping/android/data/di/RepositoryModule.kt index dedd54ab..558a24eb 100644 --- a/data/src/main/kotlin/ac/dnd/bookkeeping/android/data/di/RepositoryModule.kt +++ b/data/src/main/kotlin/ac/dnd/bookkeeping/android/data/di/RepositoryModule.kt @@ -2,8 +2,10 @@ package ac.dnd.bookkeeping.android.data.di import ac.dnd.bookkeeping.android.data.repository.bookkeeping.MockBookkeepingRepository import ac.dnd.bookkeeping.android.data.repository.authentication.MockAuthenticationRepository +import ac.dnd.bookkeeping.android.data.repository.social_login.KakaoLoginRepository import ac.dnd.bookkeeping.android.domain.repository.AuthenticationRepository import ac.dnd.bookkeeping.android.domain.repository.BookkeepingRepository +import ac.dnd.bookkeeping.android.domain.repository.social_login.SocialLoginRepository import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -24,4 +26,10 @@ internal abstract class RepositoryModule { abstract fun bindsAuthenticationRepository( authenticationRepository: MockAuthenticationRepository ): AuthenticationRepository + + @Binds + @Singleton + abstract fun bindsKakaoLoginRepository( + kakaoLoginRepository: KakaoLoginRepository + ): SocialLoginRepository } diff --git a/data/src/main/kotlin/ac/dnd/bookkeeping/android/data/repository/social_login/KakaoLoginRepository.kt b/data/src/main/kotlin/ac/dnd/bookkeeping/android/data/repository/social_login/KakaoLoginRepository.kt new file mode 100644 index 00000000..7cc92ff1 --- /dev/null +++ b/data/src/main/kotlin/ac/dnd/bookkeeping/android/data/repository/social_login/KakaoLoginRepository.kt @@ -0,0 +1,101 @@ +package ac.dnd.bookkeeping.android.data.repository.social_login + +import ac.dnd.bookkeeping.android.domain.model.social_login.UserModel +import ac.dnd.bookkeeping.android.domain.repository.social_login.SocialLoginRepository +import android.content.Context +import com.kakao.sdk.common.model.ClientError +import com.kakao.sdk.common.model.ClientErrorCause +import com.kakao.sdk.user.UserApiClient +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +class KakaoLoginRepository @Inject constructor( + @ApplicationContext private val context: Context +) : SocialLoginRepository { + + override suspend fun login(): Result = runCatching { + if (UserApiClient.instance.isKakaoTalkLoginAvailable(context)) { + try { + UserApiClient.loginWithKakaoTalk() + } catch (error: Throwable) { + if (error is ClientError && error.reason == ClientErrorCause.Cancelled) { + throw error + } else { + UserApiClient.loginWithKakaoAccount() + } + } + } else { + UserApiClient.loginWithKakaoAccount() + } + } + + private suspend fun UserApiClient.Companion.loginWithKakaoTalk(): String = + suspendCoroutine { continuation -> + instance.loginWithKakaoTalk(context) { token, error -> + if (error != null) { + continuation.resumeWithException(error) + } else { + val accessToken = token?.accessToken + if (accessToken == null) { + continuation.resumeWithException(RuntimeException("Can't Receive Kaokao Access Token")) + } else { + continuation.resume(accessToken) + } + } + } + } + + private suspend fun UserApiClient.Companion.loginWithKakaoAccount(): String = + suspendCoroutine { continuation -> + instance.loginWithKakaoAccount(context) { token, error -> + if (error != null) { + continuation.resumeWithException(error) + } else { + val accessToken = token?.accessToken + if (accessToken == null) { + continuation.resumeWithException(RuntimeException("Can't Receive Kaokao Access Token")) + } else { + continuation.resume(accessToken) + } + } + } + } + + + override suspend fun logout(): Result = runCatching { + suspendCoroutine { continuation -> + UserApiClient.instance.logout { error -> + if (error != null) { + continuation.resumeWithException(error) + } else { + continuation.resume(true) + } + } + } + } + + override suspend fun getUserInfo(): Result = runCatching { + suspendCoroutine { continuation -> + UserApiClient.instance.me { user, error -> + if (error != null) { + continuation.resumeWithException(error) + } else if (user != null) { + try { + continuation.resume( + UserModel( + socialId = user.id!!, + email = user.kakaoAccount!!.email!!, + name = user.kakaoAccount!!.profile!!.nickname!! + ) + ) + } catch (e: Exception) { + continuation.resumeWithException(e) + } + } + } + } + } +}