Skip to content

Commit 7ff3078

Browse files
committed
feat: Require login for guest keyword features
Guest users are now prompted to log in when attempting to use keyword-related features like notification toggling, adding keywords, or interacting with suggested keywords. This change leverages the existing LoginDialog component to guide users towards authentication for these functionalities.
1 parent 4d3e86b commit 7ff3078

5 files changed

Lines changed: 57 additions & 5 deletions

File tree

feature/lostandfound/src/main/java/in/koreatech/koin/feature/lostandfound/navigation/Navigation.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,19 @@ fun NavGraphBuilder.koinLostAndFoundGraph(
146146
}
147147

148148
composable<LostAndFoundNavType.LostAndFoundKeywordRoute> {
149+
val navigator = rememberNavigator()
150+
val context = LocalContext.current
149151
LostAndFoundKeyword(
150152
viewModel = hiltViewModel(),
151-
onBackClick = { navController.popBackStack() }
153+
onBackClick = { navController.popBackStack() },
154+
navigateToLogin = {
155+
navigator.navigateToSignIn(
156+
context = context,
157+
redirectUrl = DEEP_LINK_LOST_AND_FOUND_BASE
158+
).apply {
159+
context.startActivity(this)
160+
}
161+
}
152162
)
153163
}
154164
}

feature/lostandfound/src/main/java/in/koreatech/koin/feature/lostandfound/ui/keyword/LostAndFoundKeyword.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import `in`.koreatech.koin.core.designsystem.theme.KoinTheme
5757
import `in`.koreatech.koin.feature.lostandfound.R
5858
import `in`.koreatech.koin.feature.lostandfound.component.LostAndFoundAddableChipFlowGroup
5959
import `in`.koreatech.koin.feature.lostandfound.component.LostAndFoundDeletableChipFlowGroup
60+
import `in`.koreatech.koin.feature.lostandfound.ui.list.component.LoginDialog
6061
import kotlinx.collections.immutable.ImmutableList
6162
import kotlinx.collections.immutable.persistentListOf
6263
import kotlinx.collections.immutable.toPersistentList
@@ -69,6 +70,7 @@ private val ButtonShape = RoundedCornerShape(4.dp)
6970
@Composable
7071
fun LostAndFoundKeyword(
7172
onBackClick: () -> Unit,
73+
navigateToLogin: () -> Unit,
7274
modifier: Modifier = Modifier,
7375
viewModel: LostAndFoundKeywordViewModel = hiltViewModel()
7476
) {
@@ -92,6 +94,19 @@ fun LostAndFoundKeyword(
9294
onBackClick()
9395
}
9496

97+
// 비로그인 다이얼로그
98+
if (uiState.showLoginDialog) {
99+
LoginDialog(
100+
title = stringResource(R.string.recommend_login_to_get_keyword_notification_title),
101+
description = stringResource(R.string.recommend_login_to_get_keyword_notification_message),
102+
onPositive = {
103+
navigateToLogin()
104+
viewModel.dismissLoginDialog()
105+
},
106+
onNegative = viewModel::dismissLoginDialog
107+
)
108+
}
109+
95110
// Article keyword 화면처럼, 이미 등록된 키워드는 추천 키워드에서 제거
96111
val availableSuggestions by remember {
97112
derivedStateOf {

feature/lostandfound/src/main/java/in/koreatech/koin/feature/lostandfound/ui/keyword/LostAndFoundKeywordState.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ data class LostAndFoundKeywordState(
1010
val keywordInput: String = "",
1111
val isNotificationEnabled: Boolean = false,
1212
val isLoading: Boolean = false,
13-
val suggestedKeywords: ImmutableList<String> = persistentListOf()
13+
val suggestedKeywords: ImmutableList<String> = persistentListOf(),
14+
val isLoggedIn: Boolean = false,
15+
val showLoginDialog: Boolean = false
1416
)

feature/lostandfound/src/main/java/in/koreatech/koin/feature/lostandfound/ui/keyword/LostAndFoundKeywordViewModel.kt

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import `in`.koreatech.koin.domain.usecase.article.lostandfound.SaveLostItemKeywo
1010
import `in`.koreatech.koin.domain.usecase.notification.DeleteNotificationSubscriptionUseCase
1111
import `in`.koreatech.koin.domain.usecase.notification.GetNotificationPermissionInfoUseCase
1212
import `in`.koreatech.koin.domain.usecase.notification.UpdateNotificationSubscriptionUseCase
13+
import `in`.koreatech.koin.domain.usecase.user.GetUserStatusUseCase
1314
import `in`.koreatech.koin.feature.lostandfound.R
1415
import javax.inject.Inject
1516
import kotlinx.collections.immutable.persistentListOf
@@ -24,7 +25,7 @@ import org.orbitmvi.orbit.syntax.simple.repeatOnSubscription
2425
import org.orbitmvi.orbit.viewmodel.container
2526
import timber.log.Timber
2627

27-
@Suppress("LongParameterList")
28+
@Suppress("LongParameterList", "TooManyFunctions")
2829
@HiltViewModel
2930
class LostAndFoundKeywordViewModel @Inject constructor(
3031
private val fetchLostItemKeywordUseCase: FetchLostItemKeywordUseCase,
@@ -33,19 +34,31 @@ class LostAndFoundKeywordViewModel @Inject constructor(
3334
private val fetchLostItemKeywordSuggestionsUseCase: FetchLostItemKeywordSuggestionsUseCase,
3435
private val updateNotificationSubscriptionUseCase: UpdateNotificationSubscriptionUseCase,
3536
private val deleteNotificationSubscriptionUseCase: DeleteNotificationSubscriptionUseCase,
36-
private val getNotificationPermissionInfoUseCase: GetNotificationPermissionInfoUseCase
37+
private val getNotificationPermissionInfoUseCase: GetNotificationPermissionInfoUseCase,
38+
private val getUserStatusUseCase: GetUserStatusUseCase
3739
) : ViewModel(), ContainerHost<LostAndFoundKeywordState, LostAndFoundKeywordSideEffect> {
3840

3941
override val container = container<LostAndFoundKeywordState, LostAndFoundKeywordSideEffect>(
4042
LostAndFoundKeywordState()
4143
)
4244

4345
init {
46+
observeUserStatus()
4447
observeKeywords()
4548
fetchSuggestedKeywords()
4649
loadNotificationState()
4750
}
4851

52+
private fun observeUserStatus() = intent {
53+
repeatOnSubscription {
54+
getUserStatusUseCase()
55+
.catch { reduce { state.copy(isLoggedIn = false) } }
56+
.collect { user ->
57+
reduce { state.copy(isLoggedIn = !user.isAnonymous) }
58+
}
59+
}
60+
}
61+
4962
private fun observeKeywords() = intent {
5063
repeatOnSubscription {
5164
fetchLostItemKeywordUseCase()
@@ -86,6 +99,10 @@ class LostAndFoundKeywordViewModel @Inject constructor(
8699

87100
fun addKeyword(keyword: String) {
88101
intent {
102+
if (!state.isLoggedIn) {
103+
reduce { state.copy(showLoginDialog = true) }
104+
return@intent
105+
}
89106
if (state.isLoading) return@intent
90107

91108
val validationError = validateKeyword(keyword)
@@ -132,6 +149,10 @@ class LostAndFoundKeywordViewModel @Inject constructor(
132149

133150
fun toggleNotification(isEnabled: Boolean) {
134151
intent {
152+
if (!state.isLoggedIn) {
153+
reduce { state.copy(showLoginDialog = true) }
154+
return@intent
155+
}
135156
if (state.isLoading) return@intent
136157

137158
reduce { state.copy(isLoading = true, isNotificationEnabled = isEnabled) }
@@ -149,6 +170,10 @@ class LostAndFoundKeywordViewModel @Inject constructor(
149170
}
150171
}
151172

173+
fun dismissLoginDialog() = intent {
174+
reduce { state.copy(showLoginDialog = false) }
175+
}
176+
152177
private fun validateKeyword(keyword: String): Int? = when {
153178
keyword.isEmpty() -> R.string.keyword_add_require_input
154179
WHITESPACE_REGEX.containsMatchIn(keyword) -> R.string.keyword_add_blank_not_allowed

feature/lostandfound/src/main/res/values/strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
<string name="downloading">다운로드 중</string>
183183
<string name="start_download">파일을 다운로드합니다.</string>
184184
<string name="recommend_login_to_get_keyword_notification_title">키워드 알림을 받으려면\n로그인이 필요해요.</string>
185-
<string name="recommend_login_to_get_keyword_notification_message">로그인 후 간편하게 공지사항 키워드\n알림을 받아보세요!</string>
185+
<string name="recommend_login_to_get_keyword_notification_message">로그인 후 간편하게 분실물 키워드\n알림을 받아보세요!</string>
186186
<string name="title_article">게시판</string>
187187
<string name="navigation_title_article">공지사항</string>
188188
<string name="navigation_title_article_search">공지글 검색</string>

0 commit comments

Comments
 (0)