Skip to content

Commit 7f50726

Browse files
authored
Merge pull request #89 from YAPP-Github/feature/jaino/#63
#63 : 알림 설정 기능 구현
2 parents e8ae3a1 + 527a730 commit 7f50726

File tree

13 files changed

+251
-22
lines changed

13 files changed

+251
-22
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.bff.wespot.model.user.response
2+
3+
data class NotificationSetting(
4+
val isEnableVoteNotification: Boolean,
5+
val isEnableMessageNotification: Boolean,
6+
val isEnableMarketingNotification: Boolean,
7+
) {
8+
constructor() : this(false, false, false)
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.bff.wespot.data.remote.model.user.response
2+
3+
import com.bff.wespot.model.user.response.NotificationSetting
4+
import kotlinx.serialization.Serializable
5+
6+
@Serializable
7+
data class NotificationSettingDto (
8+
val isEnableVoteNotification: Boolean,
9+
val isEnableMessageNotification: Boolean,
10+
val isEnableMarketingNotification: Boolean,
11+
) {
12+
fun toNotificationSetting(): NotificationSetting = NotificationSetting(
13+
isEnableVoteNotification = isEnableVoteNotification,
14+
isEnableMessageNotification = isEnableMessageNotification,
15+
isEnableMarketingNotification = isEnableMarketingNotification,
16+
)
17+
}

data-remote/src/main/kotlin/com/bff/wespot/data/remote/source/user/UserDataSource.kt

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bff.wespot.data.remote.source.user
22

3+
import com.bff.wespot.data.remote.model.user.response.NotificationSettingDto
34
import com.bff.wespot.data.remote.model.user.request.IntroductionDto
45
import com.bff.wespot.data.remote.model.user.response.ProfileCharacterDto
56
import com.bff.wespot.data.remote.model.user.response.UserListDto
@@ -10,6 +11,10 @@ interface UserDataSource {
1011

1112
suspend fun getProfile(): Result<ProfileDto>
1213

14+
suspend fun getNotificationSetting(): Result<NotificationSettingDto>
15+
16+
suspend fun updateNotificationSetting(notificationSetting: NotificationSettingDto): Result<Unit>
17+
1318
suspend fun updateIntroduction(introduction: IntroductionDto): Result<Unit>
1419

1520
suspend fun updateCharacter(character: ProfileCharacterDto): Result<Unit>

data-remote/src/main/kotlin/com/bff/wespot/data/remote/source/user/UserDataSourceImpl.kt

+20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bff.wespot.data.remote.source.user
22

3+
import com.bff.wespot.data.remote.model.user.response.NotificationSettingDto
34
import com.bff.wespot.data.remote.model.user.request.IntroductionDto
45
import com.bff.wespot.data.remote.model.user.response.ProfileCharacterDto
56
import com.bff.wespot.network.extensions.safeRequest
@@ -33,6 +34,25 @@ class UserDataSourceImpl @Inject constructor(
3334
}
3435
}
3536

37+
override suspend fun getNotificationSetting(): Result<NotificationSettingDto> =
38+
httpClient.safeRequest {
39+
url {
40+
method = HttpMethod.Get
41+
path("users/settings")
42+
}
43+
}
44+
45+
override suspend fun updateNotificationSetting(
46+
notificationSetting: NotificationSettingDto,
47+
): Result<Unit> =
48+
httpClient.safeRequest {
49+
url {
50+
method = HttpMethod.Put
51+
path("users/settings")
52+
}
53+
setBody(notificationSetting)
54+
}
55+
3656
override suspend fun updateIntroduction(introduction: IntroductionDto): Result<Unit> =
3757
httpClient.safeRequest {
3858
url {

data/src/main/kotlin/com/bff/wespot/data/mapper/user/UserMapper.kt

+8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
package com.bff.wespot.data.mapper.user
22

3+
import com.bff.wespot.data.remote.model.user.response.NotificationSettingDto
4+
import com.bff.wespot.model.user.response.NotificationSetting
35
import com.bff.wespot.data.remote.model.user.response.ProfileCharacterDto
46
import com.bff.wespot.model.user.response.ProfileCharacter
57

8+
internal fun NotificationSetting.toNotificationSettingDto() = NotificationSettingDto(
9+
isEnableVoteNotification = isEnableVoteNotification,
10+
isEnableMessageNotification = isEnableMessageNotification,
11+
isEnableMarketingNotification = isEnableMarketingNotification,
12+
)
13+
614
internal fun ProfileCharacter.toProfileCharacterDto() = ProfileCharacterDto(
715
iconUrl = iconUrl,
816
backgroundColor = backgroundColor,

data/src/main/kotlin/com/bff/wespot/data/repository/user/UserRepositoryImpl.kt

+10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.bff.wespot.data.repository.user
22

3+
import com.bff.wespot.data.mapper.user.toNotificationSettingDto
34
import com.bff.wespot.data.mapper.user.toProfileCharacterDto
45
import com.bff.wespot.data.remote.model.user.request.IntroductionDto
56
import com.bff.wespot.data.remote.source.user.UserDataSource
67
import com.bff.wespot.domain.repository.user.UserRepository
8+
import com.bff.wespot.model.user.response.NotificationSetting
79
import com.bff.wespot.model.user.response.Profile
810
import com.bff.wespot.model.user.response.ProfileCharacter
911
import com.bff.wespot.model.user.response.User
@@ -24,6 +26,14 @@ class UserRepositoryImpl @Inject constructor(
2426
profileDto.toProfile()
2527
}
2628

29+
override suspend fun getNotificationSetting(): Result<NotificationSetting> =
30+
userDataSource.getNotificationSetting().mapCatching { it.toNotificationSetting() }
31+
32+
override suspend fun updateNotificationSetting(
33+
notificationSetting: NotificationSetting,
34+
): Result<Unit> =
35+
userDataSource.updateNotificationSetting(notificationSetting.toNotificationSettingDto())
36+
2737
override suspend fun updateIntroduction(introduction: String): Result<Unit> =
2838
userDataSource.updateIntroduction(introduction = IntroductionDto(introduction))
2939

domain/src/main/kotlin/com/bff/wespot/domain/repository/user/UserRepository.kt

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bff.wespot.domain.repository.user
22

3+
import com.bff.wespot.model.user.response.NotificationSetting
34
import com.bff.wespot.model.user.response.Profile
45
import com.bff.wespot.model.user.response.ProfileCharacter
56
import com.bff.wespot.model.user.response.User
@@ -9,6 +10,10 @@ interface UserRepository {
910

1011
suspend fun getProfile(): Result<Profile>
1112

13+
suspend fun getNotificationSetting(): Result<NotificationSetting>
14+
15+
suspend fun updateNotificationSetting(notificationSetting: NotificationSetting): Result<Unit>
16+
1217
suspend fun updateIntroduction(introduction: String): Result<Unit>
1318

1419
suspend fun updateCharacter(character: ProfileCharacter): Result<Unit>

feature/entire/src/main/java/com/bff/wespot/entire/screen/setting/NotificationSettingScreen.kt

+48-8
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,35 @@
11
package com.bff.wespot.entire.screen.screen.setting
22

33
import androidx.compose.foundation.layout.Arrangement
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.fillMaxSize
78
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.material3.CircularProgressIndicator
810
import androidx.compose.material3.ExperimentalMaterial3Api
911
import androidx.compose.material3.Scaffold
1012
import androidx.compose.material3.Text
1113
import androidx.compose.runtime.Composable
14+
import androidx.compose.runtime.LaunchedEffect
15+
import androidx.compose.runtime.getValue
1216
import androidx.compose.ui.Alignment
1317
import androidx.compose.ui.Modifier
1418
import androidx.compose.ui.res.stringResource
1519
import androidx.compose.ui.unit.dp
20+
import androidx.hilt.navigation.compose.hiltViewModel
21+
import androidx.lifecycle.Lifecycle
1622
import com.bff.wespot.designsystem.component.header.WSTopBar
1723
import com.bff.wespot.designsystem.component.toggle.WSSwitch
1824
import com.bff.wespot.designsystem.theme.Gray400
1925
import com.bff.wespot.designsystem.theme.StaticTypeScale
2026
import com.bff.wespot.designsystem.theme.WeSpotThemeManager
2127
import com.bff.wespot.entire.R
28+
import com.bff.wespot.entire.screen.state.notification.NotificationSettingAction
29+
import com.bff.wespot.entire.viewmodel.NotificationSettingViewModel
30+
import com.bff.wespot.util.OnLifecycleEvent
2231
import com.ramcosta.composedestinations.annotation.Destination
32+
import org.orbitmvi.orbit.compose.collectAsState
2333

2434
interface NotificationSettingNavigator {
2535
fun navigateUp()
@@ -30,7 +40,18 @@ interface NotificationSettingNavigator {
3040
@Destination
3141
fun NotificationSettingScreen(
3242
navigator: NotificationSettingNavigator,
43+
viewModel: NotificationSettingViewModel = hiltViewModel(),
3344
) {
45+
val action = viewModel::onAction
46+
val state by viewModel.collectAsState()
47+
48+
if (state.isLoading) {
49+
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
50+
CircularProgressIndicator()
51+
}
52+
return
53+
}
54+
3455
Scaffold(
3556
topBar = {
3657
WSTopBar(
@@ -50,33 +71,52 @@ fun NotificationSettingScreen(
5071
NotificationSettingItem(
5172
title = stringResource(R.string.vote),
5273
subTitle = stringResource(R.string.vote_notification_title),
53-
switchValue = true,
54-
onToggled = { },
74+
switchValue = state.isEnableVoteNotification,
75+
onSwitched = {
76+
action(NotificationSettingAction.OnVoteNotificationSwitched)
77+
},
5578
)
5679

5780
NotificationSettingItem(
5881
title = stringResource(R.string.message),
5982
subTitle = stringResource(R.string.message_notification_title),
60-
switchValue = true,
61-
onToggled = { },
83+
switchValue = state.isEnableMessageNotification,
84+
onSwitched = {
85+
action(NotificationSettingAction.OnMessageNotificationSwitched)
86+
},
6287
)
6388

6489
NotificationSettingItem(
6590
title = stringResource(R.string.event_benefit),
6691
subTitle = stringResource(R.string.event_benefit_notification_title),
67-
switchValue = false,
68-
onToggled = { },
92+
switchValue = state.isEnableMarketingNotification,
93+
onSwitched = {
94+
action(NotificationSettingAction.OnEventNotificationSwitched)
95+
},
6996
)
7097
}
7198
}
99+
100+
OnLifecycleEvent { _, event ->
101+
when (event) {
102+
Lifecycle.Event.ON_PAUSE -> {
103+
action(NotificationSettingAction.OnNotificationSettingScreenExited)
104+
}
105+
else -> { }
106+
}
107+
}
108+
109+
LaunchedEffect(Unit) {
110+
action(NotificationSettingAction.OnNotificationSettingScreenEntered)
111+
}
72112
}
73113

74114
@Composable
75115
fun NotificationSettingItem(
76116
title: String,
77117
subTitle: String,
78118
switchValue: Boolean,
79-
onToggled: (Boolean) -> Unit,
119+
onSwitched: (Boolean) -> Unit,
80120
) {
81121
Row(
82122
verticalAlignment = Alignment.CenterVertically,
@@ -101,7 +141,7 @@ fun NotificationSettingItem(
101141

102142
WSSwitch(
103143
checked = switchValue,
104-
onCheckedChange = onToggled,
144+
onCheckedChange = onSwitched,
105145
)
106146
}
107147
}

feature/entire/src/main/java/com/bff/wespot/entire/screen/setting/SettingScreen.kt

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
package com.bff.wespot.entire.screen.screen.setting
22

3-
import androidx.compose.foundation.clickable
43
import androidx.compose.foundation.layout.Arrangement
54
import androidx.compose.foundation.layout.Column
65
import androidx.compose.foundation.layout.fillMaxSize
76
import androidx.compose.foundation.layout.fillMaxWidth
87
import androidx.compose.foundation.layout.padding
98
import androidx.compose.material3.ExperimentalMaterial3Api
109
import androidx.compose.material3.HorizontalDivider
11-
import androidx.compose.material3.Icon
1210
import androidx.compose.material3.Scaffold
1311
import androidx.compose.runtime.Composable
1412
import androidx.compose.ui.Modifier
15-
import androidx.compose.ui.graphics.vector.ImageVector
1613
import androidx.compose.ui.res.stringResource
17-
import androidx.compose.ui.res.vectorResource
1814
import androidx.compose.ui.unit.dp
1915
import com.bff.wespot.designsystem.component.header.WSTopBar
2016
import com.bff.wespot.designsystem.theme.WeSpotThemeManager
@@ -41,16 +37,6 @@ fun SettingScreen(
4137
title = "",
4238
canNavigateBack = true,
4339
navigateUp = { navigator.navigateUp() },
44-
action = {
45-
Icon(
46-
modifier = Modifier
47-
.padding(end = 16.dp)
48-
.clickable { navigator.navigateToNotificationSetting() },
49-
imageVector = ImageVector.vectorResource(R.drawable.ic_setting),
50-
contentDescription = stringResource(R.string.setting_icon),
51-
tint = WeSpotThemeManager.colors.secondaryBtnColor,
52-
)
53-
},
5440
)
5541
},
5642
) {
@@ -62,6 +48,7 @@ fun SettingScreen(
6248
verticalArrangement = Arrangement.spacedBy(24.dp),
6349
) {
6450
EntireListItem(text = stringResource(R.string.notification_setting)) {
51+
navigator.navigateToNotificationSetting()
6552
}
6653

6754
HorizontalDivider(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.bff.wespot.entire.screen.state.notification
2+
3+
sealed class NotificationSettingAction {
4+
data object OnNotificationSettingScreenEntered : NotificationSettingAction()
5+
data object OnNotificationSettingScreenExited : NotificationSettingAction()
6+
data object OnVoteNotificationSwitched : NotificationSettingAction()
7+
data object OnMessageNotificationSwitched : NotificationSettingAction()
8+
data object OnEventNotificationSwitched : NotificationSettingAction()
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.bff.wespot.entire.screen.state.notification
2+
3+
sealed class NotificationSettingSideEffect
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.bff.wespot.entire.screen.state.notification
2+
3+
import com.bff.wespot.model.user.response.NotificationSetting
4+
5+
data class NotificationSettingUiState(
6+
val isLoading: Boolean = false,
7+
val hasScreenBeenEntered: Boolean = false,
8+
val initialNotificationSetting: NotificationSetting = NotificationSetting(),
9+
val isEnableVoteNotification: Boolean = false,
10+
val isEnableMessageNotification: Boolean = false,
11+
val isEnableMarketingNotification: Boolean = false,
12+
)

0 commit comments

Comments
 (0)