diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index e152301..2b5e7b0 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -13,6 +13,7 @@
+
diff --git a/app/build.gradle b/app/build.gradle
index b38463a..243d740 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,6 +2,8 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
+apply plugin: 'kotlin-kapt'
+apply plugin: 'dagger.hilt.android.plugin'
android {
namespace 'com.nocapstone.buddyvet'
@@ -13,7 +15,7 @@ android {
targetSdk 33
versionCode 1
versionName "1.0"
-
+ manifestPlaceholders["NATIVE_APP_KEY"] = "d48bcd0a6e882bce9b756ab78c9acd6e"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -40,7 +42,10 @@ dependencies {
api project(path: ':home')
api project(path: ':onboarding')
api project(path: ':common-ui')
+ api project(path: ':common')
+ implementation "com.google.dagger:hilt-android:$rootProject.hiltVersion"
+ kapt "com.google.dagger:hilt-android-compiler:$rootProject.hiltVersion"
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 61963d6..c6bbd1d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.nocapstone.buddyvet">
+
+
+
+
+
+
+
+
+
+
+
@@ -26,6 +39,20 @@
android:name="android.app.lib_name"
android:value="" />
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/nocapstone/buddyvet/BuddyVetApplication.kt b/app/src/main/java/com/nocapstone/buddyvet/BuddyVetApplication.kt
index 1074dcb..675258d 100644
--- a/app/src/main/java/com/nocapstone/buddyvet/BuddyVetApplication.kt
+++ b/app/src/main/java/com/nocapstone/buddyvet/BuddyVetApplication.kt
@@ -3,7 +3,9 @@ package com.nocapstone.buddyvet
import android.app.Application
import com.kakao.sdk.common.KakaoSdk
import com.nocapstone.common.util.NATIVE_APP_KEY
+import dagger.hilt.android.HiltAndroidApp
+@HiltAndroidApp
class BuddyVetApplication : Application(){
override fun onCreate() {
diff --git a/app/src/main/java/com/nocapstone/buddyvet/SplashActivity.kt b/app/src/main/java/com/nocapstone/buddyvet/SplashActivity.kt
new file mode 100644
index 0000000..35a2ede
--- /dev/null
+++ b/app/src/main/java/com/nocapstone/buddyvet/SplashActivity.kt
@@ -0,0 +1,57 @@
+package com.nocapstone.buddyvet
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import androidx.activity.viewModels
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.nocapstone.buddyvet.databinding.ActivitySplashBinding
+import com.nocapstone.onboarding.LoginUtil
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
+
+
+class SplashActivity : AppCompatActivity() {
+
+ private lateinit var binding: ActivitySplashBinding
+ private val viewModel: SplashViewModel by viewModels()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_splash)
+ }
+
+
+ private fun tryAutoLogin() {
+ lifecycleScope.launch {
+ lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ // 하나라도 실패했을 경우
+ viewModel.failure.collectLatest {
+ if (it >= 1){} // Todo Login 실패 로직
+ }
+ }
+ launch {
+ viewModel.success.collectLatest {
+ if (it == 2){} // Todo Login 성공 로직
+ }
+ }
+ }
+ }
+
+ viewModel.with
+
+ }
+
+
+ //LoginUtil에 Login로직 시행
+ private fun loginWithKakao() {
+ LoginUtil.loginWithKaKao(this, { _, _ ->
+ viewModel.addSuccess()
+ }, { _, _ ->
+ viewModel.addFailure()
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nocapstone/buddyvet/SplashViewModel.kt b/app/src/main/java/com/nocapstone/buddyvet/SplashViewModel.kt
new file mode 100644
index 0000000..a5b182e
--- /dev/null
+++ b/app/src/main/java/com/nocapstone/buddyvet/SplashViewModel.kt
@@ -0,0 +1,31 @@
+package com.nocapstone.buddyvet
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+
+class SplashViewModel : ViewModel() {
+
+ private val _success = MutableStateFlow(0)
+ val success : StateFlow = _success
+
+ private val _failure = MutableStateFlow(0)
+ val failure: StateFlow = _failure
+
+ fun addSuccess() {
+ _success.value++
+ }
+
+ fun addFailure() {
+ _failure.value++
+ }
+
+ fun withRefreshToken(callback: (String?) -> Unit) {
+ viewModelScope.launch {
+ callback.invoke()
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_splash.xml b/app/src/main/res/layout/activity_splash.xml
new file mode 100644
index 0000000..398779a
--- /dev/null
+++ b/app/src/main/res/layout/activity_splash.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
index c35af24..c724467 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,9 +14,17 @@ buildscript {
fragment_version = '1.5.5'
activity_version = '1.6.1'
kakao_version = '2.12.1'
+ dataStorePreferences_version = '1.0.0'
+
+ retrofit2Version = '2.9.0'
+ okHttpVersion = '4.10.0'
+
+ hiltVersion = '2.44'
+
}
dependencies {
+ classpath "com.google.dagger:hilt-android-gradle-plugin:$hiltVersion"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
diff --git a/common-ui/build.gradle b/common-ui/build.gradle
index 4f15764..ffd6404 100644
--- a/common-ui/build.gradle
+++ b/common-ui/build.gradle
@@ -2,7 +2,8 @@ plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
-
+apply plugin: 'kotlin-kapt'
+apply plugin: 'dagger.hilt.android.plugin'
android {
@@ -37,10 +38,15 @@ android {
dependencies {
+ api project(path: ':foundation')
+
+
api "androidx.navigation:navigation-fragment-ktx:$rootProject.nav_version"
api "androidx.navigation:navigation-ui-ktx:$rootProject.nav_version"
implementation "androidx.activity:activity-ktx:$rootProject.activity_version"
+ implementation "com.google.dagger:hilt-android:$rootProject.hiltVersion"
+ kapt "com.google.dagger:hilt-android-compiler:$rootProject.hiltVersion"
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
diff --git a/common/build.gradle b/common/build.gradle
index 85ba5ca..6636918 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -2,6 +2,8 @@ plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
+apply plugin: 'kotlin-kapt'
+apply plugin: 'dagger.hilt.android.plugin'
android {
namespace 'com.nocapstone.common'
@@ -32,9 +34,17 @@ android {
dependencies {
- api "com.kakao.sdk:v2-all:$rootProject.kakao_version"
+ api project(path: ':foundation')
+
+
+ // Preferences DataStore
+ implementation("androidx.datastore:datastore-preferences:$rootProject.dataStorePreferences_version")
+ api "com.kakao.sdk:v2-all:$rootProject.kakao_version"
+
+ implementation "com.google.dagger:hilt-android:$rootProject.hiltVersion"
+ kapt "com.google.dagger:hilt-android-compiler:$rootProject.hiltVersion"
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
diff --git a/common/src/main/java/com/nocapstone/common/util/DataStoreUseCase.kt b/common/src/main/java/com/nocapstone/common/util/DataStoreUseCase.kt
new file mode 100644
index 0000000..4e8e91c
--- /dev/null
+++ b/common/src/main/java/com/nocapstone/common/util/DataStoreUseCase.kt
@@ -0,0 +1,14 @@
+package com.nocapstone.common.util
+
+import androidx.datastore.core.DataStore
+import kotlinx.coroutines.flow.Flow
+import java.util.prefs.Preferences
+
+@Singletone
+class DataStoreUseCase(private val dataStore: DataStore) {
+
+ val refreshToken: Flow =
+ dataStore.data.map { preferences -> preferences[refreshTokenKey] }
+
+
+}
\ No newline at end of file
diff --git a/foundation/.gitignore b/foundation/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/foundation/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/foundation/build.gradle b/foundation/build.gradle
new file mode 100644
index 0000000..00e2004
--- /dev/null
+++ b/foundation/build.gradle
@@ -0,0 +1,46 @@
+plugins {
+ id 'com.android.library'
+ id 'org.jetbrains.kotlin.android'
+}
+apply plugin: 'kotlin-kapt'
+apply plugin: 'dagger.hilt.android.plugin'
+
+
+android {
+ namespace 'com.example.foundation'
+ compileSdk 33
+
+ defaultConfig {
+ minSdk 23
+ targetSdk 33
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+}
+
+dependencies {
+ // Retrofit2
+ api "com.squareup.okhttp3:okhttp:$rootProject.okHttpVersion"
+ api "com.squareup.okhttp3:logging-interceptor:$rootProject.okHttpVersion"
+ api "com.squareup.retrofit2:retrofit:$rootProject.retrofit2Version"
+ api "com.squareup.retrofit2:converter-gson:$rootProject.retrofit2Version"
+
+ // Hilt
+ implementation "com.google.dagger:hilt-android:$rootProject.hiltVersion"
+ kapt "com.google.dagger:hilt-android-compiler:$rootProject.hiltVersion"
+}
\ No newline at end of file
diff --git a/foundation/consumer-rules.pro b/foundation/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/foundation/proguard-rules.pro b/foundation/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/foundation/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/foundation/src/androidTest/java/com/example/foundation/ExampleInstrumentedTest.kt b/foundation/src/androidTest/java/com/example/foundation/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..8379c8f
--- /dev/null
+++ b/foundation/src/androidTest/java/com/example/foundation/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.foundation
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.foundation.test", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/foundation/src/main/AndroidManifest.xml b/foundation/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a5918e6
--- /dev/null
+++ b/foundation/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/foundation/src/test/java/com/example/foundation/ExampleUnitTest.kt b/foundation/src/test/java/com/example/foundation/ExampleUnitTest.kt
new file mode 100644
index 0000000..756bb8c
--- /dev/null
+++ b/foundation/src/test/java/com/example/foundation/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.foundation
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/onboarding/build.gradle b/onboarding/build.gradle
index 153654f..3874499 100644
--- a/onboarding/build.gradle
+++ b/onboarding/build.gradle
@@ -45,6 +45,7 @@ dependencies {
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.8.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
diff --git a/onboarding/src/main/AndroidManifest.xml b/onboarding/src/main/AndroidManifest.xml
index a5918e6..b2d3ea1 100644
--- a/onboarding/src/main/AndroidManifest.xml
+++ b/onboarding/src/main/AndroidManifest.xml
@@ -1,4 +1,2 @@
-
-
-
\ No newline at end of file
+
diff --git a/onboarding/src/main/java/com/nocapstone/onboarding/LoginFragment.kt b/onboarding/src/main/java/com/nocapstone/onboarding/LoginFragment.kt
index 4e84c33..74f21dd 100644
--- a/onboarding/src/main/java/com/nocapstone/onboarding/LoginFragment.kt
+++ b/onboarding/src/main/java/com/nocapstone/onboarding/LoginFragment.kt
@@ -1,5 +1,6 @@
package com.nocapstone.onboarding
+import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
@@ -7,6 +8,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.navigation.fragment.findNavController
+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 com.nocapstone.onboarding.databinding.FragmentLoginBinding
diff --git a/onboarding/src/main/java/com/nocapstone/onboarding/LoginUtil.kt b/onboarding/src/main/java/com/nocapstone/onboarding/LoginUtil.kt
new file mode 100644
index 0000000..79aaf93
--- /dev/null
+++ b/onboarding/src/main/java/com/nocapstone/onboarding/LoginUtil.kt
@@ -0,0 +1,50 @@
+package com.nocapstone.onboarding
+
+import android.content.Context
+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
+
+class LoginUtil {
+
+ companion object {
+
+ fun loginWithKaKao(
+ context: Context,
+ onLoginSuccess: (OAuthToken?, Throwable?) -> Unit,
+ onLoginFailure: (OAuthToken?, Throwable?) -> Unit
+ ) {
+ val callback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
+ // 에러가 비어있지 않다면 즉 에러가 존재한다면
+ if (error != null) onLoginFailure(token, error)
+ // 토큰이 비어있지 않다면 즉 토근이 존재한다면
+ else if (token != null) onLoginSuccess(token, error)
+ }
+
+ // 카카오톡이 설치되어 있다면 카카오톡으로 로그인, 아니면 카카오계정으로 로그인
+ if (UserApiClient.instance.isKakaoTalkLoginAvailable(context)) {
+ UserApiClient.instance.loginWithKakaoTalk(context) { token, error ->
+ // 카카오톡에 연결된 카카오계정이 없는 경우, 카카오계정으로 로그인 시도한다.
+ if (error != null) {
+ onLoginFailure(token, error)
+
+ // 단, 사용자가 의독적로 로그인을 취소한 경우는 제외
+ if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
+ onLoginFailure(token, error)
+ return@loginWithKakaoTalk
+ }
+ //카카오 계정으로 로그인
+ UserApiClient.instance.loginWithKakaoAccount(context, callback = callback)
+ } else if (token != null) onLoginSuccess(token, error)
+ }
+ }
+ // 카카오톡이 설치되어 있지 않다면 카카오 계정으로 로그인
+ else {
+ UserApiClient.instance.loginWithKakaoAccount(context, callback = callback)
+ }
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/onboarding/src/main/res/layout/fragment_on_boarding1.xml b/onboarding/src/main/res/layout/fragment_on_boarding1.xml
index fbbac86..2dba660 100644
--- a/onboarding/src/main/res/layout/fragment_on_boarding1.xml
+++ b/onboarding/src/main/res/layout/fragment_on_boarding1.xml
@@ -7,6 +7,7 @@
android:layout_height="match_parent"
tools:context=".OnBoarding1Fragment">
+