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(