Skip to content

Commit d93e954

Browse files
authored
Merge pull request #121 from Nexters/feature/clean-up
[FIX] 마이 페이지 화면 AccessToken 만료, 서버 에러 대응
2 parents b1f940e + b853704 commit d93e954

File tree

20 files changed

+60
-52
lines changed

20 files changed

+60
-52
lines changed

build-logic/src/main/kotlin/com/nexters/ilab/android/Config.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ internal object ApplicationConfig {
44
const val MinSdk = 26
55
const val TargetSdk = 34
66
const val CompileSdk = 34
7-
const val VersionCode = 6
8-
const val VersionName = "1.0.5"
7+
const val VersionCode = 7
8+
const val VersionName = "1.0.6"
99
val JavaVersion = org.gradle.api.JavaVersion.VERSION_17
1010
const val JavaVersionAsInt = 17
1111
}

core/data/src/main/kotlin/com/nexters/ilab/android/core/data/repository/TokenRepositoryImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class TokenRepositoryImpl @Inject constructor(
3131
return dataSource.getUUID()
3232
}
3333

34-
override suspend fun clear() {
35-
dataSource.clear()
34+
override suspend fun clearAuthToken() {
35+
dataSource.clearAuthToken()
3636
}
3737
}

core/datastore/src/main/kotlin/com/nexters/ilab/android/core/datastore/TokenDataSource.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ interface TokenDataSource {
77
suspend fun getAccessToken(): String
88
suspend fun getRefreshToken(): String
99
suspend fun getUUID(): Long
10-
suspend fun clear()
10+
suspend fun clearAuthToken()
1111
}

core/datastore/src/main/kotlin/com/nexters/ilab/android/core/datastore/TokenDataSourceImpl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class TokenDataSourceImpl @Inject constructor(
5151
else throw exception
5252
}.first()[KEY_REFRESH_TOKEN] ?: ""
5353

54-
override suspend fun clear() {
54+
override suspend fun clearAuthToken() {
5555
dataStore.edit { it.clear() }
5656
}
5757
}

core/designsystem/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ android {
1212
dependencies {
1313
implementations(
1414
libs.androidx.core,
15-
libs.androidx.splash,
1615
libs.coil.compose,
1716
)
1817
}

core/designsystem/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<string name="mypage_name_postfix">님</string>
2525
<string name="mypage_dropdown_delete">삭제하기</string>
2626
<string name="mypage_dropdown_share">공유하기</string>
27+
<string name="mypage_logout">로그인 세션이 종료되어 다시 로그인이 필요합니다.</string>
2728

2829
<!-- Setting -->
2930
<string name="setting_title">설정</string>

core/domain/src/main/kotlin/com/nexters/ilab/android/core/domain/repository/TokenRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ interface TokenRepository {
77
suspend fun getAccessToken(): String
88
suspend fun getRefreshToken(): String
99
suspend fun getUUID(): Long
10-
suspend fun clear()
10+
suspend fun clearAuthToken()
1111
}

feature/intro/src/main/kotlin/com/nexters/ilab/android/feature/intro/IntroActivity.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ package com.nexters.ilab.android.feature.intro
33
import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
6-
import androidx.activity.viewModels
6+
import androidx.activity.enableEdgeToEdge
77
import androidx.compose.runtime.DisposableEffect
88
import androidx.compose.ui.graphics.Color
9-
import androidx.activity.enableEdgeToEdge
109
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
1110
import com.nexters.ilab.android.core.designsystem.theme.ILabTheme
12-
import com.nexters.ilab.android.feature.intro.viewmodel.IntroViewModel
1311
import com.nexters.ilab.android.feature.navigator.LoginNavigator
1412
import com.nexters.ilab.android.feature.navigator.MainNavigator
1513
import dagger.hilt.android.AndroidEntryPoint
@@ -18,8 +16,6 @@ import javax.inject.Inject
1816

1917
@AndroidEntryPoint
2018
class IntroActivity : ComponentActivity() {
21-
private val viewModel: IntroViewModel by viewModels()
22-
2319
@Inject
2420
lateinit var loginNavigator: LoginNavigator
2521

@@ -58,7 +54,6 @@ class IntroActivity : ComponentActivity() {
5854
withFinish = true,
5955
)
6056
},
61-
viewModel = viewModel,
6257
)
6358
}
6459
}

feature/intro/src/main/kotlin/com/nexters/ilab/android/feature/intro/viewmodel/IntroViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class IntroViewModel @Inject constructor(
3939

4040
fun autoLoginFail() = intent {
4141
viewModelScope.launch {
42-
repository.clear()
42+
repository.clearAuthToken()
4343
postSideEffect(IntroSideEffect.AutoLoginFail)
4444
}
4545
}

feature/login/src/main/kotlin/com/nexters/ilab/android/feature/login/LoginActivity.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,16 @@ import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
66
import androidx.activity.enableEdgeToEdge
7-
import androidx.activity.viewModels
87
import androidx.compose.runtime.DisposableEffect
98
import androidx.compose.ui.graphics.Color
109
import com.nexters.ilab.android.core.designsystem.theme.ILabTheme
11-
import com.nexters.ilab.android.feature.login.viewmodel.LoginViewModel
1210
import com.nexters.ilab.android.feature.navigator.MainNavigator
1311
import dagger.hilt.android.AndroidEntryPoint
1412
import tech.thdev.compose.exteions.system.ui.controller.rememberExSystemUiController
1513
import javax.inject.Inject
1614

1715
@AndroidEntryPoint
1816
class LoginActivity : ComponentActivity() {
19-
private val viewModel: LoginViewModel by viewModels()
20-
2117
@Inject
2218
lateinit var mainNavigator: MainNavigator
2319

@@ -46,7 +42,6 @@ class LoginActivity : ComponentActivity() {
4642
withFinish = true,
4743
)
4844
},
49-
viewModel = viewModel,
5045
)
5146
}
5247
}

feature/login/src/main/kotlin/com/nexters/ilab/android/feature/login/viewmodel/LoginViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class LoginViewModel @Inject constructor(
4040
}
4141
.onFailure { exception ->
4242
Timber.e(exception)
43-
tokenRepository.clear()
43+
tokenRepository.clearAuthToken()
4444
postSideEffect(LoginSideEffect.LoginFail(exception))
4545
}
4646
reduce {

feature/main/src/main/AndroidManifest.xml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,10 @@
55

66
<activity
77
android:name=".MainActivity"
8-
android:exported="true"
8+
android:exported="false"
99
android:screenOrientation="portrait"
1010
android:theme="@style/Theme.ILab">
1111

12-
<!-- <intent-filter>-->
13-
<!-- <action android:name="android.intent.action.MAIN" />-->
14-
15-
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
16-
<!-- </intent-filter>-->
17-
1812
</activity>
1913

2014
</application>

feature/main/src/main/kotlin/com/nexters/ilab/android/feature/main/MainScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ internal fun MainScreen(
108108
padding = padding,
109109
onSettingClick = navigator::navigateToSetting,
110110
onNavigateToMyAlbum = navigator::navigateToMyAlbum,
111+
onNavigateToLogin = onNavigateToLogin,
111112
)
112113

113114
myAlbumNavGraph(

feature/mypage/src/main/kotlin/com/nexters/ilab/android/feature/mypage/MyPageScreen.kt

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.nexters.ilab.android.feature.mypage
33
import android.content.ClipData
44
import android.content.Intent
55
import android.net.Uri
6+
import android.widget.Toast
67
import androidx.activity.compose.rememberLauncherForActivityResult
78
import androidx.activity.result.contract.ActivityResultContracts
89
import androidx.compose.foundation.Image
@@ -48,6 +49,7 @@ import androidx.compose.ui.draw.clip
4849
import androidx.compose.ui.graphics.Color
4950
import androidx.compose.ui.graphics.vector.ImageVector
5051
import androidx.compose.ui.layout.ContentScale
52+
import androidx.compose.ui.platform.LocalContext
5153
import androidx.compose.ui.res.painterResource
5254
import androidx.compose.ui.res.stringResource
5355
import androidx.compose.ui.res.vectorResource
@@ -72,7 +74,6 @@ import com.nexters.ilab.core.ui.component.ILabTopAppBar
7274
import com.nexters.ilab.core.ui.component.LoadingIndicator
7375
import com.nexters.ilab.core.ui.component.NetworkErrorDialog
7476
import com.nexters.ilab.core.ui.component.NetworkImage
75-
import com.nexters.ilab.core.ui.component.ServerErrorDialog
7677
import com.nexters.ilab.core.ui.component.TopAppBarNavigationType
7778
import kotlinx.collections.immutable.ImmutableList
7879

@@ -81,9 +82,11 @@ internal fun MyPageRoute(
8182
padding: PaddingValues,
8283
onSettingClick: () -> Unit,
8384
onNavigateToMyAlbum: (String, List<String>) -> Unit,
85+
onNavigateToLogin: () -> Unit,
8486
viewModel: MyPageViewModel = hiltViewModel(),
8587
) {
8688
val uiState by viewModel.container.stateFlow.collectAsStateWithLifecycle()
89+
val context = LocalContext.current
8790

8891
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { _ ->
8992
viewModel.deleteCacheDir()
@@ -100,7 +103,7 @@ internal fun MyPageRoute(
100103
putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList)
101104
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
102105
// https://stackoverflow.com/questions/57689792/permission-denial-while-sharing-file-with-fileprovider
103-
val clipData = ClipData.newRawUri("", uriList.get(0)).apply {
106+
val clipData = ClipData.newRawUri("", uriList[0]).apply {
104107
for (i in 1 until uriList.size) {
105108
addItem(ClipData.Item(uriList[i]))
106109
}
@@ -119,6 +122,10 @@ internal fun MyPageRoute(
119122
sideEffect.imageUrlList,
120123
)
121124
}
125+
126+
is MyPageSideEffect.ShowToast -> {
127+
Toast.makeText(context, sideEffect.message.asString(context), Toast.LENGTH_SHORT).show()
128+
}
122129
}
123130
}
124131
}
@@ -131,8 +138,10 @@ internal fun MyPageRoute(
131138
onShareBtnClick = viewModel::shareMyAlbum,
132139
onDeleteBtnClick = viewModel::deleteMyAlbum,
133140
onAlbumClick = viewModel::onAlbumClick,
134-
dismissServerErrorDialog = viewModel::dismissServerErrorDialog,
141+
// dismissServerErrorDialog = viewModel::dismissServerErrorDialog,
135142
dismissNetworkErrorDialog = viewModel::dismissNetworkErrorDialog,
143+
onNavigateToLogin = onNavigateToLogin,
144+
clearAuthToken = viewModel::clearAuthToken,
136145
)
137146
}
138147

@@ -145,8 +154,10 @@ internal fun MyPageScreen(
145154
onShareBtnClick: () -> Unit,
146155
onDeleteBtnClick: (Int) -> Unit,
147156
onAlbumClick: (Int) -> Unit,
148-
dismissServerErrorDialog: () -> Unit,
157+
// dismissServerErrorDialog: () -> Unit,
149158
dismissNetworkErrorDialog: () -> Unit,
159+
onNavigateToLogin: () -> Unit,
160+
clearAuthToken: () -> Unit,
150161
) {
151162
Column(
152163
modifier = Modifier
@@ -158,12 +169,14 @@ internal fun MyPageScreen(
158169
LoadingIndicator(modifier = Modifier.fillMaxSize())
159170
}
160171
if (uiState.isServerErrorDialogVisible) {
161-
ServerErrorDialog(
162-
onRetryClick = {
163-
dismissServerErrorDialog()
164-
getUserInfo()
165-
},
166-
)
172+
// ServerErrorDialog(
173+
// onRetryClick = {
174+
// dismissServerErrorDialog()
175+
// getUserInfo()
176+
// },
177+
// )
178+
clearAuthToken()
179+
onNavigateToLogin()
167180
}
168181
if (uiState.isNetworkErrorDialogVisible) {
169182
NetworkErrorDialog(
@@ -442,14 +455,16 @@ fun MyPageScreenPreview() {
442455
onAlbumClick = {},
443456
getUserInfo = {},
444457
dismissNetworkErrorDialog = {},
445-
dismissServerErrorDialog = {},
458+
// dismissServerErrorDialog = {},
459+
onNavigateToLogin = {},
460+
clearAuthToken = {},
446461
)
447462
}
448463
}
449464

450465
@DevicePreview
451466
@Composable
452-
fun MyPageScreenTestPreview() {
467+
fun MyPageScreenEmptyPreview() {
453468
ILabTheme {
454469
MyPageContentEmpty()
455470
}

feature/mypage/src/main/kotlin/com/nexters/ilab/android/feature/mypage/navigation/MyPageNavigation.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ fun NavGraphBuilder.myPageNavGraph(
1717
padding: PaddingValues,
1818
onSettingClick: () -> Unit,
1919
onNavigateToMyAlbum: (String, List<String>) -> Unit,
20+
onNavigateToLogin: () -> Unit,
2021
) {
2122
composable(route = MY_PAGE_ROUTE) {
2223
MyPageRoute(
2324
padding = padding,
2425
onSettingClick = onSettingClick,
2526
onNavigateToMyAlbum = onNavigateToMyAlbum,
27+
onNavigateToLogin = onNavigateToLogin,
2628
)
2729
}
2830
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.nexters.ilab.android.feature.mypage.viewmodel
22

3+
import com.nexters.ilab.android.core.common.UiText
4+
35
sealed interface MyPageSideEffect {
46
data class ShareMyAlbum(val imageUriList: List<String>) : MyPageSideEffect
57
data class NavigateToMyAlbum(
68
val imageUrlList: List<String>,
79
val imageStyle: String,
810
) : MyPageSideEffect
11+
12+
data class ShowToast(val message: UiText) : MyPageSideEffect
913
}

feature/mypage/src/main/kotlin/com/nexters/ilab/android/feature/mypage/viewmodel/MyPageViewModel.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package com.nexters.ilab.android.feature.mypage.viewmodel
33
import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
55
import com.nexters.ilab.android.core.common.ErrorHandlerActions
6+
import com.nexters.ilab.android.core.common.UiText
67
import com.nexters.ilab.android.core.common.handleException
8+
import com.nexters.ilab.android.core.designsystem.R
79
import com.nexters.ilab.android.core.domain.repository.AuthRepository
810
import com.nexters.ilab.android.core.domain.repository.DeleteMyAlbumRepository
911
import com.nexters.ilab.android.core.domain.repository.FileRepository
12+
import com.nexters.ilab.android.core.domain.repository.TokenRepository
1013
import dagger.hilt.android.lifecycle.HiltViewModel
1114
import kotlinx.collections.immutable.toImmutableList
1215
import kotlinx.coroutines.launch
@@ -23,6 +26,7 @@ class MyPageViewModel @Inject constructor(
2326
private val authRepository: AuthRepository,
2427
private val fileRepository: FileRepository,
2528
private val deleteMyAlbumRepository: DeleteMyAlbumRepository,
29+
private val tokenRepository: TokenRepository,
2630
) : ViewModel(), ContainerHost<MyPageState, MyPageSideEffect>, ErrorHandlerActions {
2731
override val container = container<MyPageState, MyPageSideEffect>(MyPageState())
2832

@@ -135,8 +139,12 @@ class MyPageViewModel @Inject constructor(
135139
}
136140
}
137141

138-
override fun onCleared() {
139-
super.onCleared()
140-
Timber.d("MyPageViewModel is cleared")
142+
fun clearAuthToken() = intent {
143+
viewModelScope.launch {
144+
tokenRepository.clearAuthToken()
145+
postSideEffect(
146+
MyPageSideEffect.ShowToast(UiText.StringResource(R.string.mypage_logout)),
147+
)
148+
}
141149
}
142150
}

feature/setting/src/main/kotlin/com/nexters/ilab/android/feature/setting/viewmodel/SettingViewModel.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class SettingViewModel @Inject constructor(
2929
reduce { state.copy(isLoading = true) }
3030
authRepository.signOut()
3131
.onSuccess {
32-
tokenRepository.clear()
32+
tokenRepository.clearAuthToken()
3333
postSideEffect(SettingSideEffect.LogoutSuccess)
3434
}.onFailure { exception ->
3535
Timber.d("$exception")
@@ -41,11 +41,7 @@ class SettingViewModel @Inject constructor(
4141

4242
fun getVersionInfo(context: Context): String {
4343
val packageInfo: PackageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
44-
if (packageInfo != null) {
45-
return packageInfo.versionName
46-
} else {
47-
return "버전 정보가 없습니다."
48-
}
44+
return packageInfo.versionName
4945
}
5046

5147
fun deleteAccount() = intent {
@@ -54,7 +50,7 @@ class SettingViewModel @Inject constructor(
5450
reduce { state.copy(isLoading = true) }
5551
authRepository.deleteAccount()
5652
.onSuccess {
57-
tokenRepository.clear()
53+
tokenRepository.clearAuthToken()
5854
postSideEffect(SettingSideEffect.LogoutSuccess)
5955
}.onFailure { exception ->
6056
Timber.d("$exception")

feature/uploadphoto/src/main/kotlin/com/nexters/ilab/android/feature/uploadphoto/navigation/UploadPhotoNavigation.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ fun NavGraphBuilder.uploadPhotoNavGraph(
5858
) {
5959
composable(route = UPLOAD_ROUTE) { entry ->
6060
val viewModel = entry.sharedViewModel<UploadPhotoViewModel>(navController)
61-
6261
UploadPhotoRoute(
6362
onBackClick = onBackClick,
6463
onNavigateToPrivacyPolicy = onNavigateToPrivacyPolicy,

gradle/libs.versions.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.
5555
kotlin-ktlint = { group = "com.pinterest", name = "ktlint", version.ref = "kotlin-ktlint-source" }
5656
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
5757
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
58-
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" }
5958
kotlinx-collections-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "kotlinx-collections-immutable" }
6059

6160
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }

0 commit comments

Comments
 (0)