Skip to content

Commit

Permalink
[Merge] #7 -> develop
Browse files Browse the repository at this point in the history
[FEAT/#7] kakao login
  • Loading branch information
chattymin authored Dec 31, 2023
2 parents eb1d47f + 6048c07 commit 0f281f9
Show file tree
Hide file tree
Showing 18 changed files with 277 additions and 14 deletions.
17 changes: 14 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,21 @@ android {
"BASE_URL",
gradleLocalProperties(rootDir).getProperty("base.url"),
)
buildConfigField(
"String",
"NATIVE_APP_KEY",
gradleLocalProperties(rootDir).getProperty("native.app.key"),
)
manifestPlaceholders["NATIVE_APP_KEY"] =
gradleLocalProperties(rootDir).getProperty("native.app.key")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}
Expand Down Expand Up @@ -95,4 +102,8 @@ dependencies {
implementation(timber)
implementation(ossLicense)
}
}

KakaoDependencies.run {
implementation(user)
}
}
17 changes: 16 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">

<activity
android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="oauth"
android:scheme="kakao${NATIVE_APP_KEY}" />
</intent-filter>
</activity>

<activity
android:name="com.going.presentation.mock.MockActivity"
android:exported="true"
Expand All @@ -28,4 +43,4 @@

</application>

</manifest>
</manifest>
7 changes: 6 additions & 1 deletion app/src/main/java/com/going/going/MyApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.going.going

import android.app.Application
import androidx.appcompat.app.AppCompatDelegate
import com.kakao.sdk.common.KakaoSdk
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber

Expand All @@ -13,6 +14,7 @@ class MyApp : Application() {

initTimber()
setDayMode()
initKakaoSdk()
}

private fun initTimber() {
Expand All @@ -23,4 +25,7 @@ class MyApp : Application() {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}

}
private fun initKakaoSdk() {
KakaoSdk.init(this, BuildConfig.NATIVE_APP_KEY)
}
}
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ buildscript {

tasks.register("clean", Delete::class) {
delete(rootProject.buildDir)
}
}
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ object Constants {
const val targetSdk = 34
const val versionCode = 1
const val versionName = "1.0"
}
}
6 changes: 5 additions & 1 deletion buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@ object FirebaseDependencies {
const val crashlytics = "com.google.firebase:firebase-crashlytics-ktx"
const val analytics = "com.google.firebase:firebase-analytics-ktx"
const val remoteConfig = "com.google.firebase:firebase-config-ktx"
}
}

object KakaoDependencies {
const val user = "com.kakao.sdk:v2-user:${Versions.kakaoVersion}"
}
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ object Versions {
const val balloonVersion = "1.4.5"
const val lottieVersion = "6.0.0"
const val circularProgressBar = "3.1.0"
const val kakaoVersion = "2.14.0"
const val kakaoVersion = "2.19.0"
const val circleIndicatorVersion = "2.1.6"
const val shimmerVersion = "0.5.0"
const val navigationVersion = "2.6.0"
Expand All @@ -44,4 +44,4 @@ object Versions {

val javaVersion = JavaVersion.VERSION_17
const val jvmVersion = "17"
}
}
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,
)
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Tue Dec 26 03:22:09 KST 2023
#Fri Dec 29 23:45:17 KST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
Expand Down
6 changes: 5 additions & 1 deletion 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
@@ -0,0 +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)

initKakaoLoginBtnClickListener()
observeInfo()
}

private fun initKakaoLoginBtnClickListener() {
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
@@ -0,0 +1,82 @@
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() {
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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,4 @@ class MockActivity() : BaseActivity<ActivityMockBinding>(R.layout.activity_mock)
super.onDestroy()
_adapter = null
}

}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions presentation/src/main/res/layout/activity_login.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/tv_sign_in_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:lineHeight="42dp"
android:text="@string/sign_in_tv_title"
android:textColor="@color/white"
app:layout_constraintBottom_toTopOf="@id/iv_sign_in"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

<ImageView
android:id="@+id/iv_sign_in"
android:layout_width="0dp"
android:layout_height="0dp"
android:minHeight="340dp"
android:scaleType="centerCrop"
android:src="@drawable/img_sign_in_main"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/btn_sign_in"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:src="@drawable/img_sign_in_kakao_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_sign_in" />

<TextView
android:id="@+id/tv_sign_in_terms"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:lineHeight="42dp"
android:text="@string/sign_in_tv_terms"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_sign_in" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
3 changes: 3 additions & 0 deletions presentation/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@

<string name="server_error">서버 통신에 실패했습니다.</string>

<string name="sign_in_tv_title">여행을 시작해보세요</string>
<string name="sign_in_tv_terms"><u>개인정보처리방침</u></string>

</resources>
3 changes: 3 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()

// KakaoSDK repository
maven(url = "https://devrepo.kakao.com/nexus/content/groups/public/")
}
}

Expand Down

0 comments on commit 0f281f9

Please sign in to comment.