Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT/#49] Local DB 구현 및 이슈 해결 #60

Merged
merged 12 commits into from
Jul 20, 2023
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".presentation.main.SplashActivity"
android:name=".presentation.splash.SplashActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.YELLO.Splash">
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/yello/di/DataSourceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ object DataSourceModule {
@Singleton
fun provideRecommendDataSource(recommendDataSourceImpl: RecommendDataSourceImpl): RecommendDataSource =
recommendDataSourceImpl
}
}
6 changes: 6 additions & 0 deletions app/src/main/java/com/yello/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.yello.di

import com.example.data.repository.AuthRepositoryImpl
import com.example.data.repository.OnboardingRepositoryImpl
import com.example.data.repository.ProfileRepositoryImpl
import com.example.data.repository.RecommendRepositoryImpl
import com.example.data.repository.VoteRepositoryImpl
import com.example.data.repository.YelloRepositoryImpl
import com.example.domain.repository.AuthRepository
import com.example.domain.repository.OnboardingRepository
import com.example.domain.repository.ProfileRepository
import com.example.domain.repository.RecommendRepository
Expand Down Expand Up @@ -43,4 +45,8 @@ object RepositoryModule {
@Singleton
fun provideRecommendRepository(recommendRepositoryImpl: RecommendRepositoryImpl): RecommendRepository =
recommendRepositoryImpl

@Provides
@Singleton
fun provideAuthRepository(authRepositoryImpl: AuthRepositoryImpl): AuthRepository = authRepositoryImpl
}
60 changes: 37 additions & 23 deletions app/src/main/java/com/yello/presentation/auth/SignInActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class SignInActivity : BindingActivity<ActivitySignInBinding>(R.layout.activity_
Timber.tag(TAG_AUTH).d(keyHash)

initSignInButtonListener()
setupGetUserProfileState()
}

private fun initSignInButtonListener() {
Expand All @@ -57,7 +58,6 @@ class SignInActivity : BindingActivity<ActivitySignInBinding>(R.layout.activity_
accountLoginCallback = { token, error ->
if (error != null) {
Timber.tag(TAG_AUTH).e(error, getString(R.string.sign_in_error_kakao_account_login))

} else if (token != null) {
setDataFromObserver(token)
} else {
Expand Down Expand Up @@ -125,22 +125,19 @@ class SignInActivity : BindingActivity<ActivitySignInBinding>(R.layout.activity_
viewModel.postState.observe(this) { state ->
when (state) {
is UiState.Success -> {
// 500(가입된 아이디): 온보딩뷰 생략하고 바로 메인화면으로 이동
// TODO: 서비스 토큰 값 저장
val serviceAccessToken = state.data?.accessToken
startMainActivity()
// 500(가입된 아이디): 온보딩 뷰 생략하고 바로 메인 화면으로 이동
viewModel.getUserData()
}

is UiState.Failure -> {
if (state.msg == "403") {
// 403(가입되지 않은 아이디): 온보딩뷰로 이동
// 403(가입되지 않은 아이디): 온보딩 뷰로 이동
getKakaoInfo()
startSocialSyncActivity()
} else {
// 401 : 에러 발생
yelloSnackbar(
binding.root.rootView,
getString(R.string.sign_in_error_connection)
getString(R.string.sign_in_error_connection),
)
}
}
Expand All @@ -164,28 +161,45 @@ class SignInActivity : BindingActivity<ActivitySignInBinding>(R.layout.activity_

private fun getKakaoInfo() {
UserApiClient.instance.me { user, _ ->
if (user != null) {
viewModel.setKakaoInfo(
kakaoId = user.id?.toInt() ?: return@me,
email = user.kakaoAccount?.email ?: "",
profileImage = user.kakaoAccount?.profile?.thumbnailImageUrl ?: "",
)
return@me
try {
if (user != null) {
Timber.d("KAKAO INFO : $user")
Intent(this, SocialSyncActivity::class.java).apply {
putExtra(EXTRA_KAKAO_ID, user.id)
putExtra(EXTRA_EMAIL, user.kakaoAccount?.email)
putExtra(EXTRA_PROFILE_IMAGE, user.kakaoAccount?.profile?.profileImageUrl)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(this)
}
finish()
return@me
}
} catch (e: IllegalArgumentException) {
yelloSnackbar(binding.root, getString(R.string.msg_error))
}
}
Timber.e("카카오 정보 불러오기 실패")
yelloSnackbar(binding.root, getString(R.string.msg_error))
}

private fun startSocialSyncActivity() {
Intent(this, SocialSyncActivity::class.java).apply {
putExtra(EXTRA_KAKAO_ID, viewModel.kakaoUserId.value)
putExtra(EXTRA_EMAIL, viewModel.email.value)
putExtra(EXTRA_PROFILE_IMAGE, viewModel.profileImage.value)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(this)
private fun setupGetUserProfileState() {
viewModel.getUserProfileState.observe(this) { state ->
when (state) {
is UiState.Success -> {
startMainActivity()
}

is UiState.Failure -> {
yelloSnackbar(binding.root, getString(R.string.msg_error))
}

is UiState.Empty -> {
yelloSnackbar(binding.root, getString(R.string.msg_error))
}

is UiState.Loading -> {}
}
}
finish()
}

private fun startMainActivity() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,30 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.domain.entity.RequestServiceTokenModel
import com.example.domain.entity.ServiceTokenModel
import com.example.domain.repository.AuthRepository
import com.example.domain.repository.OnboardingRepository
import com.example.domain.repository.ProfileRepository
import com.example.ui.view.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.launch
import retrofit2.HttpException
import javax.inject.Inject
import timber.log.Timber

@HiltViewModel
class SignInViewModel @Inject constructor(
private val onboardingRepository: OnboardingRepository,
private val authRepository: AuthRepository,
private val profileRepository: ProfileRepository,
) : ViewModel() {

private val _postState = MutableLiveData<UiState<ServiceTokenModel?>>()
val postState: LiveData<UiState<ServiceTokenModel?>> = _postState

private val _getUserProfileState = MutableLiveData<UiState<Unit>>()
val getUserProfileState: LiveData<UiState<Unit>>
get() = _getUserProfileState

private val _kakaoUserId = MutableLiveData(-1)
val kakaoUserId: LiveData<Int>
get() = _kakaoUserId
Expand Down Expand Up @@ -48,7 +57,12 @@ class SignInViewModel @Inject constructor(
RequestServiceTokenModel(accessToken, social),
)
}.onSuccess {
if (it == null) {
_postState.value = UiState.Empty
return@launch
}
_postState.value = UiState.Success(it)
authRepository.setAutoLogin(it.accessToken, it.refreshToken)
}.onFailure {
if (it is HttpException && it.code() == 403) {
_postState.value = UiState.Failure("403")
Expand All @@ -61,7 +75,29 @@ class SignInViewModel @Inject constructor(
}
}

fun getUserData() {
viewModelScope.launch {
runCatching {
profileRepository.getUserData()
}.onSuccess { profile ->
if (profile == null) {
_getUserProfileState.value = UiState.Empty
return@launch
}

_getUserProfileState.value = UiState.Success(Unit)
authRepository.setYelloId(profile.yelloId)
}
.onFailure { t ->
if (t is HttpException) {
Timber.e("GET USER PROFILE FAILURE : $t")
_getUserProfileState.value = UiState.Failure(t.code().toString())
}
}
}
}

private companion object {
const val KAKAO = "KAKAO"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ class SocialSyncActivity :

private fun startOnBoardingActivity() {
intent.apply {
val kakaoId = getLongExtra(EXTRA_KAKAO_ID, -1)
val email = getStringExtra(EXTRA_EMAIL)
val profileImage = getStringExtra(EXTRA_PROFILE_IMAGE)
Timber.d("KAKAO ID : $kakaoId, EMAIL : $email, PROFILE : $profileImage")
Intent(this@SocialSyncActivity, OnBoardingActivity::class.java).apply {
putExtra(EXTRA_KAKAO_ID, getIntExtra(EXTRA_KAKAO_ID, -1))
putExtra(EXTRA_EMAIL, getStringExtra(EXTRA_EMAIL))
putExtra(EXTRA_PROFILE_IMAGE, getStringExtra(EXTRA_PROFILE_IMAGE))
putExtra(EXTRA_KAKAO_ID, kakaoId)
putExtra(EXTRA_EMAIL, email)
putExtra(EXTRA_PROFILE_IMAGE, profileImage)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(this)
}
Expand All @@ -56,4 +60,4 @@ class SocialSyncActivity :
private companion object {
const val TAG_SYNC = "authSocialSync"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.domain.entity.ProfileFriendsListModel
import com.example.domain.entity.ProfileUserModel
import com.example.domain.repository.AuthRepository
import com.example.domain.repository.ProfileRepository
import com.example.ui.view.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -16,7 +17,8 @@ import kotlin.math.ceil

@HiltViewModel
class ProfileViewModel @Inject constructor(
private val profileRepository: ProfileRepository
private val profileRepository: ProfileRepository,
private val authRepository: AuthRepository,
) : ViewModel() {

private val _getState = MutableLiveData<UiState<ProfileUserModel>>()
Expand Down Expand Up @@ -84,7 +86,7 @@ class ProfileViewModel @Inject constructor(
if (isPagingFinish) return@launch
runCatching {
profileRepository.getFriendsData(
++currentPage
++currentPage,
)
}.onSuccess {
it ?: return@launch
Expand All @@ -103,6 +105,7 @@ class ProfileViewModel @Inject constructor(
_deleteUserState.value = UiState.Loading
runCatching {
profileRepository.deleteUserData()
clearLocalInfo()
}.onSuccess {
_deleteUserState.value = UiState.Success(it)
}.onFailure {
Expand All @@ -117,7 +120,7 @@ class ProfileViewModel @Inject constructor(
_deleteFriendState.value = UiState.Loading
runCatching {
profileRepository.deleteFriendData(
friendId
friendId,
)
}.onSuccess {
_deleteFriendState.value = UiState.Success(it)
Expand All @@ -126,4 +129,8 @@ class ProfileViewModel @Inject constructor(
}
}
}
}

fun clearLocalInfo() {
authRepository.clearLocalPref()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import com.example.ui.base.BindingActivity
import com.example.ui.view.setOnSingleClickListener
import com.kakao.sdk.user.UserApiClient
import com.yello.R
import com.yello.databinding.ActivityProfileManageBinding
import com.yello.presentation.main.profile.ProfileViewModel
import timber.log.Timber

class ProfileManageActivity :
BindingActivity<ActivityProfileManageBinding>(R.layout.activity_profile_manage) {
private val viewModel by viewModels<ProfileViewModel>()

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

initBackButton(this)
initProfileQuitActivityWithoutFinish()


binding.btnProfileManageCenter.setOnSingleClickListener {
// TODO: 버튼 3개 링크 설정
}
Expand All @@ -45,18 +47,17 @@ class ProfileManageActivity :
}
}

// 카카오 로그아웃 후 앱 재시작
private fun logoutKakaoAccount() {
UserApiClient.instance.logout { error ->
if (error != null) {
Timber.d(getString(R.string.profile_error_logout))
Timber.d(getString(R.string.profile_error_logout) + ": $error")
} else {
viewModel.clearLocalInfo()
restartApp(this)
}
}
}

// 앱 재시작 로직
private fun restartApp(context: Context) {
val packageManager = context.packageManager
val intent = packageManager.getLaunchIntentForPackage(context.packageName)
Expand All @@ -65,4 +66,4 @@ class ProfileManageActivity :
context.startActivity(mainIntent)
Runtime.getRuntime().exit(0)
}
}
}
Loading