Skip to content

Commit 60d18e1

Browse files
committed
[BOOK-147] feat: 설정 화면으로 로그아웃 기능 이동
1 parent 65b3dbf commit 60d18e1

File tree

6 files changed

+113
-128
lines changed

6 files changed

+113
-128
lines changed

core/designsystem/src/main/kotlin/com/ninecraft/booket/core/designsystem/component/ReedDialog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ fun ReedDialog(
5858
textAlign = TextAlign.Center,
5959
style = ReedTheme.typography.headline1SemiBold,
6060
)
61-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
6261
subtext?.let {
62+
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
6363
Text(
6464
text = subtext,
6565
color = ReedTheme.colors.contentSecondary,

feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsPresenter.kt

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@ package com.ninecraft.booket.feature.settings
33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.getValue
55
import androidx.compose.runtime.mutableStateOf
6+
import androidx.compose.runtime.rememberCoroutineScope
67
import androidx.compose.runtime.setValue
8+
import com.ninecraft.booket.core.common.utils.handleException
9+
import com.ninecraft.booket.core.data.api.repository.AuthRepository
10+
import com.ninecraft.booket.screens.LoginScreen
711
import com.ninecraft.booket.screens.OssLicensesScreen
812
import com.ninecraft.booket.screens.SettingsScreen
13+
import com.orhanobut.logger.Logger
914
import com.slack.circuit.codegen.annotations.CircuitInject
1015
import com.slack.circuit.retained.rememberRetained
1116
import com.slack.circuit.runtime.Navigator
@@ -14,19 +19,28 @@ import dagger.assisted.Assisted
1419
import dagger.assisted.AssistedFactory
1520
import dagger.assisted.AssistedInject
1621
import dagger.hilt.android.components.ActivityRetainedComponent
22+
import kotlinx.coroutines.launch
1723

1824
class SettingsPresenter @AssistedInject constructor(
1925
@Assisted val navigator: Navigator,
26+
private val authRepository: AuthRepository,
2027
) : Presenter<SettingsUiState> {
2128

2229
@Composable
2330
override fun present(): SettingsUiState {
24-
var isLogoutBottomSheetVisible by rememberRetained { mutableStateOf(false) }
31+
val scope = rememberCoroutineScope()
32+
var isLoading by rememberRetained { mutableStateOf(false) }
33+
var sideEffect by rememberRetained { mutableStateOf<SettingsSideEffect?>(null) }
34+
var isLogoutDialogVisible by rememberRetained { mutableStateOf(false) }
2535
var isWithdrawBottomSheetVisible by rememberRetained { mutableStateOf(false) }
2636
var isWithdrawConfirmed by rememberRetained { mutableStateOf(false) }
2737

2838
fun handleEvent(event: SettingsUiEvent) {
2939
when (event) {
40+
is SettingsUiEvent.InitSideEffect -> {
41+
sideEffect = null
42+
}
43+
3044
is SettingsUiEvent.OnBackClick -> {
3145
navigator.pop()
3246
}
@@ -40,15 +54,15 @@ class SettingsPresenter @AssistedInject constructor(
4054
}
4155

4256
is SettingsUiEvent.OnLogoutClick -> {
43-
isLogoutBottomSheetVisible = true
57+
isLogoutDialogVisible = true
4458
}
4559

4660
is SettingsUiEvent.OnWithdrawClick -> {
4761
isWithdrawBottomSheetVisible = true
4862
}
4963

5064
is SettingsUiEvent.OnBottomSheetDismissed -> {
51-
isLogoutBottomSheetVisible = false
65+
isLogoutDialogVisible = false
5266
isWithdrawBottomSheetVisible = false
5367
isWithdrawConfirmed = false
5468
}
@@ -58,7 +72,33 @@ class SettingsPresenter @AssistedInject constructor(
5872
}
5973

6074
is SettingsUiEvent.Logout -> {
61-
// TODO: 로그아웃 처리 -> 성공 시 로그인 화면으로 이동
75+
scope.launch {
76+
try {
77+
isLoading = true
78+
authRepository.logout()
79+
.onSuccess {
80+
navigator.resetRoot(LoginScreen)
81+
}
82+
.onFailure { exception ->
83+
val handleErrorMessage = { message: String ->
84+
Logger.e(message)
85+
sideEffect = SettingsSideEffect.ShowToast(message)
86+
}
87+
88+
handleException(
89+
exception = exception,
90+
onServerError = handleErrorMessage,
91+
onNetworkError = handleErrorMessage,
92+
onLoginRequired = {
93+
navigator.resetRoot(LoginScreen)
94+
},
95+
)
96+
}
97+
} finally {
98+
isLoading = false
99+
}
100+
}
101+
isLogoutDialogVisible = false
62102
}
63103

64104
is SettingsUiEvent.Withdraw -> {
@@ -67,9 +107,11 @@ class SettingsPresenter @AssistedInject constructor(
67107
}
68108
}
69109
return SettingsUiState(
70-
isLogoutBottomSheetVisible = isLogoutBottomSheetVisible,
110+
isLoading = isLoading,
111+
isLogoutDialogVisible = isLogoutDialogVisible,
71112
isWithdrawBottomSheetVisible = isWithdrawBottomSheetVisible,
72113
isWithdrawConfirmed = isWithdrawConfirmed,
114+
sideEffect = sideEffect,
73115
eventSink = ::handleEvent,
74116
)
75117
}

feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsScreen.kt

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package com.ninecraft.booket.feature.settings
22

33
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Box
45
import androidx.compose.foundation.layout.Column
56
import androidx.compose.foundation.layout.Row
67
import androidx.compose.foundation.layout.Spacer
78
import androidx.compose.foundation.layout.fillMaxSize
89
import androidx.compose.foundation.layout.fillMaxWidth
910
import androidx.compose.foundation.layout.height
1011
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.material3.CircularProgressIndicator
1113
import androidx.compose.material3.ExperimentalMaterial3Api
1214
import androidx.compose.material3.Icon
1315
import androidx.compose.material3.Text
@@ -24,11 +26,11 @@ import androidx.compose.ui.res.stringResource
2426
import androidx.compose.ui.res.vectorResource
2527
import com.ninecraft.booket.core.common.extensions.clickableSingle
2628
import com.ninecraft.booket.core.designsystem.DevicePreview
29+
import com.ninecraft.booket.core.designsystem.component.ReedDialog
2730
import com.ninecraft.booket.core.designsystem.component.appbar.ReedBackTopAppBar
2831
import com.ninecraft.booket.core.designsystem.component.divider.ReedDivider
2932
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
3033
import com.ninecraft.booket.core.designsystem.theme.White
31-
import com.ninecraft.booket.feature.settings.component.LogoutConfirmationBottomSheet
3234
import com.ninecraft.booket.feature.settings.component.WithdrawConfirmationBottomSheet
3335
import com.ninecraft.booket.screens.SettingsScreen
3436
import com.slack.circuit.codegen.annotations.CircuitInject
@@ -42,7 +44,11 @@ internal fun Settings(
4244
state: SettingsUiState,
4345
modifier: Modifier = Modifier,
4446
) {
45-
val logoutSheetState = rememberModalBottomSheetState()
47+
HandleSettingsSideEffects(
48+
state = state,
49+
eventSink = state.eventSink,
50+
)
51+
4652
val withDrawSheetState = rememberModalBottomSheetState()
4753
val coroutineScope = rememberCoroutineScope()
4854

@@ -131,21 +137,28 @@ internal fun Settings(
131137
)
132138
}
133139

134-
if (state.isLogoutBottomSheetVisible) {
135-
LogoutConfirmationBottomSheet(
140+
if (state.isLoading) {
141+
Box(
142+
modifier = Modifier.fillMaxSize(),
143+
) {
144+
CircularProgressIndicator(
145+
modifier = Modifier.align(Alignment.Center),
146+
color = ReedTheme.colors.contentBrand,
147+
)
148+
}
149+
}
150+
151+
if (state.isLogoutDialogVisible) {
152+
ReedDialog(
153+
title = stringResource(R.string.settings_logout_title),
154+
confirmButtonText = stringResource(R.string.settings_logout),
155+
dismissButtonText = stringResource(R.string.settings_cancel),
156+
onConfirmRequest = {
157+
state.eventSink(SettingsUiEvent.Logout)
158+
},
136159
onDismissRequest = {
137160
state.eventSink(SettingsUiEvent.OnBottomSheetDismissed)
138161
},
139-
sheetState = logoutSheetState,
140-
onCancelButtonClick = {
141-
coroutineScope.launch {
142-
logoutSheetState.hide()
143-
state.eventSink(SettingsUiEvent.OnBottomSheetDismissed)
144-
}
145-
},
146-
onLogoutButtonClick = {
147-
state.eventSink(SettingsUiEvent.Logout)
148-
},
149162
)
150163
}
151164

@@ -212,9 +225,11 @@ private fun SettingsScreenPreview() {
212225
ReedTheme {
213226
Settings(
214227
state = SettingsUiState(
215-
isLogoutBottomSheetVisible = false,
228+
isLoading = false,
229+
isLogoutDialogVisible = false,
216230
isWithdrawBottomSheetVisible = false,
217231
isWithdrawConfirmed = false,
232+
sideEffect = null,
218233
eventSink = {},
219234
),
220235
)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.ninecraft.booket.feature.settings
2+
3+
import android.widget.Toast
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.LaunchedEffect
6+
import androidx.compose.ui.platform.LocalContext
7+
8+
@Composable
9+
internal fun HandleSettingsSideEffects(
10+
state: SettingsUiState,
11+
eventSink: (SettingsUiEvent) -> Unit,
12+
) {
13+
val context = LocalContext.current
14+
15+
LaunchedEffect(state) {
16+
when (state.sideEffect) {
17+
is SettingsSideEffect.ShowToast -> {
18+
Toast.makeText(context, state.sideEffect.message, Toast.LENGTH_SHORT).show()
19+
}
20+
null -> {}
21+
}
22+
23+
if (state.sideEffect != null) {
24+
eventSink(SettingsUiEvent.InitSideEffect)
25+
}
26+
}
27+
}

feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUiState.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@ import com.slack.circuit.runtime.CircuitUiEvent
44
import com.slack.circuit.runtime.CircuitUiState
55

66
data class SettingsUiState(
7-
val isLogoutBottomSheetVisible: Boolean,
7+
val isLoading: Boolean,
8+
val isLogoutDialogVisible: Boolean,
89
val isWithdrawBottomSheetVisible: Boolean,
910
val isWithdrawConfirmed: Boolean,
11+
val sideEffect: SettingsSideEffect? = null,
1012
val eventSink: (SettingsUiEvent) -> Unit,
1113
) : CircuitUiState
1214

15+
sealed interface SettingsSideEffect {
16+
data class ShowToast(val message: String) : SettingsSideEffect
17+
}
18+
1319
sealed interface SettingsUiEvent : CircuitUiEvent {
20+
data object InitSideEffect : SettingsUiEvent
1421
data object OnBackClick : SettingsUiEvent
1522
data class OnTermDetailClick(val title: String) : SettingsUiEvent
1623
data object OnOssLicensesClick : SettingsUiEvent

feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/component/LogoutConfirmationBottomSheet.kt

Lines changed: 0 additions & 106 deletions
This file was deleted.

0 commit comments

Comments
 (0)