Skip to content

Commit

Permalink
[D83T-11] 카카오 로그인 기능 추가 + 내부저장소 저장
Browse files Browse the repository at this point in the history
  • Loading branch information
YHKOO95 committed Feb 16, 2023
1 parent dec628c commit 1861a03
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 36 deletions.
14 changes: 12 additions & 2 deletions data/src/main/java/com/d83t/bpm/data/datastore/DataStoreManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@ package com.d83t.bpm.data.datastore
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import kotlinx.coroutines.flow.flow

class DataStoreManager @Inject constructor(private val context: Context) {
private val Context.instance: DataStore<Preferences> by preferencesDataStore(name = "bpm")

fun getKakaoId(): Flow<String> {
fun getKakaoId(): Flow<String?> {
return context.instance.data.map { preferences ->
preferences[stringPreferencesKey(name = "kakaoId")] ?: "null"
preferences[stringPreferencesKey(name = "kakaoId")]
}
}

suspend fun setKakaoUserId(kakaoId : String) : Flow<String?> {
return flow {
context.instance.edit { preferences ->
preferences[stringPreferencesKey(name = "kakaoId")] = kakaoId
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ class SplashRepositoryImpl @Inject constructor(
private val dataStoreManager: DataStoreManager
) : SplashRepository {

override fun getStoredId(): Flow<String> {
override fun getKakaoUserId(): Flow<String?> {
return dataStoreManager.getKakaoId()
}

override suspend fun setKakaoUserId(kakaoId : String): Flow<String?> {
return dataStoreManager.setKakaoUserId(kakaoId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ import kotlinx.coroutines.flow.Flow

interface SplashRepository {

fun getStoredId(): Flow<String>
fun getKakaoUserId(): Flow<String?>

suspend fun setKakaoUserId(kakaoId : String): Flow<String?>
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.d83t.bpm.domain.usecase.splash

import com.d83t.bpm.domain.repository.SplashRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class GetKakaoUserIdUseCase @Inject constructor(
private val splashRepository: SplashRepository
) {
operator fun invoke(): Flow<String?> {
return splashRepository.getKakaoUserId()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.d83t.bpm.domain.usecase.splash

import com.d83t.bpm.domain.repository.SplashRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow

class SetKakaoUserIdUseCase @Inject constructor(
private val splashRepository: SplashRepository
) {
suspend operator fun invoke(kakaoId: String): Flow<String?> {
return splashRepository.setKakaoUserId(kakaoId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package com.d83t.bpm.presentation.di
import com.d83t.bpm.domain.repository.MainRepository
import com.d83t.bpm.domain.repository.SplashRepository
import com.d83t.bpm.domain.usecase.GetSampleTextUseCase
import com.d83t.bpm.domain.usecase.GetStoredIdUseCase
import com.d83t.bpm.domain.usecase.splash.GetKakaoUserIdUseCase
import com.d83t.bpm.domain.usecase.splash.SetKakaoUserIdUseCase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -22,7 +23,13 @@ object UseCaseModule {

@Provides
@ViewModelScoped
fun provideGetStoredIdUseCase(splashRepository: SplashRepository): GetStoredIdUseCase {
return GetStoredIdUseCase(splashRepository)
fun provideGetKakaoUserIdUseCase(splashRepository: SplashRepository): GetKakaoUserIdUseCase {
return GetKakaoUserIdUseCase(splashRepository)
}

@Provides
@ViewModelScoped
fun provideSetKakaoUserIdUseCase(splashRepository: SplashRepository): SetKakaoUserIdUseCase {
return SetKakaoUserIdUseCase(splashRepository)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.d83t.bpm.presentation.ui.main

import android.content.Context
import android.content.Intent
import androidx.activity.viewModels
import com.d83t.bpm.presentation.base.BaseActivity
import com.d83t.bpm.presentation.databinding.ActivityMainBinding
Expand Down Expand Up @@ -34,4 +36,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl

}
}

companion object {

fun newIntent(context: Context): Intent {
return Intent(context, MainActivity::class.java)
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.d83t.bpm.presentation.R
import com.d83t.bpm.presentation.base.BaseComponentActivity
import com.d83t.bpm.presentation.compose.theme.BPMShapes
import com.d83t.bpm.presentation.compose.theme.BPMTheme
import com.d83t.bpm.presentation.compose.theme.BPMTypography
import com.d83t.bpm.presentation.ui.main.MainActivity
import com.d83t.bpm.presentation.compose.theme.*
import com.d83t.bpm.presentation.util.repeatCallDefaultOnStarted
import com.d83t.bpm.presentation.util.showDebugToast
import com.d83t.bpm.presentation.util.showToast
import com.kakao.sdk.user.UserApiClient
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
Expand All @@ -40,15 +47,22 @@ import kotlinx.coroutines.launch
@SuppressLint("CustomSplashScreen")
@AndroidEntryPoint
class SplashActivity : BaseComponentActivity() {

override val viewModel: SplashViewModel by viewModels()

private val startButtonVisibilityState = mutableStateOf(false)

private val kakaoLoginInstance: UserApiClient by lazy {
UserApiClient.instance
}

override fun initUi() {
setContent {
BPMTheme {
SplashActivityContent(
startButtonVisibilityState = startButtonVisibilityState,
onClickStartButton = {
// TODO : SignUp With Kakao
setupLogin()
}
)
}
Expand All @@ -65,17 +79,47 @@ class SplashActivity : BaseComponentActivity() {
viewModel.getStoredId()
}
}
is SplashState.KakaoId -> {
if (state.id == "null") {
is SplashState.SignUp -> {
if (state.id == "null" || state.id.isNullOrEmpty()) {
startButtonVisibilityState.value = true
} else {
// TODO : SignIn
viewModel.setFinish()
}
}
SplashState.SignIn -> {
viewModel.setFinish()
}
SplashState.Finish -> {
goToMainActivity()
}
}
}
}
}

private fun setupLogin() {
// 카카오톡으로 로그인
if (kakaoLoginInstance.isKakaoTalkLoginAvailable(this)) {
kakaoLoginInstance.loginWithKakaoTalk(this) { loginInfo, error ->
if (error != null) {
// 로그인 실패
showDebugToast("login failed! cause : ${error.message}")
showToast("로그인에 실패하였습니다. 다시 시도해 주세요.")
} else if (loginInfo != null) {
// 로그인 성공
viewModel.setLoginId(loginInfo.idToken ?: "")
showDebugToast("login succeed. user token : ${loginInfo.idToken}")
}
}
} else {
showToast("로그인에 실패하였습니다. 다시 시도해 주세요.")
}
}

private fun goToMainActivity() {
startActivity(MainActivity.newIntent(this))
finish()
}
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ import com.d83t.bpm.presentation.util.ComposeUiState

sealed interface SplashState : ComposeUiState {
object Init : SplashState
data class KakaoId(val id: String) : SplashState
data class SignUp(val id: String?) : SplashState

object SignIn : SplashState
object Finish : SplashState
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
package com.d83t.bpm.presentation.ui.splash

interface SplashViewEvent {
object Click : SplashViewEvent
}
sealed interface SplashViewEvent
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
package com.d83t.bpm.presentation.ui.splash

import androidx.lifecycle.viewModelScope
import com.d83t.bpm.domain.usecase.GetStoredIdUseCase
import com.d83t.bpm.domain.usecase.splash.GetKakaoUserIdUseCase
import com.d83t.bpm.domain.usecase.splash.SetKakaoUserIdUseCase
import com.d83t.bpm.presentation.base.BaseViewModel
import com.d83t.bpm.presentation.di.IoDispatcher
import com.d83t.bpm.presentation.di.MainDispatcher
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

@HiltViewModel
class SplashViewModel @Inject constructor(
private val getStoredIdUseCase: GetStoredIdUseCase,
private val getKakaoUserIdUseCase: GetKakaoUserIdUseCase,
private val setKakaoUserIdUseCase: SetKakaoUserIdUseCase,
@MainDispatcher private val mainDispatcher: CoroutineDispatcher,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
) : BaseViewModel() {
Expand All @@ -27,12 +35,43 @@ class SplashViewModel @Inject constructor(
val state: StateFlow<SplashState>
get() = _state

private val exceptionHandler: CoroutineExceptionHandler by lazy {
CoroutineExceptionHandler { coroutineContext, throwable ->
when (state.value) {
SplashState.SignIn -> {
// TODO : Exception Handling
}
else -> {
// TODO : Exception Handling
}
}

}
}

fun getStoredId() {
viewModelScope.launch(ioDispatcher) {
val kakaoId = getStoredIdUseCase().first()
withContext(mainDispatcher) {
_state.emit(SplashState.KakaoId(kakaoId))
}
getKakaoUserIdUseCase().onEach {
withContext(mainDispatcher) {
_state.emit(SplashState.SignUp(it))
}
}.launchIn(viewModelScope)
}
}

fun setLoginId(kakaoId: String) {
viewModelScope.launch(ioDispatcher + exceptionHandler) {
setKakaoUserIdUseCase(kakaoId).onEach {
withContext(mainDispatcher) {
_state.emit(SplashState.SignUp(it))
}
}.launchIn(viewModelScope)
}
}

fun setFinish() {
viewModelScope.launch {
_state.emit(SplashState.Finish)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ import android.widget.Toast

fun Context.showToast(text: String) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}

fun Context.showDebugToast(text: String) {
Toast.makeText(this, "Debug Mode! $text", Toast.LENGTH_SHORT).show()
}
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()

maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }
}
}
rootProject.name = "BPM"
Expand Down

0 comments on commit 1861a03

Please sign in to comment.