Add notification setting to enable/disable being notified for room invite (#1944)
This commit is contained in:
parent
43775c38d6
commit
c0dac24a60
10 changed files with 75 additions and 6 deletions
|
|
@ -17,11 +17,11 @@
|
||||||
package io.element.android.features.preferences.impl.notifications
|
package io.element.android.features.preferences.impl.notifications
|
||||||
|
|
||||||
sealed interface NotificationSettingsEvents {
|
sealed interface NotificationSettingsEvents {
|
||||||
|
|
||||||
data object RefreshSystemNotificationsEnabled : NotificationSettingsEvents
|
data object RefreshSystemNotificationsEnabled : NotificationSettingsEvents
|
||||||
data class SetNotificationsEnabled(val enabled: Boolean) : NotificationSettingsEvents
|
data class SetNotificationsEnabled(val enabled: Boolean) : NotificationSettingsEvents
|
||||||
data class SetAtRoomNotificationsEnabled(val enabled: Boolean) : NotificationSettingsEvents
|
data class SetAtRoomNotificationsEnabled(val enabled: Boolean) : NotificationSettingsEvents
|
||||||
data class SetCallNotificationsEnabled(val enabled: Boolean) : NotificationSettingsEvents
|
data class SetCallNotificationsEnabled(val enabled: Boolean) : NotificationSettingsEvents
|
||||||
|
data class SetInviteForMeNotificationsEnabled(val enabled: Boolean) : NotificationSettingsEvents
|
||||||
data object FixConfigurationMismatch : NotificationSettingsEvents
|
data object FixConfigurationMismatch : NotificationSettingsEvents
|
||||||
data object ClearConfigurationMismatchError : NotificationSettingsEvents
|
data object ClearConfigurationMismatchError : NotificationSettingsEvents
|
||||||
data object ClearNotificationChangeError : NotificationSettingsEvents
|
data object ClearNotificationChangeError : NotificationSettingsEvents
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@ class NotificationSettingsPresenter @Inject constructor(
|
||||||
is NotificationSettingsEvents.SetCallNotificationsEnabled -> {
|
is NotificationSettingsEvents.SetCallNotificationsEnabled -> {
|
||||||
localCoroutineScope.setCallNotificationsEnabled(event.enabled, changeNotificationSettingAction)
|
localCoroutineScope.setCallNotificationsEnabled(event.enabled, changeNotificationSettingAction)
|
||||||
}
|
}
|
||||||
|
is NotificationSettingsEvents.SetInviteForMeNotificationsEnabled -> {
|
||||||
|
localCoroutineScope.setInviteForMeNotificationsEnabled(event.enabled, changeNotificationSettingAction)
|
||||||
|
}
|
||||||
is NotificationSettingsEvents.SetNotificationsEnabled -> localCoroutineScope.setNotificationsEnabled(userPushStore, event.enabled)
|
is NotificationSettingsEvents.SetNotificationsEnabled -> localCoroutineScope.setNotificationsEnabled(userPushStore, event.enabled)
|
||||||
NotificationSettingsEvents.ClearConfigurationMismatchError -> {
|
NotificationSettingsEvents.ClearConfigurationMismatchError -> {
|
||||||
matrixSettings.value = NotificationSettingsState.MatrixSettings.Invalid(fixFailed = false)
|
matrixSettings.value = NotificationSettingsState.MatrixSettings.Invalid(fixFailed = false)
|
||||||
|
|
@ -123,10 +126,12 @@ class NotificationSettingsPresenter @Inject constructor(
|
||||||
|
|
||||||
val callNotificationsEnabled = notificationSettingsService.isCallEnabled().getOrThrow()
|
val callNotificationsEnabled = notificationSettingsService.isCallEnabled().getOrThrow()
|
||||||
val atRoomNotificationsEnabled = notificationSettingsService.isRoomMentionEnabled().getOrThrow()
|
val atRoomNotificationsEnabled = notificationSettingsService.isRoomMentionEnabled().getOrThrow()
|
||||||
|
val inviteForMeNotificationsEnabled = notificationSettingsService.isInviteForMeEnabled().getOrThrow()
|
||||||
|
|
||||||
target.value = NotificationSettingsState.MatrixSettings.Valid(
|
target.value = NotificationSettingsState.MatrixSettings.Valid(
|
||||||
atRoomNotificationsEnabled = atRoomNotificationsEnabled,
|
atRoomNotificationsEnabled = atRoomNotificationsEnabled,
|
||||||
callNotificationsEnabled = callNotificationsEnabled,
|
callNotificationsEnabled = callNotificationsEnabled,
|
||||||
|
inviteForMeNotificationsEnabled = inviteForMeNotificationsEnabled,
|
||||||
defaultGroupNotificationMode = encryptedGroupDefaultMode,
|
defaultGroupNotificationMode = encryptedGroupDefaultMode,
|
||||||
defaultOneToOneNotificationMode = encryptedOneToOneDefaultMode,
|
defaultOneToOneNotificationMode = encryptedOneToOneDefaultMode,
|
||||||
)
|
)
|
||||||
|
|
@ -175,6 +180,12 @@ class NotificationSettingsPresenter @Inject constructor(
|
||||||
}.runCatchingUpdatingState(action)
|
}.runCatchingUpdatingState(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun CoroutineScope.setInviteForMeNotificationsEnabled(enabled: Boolean, action: MutableState<Async<Unit>>) = launch {
|
||||||
|
suspend {
|
||||||
|
notificationSettingsService.setInviteForMeEnabled(enabled).getOrThrow()
|
||||||
|
}.runCatchingUpdatingState(action)
|
||||||
|
}
|
||||||
|
|
||||||
private fun CoroutineScope.setNotificationsEnabled(userPushStore: UserPushStore, enabled: Boolean) = launch {
|
private fun CoroutineScope.setNotificationsEnabled(userPushStore: UserPushStore, enabled: Boolean) = launch {
|
||||||
userPushStore.setNotificationEnabledForDevice(enabled)
|
userPushStore.setNotificationEnabledForDevice(enabled)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ data class NotificationSettingsState(
|
||||||
data class Valid(
|
data class Valid(
|
||||||
val atRoomNotificationsEnabled: Boolean,
|
val atRoomNotificationsEnabled: Boolean,
|
||||||
val callNotificationsEnabled: Boolean,
|
val callNotificationsEnabled: Boolean,
|
||||||
|
val inviteForMeNotificationsEnabled: Boolean,
|
||||||
val defaultGroupNotificationMode: RoomNotificationMode?,
|
val defaultGroupNotificationMode: RoomNotificationMode?,
|
||||||
val defaultOneToOneNotificationMode: RoomNotificationMode?,
|
val defaultOneToOneNotificationMode: RoomNotificationMode?,
|
||||||
) : MatrixSettings
|
) : MatrixSettings
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ fun aNotificationSettingsState(
|
||||||
matrixSettings = NotificationSettingsState.MatrixSettings.Valid(
|
matrixSettings = NotificationSettingsState.MatrixSettings.Valid(
|
||||||
atRoomNotificationsEnabled = true,
|
atRoomNotificationsEnabled = true,
|
||||||
callNotificationsEnabled = true,
|
callNotificationsEnabled = true,
|
||||||
|
inviteForMeNotificationsEnabled = true,
|
||||||
defaultGroupNotificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
|
defaultGroupNotificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
|
||||||
defaultOneToOneNotificationMode = RoomNotificationMode.ALL_MESSAGES,
|
defaultOneToOneNotificationMode = RoomNotificationMode.ALL_MESSAGES,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ fun NotificationSettingsView(
|
||||||
onMentionNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetAtRoomNotificationsEnabled(it)) },
|
onMentionNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetAtRoomNotificationsEnabled(it)) },
|
||||||
// TODO We are removing the call notification toggle until support for call notifications has been added
|
// TODO We are removing the call notification toggle until support for call notifications has been added
|
||||||
// onCallsNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetCallNotificationsEnabled(it)) },
|
// onCallsNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetCallNotificationsEnabled(it)) },
|
||||||
|
onInviteForMeNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetInviteForMeNotificationsEnabled(it)) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
AsyncView(
|
AsyncView(
|
||||||
|
|
@ -98,6 +99,7 @@ private fun NotificationSettingsContentView(
|
||||||
onMentionNotificationsChanged: (Boolean) -> Unit,
|
onMentionNotificationsChanged: (Boolean) -> Unit,
|
||||||
// TODO We are removing the call notification toggle until support for call notifications has been added
|
// TODO We are removing the call notification toggle until support for call notifications has been added
|
||||||
// onCallsNotificationsChanged: (Boolean) -> Unit,
|
// onCallsNotificationsChanged: (Boolean) -> Unit,
|
||||||
|
onInviteForMeNotificationsChanged: (Boolean) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
@ -147,8 +149,8 @@ private fun NotificationSettingsContentView(
|
||||||
onCheckedChange = onMentionNotificationsChanged
|
onCheckedChange = onMentionNotificationsChanged
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// TODO We are removing the call notification toggle until support for call notifications has been added
|
PreferenceCategory(title = stringResource(id = R.string.screen_notification_settings_additional_settings_section_title)) {
|
||||||
// PreferenceCategory(title = stringResource(id = CommonStrings.screen_notification_settings_additional_settings_section_title)) {
|
// TODO We are removing the call notification toggle until support for call notifications has been added
|
||||||
// PreferenceSwitch(
|
// PreferenceSwitch(
|
||||||
// modifier = Modifier,
|
// modifier = Modifier,
|
||||||
// title = stringResource(id = CommonStrings.screen_notification_settings_calls_label),
|
// title = stringResource(id = CommonStrings.screen_notification_settings_calls_label),
|
||||||
|
|
@ -156,7 +158,14 @@ private fun NotificationSettingsContentView(
|
||||||
// switchAlignment = Alignment.Top,
|
// switchAlignment = Alignment.Top,
|
||||||
// onCheckedChange = onCallsNotificationsChanged
|
// onCheckedChange = onCallsNotificationsChanged
|
||||||
// )
|
// )
|
||||||
// }
|
PreferenceSwitch(
|
||||||
|
modifier = Modifier,
|
||||||
|
title = stringResource(id = R.string.screen_notification_settings_invite_for_me_label),
|
||||||
|
isChecked = matrixSettings.inviteForMeNotificationsEnabled,
|
||||||
|
switchAlignment = Alignment.Top,
|
||||||
|
onCheckedChange = onInviteForMeNotificationsChanged
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ If you proceed, some of your settings may change."</string>
|
||||||
<string name="screen_notification_settings_enable_notifications">"Enable notifications on this device"</string>
|
<string name="screen_notification_settings_enable_notifications">"Enable notifications on this device"</string>
|
||||||
<string name="screen_notification_settings_failed_fixing_configuration">"The configuration has not been corrected, please try again."</string>
|
<string name="screen_notification_settings_failed_fixing_configuration">"The configuration has not been corrected, please try again."</string>
|
||||||
<string name="screen_notification_settings_group_chats">"Group chats"</string>
|
<string name="screen_notification_settings_group_chats">"Group chats"</string>
|
||||||
|
<string name="screen_notification_settings_invite_for_me_label">"Invitations"</string>
|
||||||
<string name="screen_notification_settings_mentions_only_disclaimer">"Your homeserver does not support this option in encrypted rooms, you may not get notified in some rooms."</string>
|
<string name="screen_notification_settings_mentions_only_disclaimer">"Your homeserver does not support this option in encrypted rooms, you may not get notified in some rooms."</string>
|
||||||
<string name="screen_notification_settings_mentions_section_title">"Mentions"</string>
|
<string name="screen_notification_settings_mentions_section_title">"Mentions"</string>
|
||||||
<string name="screen_notification_settings_mode_all">"All"</string>
|
<string name="screen_notification_settings_mode_all">"All"</string>
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class NotificationSettingsPresenterTests {
|
||||||
val valid = loadedState.matrixSettings as? NotificationSettingsState.MatrixSettings.Valid
|
val valid = loadedState.matrixSettings as? NotificationSettingsState.MatrixSettings.Valid
|
||||||
assertThat(valid?.atRoomNotificationsEnabled).isFalse()
|
assertThat(valid?.atRoomNotificationsEnabled).isFalse()
|
||||||
assertThat(valid?.callNotificationsEnabled).isFalse()
|
assertThat(valid?.callNotificationsEnabled).isFalse()
|
||||||
|
assertThat(valid?.inviteForMeNotificationsEnabled).isFalse()
|
||||||
assertThat(valid?.defaultGroupNotificationMode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
|
assertThat(valid?.defaultGroupNotificationMode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
|
||||||
assertThat(valid?.defaultOneToOneNotificationMode).isEqualTo(RoomNotificationMode.ALL_MESSAGES)
|
assertThat(valid?.defaultOneToOneNotificationMode).isEqualTo(RoomNotificationMode.ALL_MESSAGES)
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
|
|
@ -166,6 +167,28 @@ class NotificationSettingsPresenterTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `present - set invite for me notifications enabled`() = runTest {
|
||||||
|
val presenter = createNotificationSettingsPresenter()
|
||||||
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
presenter.present()
|
||||||
|
}.test {
|
||||||
|
val loadedState = consumeItemsUntilPredicate {
|
||||||
|
(it.matrixSettings as? NotificationSettingsState.MatrixSettings.Valid)?.inviteForMeNotificationsEnabled == false
|
||||||
|
}.last()
|
||||||
|
val validMatrixState = loadedState.matrixSettings as? NotificationSettingsState.MatrixSettings.Valid
|
||||||
|
Truth.assertThat(validMatrixState?.inviteForMeNotificationsEnabled).isFalse()
|
||||||
|
|
||||||
|
loadedState.eventSink(NotificationSettingsEvents.SetInviteForMeNotificationsEnabled(true))
|
||||||
|
val updatedState = consumeItemsUntilPredicate {
|
||||||
|
(it.matrixSettings as? NotificationSettingsState.MatrixSettings.Valid)?.inviteForMeNotificationsEnabled == true
|
||||||
|
}.last()
|
||||||
|
val updatedMatrixState = updatedState.matrixSettings as? NotificationSettingsState.MatrixSettings.Valid
|
||||||
|
Truth.assertThat(updatedMatrixState?.inviteForMeNotificationsEnabled).isTrue()
|
||||||
|
cancelAndIgnoreRemainingEvents()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - set atRoom notifications enabled`() = runTest {
|
fun `present - set atRoom notifications enabled`() = runTest {
|
||||||
val presenter = createNotificationSettingsPresenter()
|
val presenter = createNotificationSettingsPresenter()
|
||||||
|
|
|
||||||
|
|
@ -38,5 +38,7 @@ interface NotificationSettingsService {
|
||||||
suspend fun setRoomMentionEnabled(enabled: Boolean): Result<Unit>
|
suspend fun setRoomMentionEnabled(enabled: Boolean): Result<Unit>
|
||||||
suspend fun isCallEnabled(): Result<Boolean>
|
suspend fun isCallEnabled(): Result<Boolean>
|
||||||
suspend fun setCallEnabled(enabled: Boolean): Result<Unit>
|
suspend fun setCallEnabled(enabled: Boolean): Result<Unit>
|
||||||
|
suspend fun isInviteForMeEnabled(): Result<Boolean>
|
||||||
|
suspend fun setInviteForMeEnabled(enabled: Boolean): Result<Unit>
|
||||||
suspend fun getRoomsWithUserDefinedRules(): Result<List<String>>
|
suspend fun getRoomsWithUserDefinedRules(): Result<List<String>>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,18 @@ class RustNotificationSettingsService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun isInviteForMeEnabled(): Result<Boolean> = withContext(dispatchers.io) {
|
||||||
|
runCatching {
|
||||||
|
notificationSettings.isInviteForMeEnabled()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setInviteForMeEnabled(enabled: Boolean): Result<Unit> = withContext(dispatchers.io) {
|
||||||
|
runCatching {
|
||||||
|
notificationSettings.setInviteForMeEnabled(enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getRoomsWithUserDefinedRules(): Result<List<String>> =
|
override suspend fun getRoomsWithUserDefinedRules(): Result<List<String>> =
|
||||||
runCatching {
|
runCatching {
|
||||||
notificationSettings.getRoomsWithUserDefinedRules(enabled = true)
|
notificationSettings.getRoomsWithUserDefinedRules(enabled = true)
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class FakeNotificationSettingsService(
|
||||||
private var roomNotificationMode: RoomNotificationMode = initialRoomMode
|
private var roomNotificationMode: RoomNotificationMode = initialRoomMode
|
||||||
private var roomNotificationModeIsDefault: Boolean = initialRoomModeIsDefault
|
private var roomNotificationModeIsDefault: Boolean = initialRoomModeIsDefault
|
||||||
private var callNotificationsEnabled = false
|
private var callNotificationsEnabled = false
|
||||||
|
private var inviteNotificationsEnabled = false
|
||||||
private var atRoomNotificationsEnabled = false
|
private var atRoomNotificationsEnabled = false
|
||||||
private var setNotificationModeError: Throwable? = null
|
private var setNotificationModeError: Throwable? = null
|
||||||
private var restoreDefaultNotificationModeError: Throwable? = null
|
private var restoreDefaultNotificationModeError: Throwable? = null
|
||||||
|
|
@ -52,7 +53,7 @@ class FakeNotificationSettingsService(
|
||||||
override suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, isOneToOne: Boolean): Result<RoomNotificationSettings> {
|
override suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, isOneToOne: Boolean): Result<RoomNotificationSettings> {
|
||||||
return Result.success(
|
return Result.success(
|
||||||
RoomNotificationSettings(
|
RoomNotificationSettings(
|
||||||
mode = if(roomNotificationModeIsDefault) defaultEncryptedGroupRoomNotificationMode else roomNotificationMode,
|
mode = if (roomNotificationModeIsDefault) defaultEncryptedGroupRoomNotificationMode else roomNotificationMode,
|
||||||
isDefault = roomNotificationModeIsDefault
|
isDefault = roomNotificationModeIsDefault
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -149,6 +150,15 @@ class FakeNotificationSettingsService(
|
||||||
return Result.success(Unit)
|
return Result.success(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun isInviteForMeEnabled(): Result<Boolean> {
|
||||||
|
return Result.success(inviteNotificationsEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setInviteForMeEnabled(enabled: Boolean): Result<Unit> {
|
||||||
|
inviteNotificationsEnabled = enabled
|
||||||
|
return Result.success(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getRoomsWithUserDefinedRules(): Result<List<String>> {
|
override suspend fun getRoomsWithUserDefinedRules(): Result<List<String>> {
|
||||||
return Result.success(if (roomNotificationModeIsDefault) listOf() else listOf(A_ROOM_ID.value))
|
return Result.success(if (roomNotificationModeIsDefault) listOf() else listOf(A_ROOM_ID.value))
|
||||||
}
|
}
|
||||||
|
|
@ -168,5 +178,4 @@ class FakeNotificationSettingsService(
|
||||||
fun givenSetDefaultNotificationModeError(throwable: Throwable?) {
|
fun givenSetDefaultNotificationModeError(throwable: Throwable?) {
|
||||||
setDefaultNotificationModeError = throwable
|
setDefaultNotificationModeError = throwable
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue