From 53aeb1acc0dd8194650f93089651087aa9e52bca Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 14:43:49 +0900 Subject: [PATCH 1/9] =?UTF-8?q?[Fix]=20=EC=9E=98=EB=AA=BB=EB=90=9C=20depen?= =?UTF-8?q?dency=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 6 ++--- .../users/response/AliasChoiceResponse.kt | 12 +++++----- .../users/response/MyFollowingsResponse.kt | 22 +++++++++---------- .../users/response/OthersFollowersResponse.kt | 22 +++++++++---------- .../model/users/response/SignupResponse.kt | 6 ++--- .../users/response/UserSearchResponse.kt | 14 ++++++------ 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 40c235b5..1d05b3e1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -67,7 +67,7 @@ dependencies { implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.material3) implementation(libs.androidx.navigation.compose) - implementation(libs.androidx.foundation) + //implementation(libs.androidx.foundation) implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.navigation.runtime.android) implementation(libs.kotlinx.serialization.json) @@ -91,7 +91,7 @@ dependencies { // Retrofit implementation(libs.retrofit) - implementation(libs.converter.gson) + //implementation(libs.converter.gson) implementation(libs.retrofit.kotlin.serialization.converter) // OkHttp @@ -102,7 +102,7 @@ dependencies { implementation("com.kakao.sdk:v2-all:2.21.6") // 토큰 저장을 위한 DataStore - implementation ("androidx.datastore:datastore-preferences:1.1.1") + //implementation ("androidx.datastore:datastore-preferences:1.1.1") // 구글 로그인 implementation(platform("com.google.firebase:firebase-bom:34.1.0")) diff --git a/app/src/main/java/com/texthip/thip/data/model/users/response/AliasChoiceResponse.kt b/app/src/main/java/com/texthip/thip/data/model/users/response/AliasChoiceResponse.kt index b4753a6f..1529507b 100644 --- a/app/src/main/java/com/texthip/thip/data/model/users/response/AliasChoiceResponse.kt +++ b/app/src/main/java/com/texthip/thip/data/model/users/response/AliasChoiceResponse.kt @@ -1,17 +1,17 @@ package com.texthip.thip.data.model.users.response -import com.google.gson.annotations.SerializedName +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class AliasChoiceResponse( - @SerializedName("aliasChoices") val aliasChoices: List + @SerialName("aliasChoices") val aliasChoices: List ) @Serializable data class AliasChoice( - @SerializedName("aliasName") val aliasName: String, - @SerializedName("categoryName") val categoryName: String, - @SerializedName("imageUrl") val imageUrl: String, - @SerializedName("aliasColor") val aliasColor: String + @SerialName("aliasName") val aliasName: String, + @SerialName("categoryName") val categoryName: String, + @SerialName("imageUrl") val imageUrl: String, + @SerialName("aliasColor") val aliasColor: String ) \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/data/model/users/response/MyFollowingsResponse.kt b/app/src/main/java/com/texthip/thip/data/model/users/response/MyFollowingsResponse.kt index aa96cb6e..b16a183a 100644 --- a/app/src/main/java/com/texthip/thip/data/model/users/response/MyFollowingsResponse.kt +++ b/app/src/main/java/com/texthip/thip/data/model/users/response/MyFollowingsResponse.kt @@ -1,22 +1,22 @@ package com.texthip.thip.data.model.users.response -import com.google.gson.annotations.SerializedName +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class MyFollowingsResponse( - @SerializedName("followings") val followings: List, - @SerializedName("totalFollowingCount") val totalFollowingCount: Int, - @SerializedName("nextCursor") val nextCursor: String?, - @SerializedName("isLast") val isLast: Boolean + @SerialName("followings") val followings: List, + @SerialName("totalFollowingCount") val totalFollowingCount: Int, + @SerialName("nextCursor") val nextCursor: String?, + @SerialName("isLast") val isLast: Boolean ) @Serializable data class FollowingList( - @SerializedName("userId") val userId: Long, - @SerializedName("nickname") val nickname: String, - @SerializedName("profileImageUrl") val profileImageUrl: String?, - @SerializedName("aliasName") val aliasName: String, - @SerializedName("aliasColor") val aliasColor: String, - @SerializedName("isFollowing") val isFollowing: Boolean + @SerialName("userId") val userId: Long, + @SerialName("nickname") val nickname: String, + @SerialName("profileImageUrl") val profileImageUrl: String?, + @SerialName("aliasName") val aliasName: String, + @SerialName("aliasColor") val aliasColor: String, + @SerialName("isFollowing") val isFollowing: Boolean ) \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt b/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt index 71728031..81bcdd0c 100644 --- a/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt +++ b/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt @@ -1,22 +1,22 @@ package com.texthip.thip.data.model.users.response -import com.google.gson.annotations.SerializedName +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class OthersFollowersResponse( - @SerializedName("followers") val followers: List, - @SerializedName("totalFollowerCount") val totalFollowerCount: Int, - @SerializedName("nextCursor") val nextCursor: String?, - @SerializedName("isLast") val isLast: Boolean + @SerialName("followers") val followers: List, + @SerialName("totalFollowerCount") val totalFollowerCount: Int, + @SerialName("nextCursor") val nextCursor: String?, + @SerialName("isLast") val isLast: Boolean ) @Serializable data class FollowerList( - @SerializedName("userId") val userId: Long, - @SerializedName("nickname") val nickname: String, - @SerializedName("profileImageUrl") val profileImageUrl: String?, - @SerializedName("aliasName") val aliasName: String, - @SerializedName("aliasColor") val aliasColor: String, - @SerializedName("followerCount") val followerCount: Int + @SerialName("userId") val userId: Long, + @SerialName("nickname") val nickname: String, + @SerialName("profileImageUrl") val profileImageUrl: String?, + @SerialName("aliasName") val aliasName: String, + @SerialName("aliasColor") val aliasColor: String, + @SerialName("followerCount") val followerCount: Int ) \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/data/model/users/response/SignupResponse.kt b/app/src/main/java/com/texthip/thip/data/model/users/response/SignupResponse.kt index 9d0c63d6..ac7ff41c 100644 --- a/app/src/main/java/com/texthip/thip/data/model/users/response/SignupResponse.kt +++ b/app/src/main/java/com/texthip/thip/data/model/users/response/SignupResponse.kt @@ -1,10 +1,10 @@ package com.texthip.thip.data.model.users.response -import com.google.gson.annotations.SerializedName +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class SignupResponse( - @SerializedName("accessToken") val accessToken: String, - @SerializedName("userId") val userId: Long + @SerialName("accessToken") val accessToken: String, + @SerialName("userId") val userId: Long ) \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/data/model/users/response/UserSearchResponse.kt b/app/src/main/java/com/texthip/thip/data/model/users/response/UserSearchResponse.kt index 9267f7d7..0558eaff 100644 --- a/app/src/main/java/com/texthip/thip/data/model/users/response/UserSearchResponse.kt +++ b/app/src/main/java/com/texthip/thip/data/model/users/response/UserSearchResponse.kt @@ -1,7 +1,7 @@ package com.texthip.thip.data.model.users.response -import com.google.gson.annotations.SerializedName import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName @Serializable data class UserSearchResponse( @@ -9,10 +9,10 @@ data class UserSearchResponse( ) @Serializable data class UserItem( - @SerializedName("userId") val userId: Int, - @SerializedName("nickname") val nickname: String, - @SerializedName("profileImageUrl") val profileImageUrl: String?, - @SerializedName("aliasName") val aliasName: String, - @SerializedName("aliasColor") val aliasColor: String, - @SerializedName("followerCount") val followerCount: Int + @SerialName("userId") val userId: Int, + @SerialName("nickname") val nickname: String, + @SerialName("profileImageUrl") val profileImageUrl: String?, + @SerialName("aliasName") val aliasName: String, + @SerialName("aliasColor") val aliasColor: String, + @SerialName("followerCount") val followerCount: Int ) \ No newline at end of file From 3ee77f50366e2e17b8a6b7377e62e96717bc7887 Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 14:45:29 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[Fix]=20:=20=EC=8A=A4=ED=94=8C=EB=9E=98?= =?UTF-8?q?=EC=8B=9C=20screen,=20view=20model=20=EC=88=98=EC=A0=95=20-=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=EC=9D=B4=20=EC=9E=88=EB=8B=A4=EB=A9=B4=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=99=94=EB=A9=B4=EC=9D=B4=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20=EB=A9=94=EC=9D=B8=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B0=80=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/ui/signin/screen/SplashScreen.kt | 16 +++++----- .../ui/signin/viewmodel/SplashViewModel.kt | 31 ++++++++++++++++--- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/signin/screen/SplashScreen.kt b/app/src/main/java/com/texthip/thip/ui/signin/screen/SplashScreen.kt index ad79335c..ca14c54b 100644 --- a/app/src/main/java/com/texthip/thip/ui/signin/screen/SplashScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/signin/screen/SplashScreen.kt @@ -1,5 +1,3 @@ -package com.texthip.thip.ui.signin.screen - import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -24,6 +22,7 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.texthip.thip.R +import com.texthip.thip.ui.signin.viewmodel.SplashDestination import com.texthip.thip.ui.signin.viewmodel.SplashViewModel import com.texthip.thip.ui.theme.Purple import com.texthip.thip.ui.theme.ThipTheme.colors @@ -32,13 +31,16 @@ import com.texthip.thip.ui.theme.ThipTheme.typography @Composable fun SplashScreen( viewModel: SplashViewModel = hiltViewModel(), - onNavigateToLogin: () -> Unit = {} + onNavigateToLogin: () -> Unit = {}, + onNavigateToHome: () -> Unit = {} ) { - val navigateToLogin by viewModel.navigateToLogin.collectAsStateWithLifecycle() + val destination by viewModel.destination.collectAsStateWithLifecycle() - LaunchedEffect(navigateToLogin) { - if (navigateToLogin) { - onNavigateToLogin() + LaunchedEffect(destination) { + when (destination) { + SplashDestination.NavigateToLogin -> onNavigateToLogin() + SplashDestination.NavigateToHome -> onNavigateToHome() + else -> {} } } diff --git a/app/src/main/java/com/texthip/thip/ui/signin/viewmodel/SplashViewModel.kt b/app/src/main/java/com/texthip/thip/ui/signin/viewmodel/SplashViewModel.kt index 72b07245..d0abc258 100644 --- a/app/src/main/java/com/texthip/thip/ui/signin/viewmodel/SplashViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/signin/viewmodel/SplashViewModel.kt @@ -2,6 +2,7 @@ package com.texthip.thip.ui.signin.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.texthip.thip.data.manager.TokenManager import dagger.hilt.android.lifecycle.HiltViewModel import jakarta.inject.Inject import kotlinx.coroutines.delay @@ -9,15 +10,35 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +sealed interface SplashDestination { + data object Loading : SplashDestination + data object NavigateToLogin : SplashDestination + data object NavigateToHome : SplashDestination +} + @HiltViewModel -class SplashViewModel @Inject constructor() : ViewModel() { - private val _navigateToLogin = MutableStateFlow(false) - val navigateToLogin = _navigateToLogin.asStateFlow() +class SplashViewModel @Inject constructor( + private val tokenManager: TokenManager +) : ViewModel() { + + private val _destination = MutableStateFlow(SplashDestination.Loading) + val destination = _destination.asStateFlow() init { + checkLoginStatus() + } + + private fun checkLoginStatus() { viewModelScope.launch { - delay(3000) - _navigateToLogin.value = true + delay(2000L) // 스플래시 최소 노출 시간 + + val token = tokenManager.getTokenOnce() + + if (token.isNullOrBlank()) { + _destination.value = SplashDestination.NavigateToLogin + } else { + _destination.value = SplashDestination.NavigateToHome + } } } } \ No newline at end of file From ac987c1dbd271a5c2642be79c498ab92959aafe2 Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 14:46:08 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[Fix]=20:=20=ED=86=A0=ED=81=B0=EB=A7=A4?= =?UTF-8?q?=EB=8B=88=EC=A0=80=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95,=20=EC=9C=A0=EC=A0=80=20=EB=A0=88=ED=8F=AC=EC=A7=80?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EC=97=90=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../texthip/thip/data/manager/TokenManager.kt | 73 ++++++------------- .../thip/data/repository/UserRepository.kt | 2 +- 2 files changed, 25 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/data/manager/TokenManager.kt b/app/src/main/java/com/texthip/thip/data/manager/TokenManager.kt index 66d20968..db370f35 100644 --- a/app/src/main/java/com/texthip/thip/data/manager/TokenManager.kt +++ b/app/src/main/java/com/texthip/thip/data/manager/TokenManager.kt @@ -1,94 +1,69 @@ package com.texthip.thip.data.manager -import android.content.Context import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey -import androidx.datastore.preferences.preferencesDataStore -import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import javax.inject.Inject import javax.inject.Singleton -private val Context.dataStore: DataStore by preferencesDataStore(name = "thip_tokens") @Singleton class TokenManager @Inject constructor( - @ApplicationContext private val context: Context + private val dataStore: DataStore ) { companion object { - //토큰저장에 사용되는 키 - private val APP_TOKEN_KEY = stringPreferencesKey("app_token") - private val TEMP_TOKEN_KEY = stringPreferencesKey("temp_token") - private val ACCESS_TOKEN_KEY = stringPreferencesKey("access_token") + private val APP_TOKEN_KEY = stringPreferencesKey("app_token") // 정식 액세스토큰 + private val TEMP_TOKEN_KEY = stringPreferencesKey("temp_token") // 임시 토큰 private val REFRESH_TOKEN_KEY = stringPreferencesKey("refresh_token") } - //토큰 저장 + // ====== 정식 토큰 ====== suspend fun saveToken(token: String) { - context.dataStore.edit { prefs -> + dataStore.edit { prefs -> prefs[APP_TOKEN_KEY] = token } } - //저장된 토큰을 Flow 형태로 불러옴 fun getToken(): Flow { - return context.dataStore.data.map { prefs -> - prefs[APP_TOKEN_KEY] - } + return dataStore.data.map { prefs -> prefs[APP_TOKEN_KEY] } + } + + suspend fun getTokenOnce(): String? { + return dataStore.data.map { prefs -> prefs[APP_TOKEN_KEY] }.first() } - //저장된 토큰 삭제 (로그아웃 시?) suspend fun deleteToken() { - context.dataStore.edit { prefs -> - prefs.remove(APP_TOKEN_KEY) - } + dataStore.edit { prefs -> prefs.remove(APP_TOKEN_KEY) } } - // 임시 토큰 저장 + // ====== 임시 토큰 ====== suspend fun saveTempToken(token: String) { - context.dataStore.edit { prefs -> - prefs[TEMP_TOKEN_KEY] = token - } + dataStore.edit { prefs -> prefs[TEMP_TOKEN_KEY] = token } } - // 임시 토큰 읽기 - suspend fun getTempToken(): String? { - return context.dataStore.data.map { prefs -> - prefs[TEMP_TOKEN_KEY] - }.first() // Flow에서 첫 번째 값을 한번만 읽어옴 + suspend fun getTempTokenOnce(): String? { + return dataStore.data.map { prefs -> prefs[TEMP_TOKEN_KEY] }.first() } - // 임시 토큰 삭제 suspend fun deleteTempToken() { - context.dataStore.edit { prefs -> - prefs.remove(TEMP_TOKEN_KEY) - } + dataStore.edit { prefs -> prefs.remove(TEMP_TOKEN_KEY) } } - - // 정식 토큰들(Access, Refresh) 저장 - suspend fun saveAccessTokens(accessToken: String, refreshToken: String) { - context.dataStore.edit { prefs -> - prefs[ACCESS_TOKEN_KEY] = accessToken - prefs[REFRESH_TOKEN_KEY] = refreshToken - } + // ====== Refresh 토큰 (추후 확장용) ====== + suspend fun saveRefreshToken(token: String) { + dataStore.edit { prefs -> prefs[REFRESH_TOKEN_KEY] = token } } - // Access Token 읽기 (Flow로 제공하여 토큰 변화를 감지할 수 있게 함) - fun getAccessToken(): kotlinx.coroutines.flow.Flow { - return context.dataStore.data.map { prefs -> - prefs[ACCESS_TOKEN_KEY] - } + suspend fun getRefreshTokenOnce(): String? { + return dataStore.data.map { prefs -> prefs[REFRESH_TOKEN_KEY] }.first() } - // 모든 토큰 삭제 (로그아웃 시) suspend fun clearTokens() { - context.dataStore.edit { prefs -> - prefs.clear() - } + dataStore.edit { prefs -> prefs.clear() } } -} \ No newline at end of file +} + diff --git a/app/src/main/java/com/texthip/thip/data/repository/UserRepository.kt b/app/src/main/java/com/texthip/thip/data/repository/UserRepository.kt index 2b55e4f4..96afd970 100644 --- a/app/src/main/java/com/texthip/thip/data/repository/UserRepository.kt +++ b/app/src/main/java/com/texthip/thip/data/repository/UserRepository.kt @@ -115,7 +115,7 @@ class UserRepository @Inject constructor( suspend fun signup(request: SignupRequest): Result { Log.d("SignupDebug", "UserRepository.signup() 호출됨. 요청 닉네임: ${request.nickname}") - val tempToken = tokenManager.getTempToken() + val tempToken = tokenManager.getTempTokenOnce() Log.d("SignupDebug", "가져온 임시 토큰: $tempToken") From 9ac0f3d8ad6cf02003206d176839075681e605c0 Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 14:47:02 +0900 Subject: [PATCH 4/9] =?UTF-8?q?[Fix]=20:=20main=20activity=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 --- .../java/com/texthip/thip/MainActivity.kt | 25 +++++++++++++++++-- .../java/com/texthip/thip/ThipApplication.kt | 8 ++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/MainActivity.kt b/app/src/main/java/com/texthip/thip/MainActivity.kt index cc0d9d64..a6e16e42 100644 --- a/app/src/main/java/com/texthip/thip/MainActivity.kt +++ b/app/src/main/java/com/texthip/thip/MainActivity.kt @@ -40,7 +40,28 @@ fun RootNavHost() { startDestination = CommonRoutes.Splash ) { // --- 인증 관련 화면들 --- - authNavigation(navController) + authNavigation( + onNavigateToLogin = { + navController.navigate(CommonRoutes.Login) { + popUpTo(CommonRoutes.Splash) { inclusive = true } + } + }, + onNavigateToHome = { + navController.navigate(CommonRoutes.Main) { + popUpTo(CommonRoutes.Splash) { inclusive = true } + } + }, + onNavigateToSignup = { + navController.navigate(CommonRoutes.SignupFlow) + }, + onNavigateToMainAfterSignup = { + navController.navigate(CommonRoutes.Main) { // 혹은 MainGraph + popUpTo(CommonRoutes.Splash) { inclusive = true } + } + }, + navController = navController + ) + // --- 메인 관련 화면들 --- composable { // MainScreen으로 가는 경로 추가 @@ -48,7 +69,7 @@ fun RootNavHost() { onNavigateToLogin = { navController.navigate(CommonRoutes.Login) { // 메인 화면으로 돌아올 수 없도록 모든 화면 기록 삭제 - popUpTo(navController.graph.id) { + popUpTo(CommonRoutes.Main) { inclusive = true } } diff --git a/app/src/main/java/com/texthip/thip/ThipApplication.kt b/app/src/main/java/com/texthip/thip/ThipApplication.kt index 27619c91..58da5b7b 100644 --- a/app/src/main/java/com/texthip/thip/ThipApplication.kt +++ b/app/src/main/java/com/texthip/thip/ThipApplication.kt @@ -1,13 +1,17 @@ package com.texthip.thip -import com.kakao.sdk.common.KakaoSdk import android.app.Application +import com.kakao.sdk.common.KakaoSdk +import com.texthip.thip.data.manager.TokenManager import dagger.hilt.android.HiltAndroidApp -import com.texthip.thip.BuildConfig +import javax.inject.Inject @HiltAndroidApp class ThipApplication : Application(){ + @Inject + lateinit var tokenManager: TokenManager + override fun onCreate() { super.onCreate() From fac69fb5aff0d8bd7cbc8ba8d06376bf1c7eb74c Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 14:47:28 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[Fix]=20:=20auth=20navigation=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navigator/navigations/AuthNavigation.kt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/AuthNavigation.kt b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/AuthNavigation.kt index d4c1a89b..84662a7f 100644 --- a/app/src/main/java/com/texthip/thip/ui/navigator/navigations/AuthNavigation.kt +++ b/app/src/main/java/com/texthip/thip/ui/navigator/navigations/AuthNavigation.kt @@ -1,5 +1,6 @@ package com.texthip.thip.ui.navigator.navigations +import SplashScreen import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.hilt.navigation.compose.hiltViewModel @@ -8,29 +9,33 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable import androidx.navigation.navigation -import com.texthip.thip.ui.navigator.extensions.navigateToLogin import com.texthip.thip.ui.navigator.extensions.navigateToMainAfterSignup -import com.texthip.thip.ui.navigator.extensions.navigateToSignup import com.texthip.thip.ui.navigator.routes.CommonRoutes import com.texthip.thip.ui.signin.mock.SignupUserInfo import com.texthip.thip.ui.signin.screen.LoginScreen import com.texthip.thip.ui.signin.screen.SignupDoneScreen import com.texthip.thip.ui.signin.screen.SignupGenreScreen import com.texthip.thip.ui.signin.screen.SignupNicknameScreen -import com.texthip.thip.ui.signin.screen.SplashScreen import com.texthip.thip.ui.signin.screen.TutorialScreen import com.texthip.thip.ui.signin.viewmodel.SignupViewModel -fun NavGraphBuilder.authNavigation(navController: NavHostController) { +fun NavGraphBuilder.authNavigation( + navController: NavHostController, + onNavigateToLogin: () -> Unit, + onNavigateToHome: () -> Unit, + onNavigateToSignup: () -> Unit, + onNavigateToMainAfterSignup: () -> Unit +) { composable { SplashScreen( - onNavigateToLogin = { navController.navigateToLogin() } + onNavigateToLogin = onNavigateToLogin, + onNavigateToHome = onNavigateToHome ) } composable { LoginScreen( - onNavigateToSignup = { navController.navigateToSignup() }, - onLoginSuccess = { navController.navigateToMainAfterSignup() } + onNavigateToSignup = onNavigateToSignup, + onLoginSuccess = onNavigateToMainAfterSignup ) } navigation( From 19bfc2e466ee34b150c32c88ee58b3d02b7229e0 Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 14:47:57 +0900 Subject: [PATCH 6/9] =?UTF-8?q?[Fix]=20:=20=EC=9D=B8=ED=84=B0=EC=85=89?= =?UTF-8?q?=ED=84=B0=20=EC=88=98=EC=A0=95=20-=20=ED=97=A4=EB=8D=94?= =?UTF-8?q?=EC=97=90=20=EC=A0=95=EC=8B=9D=20=ED=86=A0=ED=81=B0=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EC=9C=BC=EB=A9=B4=20=EC=9E=84=EC=8B=9C=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/utils/auth/AuthInterceptor.kt | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/utils/auth/AuthInterceptor.kt b/app/src/main/java/com/texthip/thip/utils/auth/AuthInterceptor.kt index d9d8c0e1..71e9f700 100644 --- a/app/src/main/java/com/texthip/thip/utils/auth/AuthInterceptor.kt +++ b/app/src/main/java/com/texthip/thip/utils/auth/AuthInterceptor.kt @@ -1,7 +1,6 @@ package com.texthip.thip.utils.auth import com.texthip.thip.data.manager.TokenManager -import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import okhttp3.Interceptor import okhttp3.Response @@ -11,26 +10,24 @@ class AuthInterceptor @Inject constructor( private val tokenManager: TokenManager ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { - val originalRequest = chain.request() + val original = chain.request() - // 1. 요청에 이미 Authorization 헤더가 있는지 확인합니다. - if (originalRequest.header("Authorization") != null) { - // 이미 헤더가 있다면, 아무 작업도 하지 않고 그대로 보냅니다. - return chain.proceed(originalRequest) + if (original.header("Authorization") != null) { + return chain.proceed(original) } - val appToken = runBlocking { tokenManager.getToken().first() } - val tempToken = runBlocking { tokenManager.getTempToken() } - val tokenToSend = appToken ?: tempToken - val requestBuilder = chain.request().newBuilder() + // 1. 정식 토큰을 먼저 확인합니다. + val token = runBlocking { tokenManager.getTokenOnce() } + // 2. 정식 토큰이 없으면, 임시 토큰을 확인합니다. + val tempToken = runBlocking { tokenManager.getTempTokenOnce() } - if (!tokenToSend.isNullOrBlank()) { - requestBuilder.addHeader( - "Authorization", - "Bearer $tokenToSend" - ) - } + // 보낼 토큰을 결정합니다 (정식 토큰 우선). + val tokenToSend = token ?: tempToken + + val newRequest = original.newBuilder().apply { + tokenToSend?.let { addHeader("Authorization", "Bearer $it") } + }.build() - return chain.proceed(requestBuilder.build()) + return chain.proceed(newRequest) } -} \ No newline at end of file +} From c0af2d1138d7e96939146de13dc3068aa822b8f9 Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 14:48:11 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[Fix]=20:=20DataStoreModule=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../texthip/thip/data/di/DataStoreModule.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 app/src/main/java/com/texthip/thip/data/di/DataStoreModule.kt diff --git a/app/src/main/java/com/texthip/thip/data/di/DataStoreModule.kt b/app/src/main/java/com/texthip/thip/data/di/DataStoreModule.kt new file mode 100644 index 00000000..ab84768c --- /dev/null +++ b/app/src/main/java/com/texthip/thip/data/di/DataStoreModule.kt @@ -0,0 +1,25 @@ +package com.texthip.thip.data.di + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.preferencesDataStore +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import androidx.datastore.preferences.core.Preferences +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object DataStoreModule { + + private val Context.dataStore: DataStore by preferencesDataStore(name = "thip_tokens") + + @Provides + @Singleton + fun provideDataStore(@ApplicationContext context: Context): DataStore { + return context.dataStore + } +} From a204a9906becb63304b25bd43514c238f6d23cde Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 15:02:25 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[Fix]:=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=EC=A4=91=20=EC=9E=98=EB=AA=BB=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=20=EA=B2=83=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/data/model/users/response/OthersFollowersResponse.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt b/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt index 81bcdd0c..502b9acc 100644 --- a/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt +++ b/app/src/main/java/com/texthip/thip/data/model/users/response/OthersFollowersResponse.kt @@ -18,5 +18,6 @@ data class FollowerList( @SerialName("profileImageUrl") val profileImageUrl: String?, @SerialName("aliasName") val aliasName: String, @SerialName("aliasColor") val aliasColor: String, - @SerialName("followerCount") val followerCount: Int + @SerialName("followerCount") val followerCount: Int, + @SerialName("isMyself") val isMyself: Boolean ) \ No newline at end of file From 285749397aca28de91ab5c9b0b6b9259491208ff Mon Sep 17 00:00:00 2001 From: JJUYAAA Date: Thu, 21 Aug 2025 15:34:06 +0900 Subject: [PATCH 9/9] =?UTF-8?q?[Fix]:=20=EC=B9=B4=EC=B9=B4=EC=98=A4,=20?= =?UTF-8?q?=EA=B5=AC=EA=B8=80=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=99=84=EC=A0=84=ED=9E=88=20=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/ui/mypage/screen/MypageScreen.kt | 6 +++++- .../ui/mypage/viewmodel/MyPageViewModel.kt | 20 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt b/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt index 8ce331c8..4b884548 100644 --- a/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt +++ b/app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt @@ -1,5 +1,6 @@ package com.texthip.thip.ui.mypage.screen +import android.content.Context import android.content.Intent import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -58,6 +59,7 @@ fun MyPageScreen( onDeleteAccount: () -> Unit, onNavigateToLogin: () -> Unit ) { + val context = LocalContext.current val uiState by viewModel.uiState.collectAsState() LaunchedEffect(Unit) { viewModel.fetchMyPageInfo() @@ -75,7 +77,9 @@ fun MyPageScreen( onCustomerServiceClick = onCustomerService, onLogoutClick = { viewModel.onLogoutClick() }, onDismissLogoutDialog = { viewModel.onDismissLogoutDialog() }, - onConfirmLogout = { viewModel.confirmLogout() }, + onConfirmLogout = { viewModel.confirmLogout( + context = context + ) }, onDeleteAccount = onDeleteAccount ) } diff --git a/app/src/main/java/com/texthip/thip/ui/mypage/viewmodel/MyPageViewModel.kt b/app/src/main/java/com/texthip/thip/ui/mypage/viewmodel/MyPageViewModel.kt index 2cb54f5a..4cb77adc 100644 --- a/app/src/main/java/com/texthip/thip/ui/mypage/viewmodel/MyPageViewModel.kt +++ b/app/src/main/java/com/texthip/thip/ui/mypage/viewmodel/MyPageViewModel.kt @@ -1,7 +1,12 @@ package com.texthip.thip.ui.mypage.viewmodel +import android.content.Context +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.google.android.gms.auth.api.signin.GoogleSignIn +import com.google.android.gms.auth.api.signin.GoogleSignInOptions +import com.kakao.sdk.user.UserApiClient import com.texthip.thip.data.manager.TokenManager import com.texthip.thip.data.repository.UserRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -62,9 +67,22 @@ class MyPageViewModel @Inject constructor( _uiState.update { it.copy(showLogoutDialog = false) } } - fun confirmLogout() { + fun confirmLogout(context: Context) { viewModelScope.launch { tokenManager.clearTokens() + // 2. 카카오 SDK에서 로그아웃 + UserApiClient.instance.unlink { error -> + if (error != null) { + Log.e("MyPageViewModel", "카카오 로그아웃 실패", error) + } else { + Log.d("MyPageViewModel", "카카오 로그아웃 성공") + } + } + + // 3. 구글 SDK에서 로그아웃 + val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).build() + GoogleSignIn.getClient(context, gso).signOut() + _uiState.update { it.copy(showLogoutDialog = false, isLogoutCompleted = true) } } }