Skip to content

Commit 07596ab

Browse files
authored
Merge pull request #217 from YAPP-Github/BOOK-420-fix/#216
fix: 로그인 필요 기능 진입 시 다이얼로그 노출하도록 수정
2 parents a41d39c + 82e4da2 commit 07596ab

File tree

11 files changed

+121
-109
lines changed

11 files changed

+121
-109
lines changed

core/common/src/main/kotlin/com/ninecraft/booket/core/common/constants/ErrorDialogSpec.kt

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.ninecraft.booket.core.common.event
2+
3+
import com.ninecraft.booket.core.common.constants.ErrorScope
4+
import com.ninecraft.booket.core.common.utils.isNetworkError
5+
import retrofit2.HttpException
6+
7+
fun postErrorDialog(
8+
errorScope: ErrorScope,
9+
exception: Throwable,
10+
confirmLabel: String = "확인",
11+
onConfirm: () -> Unit = {},
12+
) {
13+
val (title, message) = when {
14+
exception.isNetworkError() -> {
15+
null to "네트워크 연결이 불안정합니다.\n인터넷 연결을 확인해주세요"
16+
}
17+
18+
exception is HttpException -> {
19+
when (errorScope) {
20+
ErrorScope.GLOBAL -> {
21+
null to "알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
22+
}
23+
24+
ErrorScope.LOGIN -> {
25+
"로그인 오류" to "예기치 않은 오류가 발생했습니다.\n다시 로그인 해주세요."
26+
}
27+
28+
ErrorScope.AUTH_SESSION_EXPIRED -> {
29+
null to "세션이 만료되었어요.\n다시 로그인 해주세요"
30+
}
31+
}
32+
}
33+
34+
else -> {
35+
null to "알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
36+
}
37+
}
38+
39+
val spec = DialogSpec(
40+
title = title,
41+
message = message,
42+
confirmLabel = confirmLabel,
43+
onConfirm = onConfirm,
44+
)
45+
46+
EventHelper.sendEvent(event = ReedEvent.ShowDialog(spec))
47+
}
48+
49+
fun postLoginRequiredDialog(onConfirm: () -> Unit) {
50+
val spec = DialogSpec(
51+
message = "로그인이 필요한 기능입니다.\n로그인 해주세요.",
52+
confirmLabel = "로그인 하기",
53+
onConfirm = onConfirm,
54+
dismissLabel = "닫기",
55+
)
56+
57+
EventHelper.sendEvent(event = ReedEvent.ShowDialog(spec))
58+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.ninecraft.booket.core.common.event
2+
3+
data class DialogSpec(
4+
val message: String,
5+
val confirmLabel: String,
6+
val onConfirm: () -> Unit,
7+
val title: String? = null,
8+
val dismissLabel: String? = null,
9+
val onDismissRequest: () -> Unit = {},
10+
)

core/common/src/main/kotlin/com/ninecraft/booket/core/common/event/ErrorEventHelper.kt

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.ninecraft.booket.core.common.event
2+
3+
import kotlinx.coroutines.channels.Channel
4+
import kotlinx.coroutines.flow.receiveAsFlow
5+
6+
object EventHelper {
7+
private val _eventFlow = Channel<ReedEvent>(Channel.BUFFERED)
8+
val eventFlow = _eventFlow.receiveAsFlow()
9+
10+
fun sendEvent(event: ReedEvent) {
11+
_eventFlow.trySend(event)
12+
}
13+
}
14+
15+
sealed interface ReedEvent {
16+
data class ShowDialog(val spec: DialogSpec) : ReedEvent
17+
}

core/common/src/main/kotlin/com/ninecraft/booket/core/common/utils/HandleException.kt

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package com.ninecraft.booket.core.common.utils
22

3-
import androidx.annotation.StringRes
4-
import com.ninecraft.booket.core.common.R
5-
import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
63
import com.ninecraft.booket.core.common.constants.ErrorScope
7-
import com.ninecraft.booket.core.common.event.ErrorEvent
8-
import com.ninecraft.booket.core.common.event.ErrorEventHelper
4+
import com.ninecraft.booket.core.common.event.postErrorDialog
95
import com.ninecraft.booket.core.network.response.ErrorResponse
106
import com.orhanobut.logger.Logger
117
import kotlinx.serialization.SerializationException
@@ -26,7 +22,7 @@ fun handleException(
2622
postErrorDialog(
2723
errorScope = ErrorScope.AUTH_SESSION_EXPIRED,
2824
exception = exception,
29-
action = {
25+
onConfirm = {
3026
onLoginRequired()
3127
},
3228
)
@@ -51,48 +47,6 @@ fun handleException(
5147
}
5248
}
5349

54-
fun postErrorDialog(
55-
errorScope: ErrorScope,
56-
exception: Throwable,
57-
@StringRes buttonLabelResId: Int = R.string.confirm,
58-
action: () -> Unit = {},
59-
) {
60-
val (title, message) = when {
61-
exception.isNetworkError() -> {
62-
null to "네트워크 연결이 불안정합니다.\n인터넷 연결을 확인해주세요"
63-
}
64-
65-
exception is HttpException -> {
66-
when (errorScope) {
67-
ErrorScope.GLOBAL -> {
68-
null to "알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
69-
}
70-
71-
ErrorScope.LOGIN -> {
72-
"로그인 오류" to "예기치 않은 오류가 발생했습니다.\n다시 로그인 해주세요."
73-
}
74-
75-
ErrorScope.AUTH_SESSION_EXPIRED -> {
76-
null to "세션이 만료되었어요.\n다시 로그인 해주세요"
77-
}
78-
}
79-
}
80-
81-
else -> {
82-
null to "알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
83-
}
84-
}
85-
86-
val spec = ErrorDialogSpec(
87-
title = title,
88-
message = message,
89-
buttonLabelResId = buttonLabelResId,
90-
action = action,
91-
)
92-
93-
ErrorEventHelper.sendError(event = ErrorEvent.ShowDialog(spec))
94-
}
95-
9650
private fun HttpException.parseErrorMessage(): String? {
9751
return try {
9852
val errorBody = response()?.errorBody()?.string()

feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import androidx.compose.runtime.mutableStateOf
77
import androidx.compose.runtime.rememberCoroutineScope
88
import androidx.compose.runtime.setValue
99
import com.ninecraft.booket.core.common.analytics.AnalyticsHelper
10-
import com.ninecraft.booket.core.common.utils.UiText
10+
import com.ninecraft.booket.core.common.event.postLoginRequiredDialog
1111
import com.ninecraft.booket.core.common.utils.handleException
1212
import com.ninecraft.booket.core.data.api.repository.AuthRepository
1313
import com.ninecraft.booket.core.data.api.repository.BookRepository
@@ -35,7 +35,6 @@ import dagger.hilt.android.components.ActivityRetainedComponent
3535
import kotlinx.collections.immutable.persistentListOf
3636
import kotlinx.collections.immutable.toPersistentList
3737
import kotlinx.coroutines.launch
38-
import com.ninecraft.booket.core.designsystem.R as designR
3938

4039
class LibraryPresenter @AssistedInject constructor(
4140
@Assisted private val navigator: Navigator,
@@ -127,10 +126,13 @@ class LibraryPresenter @AssistedInject constructor(
127126

128127
is LibraryUiEvent.OnLibrarySearchClick -> {
129128
if (userState is UserState.Guest) {
130-
scope.launch {
131-
sideEffect = LibrarySideEffect.ShowToast(UiText.StringResource(designR.string.login_required))
132-
navigator.redirectToLogin()
133-
}
129+
postLoginRequiredDialog(
130+
onConfirm = {
131+
scope.launch {
132+
navigator.redirectToLogin()
133+
}
134+
},
135+
)
134136
} else {
135137
navigator.goTo(LibrarySearchScreen)
136138
}

feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import androidx.compose.runtime.rememberCoroutineScope
77
import androidx.compose.runtime.setValue
88
import com.ninecraft.booket.core.common.analytics.AnalyticsHelper
99
import com.ninecraft.booket.core.common.constants.ErrorScope
10-
import com.ninecraft.booket.core.common.utils.postErrorDialog
10+
import com.ninecraft.booket.core.common.event.postErrorDialog
1111
import com.ninecraft.booket.core.data.api.repository.AuthRepository
1212
import com.ninecraft.booket.core.data.api.repository.UserRepository
1313
import com.ninecraft.booket.feature.screens.HomeScreen

feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ import androidx.compose.runtime.mutableStateOf
1111
import androidx.compose.runtime.remember
1212
import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.graphics.Color
14-
import androidx.compose.ui.res.stringResource
1514
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
16-
import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
17-
import com.ninecraft.booket.core.common.event.ErrorEvent
18-
import com.ninecraft.booket.core.common.event.ErrorEventHelper
15+
import com.ninecraft.booket.core.common.event.DialogSpec
16+
import com.ninecraft.booket.core.common.event.EventHelper
17+
import com.ninecraft.booket.core.common.event.ReedEvent
1918
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
2019
import com.ninecraft.booket.core.ui.component.ReedDialog
2120
import com.ninecraft.booket.feature.screens.SplashScreen
@@ -55,13 +54,13 @@ class MainActivity : ComponentActivity() {
5554
val backStack = rememberSaveableBackStack(root = SplashScreen)
5655
val navigator = rememberCircuitNavigator(backStack)
5756

58-
val dialogSpec = remember { mutableStateOf<ErrorDialogSpec?>(null) }
57+
val dialogSpec = remember { mutableStateOf<DialogSpec?>(null) }
5958

60-
// 전역 에러 수신
59+
// 전역 이벤트 수신
6160
LaunchedEffect(Unit) {
62-
ErrorEventHelper.errorEvent.collect { event ->
61+
EventHelper.eventFlow.collect { event ->
6362
when (event) {
64-
is ErrorEvent.ShowDialog -> {
63+
is ReedEvent.ShowDialog -> {
6564
dialogSpec.value = event.spec
6665
}
6766
}
@@ -72,10 +71,10 @@ class MainActivity : ComponentActivity() {
7271
ReedDialog(
7372
title = spec.title,
7473
description = spec.message,
75-
confirmButtonText = stringResource(spec.buttonLabelResId),
76-
74+
confirmButtonText = spec.confirmLabel,
75+
dismissButtonText = spec.dismissLabel,
7776
onConfirmRequest = {
78-
spec.action()
77+
spec.onConfirm()
7978
dialogSpec.value = null
8079
},
8180
onDismissRequest = {

feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import androidx.compose.runtime.rememberCoroutineScope
1010
import androidx.compose.runtime.setValue
1111
import com.ninecraft.booket.core.common.analytics.AnalyticsHelper
1212
import com.ninecraft.booket.core.common.constants.BookStatus
13+
import com.ninecraft.booket.core.common.event.postLoginRequiredDialog
1314
import com.ninecraft.booket.core.common.utils.UiText
1415
import com.ninecraft.booket.core.common.utils.handleException
1516
import com.ninecraft.booket.core.data.api.repository.AuthRepository
@@ -38,7 +39,6 @@ import kotlinx.collections.immutable.persistentListOf
3839
import kotlinx.collections.immutable.toImmutableList
3940
import kotlinx.collections.immutable.toPersistentList
4041
import kotlinx.coroutines.launch
41-
import com.ninecraft.booket.core.designsystem.R as designR
4242

4343
class BookSearchPresenter @AssistedInject constructor(
4444
@Assisted private val navigator: Navigator,
@@ -120,13 +120,18 @@ class BookSearchPresenter @AssistedInject constructor(
120120
}
121121

122122
fun upsertBook(isbn13: String, bookStatus: String) {
123-
scope.launch {
124-
if (userState is UserState.Guest) {
125-
sideEffect = BookSearchSideEffect.ShowToast(UiText.StringResource(designR.string.login_required))
126-
navigator.redirectToLogin()
127-
return@launch
128-
}
123+
if (userState is UserState.Guest) {
124+
postLoginRequiredDialog(
125+
onConfirm = {
126+
scope.launch {
127+
navigator.redirectToLogin()
128+
}
129+
},
130+
)
131+
return
132+
}
129133

134+
scope.launch {
130135
repository.upsertBook(isbn13, bookStatus)
131136
.onSuccess {
132137
registeredUserBookId = it.userBookId

0 commit comments

Comments
 (0)