From 65d973fd8bee3d892586094365cc03c506e2244d Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 01:56:55 +0900
Subject: [PATCH 01/13] =?UTF-8?q?[TNT-103]=20chore:=20=EC=B9=B4=EC=B9=B4?=
=?UTF-8?q?=EC=98=A4=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=9D=BC=EC=9D=B4?=
=?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=A2=85=EC=86=8D=EC=84=B1=20?=
=?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
gradle/libs.versions.toml | 5 +++++
settings.gradle.kts | 1 +
2 files changed, 6 insertions(+)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 6ebda7d1..fb3a582a 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -49,6 +49,9 @@ material = "1.12.0"
## Coil
coil = "2.7.0"
+## Auth
+kakao = "2.20.6"
+
[libraries]
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" }
android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
@@ -106,6 +109,8 @@ ktlint-plugin = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref =
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
+kakao-user = { module = "com.kakao.sdk:v2-user", version.ref = "kakao" }
+
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 81bbafcd..2bdb221c 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -18,6 +18,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
+ maven { url = java.net.URI("https://devrepo.kakao.com/nexus/content/groups/public/") }
}
}
From 01098668da12564563eba19b880b113caebbb57f Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 02:01:44 +0900
Subject: [PATCH 02/13] =?UTF-8?q?[TNT-103]=20feat:=20=EC=B9=B4=EC=B9=B4?=
=?UTF-8?q?=EC=98=A4=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EC=B4=88=20?=
=?UTF-8?q?=EC=84=B8=ED=8C=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/android-ci.yaml | 1 +
app/build.gradle.kts | 10 ++++++++++
app/src/main/AndroidManifest.xml | 18 +++++++++++++++++-
app/src/main/java/co/kr/tnt/TnTApplication.kt | 9 ++++++++-
4 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/android-ci.yaml b/.github/workflows/android-ci.yaml
index cb8e2c6f..915bd026 100644
--- a/.github/workflows/android-ci.yaml
+++ b/.github/workflows/android-ci.yaml
@@ -19,6 +19,7 @@ jobs:
run: |
echo RELEASE_BASE_API_URL=\"${{ secrets.RELEASE_BASE_API_URL }}\" >> ./local.properties
echo DEBUG_BASE_API_URL=\"${{ secrets.DEBUG_BASE_API_URL }}\" >> ./local.properties
+ echo KAKAO_NATIVE_APP_KEY=\"${{ secrets.KAKAO_NATIVE_APP_KEY }}\" >> ./local.properties
- name: Grant execute permission for gradlew
run: chmod +x gradlew
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index b65e7441..0a689233 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,3 +1,9 @@
+import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
+
+private val kakaoNativeAppKey: String =
+ gradleLocalProperties(rootDir, providers)
+ .getProperty("KAKAO_NATIVE_APP_KEY")
+
plugins {
id("tnt.android.application")
id("tnt.android.compose")
@@ -15,6 +21,9 @@ android {
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+
+ buildConfigField("String", "KAKAO_NATIVE_APP_KEY", kakaoNativeAppKey)
+ manifestPlaceholders["KAKAO_NATIVE_APP_KEY"] = kakaoNativeAppKey
}
buildTypes {
@@ -51,4 +60,5 @@ dependencies {
implementation(projects.data.session)
implementation(libs.androidx.activity.compose)
+ implementation(libs.kakao.user)
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 677952eb..e77ab5a7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,6 +14,22 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.TnT"
- tools:targetApi="31" />
+ tools:targetApi="31" >
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/co/kr/tnt/TnTApplication.kt b/app/src/main/java/co/kr/tnt/TnTApplication.kt
index 31ba9953..1b7232f0 100644
--- a/app/src/main/java/co/kr/tnt/TnTApplication.kt
+++ b/app/src/main/java/co/kr/tnt/TnTApplication.kt
@@ -1,7 +1,14 @@
package co.kr.tnt
import android.app.Application
+import com.kakao.sdk.common.KakaoSdk
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
-class TnTApplication : Application()
+class TnTApplication : Application() {
+ override fun onCreate() {
+ super.onCreate()
+
+ KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
+ }
+}
From 5d227de849e36e5b3a7bc2760c5db4659484e69a Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 03:12:40 +0900
Subject: [PATCH 03/13] =?UTF-8?q?[TNT-103]=20chore:=20core:login=20?=
=?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=B5=9C=EC=B4=88=20=EC=83=9D=EC=84=B1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/build.gradle.kts | 6 ++----
app/src/main/AndroidManifest.xml | 14 --------------
core/login/.gitignore | 1 +
core/login/build.gradle.kts | 19 +++++++++++++++++++
core/login/src/main/AndroidManifest.xml | 20 ++++++++++++++++++++
settings.gradle.kts | 1 +
6 files changed, 43 insertions(+), 18 deletions(-)
create mode 100644 core/login/.gitignore
create mode 100644 core/login/build.gradle.kts
create mode 100644 core/login/src/main/AndroidManifest.xml
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 0a689233..839b7180 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,8 +1,7 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
private val kakaoNativeAppKey: String =
- gradleLocalProperties(rootDir, providers)
- .getProperty("KAKAO_NATIVE_APP_KEY")
+ gradleLocalProperties(rootDir, providers).getProperty("KAKAO_NATIVE_APP_KEY")
plugins {
id("tnt.android.application")
@@ -22,8 +21,7 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
- buildConfigField("String", "KAKAO_NATIVE_APP_KEY", kakaoNativeAppKey)
- manifestPlaceholders["KAKAO_NATIVE_APP_KEY"] = kakaoNativeAppKey
+ buildConfigField("String", "KAKAO_NATIVE_APP_KEY", "\"${kakaoNativeAppKey}\"")
}
buildTypes {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e77ab5a7..318fa9a2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,20 +16,6 @@
android:theme="@style/Theme.TnT"
tools:targetApi="31" >
-
-
-
-
-
-
-
-
-
-
diff --git a/core/login/.gitignore b/core/login/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/core/login/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/core/login/build.gradle.kts b/core/login/build.gradle.kts
new file mode 100644
index 00000000..65c39260
--- /dev/null
+++ b/core/login/build.gradle.kts
@@ -0,0 +1,19 @@
+import co.kr.tnt.setNamespace
+import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
+
+plugins {
+ id("tnt.android.library")
+}
+
+android {
+ setNamespace("core.login")
+
+ defaultConfig {
+ manifestPlaceholders["KAKAO_NATIVE_APP_KEY"] =
+ gradleLocalProperties(rootDir, providers).getProperty("KAKAO_NATIVE_APP_KEY")
+ }
+}
+
+dependencies {
+ implementation(libs.kakao.user)
+}
diff --git a/core/login/src/main/AndroidManifest.xml b/core/login/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..987b51ca
--- /dev/null
+++ b/core/login/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 2bdb221c..ddcff407 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -37,6 +37,7 @@ include(
":core:designsystem",
":core:navigation",
":core:ui",
+ ":core:login",
)
include(
From bd6c4dff27cd3d441aeffbac1c2040e4c3305ba8 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 03:51:12 +0900
Subject: [PATCH 04/13] =?UTF-8?q?[TNT-103]=20feat:=20=EC=B9=B4=EC=B9=B4?=
=?UTF-8?q?=EC=98=A4=20=EB=A1=9C=EA=B7=B8=EC=9D=B8,=20=EB=A1=9C=EA=B7=B8?=
=?UTF-8?q?=EC=95=84=EC=9B=83,=20=EC=97=B0=EA=B2=B0=20=ED=95=B4=EC=A0=9C?=
=?UTF-8?q?=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/co/kr/tnt/login/LoginAccessToken.kt | 5 ++
.../java/co/kr/tnt/login/LoginException.kt | 9 +++
.../src/main/java/co/kr/tnt/login/LoginSdk.kt | 9 +++
.../co/kr/tnt/login/kakao/KakaoAccessToken.kt | 6 ++
.../co/kr/tnt/login/kakao/KakaoLoginSdk.kt | 78 +++++++++++++++++++
5 files changed, 107 insertions(+)
create mode 100644 core/login/src/main/java/co/kr/tnt/login/LoginAccessToken.kt
create mode 100644 core/login/src/main/java/co/kr/tnt/login/LoginException.kt
create mode 100644 core/login/src/main/java/co/kr/tnt/login/LoginSdk.kt
create mode 100644 core/login/src/main/java/co/kr/tnt/login/kakao/KakaoAccessToken.kt
create mode 100644 core/login/src/main/java/co/kr/tnt/login/kakao/KakaoLoginSdk.kt
diff --git a/core/login/src/main/java/co/kr/tnt/login/LoginAccessToken.kt b/core/login/src/main/java/co/kr/tnt/login/LoginAccessToken.kt
new file mode 100644
index 00000000..fb31782a
--- /dev/null
+++ b/core/login/src/main/java/co/kr/tnt/login/LoginAccessToken.kt
@@ -0,0 +1,5 @@
+package co.kr.tnt.login
+
+interface LoginAccessToken {
+ val value: String
+}
diff --git a/core/login/src/main/java/co/kr/tnt/login/LoginException.kt b/core/login/src/main/java/co/kr/tnt/login/LoginException.kt
new file mode 100644
index 00000000..f7c7c7c4
--- /dev/null
+++ b/core/login/src/main/java/co/kr/tnt/login/LoginException.kt
@@ -0,0 +1,9 @@
+package co.kr.tnt.login
+
+sealed class LoginException(override val message: String?) : Exception(message) {
+ /** 유저가 뒤로가기 동작 등으로 로그인 자체를 취소한 경우 */
+ data class CancelException(override val message: String?) : LoginException(message)
+
+ /** 유저가 실제 로그인을 시도하였으나 SDK의 문제로 로그인에 실패한 경우 */
+ data class AuthException(override val message: String?) : LoginException(message)
+}
diff --git a/core/login/src/main/java/co/kr/tnt/login/LoginSdk.kt b/core/login/src/main/java/co/kr/tnt/login/LoginSdk.kt
new file mode 100644
index 00000000..9382c3e1
--- /dev/null
+++ b/core/login/src/main/java/co/kr/tnt/login/LoginSdk.kt
@@ -0,0 +1,9 @@
+package co.kr.tnt.login
+
+import android.content.Context
+
+interface LoginSdk {
+ suspend fun login(context: Context): Result
+ suspend fun logout(): Result
+ suspend fun unlink(): Result
+}
diff --git a/core/login/src/main/java/co/kr/tnt/login/kakao/KakaoAccessToken.kt b/core/login/src/main/java/co/kr/tnt/login/kakao/KakaoAccessToken.kt
new file mode 100644
index 00000000..287afbfb
--- /dev/null
+++ b/core/login/src/main/java/co/kr/tnt/login/kakao/KakaoAccessToken.kt
@@ -0,0 +1,6 @@
+package co.kr.tnt.login.kakao
+
+import co.kr.tnt.login.LoginAccessToken
+
+@JvmInline
+value class KakaoAccessToken(override val value: String) : LoginAccessToken
diff --git a/core/login/src/main/java/co/kr/tnt/login/kakao/KakaoLoginSdk.kt b/core/login/src/main/java/co/kr/tnt/login/kakao/KakaoLoginSdk.kt
new file mode 100644
index 00000000..d6840f36
--- /dev/null
+++ b/core/login/src/main/java/co/kr/tnt/login/kakao/KakaoLoginSdk.kt
@@ -0,0 +1,78 @@
+package co.kr.tnt.login.kakao
+
+import android.content.Context
+import co.kr.tnt.login.LoginAccessToken
+import co.kr.tnt.login.LoginException.AuthException
+import co.kr.tnt.login.LoginException.CancelException
+import co.kr.tnt.login.LoginSdk
+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.suspendCancellableCoroutine
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
+
+@Singleton
+class KakaoLoginSdk @Inject constructor() : LoginSdk {
+ override suspend fun login(context: Context): Result = runCatching {
+ suspendCancellableCoroutine { continuation ->
+ val callback: (OAuthToken?, Throwable?) -> Unit = callback@{ token, throwable ->
+ if (!continuation.isActive) {
+ return@callback
+ }
+
+ when {
+ throwable != null -> {
+ if (throwable is ClientError && throwable.reason == ClientErrorCause.Cancelled) {
+ continuation.resumeWithException(CancelException(throwable.message))
+ return@callback
+ }
+
+ continuation.resumeWithException(AuthException(throwable.message))
+ }
+
+ token != null -> continuation.resume(KakaoAccessToken(token.accessToken))
+ }
+ }
+
+ val userApiClient = UserApiClient.instance
+
+ if (userApiClient.isKakaoTalkLoginAvailable(context)) {
+ // 카카오톡 로그인
+ userApiClient.loginWithKakaoTalk(context, callback = callback)
+ } else {
+ // 카카오톡 웹 로그인
+ userApiClient.loginWithKakaoAccount(context, callback = callback)
+ }
+ }
+ }
+
+ override suspend fun logout(): Result = runCatching {
+ suspendCancellableCoroutine { continuation ->
+ val userApiClient = UserApiClient.instance
+
+ userApiClient.logout { throwable ->
+ when {
+ throwable != null -> continuation.resumeWithException(AuthException(throwable.message))
+ else -> continuation.resume(Unit)
+ }
+ }
+ }
+ }
+
+ override suspend fun unlink(): Result = runCatching {
+ suspendCancellableCoroutine { continuation ->
+ val userApiClient = UserApiClient.instance
+
+ userApiClient.unlink { throwable ->
+ when {
+ throwable != null -> continuation.resumeWithException(AuthException(throwable.message))
+ else -> continuation.resume(Unit)
+ }
+ }
+ }
+ }
+}
From ac9c40355dccaf97a0216f940bc702921f947717 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 03:52:58 +0900
Subject: [PATCH 05/13] =?UTF-8?q?[TNT-103]=20feat:=20=EB=A1=9C=EA=B7=B8?=
=?UTF-8?q?=EC=9D=B8=20=ED=99=94=EB=A9=B4=20=EB=82=B4=20=EC=B9=B4=EC=B9=B4?=
=?UTF-8?q?=EC=98=A4=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=97=B0=EB=8F=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
feature/login/build.gradle.kts | 4 +++
.../java/co/kr/tnt/login/LoginContract.kt | 4 ++-
.../main/java/co/kr/tnt/login/LoginScreen.kt | 26 ++++++++++++++++++-
.../java/co/kr/tnt/login/LoginViewModel.kt | 12 ++++++++-
4 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/feature/login/build.gradle.kts b/feature/login/build.gradle.kts
index 7b7a1577..fc7c8372 100644
--- a/feature/login/build.gradle.kts
+++ b/feature/login/build.gradle.kts
@@ -7,3 +7,7 @@ plugins {
android {
setNamespace("feature.login")
}
+
+dependencies {
+ implementation(projects.core.login)
+}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
index f1ab38e4..f7fb46ef 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
@@ -16,7 +16,8 @@ internal class LoginContract {
}
sealed interface LoginUiEvent : UiEvent {
- data object OnClickKakaoLogin : LoginUiEvent
+ data class OnLoginSuccess(val accessToken: LoginAccessToken) : LoginUiEvent
+ data class OnLoginFail(val throwable: Throwable) : LoginUiEvent
data object OnCheckAllTermAgree : LoginUiEvent
data class OnCheckTerm(val termState: TermState) : LoginUiEvent
data class OnClickTermLink(val link: String) : LoginUiEvent
@@ -25,6 +26,7 @@ internal class LoginContract {
sealed interface LoginSideEffect : UiSideEffect {
data object ShowTermBottomSheet : LoginSideEffect
+ data class ShowToast(val message: String) : LoginSideEffect
data object NavigateToHome : LoginSideEffect
data object NavigateToSignup : LoginSideEffect
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
index 1c21f0d5..656e4298 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
@@ -1,5 +1,6 @@
package co.kr.tnt.login
+import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@@ -26,11 +27,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -45,7 +49,9 @@ import co.kr.tnt.feature.login.R
import co.kr.tnt.login.LoginContract.LoginSideEffect
import co.kr.tnt.login.LoginContract.LoginUiEvent
import co.kr.tnt.login.LoginContract.LoginUiState
+import co.kr.tnt.login.kakao.KakaoLoginSdk
import co.kr.tnt.login.model.TermState
+import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -54,13 +60,26 @@ internal fun LoginRoute(
navigateToHome: () -> Unit,
navigateToSignup: () -> Unit,
) {
+ val context = LocalContext.current
+ val coroutineScope = rememberCoroutineScope()
+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
var showBottomSheet by rememberSaveable { mutableStateOf(false) }
+ val kakaoLoginSdk = remember { KakaoLoginSdk() }
+
LoginScreen(
onClickKakaoLogin = {
- viewModel.setEvent(LoginUiEvent.OnClickKakaoLogin)
+ coroutineScope.launch {
+ kakaoLoginSdk.login(context)
+ .onSuccess { accessToken ->
+ viewModel.setEvent(LoginUiEvent.OnLoginSuccess(accessToken))
+ }
+ .onFailure { throwable ->
+ viewModel.setEvent(LoginUiEvent.OnLoginFail(throwable))
+ }
+ }
},
)
@@ -87,6 +106,11 @@ internal fun LoginRoute(
LoginSideEffect.ShowTermBottomSheet -> {
showBottomSheet = true
}
+
+ is LoginSideEffect.ShowToast -> {
+ Toast.makeText(context, effect.message, Toast.LENGTH_SHORT).show()
+ }
+
LoginSideEffect.NavigateToHome -> navigateToHome()
LoginSideEffect.NavigateToSignup -> navigateToSignup()
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
index c9ca727e..9206a8e0 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
@@ -14,7 +14,17 @@ internal class LoginViewModel @Inject constructor() : BaseViewModel sendEffect(LoginSideEffect.ShowTermBottomSheet)
+ is LoginUiEvent.OnLoginSuccess -> {
+ sendEffect(LoginSideEffect.ShowTermBottomSheet)
+ }
+
+ is LoginUiEvent.OnLoginFail -> {
+ if (event.throwable !is LoginException.CancelException) {
+ // TODO resource provider
+ sendEffect(LoginSideEffect.ShowToast("로그인에 실패하였습니다. 다시 시도해주세요."))
+ }
+ }
+
LoginUiEvent.OnCheckAllTermAgree -> checkAllTerms()
is LoginUiEvent.OnCheckTerm -> checkTerm(event.termState)
is LoginUiEvent.OnClickTermLink -> TODO()
From 6993175ae58cea88cb1f2e7435e9a88c43fc0888 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 19:13:08 +0900
Subject: [PATCH 06/13] =?UTF-8?q?[TNT-103]=20remove:=20=EC=98=88=EC=A0=9C?=
=?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../co/kr/data/network/di/NetworkModule.kt | 8 ++++----
.../service/{TnTService.kt => ApiService.kt} | 2 +-
.../kr/data/network/source/TnTDataSource.kt | 11 -----------
.../kr/data/network/tnt/request/TnTRequest.kt | 15 ---------------
.../data/network/tnt/response/TnTResponse.kt | 15 ---------------
.../kr/data/repository/TnTRepositoryImpl.kt | 12 ------------
.../kr/data/repository/di/RepositoryModule.kt | 10 +---------
.../main/java/co/kr/tnt/domain/model/TnT.kt | 5 -----
.../kr/tnt/domain/repository/TnTRepository.kt | 3 ---
.../co/kr/tnt/domain/usecase/TnTUseCase.kt | 13 -------------
.../main/java/co/kr/tnt/main/MainViewModel.kt | 19 -------------------
11 files changed, 6 insertions(+), 107 deletions(-)
rename data/network/src/main/java/co/kr/data/network/service/{TnTService.kt => ApiService.kt} (63%)
delete mode 100644 data/network/src/main/java/co/kr/data/network/source/TnTDataSource.kt
delete mode 100644 data/network/src/main/java/co/kr/data/network/tnt/request/TnTRequest.kt
delete mode 100644 data/network/src/main/java/co/kr/data/network/tnt/response/TnTResponse.kt
delete mode 100644 data/repository/src/main/java/co/kr/data/repository/TnTRepositoryImpl.kt
delete mode 100644 domain/src/main/java/co/kr/tnt/domain/model/TnT.kt
delete mode 100644 domain/src/main/java/co/kr/tnt/domain/repository/TnTRepository.kt
delete mode 100644 domain/src/main/java/co/kr/tnt/domain/usecase/TnTUseCase.kt
delete mode 100644 feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt
diff --git a/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt b/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt
index c66bd7b2..3ee8b348 100644
--- a/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt
+++ b/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt
@@ -2,7 +2,7 @@ package co.kr.data.network.di
import co.kr.data.network.authenticator.Authenticator
import co.kr.data.network.interceptor.SessionInterceptor
-import co.kr.data.network.service.TnTService
+import co.kr.data.network.service.ApiService
import co.kr.tnt.data.network.BuildConfig
import dagger.Module
import dagger.Provides
@@ -25,15 +25,15 @@ internal object NetworkModule {
@Provides
@Singleton
- fun provideTnTService(
+ fun provideApiService(
okHttpClient: OkHttpClient,
converterFactory: Converter.Factory,
- ): TnTService {
+ ): ApiService {
return Retrofit.Builder()
.baseUrl(BuildConfig.BASE_API_URL)
.addConverterFactory(converterFactory)
.client(okHttpClient).build()
- .create(TnTService::class.java)
+ .create(ApiService::class.java)
}
@Provides
diff --git a/data/network/src/main/java/co/kr/data/network/service/TnTService.kt b/data/network/src/main/java/co/kr/data/network/service/ApiService.kt
similarity index 63%
rename from data/network/src/main/java/co/kr/data/network/service/TnTService.kt
rename to data/network/src/main/java/co/kr/data/network/service/ApiService.kt
index e3cf54df..c7f0ef58 100644
--- a/data/network/src/main/java/co/kr/data/network/service/TnTService.kt
+++ b/data/network/src/main/java/co/kr/data/network/service/ApiService.kt
@@ -1,3 +1,3 @@
package co.kr.data.network.service
-interface TnTService
+interface ApiService
diff --git a/data/network/src/main/java/co/kr/data/network/source/TnTDataSource.kt b/data/network/src/main/java/co/kr/data/network/source/TnTDataSource.kt
deleted file mode 100644
index 80547d26..00000000
--- a/data/network/src/main/java/co/kr/data/network/source/TnTDataSource.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package co.kr.data.network.source
-
-import co.kr.data.network.service.TnTService
-import javax.inject.Inject
-import javax.inject.Singleton
-
-@Suppress("UnusedPrivateProperty")
-@Singleton
-class TnTDataSource @Inject constructor(
- private val tntService: TnTService,
-)
diff --git a/data/network/src/main/java/co/kr/data/network/tnt/request/TnTRequest.kt b/data/network/src/main/java/co/kr/data/network/tnt/request/TnTRequest.kt
deleted file mode 100644
index df555172..00000000
--- a/data/network/src/main/java/co/kr/data/network/tnt/request/TnTRequest.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package co.kr.data.network.tnt.request
-
-import co.kr.tnt.domain.model.TnT
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class TnTRequest(
- @SerialName("id")
- val id: String,
-)
-
-fun TnT.toRemote(): TnTRequest = TnTRequest(
- id = this.id,
-)
diff --git a/data/network/src/main/java/co/kr/data/network/tnt/response/TnTResponse.kt b/data/network/src/main/java/co/kr/data/network/tnt/response/TnTResponse.kt
deleted file mode 100644
index 67f14843..00000000
--- a/data/network/src/main/java/co/kr/data/network/tnt/response/TnTResponse.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package co.kr.data.network.tnt.response
-
-import co.kr.tnt.domain.model.TnT
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class TnTResponse(
- @SerialName("id")
- val id: String,
-)
-
-fun TnTResponse.toDomain(): TnT = TnT(
- id = id,
-)
diff --git a/data/repository/src/main/java/co/kr/data/repository/TnTRepositoryImpl.kt b/data/repository/src/main/java/co/kr/data/repository/TnTRepositoryImpl.kt
deleted file mode 100644
index 0ec47799..00000000
--- a/data/repository/src/main/java/co/kr/data/repository/TnTRepositoryImpl.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package co.kr.data.repository
-
-import co.kr.data.network.source.TnTDataSource
-import co.kr.data.storage.source.SessionDataSource
-import co.kr.tnt.domain.repository.TnTRepository
-import javax.inject.Inject
-
-@Suppress("UnusedPrivateProperty")
-internal class TnTRepositoryImpl @Inject constructor(
- private val tnTDataSource: TnTDataSource,
- private val sessionDataSource: SessionDataSource,
-) : TnTRepository
diff --git a/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt b/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt
index 3ad2e02b..daa56540 100644
--- a/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt
+++ b/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt
@@ -1,17 +1,9 @@
package co.kr.data.repository.di
-import co.kr.data.repository.TnTRepositoryImpl
-import co.kr.tnt.domain.repository.TnTRepository
-import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@InstallIn(SingletonComponent::class)
@Module
-internal abstract class RepositoryModule {
- @Binds
- abstract fun bindsTnTRepository(
- repository: TnTRepositoryImpl,
- ): TnTRepository
-}
+internal abstract class RepositoryModule
diff --git a/domain/src/main/java/co/kr/tnt/domain/model/TnT.kt b/domain/src/main/java/co/kr/tnt/domain/model/TnT.kt
deleted file mode 100644
index db444557..00000000
--- a/domain/src/main/java/co/kr/tnt/domain/model/TnT.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package co.kr.tnt.domain.model
-
-data class TnT(
- val id: String,
-)
diff --git a/domain/src/main/java/co/kr/tnt/domain/repository/TnTRepository.kt b/domain/src/main/java/co/kr/tnt/domain/repository/TnTRepository.kt
deleted file mode 100644
index 3af82806..00000000
--- a/domain/src/main/java/co/kr/tnt/domain/repository/TnTRepository.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package co.kr.tnt.domain.repository
-
-interface TnTRepository
diff --git a/domain/src/main/java/co/kr/tnt/domain/usecase/TnTUseCase.kt b/domain/src/main/java/co/kr/tnt/domain/usecase/TnTUseCase.kt
deleted file mode 100644
index 83c84ab2..00000000
--- a/domain/src/main/java/co/kr/tnt/domain/usecase/TnTUseCase.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package co.kr.tnt.domain.usecase
-
-import co.kr.tnt.domain.repository.TnTRepository
-import javax.inject.Inject
-
-@Suppress("UnusedPrivateProperty")
-class TnTUseCase @Inject constructor(
- private val tntRepository: TnTRepository,
-) {
- suspend operator fun invoke() {
- print(1)
- }
-}
diff --git a/feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt b/feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt
deleted file mode 100644
index 001eeecc..00000000
--- a/feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package co.kr.tnt.main
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import co.kr.tnt.domain.usecase.TnTUseCase
-import dagger.hilt.android.lifecycle.HiltViewModel
-import kotlinx.coroutines.launch
-import javax.inject.Inject
-
-@HiltViewModel
-class MainViewModel @Inject constructor(
- private val tntUseCase: TnTUseCase,
-) : ViewModel() {
- init {
- viewModelScope.launch {
- tntUseCase()
- }
- }
-}
From 769350b8467a40282032d1306e401284fb1e92b0 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 21:06:53 +0900
Subject: [PATCH 07/13] =?UTF-8?q?[TNT-103]=20feat:=20=EB=84=A4=ED=8A=B8?=
=?UTF-8?q?=EC=9B=8C=ED=81=AC=20=ED=86=B5=EC=8B=A0=20=EC=8B=9C=20=EB=8D=B0?=
=?UTF-8?q?=EC=9D=B4=ED=84=B0=20=ED=81=B4=EB=9E=98=EC=8A=A4=EC=9D=98=20?=
=?UTF-8?q?=EA=B8=B0=EB=B3=B8=EA=B0=92=EB=8F=84=20=EC=A7=81=EB=A0=AC?=
=?UTF-8?q?=ED=99=94=20=EB=8C=80=EC=83=81=EC=9C=BC=EB=A1=9C=20=ED=8F=AC?=
=?UTF-8?q?=ED=95=A8=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=84=A4=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../network/src/main/java/co/kr/data/network/di/NetworkModule.kt | 1 +
1 file changed, 1 insertion(+)
diff --git a/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt b/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt
index 3ee8b348..a62377d1 100644
--- a/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt
+++ b/data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt
@@ -61,6 +61,7 @@ internal object NetworkModule {
fun provideJson(): Json = Json {
ignoreUnknownKeys = true
coerceInputValues = true
+ encodeDefaults = true
}
@Provides
From 26a97a65cb66e4037736883a6d6843fef2ef9285 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 21:07:58 +0900
Subject: [PATCH 08/13] =?UTF-8?q?[TNT-103]=20feat:=20=EB=A1=9C=EA=B7=B8?=
=?UTF-8?q?=EC=9D=B8=20API=20=ED=98=B8=EC=B6=9C=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../co/kr/data/network/model/LoginRequest.kt | 12 +++++++
.../co/kr/data/network/model/LoginResponse.kt | 25 +++++++++++++
.../co/kr/data/network/service/ApiService.kt | 12 ++++++-
.../network/source/LoginRemoteDataSource.kt | 17 +++++++++
.../kr/data/repository/LoginRepositoryImpl.kt | 35 +++++++++++++++++++
.../kr/data/repository/di/RepositoryModule.kt | 10 +++++-
.../co/kr/data/session/SessionProviderImpl.kt | 8 ++---
...ataSource.kt => SessionLocalDataSource.kt} | 2 +-
.../java/co/kr/tnt/domain/model/AuthType.kt | 5 +++
.../co/kr/tnt/domain/model/LoginResult.kt | 8 +++++
.../tnt/domain/repository/LoginRepository.kt | 11 ++++++
11 files changed, 138 insertions(+), 7 deletions(-)
create mode 100644 data/network/src/main/java/co/kr/data/network/model/LoginRequest.kt
create mode 100644 data/network/src/main/java/co/kr/data/network/model/LoginResponse.kt
create mode 100644 data/network/src/main/java/co/kr/data/network/source/LoginRemoteDataSource.kt
create mode 100644 data/repository/src/main/java/co/kr/data/repository/LoginRepositoryImpl.kt
rename data/storage/src/main/java/co/kr/data/storage/source/{SessionDataSource.kt => SessionLocalDataSource.kt} (94%)
create mode 100644 domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt
create mode 100644 domain/src/main/java/co/kr/tnt/domain/model/LoginResult.kt
create mode 100644 domain/src/main/java/co/kr/tnt/domain/repository/LoginRepository.kt
diff --git a/data/network/src/main/java/co/kr/data/network/model/LoginRequest.kt b/data/network/src/main/java/co/kr/data/network/model/LoginRequest.kt
new file mode 100644
index 00000000..49c105a8
--- /dev/null
+++ b/data/network/src/main/java/co/kr/data/network/model/LoginRequest.kt
@@ -0,0 +1,12 @@
+package co.kr.data.network.model
+
+import co.kr.tnt.domain.model.AuthType
+import kotlinx.serialization.Serializable
+
+// TODO fcm token
+@Serializable
+data class LoginRequest(
+ val socialType: AuthType,
+ val fcmToken: String = "EMPTY",
+ val socialAccessToken: String,
+)
diff --git a/data/network/src/main/java/co/kr/data/network/model/LoginResponse.kt b/data/network/src/main/java/co/kr/data/network/model/LoginResponse.kt
new file mode 100644
index 00000000..41204721
--- /dev/null
+++ b/data/network/src/main/java/co/kr/data/network/model/LoginResponse.kt
@@ -0,0 +1,25 @@
+package co.kr.data.network.model
+
+import co.kr.tnt.domain.model.AuthType
+import co.kr.tnt.domain.model.LoginResult
+import kotlinx.serialization.Serializable
+
+/**
+ * @property sessionId 세션 ID, 비회원인 경우 null
+ */
+@Serializable
+data class LoginResponse(
+ val sessionId: String?,
+ val socialId: String,
+ val socialEmail: String,
+ val socialType: AuthType,
+ val isSignUp: Boolean,
+)
+
+fun LoginResponse.toDomain(): LoginResult =
+ LoginResult(
+ authId = socialId,
+ email = socialEmail,
+ authType = socialType,
+ isSignUp = isSignUp,
+ )
diff --git a/data/network/src/main/java/co/kr/data/network/service/ApiService.kt b/data/network/src/main/java/co/kr/data/network/service/ApiService.kt
index c7f0ef58..a3be07a3 100644
--- a/data/network/src/main/java/co/kr/data/network/service/ApiService.kt
+++ b/data/network/src/main/java/co/kr/data/network/service/ApiService.kt
@@ -1,3 +1,13 @@
package co.kr.data.network.service
-interface ApiService
+import co.kr.data.network.model.LoginRequest
+import co.kr.data.network.model.LoginResponse
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+interface ApiService {
+ @POST("/login")
+ suspend fun postLogin(
+ @Body request: LoginRequest,
+ ): LoginResponse
+}
diff --git a/data/network/src/main/java/co/kr/data/network/source/LoginRemoteDataSource.kt b/data/network/src/main/java/co/kr/data/network/source/LoginRemoteDataSource.kt
new file mode 100644
index 00000000..c87fbad9
--- /dev/null
+++ b/data/network/src/main/java/co/kr/data/network/source/LoginRemoteDataSource.kt
@@ -0,0 +1,17 @@
+package co.kr.data.network.source
+
+import co.kr.data.network.model.LoginRequest
+import co.kr.data.network.model.LoginResponse
+import co.kr.data.network.service.ApiService
+import co.kr.data.network.util.networkHandler
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class LoginRemoteDataSource @Inject constructor(
+ private val apiService: ApiService,
+) {
+ suspend fun postLogin(loginRequest: LoginRequest): LoginResponse = networkHandler {
+ apiService.postLogin(loginRequest)
+ }
+}
diff --git a/data/repository/src/main/java/co/kr/data/repository/LoginRepositoryImpl.kt b/data/repository/src/main/java/co/kr/data/repository/LoginRepositoryImpl.kt
new file mode 100644
index 00000000..12266d56
--- /dev/null
+++ b/data/repository/src/main/java/co/kr/data/repository/LoginRepositoryImpl.kt
@@ -0,0 +1,35 @@
+package co.kr.data.repository
+
+import co.kr.data.network.model.LoginRequest
+import co.kr.data.network.model.toDomain
+import co.kr.data.network.source.LoginRemoteDataSource
+import co.kr.data.storage.source.SessionLocalDataSource
+import co.kr.tnt.domain.model.AuthType
+import co.kr.tnt.domain.model.LoginResult
+import co.kr.tnt.domain.repository.LoginRepository
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+internal class LoginRepositoryImpl @Inject constructor(
+ private val loginRemoteDataSource: LoginRemoteDataSource,
+ private val sessionLocalDataSource: SessionLocalDataSource,
+) : LoginRepository {
+ override suspend fun login(
+ authType: AuthType,
+ accessToken: String,
+ ): LoginResult {
+ val response = loginRemoteDataSource.postLogin(
+ loginRequest = LoginRequest(
+ socialType = authType,
+ socialAccessToken = accessToken,
+ ),
+ )
+
+ response.sessionId?.let { sessionId ->
+ sessionLocalDataSource.updateSessionId(sessionId)
+ }
+
+ return response.toDomain()
+ }
+}
diff --git a/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt b/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt
index daa56540..a41cb991 100644
--- a/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt
+++ b/data/repository/src/main/java/co/kr/data/repository/di/RepositoryModule.kt
@@ -1,9 +1,17 @@
package co.kr.data.repository.di
+import co.kr.data.repository.LoginRepositoryImpl
+import co.kr.tnt.domain.repository.LoginRepository
+import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@InstallIn(SingletonComponent::class)
@Module
-internal abstract class RepositoryModule
+internal abstract class RepositoryModule {
+ @Binds
+ abstract fun bindsLoginRepository(
+ repository: LoginRepositoryImpl,
+ ): LoginRepository
+}
diff --git a/data/session/src/main/java/co/kr/data/session/SessionProviderImpl.kt b/data/session/src/main/java/co/kr/data/session/SessionProviderImpl.kt
index 5cb788ef..645b0bbc 100644
--- a/data/session/src/main/java/co/kr/data/session/SessionProviderImpl.kt
+++ b/data/session/src/main/java/co/kr/data/session/SessionProviderImpl.kt
@@ -1,18 +1,18 @@
package co.kr.data.session
import co.kr.data.network.provider.SessionProvider
-import co.kr.data.storage.source.SessionDataSource
+import co.kr.data.storage.source.SessionLocalDataSource
import kotlinx.coroutines.flow.firstOrNull
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
internal class SessionProviderImpl @Inject constructor(
- private val sessionDataSource: SessionDataSource,
+ private val sessionLocalDataSource: SessionLocalDataSource,
) : SessionProvider {
override suspend fun getSessionId(): String =
- sessionDataSource.sessionId.firstOrNull() ?: ""
+ sessionLocalDataSource.sessionId.firstOrNull() ?: ""
override suspend fun setSessionId(sessionId: String) =
- sessionDataSource.updateSessionId(sessionId)
+ sessionLocalDataSource.updateSessionId(sessionId)
}
diff --git a/data/storage/src/main/java/co/kr/data/storage/source/SessionDataSource.kt b/data/storage/src/main/java/co/kr/data/storage/source/SessionLocalDataSource.kt
similarity index 94%
rename from data/storage/src/main/java/co/kr/data/storage/source/SessionDataSource.kt
rename to data/storage/src/main/java/co/kr/data/storage/source/SessionLocalDataSource.kt
index 105013f4..81f155ac 100644
--- a/data/storage/src/main/java/co/kr/data/storage/source/SessionDataSource.kt
+++ b/data/storage/src/main/java/co/kr/data/storage/source/SessionLocalDataSource.kt
@@ -10,7 +10,7 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
-class SessionDataSource @Inject constructor(
+class SessionLocalDataSource @Inject constructor(
private val sessionPreferences: DataStore,
) {
val sessionId: Flow = sessionPreferences.data.map { preferences ->
diff --git a/domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt b/domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt
new file mode 100644
index 00000000..8fbe2728
--- /dev/null
+++ b/domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt
@@ -0,0 +1,5 @@
+package co.kr.tnt.domain.model
+
+enum class AuthType {
+ KAKAO,
+}
diff --git a/domain/src/main/java/co/kr/tnt/domain/model/LoginResult.kt b/domain/src/main/java/co/kr/tnt/domain/model/LoginResult.kt
new file mode 100644
index 00000000..00d8d160
--- /dev/null
+++ b/domain/src/main/java/co/kr/tnt/domain/model/LoginResult.kt
@@ -0,0 +1,8 @@
+package co.kr.tnt.domain.model
+
+data class LoginResult(
+ val authId: String,
+ val email: String,
+ val authType: AuthType,
+ val isSignUp: Boolean,
+)
diff --git a/domain/src/main/java/co/kr/tnt/domain/repository/LoginRepository.kt b/domain/src/main/java/co/kr/tnt/domain/repository/LoginRepository.kt
new file mode 100644
index 00000000..ef3e5572
--- /dev/null
+++ b/domain/src/main/java/co/kr/tnt/domain/repository/LoginRepository.kt
@@ -0,0 +1,11 @@
+package co.kr.tnt.domain.repository
+
+import co.kr.tnt.domain.model.AuthType
+import co.kr.tnt.domain.model.LoginResult
+
+interface LoginRepository {
+ suspend fun login(
+ authType: AuthType,
+ accessToken: String,
+ ): LoginResult
+}
From fa5ade5d9bab27bab0d0983a027c306f4d627007 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Sun, 26 Jan 2025 23:21:34 +0900
Subject: [PATCH 09/13] =?UTF-8?q?[TNT-103]=20feat:=20=EB=A1=9C=EA=B7=B8?=
=?UTF-8?q?=EC=9D=B8=20=EC=84=B1=EA=B3=B5=20=EC=8B=9C=20=ED=99=88=20?=
=?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=9D=B4=EB=8F=99=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../kr/tnt/home/navigation/HomeNavigation.kt | 2 +-
.../java/co/kr/tnt/login/LoginContract.kt | 9 +++-
.../main/java/co/kr/tnt/login/LoginScreen.kt | 21 +++++++--
.../java/co/kr/tnt/login/LoginViewModel.kt | 47 ++++++++++++++-----
.../main/java/co/kr/tnt/main/ui/TnTNavHost.kt | 11 ++++-
5 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt b/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
index ca9be21c..03c22710 100644
--- a/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
+++ b/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
@@ -34,7 +34,7 @@ fun NavGraphBuilder.homeNavGraph(
isTrainer = isTrainer,
)
}
+ homeDestination()
}
- homeDestination()
}
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
index f7fb46ef..b1f221a1 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
@@ -1,5 +1,6 @@
package co.kr.tnt.login
+import co.kr.tnt.domain.model.AuthType
import co.kr.tnt.domain.model.Term
import co.kr.tnt.login.model.TermState
import co.kr.tnt.ui.base.UiEvent
@@ -16,8 +17,12 @@ internal class LoginContract {
}
sealed interface LoginUiEvent : UiEvent {
- data class OnLoginSuccess(val accessToken: LoginAccessToken) : LoginUiEvent
- data class OnLoginFail(val throwable: Throwable) : LoginUiEvent
+ data class OnAuthSuccess(
+ val authType: AuthType,
+ val accessToken: String,
+ ) : LoginUiEvent
+
+ data class OnAuthFail(val throwable: Throwable) : LoginUiEvent
data object OnCheckAllTermAgree : LoginUiEvent
data class OnCheckTerm(val termState: TermState) : LoginUiEvent
data class OnClickTermLink(val link: String) : LoginUiEvent
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
index 656e4298..22908bf0 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
@@ -45,6 +45,7 @@ import co.kr.tnt.designsystem.component.TnTDivider
import co.kr.tnt.designsystem.component.TnTModalBottomSheet
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.theme.TnTTheme
+import co.kr.tnt.domain.model.AuthType
import co.kr.tnt.feature.login.R
import co.kr.tnt.login.LoginContract.LoginSideEffect
import co.kr.tnt.login.LoginContract.LoginUiEvent
@@ -74,10 +75,15 @@ internal fun LoginRoute(
coroutineScope.launch {
kakaoLoginSdk.login(context)
.onSuccess { accessToken ->
- viewModel.setEvent(LoginUiEvent.OnLoginSuccess(accessToken))
+ viewModel.setEvent(
+ LoginUiEvent.OnAuthSuccess(
+ authType = AuthType.KAKAO,
+ accessToken = accessToken.value,
+ ),
+ )
}
.onFailure { throwable ->
- viewModel.setEvent(LoginUiEvent.OnLoginFail(throwable))
+ viewModel.setEvent(LoginUiEvent.OnAuthFail(throwable))
}
}
},
@@ -111,8 +117,15 @@ internal fun LoginRoute(
Toast.makeText(context, effect.message, Toast.LENGTH_SHORT).show()
}
- LoginSideEffect.NavigateToHome -> navigateToHome()
- LoginSideEffect.NavigateToSignup -> navigateToSignup()
+ LoginSideEffect.NavigateToHome -> {
+ showBottomSheet = false
+ navigateToHome()
+ }
+
+ LoginSideEffect.NavigateToSignup -> {
+ showBottomSheet = false
+ navigateToSignup()
+ }
}
}
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
index 9206a8e0..d7ebdafe 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
@@ -1,26 +1,30 @@
package co.kr.tnt.login
+import androidx.lifecycle.viewModelScope
+import co.kr.tnt.domain.model.AuthType
+import co.kr.tnt.domain.repository.LoginRepository
import co.kr.tnt.login.LoginContract.LoginSideEffect
import co.kr.tnt.login.LoginContract.LoginUiEvent
import co.kr.tnt.login.LoginContract.LoginUiState
import co.kr.tnt.login.model.TermState
import co.kr.tnt.ui.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
-internal class LoginViewModel @Inject constructor() : BaseViewModel(
- LoginUiState(),
-) {
+internal class LoginViewModel @Inject constructor(
+ private val loginRepository: LoginRepository,
+) : BaseViewModel(
+ LoginUiState(),
+ ) {
override suspend fun handleEvent(event: LoginUiEvent) {
when (event) {
- is LoginUiEvent.OnLoginSuccess -> {
- sendEffect(LoginSideEffect.ShowTermBottomSheet)
- }
+ is LoginUiEvent.OnAuthSuccess -> login(event.authType, event.accessToken)
- is LoginUiEvent.OnLoginFail -> {
+ is LoginUiEvent.OnAuthFail -> {
if (event.throwable !is LoginException.CancelException) {
- // TODO resource provider
+ // TODO resource
sendEffect(LoginSideEffect.ShowToast("로그인에 실패하였습니다. 다시 시도해주세요."))
}
}
@@ -28,7 +32,7 @@ internal class LoginViewModel @Inject constructor() : BaseViewModel checkAllTerms()
is LoginUiEvent.OnCheckTerm -> checkTerm(event.termState)
is LoginUiEvent.OnClickTermLink -> TODO()
- LoginUiEvent.OnClickNext -> navigateToNext()
+ LoginUiEvent.OnClickNext -> sendEffect(LoginSideEffect.NavigateToSignup)
}
}
@@ -52,8 +56,27 @@ internal class LoginViewModel @Inject constructor() : BaseViewModel
+ if (loginResult.isSignUp) {
+ sendEffect(LoginSideEffect.NavigateToHome)
+ return@onSuccess
+ }
+
+ sendEffect(LoginSideEffect.ShowTermBottomSheet)
+ }.onFailure {
+ // TODO resource
+ sendEffect(LoginSideEffect.ShowToast("알 수 없는 오류가 발생했습니다. 다시 시도해주세요."))
+ }
+ }
}
}
diff --git a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
index 99079e17..34199642 100644
--- a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
+++ b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
@@ -10,6 +10,7 @@ import co.kr.tnt.home.navigation.navigateToHome
import co.kr.tnt.login.navigation.loginScreen
import co.kr.tnt.trainee.connect.navigation.traineeConnectScreen
import co.kr.tnt.trainer.connect.navigation.trainerConnectScreen
+import co.kr.tnt.navigation.Route
@Composable
fun TnTNavHost(
@@ -26,7 +27,15 @@ fun TnTNavHost(
startDestination = appState.startDestination,
) {
loginScreen(
- navigateToHome = { },
+ navigateToHome = {
+ navController.navigateToHome(isTrainer = true) {
+ popUpTo(Route.Login) {
+ inclusive = true
+ }
+ launchSingleTop = true
+ restoreState = true
+ }
+ },
navigateToSignup = { },
)
trainerConnectScreen(
From d228e108fbc68ee678ce4864d63e49b985ea4165 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Mon, 27 Jan 2025 00:07:28 +0900
Subject: [PATCH 10/13] =?UTF-8?q?[TNT-103]=20feat:=20=EB=A1=9C=EA=B7=B8?=
=?UTF-8?q?=EC=9D=B8=20=ED=95=98=EC=98=80=EC=9C=BC=EB=82=98=20=ED=9A=8C?=
=?UTF-8?q?=EC=9B=90=EC=9D=B4=20=EC=95=84=EB=8B=8C=20=EA=B2=BD=EC=9A=B0=20?=
=?UTF-8?q?=EC=97=AD=ED=95=A0=20=EC=84=A0=ED=83=9D=20=ED=99=94=EB=A9=B4?=
=?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/co/kr/tnt/navigation/RouteModel.kt | 7 +++
.../java/co/kr/tnt/domain/model/AuthType.kt | 10 ++++
.../kr/tnt/home/navigation/HomeNavigation.kt | 2 +-
.../java/co/kr/tnt/login/LoginContract.kt | 3 +-
.../main/java/co/kr/tnt/login/LoginScreen.kt | 7 ++-
.../java/co/kr/tnt/login/LoginViewModel.kt | 55 ++++++++++++-------
.../tnt/login/navigation/LoginNavigation.kt | 3 +-
feature/main/build.gradle.kts | 1 +
.../main/java/co/kr/tnt/main/ui/TnTNavHost.kt | 14 ++++-
.../tnt/roleselect/RoleSelectionNavigation.kt | 34 ++++++++++++
.../kr/tnt/roleselect/RoleSelectionScreen.kt | 11 ++++
11 files changed, 117 insertions(+), 30 deletions(-)
create mode 100644 feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionNavigation.kt
diff --git a/core/navigation/src/main/java/co/kr/tnt/navigation/RouteModel.kt b/core/navigation/src/main/java/co/kr/tnt/navigation/RouteModel.kt
index 51d0fa6d..f579b47b 100644
--- a/core/navigation/src/main/java/co/kr/tnt/navigation/RouteModel.kt
+++ b/core/navigation/src/main/java/co/kr/tnt/navigation/RouteModel.kt
@@ -17,4 +17,11 @@ sealed interface Route {
@Serializable
data object TraineeConnect : Route
+
+ @Serializable
+ data class RoleSelection(
+ val authId: String,
+ val authType: String,
+ val email: String,
+ ) : Route
}
diff --git a/domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt b/domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt
index 8fbe2728..73e4d444 100644
--- a/domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt
+++ b/domain/src/main/java/co/kr/tnt/domain/model/AuthType.kt
@@ -2,4 +2,14 @@ package co.kr.tnt.domain.model
enum class AuthType {
KAKAO,
+ ;
+
+ companion object {
+ fun from(value: String): AuthType {
+ return when (value) {
+ "KAKAO" -> KAKAO
+ else -> throw IllegalArgumentException("지원하지 않는 $value 입니다.")
+ }
+ }
+ }
}
diff --git a/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt b/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
index 03c22710..e27539c8 100644
--- a/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
+++ b/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
@@ -25,7 +25,7 @@ fun NavController.navigateToHome(
)
fun NavGraphBuilder.homeNavGraph(
- homeDestination: NavGraphBuilder.() -> Unit,
+ homeDestination: NavGraphBuilder.() -> Unit = { },
) {
navigation(startDestination = Route.Home(false)) {
composable { backstackEntry ->
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
index b1f221a1..5a4879ad 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
@@ -1,6 +1,7 @@
package co.kr.tnt.login
import co.kr.tnt.domain.model.AuthType
+import co.kr.tnt.domain.model.LoginResult
import co.kr.tnt.domain.model.Term
import co.kr.tnt.login.model.TermState
import co.kr.tnt.ui.base.UiEvent
@@ -33,6 +34,6 @@ internal class LoginContract {
data object ShowTermBottomSheet : LoginSideEffect
data class ShowToast(val message: String) : LoginSideEffect
data object NavigateToHome : LoginSideEffect
- data object NavigateToSignup : LoginSideEffect
+ data class NavigateToSignup(val loginResult: LoginResult) : LoginSideEffect
}
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
index 22908bf0..ae3b23a5 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
@@ -46,6 +46,7 @@ import co.kr.tnt.designsystem.component.TnTModalBottomSheet
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.domain.model.AuthType
+import co.kr.tnt.domain.model.LoginResult
import co.kr.tnt.feature.login.R
import co.kr.tnt.login.LoginContract.LoginSideEffect
import co.kr.tnt.login.LoginContract.LoginUiEvent
@@ -59,7 +60,7 @@ import kotlinx.coroutines.launch
internal fun LoginRoute(
viewModel: LoginViewModel = hiltViewModel(),
navigateToHome: () -> Unit,
- navigateToSignup: () -> Unit,
+ navigateToSignup: (LoginResult) -> Unit,
) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
@@ -122,9 +123,9 @@ internal fun LoginRoute(
navigateToHome()
}
- LoginSideEffect.NavigateToSignup -> {
+ is LoginSideEffect.NavigateToSignup -> {
showBottomSheet = false
- navigateToSignup()
+ navigateToSignup(effect.loginResult)
}
}
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
index d7ebdafe..b8d3f77f 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
@@ -2,6 +2,7 @@ package co.kr.tnt.login
import androidx.lifecycle.viewModelScope
import co.kr.tnt.domain.model.AuthType
+import co.kr.tnt.domain.model.LoginResult
import co.kr.tnt.domain.repository.LoginRepository
import co.kr.tnt.login.LoginContract.LoginSideEffect
import co.kr.tnt.login.LoginContract.LoginUiEvent
@@ -18,6 +19,8 @@ internal class LoginViewModel @Inject constructor(
) : BaseViewModel(
LoginUiState(),
) {
+ private var loginResult: LoginResult? = null
+
override suspend fun handleEvent(event: LoginUiEvent) {
when (event) {
is LoginUiEvent.OnAuthSuccess -> login(event.authType, event.accessToken)
@@ -32,27 +35,7 @@ internal class LoginViewModel @Inject constructor(
LoginUiEvent.OnCheckAllTermAgree -> checkAllTerms()
is LoginUiEvent.OnCheckTerm -> checkTerm(event.termState)
is LoginUiEvent.OnClickTermLink -> TODO()
- LoginUiEvent.OnClickNext -> sendEffect(LoginSideEffect.NavigateToSignup)
- }
- }
-
- private fun checkAllTerms() {
- updateState {
- copy(
- terms = terms.keys.associateWith {
- !isAllTermChecked()
- },
- )
- }
- }
-
- private fun checkTerm(termState: TermState) {
- updateState {
- copy(
- terms = terms.toMutableMap()
- .also { terms -> terms[termState] = !(terms[termState] ?: false) }
- .toMap(),
- )
+ LoginUiEvent.OnClickNext -> navigateToSignup()
}
}
@@ -72,6 +55,7 @@ internal class LoginViewModel @Inject constructor(
return@onSuccess
}
+ this@LoginViewModel.loginResult = loginResult
sendEffect(LoginSideEffect.ShowTermBottomSheet)
}.onFailure {
// TODO resource
@@ -79,4 +63,33 @@ internal class LoginViewModel @Inject constructor(
}
}
}
+
+ private fun checkAllTerms() {
+ updateState {
+ copy(
+ terms = terms.keys.associateWith {
+ !isAllTermChecked()
+ },
+ )
+ }
+ }
+
+ private fun checkTerm(termState: TermState) {
+ updateState {
+ copy(
+ terms = terms.toMutableMap()
+ .also { terms -> terms[termState] = !(terms[termState] ?: false) }
+ .toMap(),
+ )
+ }
+ }
+
+ private fun navigateToSignup() {
+ loginResult?.let { loginResult ->
+ sendEffect(LoginSideEffect.NavigateToSignup(loginResult))
+ this@LoginViewModel.loginResult = null
+ } ?: run {
+ sendEffect(LoginSideEffect.ShowToast("로그인에 실패하였습니다. 다시 시도해주세요."))
+ }
+ }
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/navigation/LoginNavigation.kt b/feature/login/src/main/java/co/kr/tnt/login/navigation/LoginNavigation.kt
index d54d3a8f..7b02f712 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/navigation/LoginNavigation.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/navigation/LoginNavigation.kt
@@ -4,6 +4,7 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptionsBuilder
import androidx.navigation.compose.composable
+import co.kr.tnt.domain.model.LoginResult
import co.kr.tnt.login.LoginRoute
import co.kr.tnt.navigation.Route
@@ -16,7 +17,7 @@ fun NavController.navigateToLogin(
fun NavGraphBuilder.loginScreen(
navigateToHome: () -> Unit,
- navigateToSignup: () -> Unit,
+ navigateToSignup: (LoginResult) -> Unit,
) {
composable {
LoginRoute(
diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts
index f10fc2ae..b8a8c346 100644
--- a/feature/main/build.gradle.kts
+++ b/feature/main/build.gradle.kts
@@ -13,6 +13,7 @@ dependencies {
implementation(projects.feature.login)
implementation(projects.feature.trainer.connect)
implementation(projects.feature.trainee.connect)
+ implementation(projects.feature.roleselect)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
diff --git a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
index 34199642..a7c47732 100644
--- a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
+++ b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
@@ -11,6 +11,8 @@ import co.kr.tnt.login.navigation.loginScreen
import co.kr.tnt.trainee.connect.navigation.traineeConnectScreen
import co.kr.tnt.trainer.connect.navigation.trainerConnectScreen
import co.kr.tnt.navigation.Route
+import co.kr.tnt.roleselect.navigateToRoleSelection
+import co.kr.tnt.roleselect.roleSelectionScreen
@Composable
fun TnTNavHost(
@@ -36,7 +38,13 @@ fun TnTNavHost(
restoreState = true
}
},
- navigateToSignup = { },
+ navigateToSignup = { loginResult ->
+ navController.navigateToRoleSelection(
+ authId = loginResult.authId,
+ authType = loginResult.authType.name,
+ email = loginResult.email,
+ )
+ },
)
trainerConnectScreen(
navigateToPrevious = { navController.popBackStack() },
@@ -50,8 +58,8 @@ fun TnTNavHost(
navController.navigateToHome(isTrainer = false, clearBackStack = true)
},
)
- homeNavGraph {
- }
+ roleSelectionScreen()
+ homeNavGraph()
}
}
}
diff --git a/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionNavigation.kt b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionNavigation.kt
new file mode 100644
index 00000000..15bfeb58
--- /dev/null
+++ b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionNavigation.kt
@@ -0,0 +1,34 @@
+package co.kr.tnt.roleselect
+
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptionsBuilder
+import androidx.navigation.compose.composable
+import androidx.navigation.toRoute
+import co.kr.tnt.navigation.Route
+
+fun NavController.navigateToRoleSelection(
+ authId: String,
+ authType: String,
+ email: String,
+ navOptions: NavOptionsBuilder.() -> Unit = {},
+) = navigate(
+ route = Route.RoleSelection(
+ authId = authId,
+ authType = authType,
+ email = email,
+ ),
+ builder = navOptions,
+)
+
+fun NavGraphBuilder.roleSelectionScreen() {
+ composable { navBackstackEntry ->
+ navBackstackEntry.toRoute().apply {
+ RoleSelectionScreen(
+ authId = authId,
+ authType = authType,
+ email = email,
+ )
+ }
+ }
+}
diff --git a/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt
index 5d85eb65..1b09876f 100644
--- a/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt
+++ b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt
@@ -26,17 +26,24 @@ import co.kr.tnt.designsystem.component.button.TnTTextButton
import co.kr.tnt.designsystem.component.button.model.ButtonSize
import co.kr.tnt.designsystem.component.button.model.ButtonType
import co.kr.tnt.designsystem.theme.TnTTheme
+import co.kr.tnt.domain.model.AuthType
import co.kr.tnt.domain.model.UserType
import co.kr.tnt.feature.roleselect.R
import co.kr.tnt.roleselect.model.RoleState
import co.kr.tnt.core.ui.R as uiResource
@Composable
+@Suppress("UnusedParameter")
fun RoleSelectionScreen(
onRoleSelected: (UserType) -> Unit = {},
onNextClick: () -> Unit = {},
+ authId: String,
+ authType: String,
+ email: String,
+ modifier: Modifier = Modifier,
) {
var selectedRole by remember { mutableStateOf(RoleState.fromDomain(UserType.Trainer())) }
+ val authType = AuthType.from(authType)
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Column(
@@ -108,6 +115,10 @@ private fun RoleScreenPreview() {
RoleSelectionScreen(
onRoleSelected = {},
onNextClick = {},
+ authId = "",
+ authType = "",
+ email = "",
+ modifier = Modifier.fillMaxSize(),
)
}
}
From ce11ce390b32a6effd316d83f4b788484ea3c775 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Mon, 27 Jan 2025 00:29:01 +0900
Subject: [PATCH 11/13] =?UTF-8?q?[TNT-103]=20fix:=20homeDestination=20?=
=?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt b/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
index e27539c8..fc4c8405 100644
--- a/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
+++ b/feature/home/src/main/java/co/kr/tnt/home/navigation/HomeNavigation.kt
@@ -34,7 +34,7 @@ fun NavGraphBuilder.homeNavGraph(
isTrainer = isTrainer,
)
}
- homeDestination()
}
+ homeDestination()
}
}
From b7861f362c02387d2675edb5a11bf65908a85d03 Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Mon, 27 Jan 2025 00:48:28 +0900
Subject: [PATCH 12/13] =?UTF-8?q?[TNT-103]=20fix:=20CI=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/android-ci.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/android-ci.yaml b/.github/workflows/android-ci.yaml
index 915bd026..3052c022 100644
--- a/.github/workflows/android-ci.yaml
+++ b/.github/workflows/android-ci.yaml
@@ -19,7 +19,7 @@ jobs:
run: |
echo RELEASE_BASE_API_URL=\"${{ secrets.RELEASE_BASE_API_URL }}\" >> ./local.properties
echo DEBUG_BASE_API_URL=\"${{ secrets.DEBUG_BASE_API_URL }}\" >> ./local.properties
- echo KAKAO_NATIVE_APP_KEY=\"${{ secrets.KAKAO_NATIVE_APP_KEY }}\" >> ./local.properties
+ echo KAKAO_NATIVE_APP_KEY=${{ secrets.KAKAO_NATIVE_APP_KEY }} >> ./local.properties
- name: Grant execute permission for gradlew
run: chmod +x gradlew
From 240ef15c5b28f8696bf8c59db30a7bcc9ae9aefc Mon Sep 17 00:00:00 2001
From: hoyahozz <85336456+hoyahozz@users.noreply.github.com>
Date: Mon, 27 Jan 2025 01:07:39 +0900
Subject: [PATCH 13/13] [TNT-103] fix: ktlint apply
---
feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
index a7c47732..84ab6f6e 100644
--- a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
+++ b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTNavHost.kt
@@ -8,11 +8,11 @@ import androidx.navigation.compose.NavHost
import co.kr.tnt.home.navigation.homeNavGraph
import co.kr.tnt.home.navigation.navigateToHome
import co.kr.tnt.login.navigation.loginScreen
-import co.kr.tnt.trainee.connect.navigation.traineeConnectScreen
-import co.kr.tnt.trainer.connect.navigation.trainerConnectScreen
import co.kr.tnt.navigation.Route
import co.kr.tnt.roleselect.navigateToRoleSelection
import co.kr.tnt.roleselect.roleSelectionScreen
+import co.kr.tnt.trainee.connect.navigation.traineeConnectScreen
+import co.kr.tnt.trainer.connect.navigation.trainerConnectScreen
@Composable
fun TnTNavHost(