Merge pull request #8114 from vector-im/feature/fre/poll_new_push_rules
[Poll] Synchronize polls push rules with message push rules (PSG-954)
This commit is contained in:
commit
f887acd854
1
changelog.d/8007.feature
Normal file
1
changelog.d/8007.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
[Poll] Synchronize polls push rules with message push rules
|
@ -47,8 +47,36 @@ object RuleIds {
|
|||||||
const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = ".m.rule.message"
|
const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = ".m.rule.message"
|
||||||
const val RULE_ID_ENCRYPTED = ".m.rule.encrypted"
|
const val RULE_ID_ENCRYPTED = ".m.rule.encrypted"
|
||||||
|
|
||||||
|
const val RULE_ID_POLL_START_ONE_TO_ONE = ".m.rule.poll_start_one_to_one"
|
||||||
|
const val RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE = ".org.matrix.msc3930.rule.poll_start_one_to_one"
|
||||||
|
const val RULE_ID_POLL_END_ONE_TO_ONE = ".m.rule.poll_end_one_to_one"
|
||||||
|
const val RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE = ".org.matrix.msc3930.rule.poll_end_one_to_one"
|
||||||
|
|
||||||
|
const val RULE_ID_POLL_START = ".m.rule.poll_start"
|
||||||
|
const val RULE_ID_POLL_START_UNSTABLE = ".org.matrix.msc3930.rule.poll_start"
|
||||||
|
const val RULE_ID_POLL_END = ".m.rule.poll_end"
|
||||||
|
const val RULE_ID_POLL_END_UNSTABLE = ".org.matrix.msc3930.rule.poll_end"
|
||||||
|
|
||||||
// Not documented
|
// Not documented
|
||||||
const val RULE_ID_FALLBACK = ".m.rule.fallback"
|
const val RULE_ID_FALLBACK = ".m.rule.fallback"
|
||||||
|
|
||||||
const val RULE_ID_REACTION = ".m.rule.reaction"
|
const val RULE_ID_REACTION = ".m.rule.reaction"
|
||||||
|
|
||||||
|
fun getSyncedRules(ruleId: String): List<String> {
|
||||||
|
return when (ruleId) {
|
||||||
|
RULE_ID_ONE_TO_ONE_ROOM -> listOf(
|
||||||
|
RULE_ID_POLL_START_ONE_TO_ONE,
|
||||||
|
RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE,
|
||||||
|
RULE_ID_POLL_END_ONE_TO_ONE,
|
||||||
|
RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE,
|
||||||
|
)
|
||||||
|
RULE_ID_ALL_OTHER_MESSAGES_ROOMS -> listOf(
|
||||||
|
RULE_ID_POLL_START,
|
||||||
|
RULE_ID_POLL_START_UNSTABLE,
|
||||||
|
RULE_ID_POLL_END,
|
||||||
|
RULE_ID_POLL_END_UNSTABLE,
|
||||||
|
)
|
||||||
|
else -> emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,22 +47,15 @@ data class RuleSet(
|
|||||||
* @param ruleId a RULE_ID_XX value
|
* @param ruleId a RULE_ID_XX value
|
||||||
* @return the matched bing rule or null it doesn't exist.
|
* @return the matched bing rule or null it doesn't exist.
|
||||||
*/
|
*/
|
||||||
fun findDefaultRule(ruleId: String?): PushRuleAndKind? {
|
fun findDefaultRule(ruleId: String): PushRuleAndKind? {
|
||||||
var result: PushRuleAndKind? = null
|
return if (RuleIds.RULE_ID_CONTAIN_USER_NAME == ruleId) {
|
||||||
// sanity check
|
findRule(content, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.CONTENT) }
|
||||||
if (null != ruleId) {
|
|
||||||
if (RuleIds.RULE_ID_CONTAIN_USER_NAME == ruleId) {
|
|
||||||
result = findRule(content, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.CONTENT) }
|
|
||||||
} else {
|
} else {
|
||||||
// assume that the ruleId is unique.
|
// assume that the ruleId is unique.
|
||||||
result = findRule(override, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.OVERRIDE) }
|
findRule(override, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.OVERRIDE) }
|
||||||
if (null == result) {
|
?: findRule(underride, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.UNDERRIDE) }
|
||||||
result = findRule(underride, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.UNDERRIDE) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a rule from its rule Id.
|
* Find a rule from its rule Id.
|
||||||
|
@ -57,6 +57,7 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
|
|||||||
val allEvents = (newJoinEvents + inviteEvents).filter { event ->
|
val allEvents = (newJoinEvents + inviteEvents).filter { event ->
|
||||||
when (event.type) {
|
when (event.type) {
|
||||||
in EventType.POLL_START.values,
|
in EventType.POLL_START.values,
|
||||||
|
in EventType.POLL_END.values,
|
||||||
in EventType.STATE_ROOM_BEACON_INFO.values,
|
in EventType.STATE_ROOM_BEACON_INFO.values,
|
||||||
EventType.MESSAGE,
|
EventType.MESSAGE,
|
||||||
EventType.REDACTION,
|
EventType.REDACTION,
|
||||||
|
@ -108,7 +108,8 @@ import im.vector.app.features.settings.ignored.IgnoredUsersViewModel
|
|||||||
import im.vector.app.features.settings.labs.VectorSettingsLabsViewModel
|
import im.vector.app.features.settings.labs.VectorSettingsLabsViewModel
|
||||||
import im.vector.app.features.settings.legals.LegalsViewModel
|
import im.vector.app.features.settings.legals.LegalsViewModel
|
||||||
import im.vector.app.features.settings.locale.LocalePickerViewModel
|
import im.vector.app.features.settings.locale.LocalePickerViewModel
|
||||||
import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceViewModel
|
import im.vector.app.features.settings.notifications.VectorSettingsNotificationViewModel
|
||||||
|
import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationViewModel
|
||||||
import im.vector.app.features.settings.push.PushGatewaysViewModel
|
import im.vector.app.features.settings.push.PushGatewaysViewModel
|
||||||
import im.vector.app.features.settings.threepids.ThreePidsSettingsViewModel
|
import im.vector.app.features.settings.threepids.ThreePidsSettingsViewModel
|
||||||
import im.vector.app.features.share.IncomingShareViewModel
|
import im.vector.app.features.share.IncomingShareViewModel
|
||||||
@ -690,9 +691,16 @@ interface MavericksViewModelModule {
|
|||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@MavericksViewModelKey(VectorSettingsNotificationPreferenceViewModel::class)
|
@MavericksViewModelKey(VectorSettingsNotificationViewModel::class)
|
||||||
fun vectorSettingsNotificationPreferenceViewModelFactory(
|
fun vectorSettingsNotificationPreferenceViewModelFactory(
|
||||||
factory: VectorSettingsNotificationPreferenceViewModel.Factory
|
factory: VectorSettingsNotificationViewModel.Factory
|
||||||
|
): MavericksAssistedViewModelFactory<*, *>
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@MavericksViewModelKey(VectorSettingsPushRuleNotificationViewModel::class)
|
||||||
|
fun vectorSettingsPushRuleNotificationPreferenceViewModelFactory(
|
||||||
|
factory: VectorSettingsPushRuleNotificationViewModel.Factory
|
||||||
): MavericksAssistedViewModelFactory<*, *>
|
): MavericksAssistedViewModelFactory<*, *>
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
|
@ -67,7 +67,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
private val nonEncryptedNotifiableEventTypes: List<String> =
|
private val nonEncryptedNotifiableEventTypes: List<String> =
|
||||||
listOf(EventType.MESSAGE) + EventType.POLL_START.values + EventType.STATE_ROOM_BEACON_INFO.values
|
listOf(EventType.MESSAGE) + EventType.POLL_START.values + EventType.POLL_END.values + EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
||||||
suspend fun resolveEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? {
|
suspend fun resolveEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? {
|
||||||
val roomID = event.roomId ?: return null
|
val roomID = event.roomId ?: return null
|
||||||
|
@ -32,7 +32,7 @@ import im.vector.app.databinding.ActivityVectorSettingsBinding
|
|||||||
import im.vector.app.features.discovery.DiscoverySettingsFragment
|
import im.vector.app.features.discovery.DiscoverySettingsFragment
|
||||||
import im.vector.app.features.navigation.SettingsActivityPayload
|
import im.vector.app.features.navigation.SettingsActivityPayload
|
||||||
import im.vector.app.features.settings.devices.VectorSettingsDevicesFragment
|
import im.vector.app.features.settings.devices.VectorSettingsDevicesFragment
|
||||||
import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceFragment
|
import im.vector.app.features.settings.notifications.VectorSettingsNotificationFragment
|
||||||
import im.vector.app.features.settings.threepids.ThreePidsSettingsFragment
|
import im.vector.app.features.settings.threepids.ThreePidsSettingsFragment
|
||||||
import im.vector.lib.core.utils.compat.getParcelableExtraCompat
|
import im.vector.lib.core.utils.compat.getParcelableExtraCompat
|
||||||
import org.matrix.android.sdk.api.failure.GlobalError
|
import org.matrix.android.sdk.api.failure.GlobalError
|
||||||
@ -92,7 +92,7 @@ class VectorSettingsActivity : VectorBaseActivity<ActivityVectorSettingsBinding>
|
|||||||
}
|
}
|
||||||
SettingsActivityPayload.Notifications -> {
|
SettingsActivityPayload.Notifications -> {
|
||||||
requestHighlightPreferenceKeyOnResume(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
requestHighlightPreferenceKeyOnResume(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
||||||
replaceFragment(views.vectorSettingsPage, VectorSettingsNotificationPreferenceFragment::class.java, null, FRAGMENT_TAG)
|
replaceFragment(views.vectorSettingsPage, VectorSettingsNotificationFragment::class.java, null, FRAGMENT_TAG)
|
||||||
}
|
}
|
||||||
is SettingsActivityPayload.DiscoverySettings -> {
|
is SettingsActivityPayload.DiscoverySettings -> {
|
||||||
replaceFragment(views.vectorSettingsPage, DiscoverySettingsFragment::class.java, payload, FRAGMENT_TAG)
|
replaceFragment(views.vectorSettingsPage, DiscoverySettingsFragment::class.java, payload, FRAGMENT_TAG)
|
||||||
|
@ -38,7 +38,12 @@ fun getStandardAction(ruleId: String, index: NotificationIndex): StandardActions
|
|||||||
NotificationIndex.SILENT -> StandardActions.Notify
|
NotificationIndex.SILENT -> StandardActions.Notify
|
||||||
NotificationIndex.NOISY -> StandardActions.Highlight
|
NotificationIndex.NOISY -> StandardActions.Highlight
|
||||||
}
|
}
|
||||||
RuleIds.RULE_ID_ONE_TO_ONE_ROOM ->
|
RuleIds.RULE_ID_ONE_TO_ONE_ROOM,
|
||||||
|
RuleIds.RULE_ID_POLL_START_ONE_TO_ONE,
|
||||||
|
RuleIds.RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE,
|
||||||
|
RuleIds.RULE_ID_POLL_END_ONE_TO_ONE,
|
||||||
|
RuleIds.RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE,
|
||||||
|
->
|
||||||
when (index) {
|
when (index) {
|
||||||
NotificationIndex.OFF -> StandardActions.DontNotify
|
NotificationIndex.OFF -> StandardActions.DontNotify
|
||||||
NotificationIndex.SILENT -> StandardActions.Notify
|
NotificationIndex.SILENT -> StandardActions.Notify
|
||||||
@ -50,7 +55,11 @@ fun getStandardAction(ruleId: String, index: NotificationIndex): StandardActions
|
|||||||
NotificationIndex.SILENT -> StandardActions.Notify
|
NotificationIndex.SILENT -> StandardActions.Notify
|
||||||
NotificationIndex.NOISY -> StandardActions.NotifyDefaultSound
|
NotificationIndex.NOISY -> StandardActions.NotifyDefaultSound
|
||||||
}
|
}
|
||||||
RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS ->
|
RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS,
|
||||||
|
RuleIds.RULE_ID_POLL_START,
|
||||||
|
RuleIds.RULE_ID_POLL_START_UNSTABLE,
|
||||||
|
RuleIds.RULE_ID_POLL_END,
|
||||||
|
RuleIds.RULE_ID_POLL_END_UNSTABLE ->
|
||||||
when (index) {
|
when (index) {
|
||||||
NotificationIndex.OFF -> StandardActions.DontNotify
|
NotificationIndex.OFF -> StandardActions.DontNotify
|
||||||
NotificationIndex.SILENT -> StandardActions.Notify
|
NotificationIndex.SILENT -> StandardActions.Notify
|
||||||
|
@ -71,7 +71,7 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
// Referenced in vector_settings_preferences_root.xml
|
// Referenced in vector_settings_preferences_root.xml
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class VectorSettingsNotificationPreferenceFragment :
|
class VectorSettingsNotificationFragment :
|
||||||
VectorSettingsBaseFragment(),
|
VectorSettingsBaseFragment(),
|
||||||
BackgroundSyncModeChooserDialog.InteractionListener {
|
BackgroundSyncModeChooserDialog.InteractionListener {
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ class VectorSettingsNotificationPreferenceFragment :
|
|||||||
|
|
||||||
private var interactionListener: VectorSettingsFragmentInteractionListener? = null
|
private var interactionListener: VectorSettingsFragmentInteractionListener? = null
|
||||||
|
|
||||||
private val viewModel: VectorSettingsNotificationPreferenceViewModel by fragmentViewModel()
|
private val viewModel: VectorSettingsNotificationViewModel by fragmentViewModel()
|
||||||
|
|
||||||
private val notificationStartForActivityResult = registerStartForActivityResult { _ ->
|
private val notificationStartForActivityResult = registerStartForActivityResult { _ ->
|
||||||
// No op
|
// No op
|
||||||
@ -116,10 +116,10 @@ class VectorSettingsNotificationPreferenceFragment :
|
|||||||
private fun observeViewEvents() {
|
private fun observeViewEvents() {
|
||||||
viewModel.observeViewEvents {
|
viewModel.observeViewEvents {
|
||||||
when (it) {
|
when (it) {
|
||||||
VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled -> onNotificationsForDeviceEnabled()
|
VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled -> onNotificationsForDeviceEnabled()
|
||||||
VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled -> onNotificationsForDeviceDisabled()
|
VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled -> onNotificationsForDeviceDisabled()
|
||||||
is VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor()
|
is VectorSettingsNotificationViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor()
|
||||||
VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged -> onNotificationMethodChanged()
|
VectorSettingsNotificationViewEvent.NotificationMethodChanged -> onNotificationMethodChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,9 +143,9 @@ class VectorSettingsNotificationPreferenceFragment :
|
|||||||
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
||||||
?.setOnPreferenceChangeListener { _, isChecked ->
|
?.setOnPreferenceChangeListener { _, isChecked ->
|
||||||
val action = if (isChecked as Boolean) {
|
val action = if (isChecked as Boolean) {
|
||||||
VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(pushDistributor = "")
|
VectorSettingsNotificationViewAction.EnableNotificationsForDevice(pushDistributor = "")
|
||||||
} else {
|
} else {
|
||||||
VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice
|
VectorSettingsNotificationViewAction.DisableNotificationsForDevice
|
||||||
}
|
}
|
||||||
viewModel.handle(action)
|
viewModel.handle(action)
|
||||||
// preference will be updated on ViewEvent reception
|
// preference will be updated on ViewEvent reception
|
||||||
@ -231,9 +231,9 @@ class VectorSettingsNotificationPreferenceFragment :
|
|||||||
private fun askUserToSelectPushDistributor(withUnregister: Boolean = false) {
|
private fun askUserToSelectPushDistributor(withUnregister: Boolean = false) {
|
||||||
unifiedPushHelper.showSelectDistributorDialog(requireContext()) { selection ->
|
unifiedPushHelper.showSelectDistributorDialog(requireContext()) { selection ->
|
||||||
if (withUnregister) {
|
if (withUnregister) {
|
||||||
viewModel.handle(VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(selection))
|
viewModel.handle(VectorSettingsNotificationViewAction.RegisterPushDistributor(selection))
|
||||||
} else {
|
} else {
|
||||||
viewModel.handle(VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(selection))
|
viewModel.handle(VectorSettingsNotificationViewAction.EnableNotificationsForDevice(selection))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,8 +18,8 @@ package im.vector.app.features.settings.notifications
|
|||||||
|
|
||||||
import im.vector.app.core.platform.VectorViewModelAction
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
|
||||||
sealed interface VectorSettingsNotificationPreferenceViewAction : VectorViewModelAction {
|
sealed interface VectorSettingsNotificationViewAction : VectorViewModelAction {
|
||||||
data class EnableNotificationsForDevice(val pushDistributor: String) : VectorSettingsNotificationPreferenceViewAction
|
data class EnableNotificationsForDevice(val pushDistributor: String) : VectorSettingsNotificationViewAction
|
||||||
object DisableNotificationsForDevice : VectorSettingsNotificationPreferenceViewAction
|
object DisableNotificationsForDevice : VectorSettingsNotificationViewAction
|
||||||
data class RegisterPushDistributor(val pushDistributor: String) : VectorSettingsNotificationPreferenceViewAction
|
data class RegisterPushDistributor(val pushDistributor: String) : VectorSettingsNotificationViewAction
|
||||||
}
|
}
|
@ -18,9 +18,9 @@ package im.vector.app.features.settings.notifications
|
|||||||
|
|
||||||
import im.vector.app.core.platform.VectorViewEvents
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
sealed interface VectorSettingsNotificationPreferenceViewEvent : VectorViewEvents {
|
sealed interface VectorSettingsNotificationViewEvent : VectorViewEvents {
|
||||||
object NotificationsForDeviceEnabled : VectorSettingsNotificationPreferenceViewEvent
|
object NotificationsForDeviceEnabled : VectorSettingsNotificationViewEvent
|
||||||
object NotificationsForDeviceDisabled : VectorSettingsNotificationPreferenceViewEvent
|
object NotificationsForDeviceDisabled : VectorSettingsNotificationViewEvent
|
||||||
object AskUserForPushDistributor : VectorSettingsNotificationPreferenceViewEvent
|
object AskUserForPushDistributor : VectorSettingsNotificationViewEvent
|
||||||
object NotificationMethodChanged : VectorSettingsNotificationPreferenceViewEvent
|
object NotificationMethodChanged : VectorSettingsNotificationViewEvent
|
||||||
}
|
}
|
@ -31,9 +31,12 @@ import im.vector.app.core.pushers.PushersManager
|
|||||||
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.DisableNotificationsForCurrentSessionUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.EnableNotificationsForCurrentSessionUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
|
class VectorSettingsNotificationViewModel @AssistedInject constructor(
|
||||||
@Assisted initialState: VectorDummyViewState,
|
@Assisted initialState: VectorDummyViewState,
|
||||||
private val pushersManager: PushersManager,
|
private val pushersManager: PushersManager,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
@ -43,23 +46,23 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
|
|||||||
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
||||||
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
||||||
private val toggleNotificationsForCurrentSessionUseCase: ToggleNotificationsForCurrentSessionUseCase,
|
private val toggleNotificationsForCurrentSessionUseCase: ToggleNotificationsForCurrentSessionUseCase,
|
||||||
) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationPreferenceViewAction, VectorSettingsNotificationPreferenceViewEvent>(initialState) {
|
) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationViewAction, VectorSettingsNotificationViewEvent>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory : MavericksAssistedViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> {
|
interface Factory : MavericksAssistedViewModelFactory<VectorSettingsNotificationViewModel, VectorDummyViewState> {
|
||||||
override fun create(initialState: VectorDummyViewState): VectorSettingsNotificationPreferenceViewModel
|
override fun create(initialState: VectorDummyViewState): VectorSettingsNotificationViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : MavericksViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
|
companion object : MavericksViewModelFactory<VectorSettingsNotificationViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
val notificationsPreferenceListener: SharedPreferences.OnSharedPreferenceChangeListener =
|
val notificationsPreferenceListener: SharedPreferences.OnSharedPreferenceChangeListener =
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
|
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
|
||||||
if (key == VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY) {
|
if (key == VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY) {
|
||||||
if (vectorPreferences.areNotificationEnabledForDevice()) {
|
if (vectorPreferences.areNotificationEnabledForDevice()) {
|
||||||
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
|
_viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled)
|
||||||
} else {
|
} else {
|
||||||
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
|
_viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,18 +80,18 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
|
|||||||
super.onCleared()
|
super.onCleared()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(action: VectorSettingsNotificationPreferenceViewAction) {
|
override fun handle(action: VectorSettingsNotificationViewAction) {
|
||||||
when (action) {
|
when (action) {
|
||||||
VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice -> handleDisableNotificationsForDevice()
|
VectorSettingsNotificationViewAction.DisableNotificationsForDevice -> handleDisableNotificationsForDevice()
|
||||||
is VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice -> handleEnableNotificationsForDevice(action.pushDistributor)
|
is VectorSettingsNotificationViewAction.EnableNotificationsForDevice -> handleEnableNotificationsForDevice(action.pushDistributor)
|
||||||
is VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor -> handleRegisterPushDistributor(action.pushDistributor)
|
is VectorSettingsNotificationViewAction.RegisterPushDistributor -> handleRegisterPushDistributor(action.pushDistributor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDisableNotificationsForDevice() {
|
private fun handleDisableNotificationsForDevice() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
disableNotificationsForCurrentSessionUseCase.execute()
|
disableNotificationsForCurrentSessionUseCase.execute()
|
||||||
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
|
_viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,10 +99,10 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
|
|||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
when (enableNotificationsForCurrentSessionUseCase.execute(distributor)) {
|
when (enableNotificationsForCurrentSessionUseCase.execute(distributor)) {
|
||||||
is EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor -> {
|
is EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor -> {
|
||||||
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
|
_viewEvents.post(VectorSettingsNotificationViewEvent.AskUserForPushDistributor)
|
||||||
}
|
}
|
||||||
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success -> {
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success -> {
|
||||||
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
|
_viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,13 +113,13 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
|
|||||||
unregisterUnifiedPushUseCase.execute(pushersManager)
|
unregisterUnifiedPushUseCase.execute(pushersManager)
|
||||||
when (registerUnifiedPushUseCase.execute(distributor)) {
|
when (registerUnifiedPushUseCase.execute(distributor)) {
|
||||||
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
|
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
|
||||||
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
|
_viewEvents.post(VectorSettingsNotificationViewEvent.AskUserForPushDistributor)
|
||||||
}
|
}
|
||||||
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
|
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
|
||||||
val areNotificationsEnabled = vectorPreferences.areNotificationEnabledForDevice()
|
val areNotificationsEnabled = vectorPreferences.areNotificationEnabledForDevice()
|
||||||
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = areNotificationsEnabled)
|
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = areNotificationsEnabled)
|
||||||
toggleNotificationsForCurrentSessionUseCase.execute(enabled = areNotificationsEnabled)
|
toggleNotificationsForCurrentSessionUseCase.execute(enabled = areNotificationsEnabled)
|
||||||
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged)
|
_viewEvents.post(VectorSettingsNotificationViewEvent.NotificationMethodChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
import com.airbnb.mvrx.withState
|
||||||
|
import im.vector.app.core.preference.VectorCheckboxPreference
|
||||||
|
import im.vector.app.features.settings.VectorSettingsBaseFragment
|
||||||
|
|
||||||
|
abstract class VectorSettingsPushRuleNotificationFragment :
|
||||||
|
VectorSettingsBaseFragment() {
|
||||||
|
|
||||||
|
private val viewModel: VectorSettingsPushRuleNotificationViewModel by fragmentViewModel()
|
||||||
|
|
||||||
|
abstract val prefKeyToPushRuleId: Map<String, String>
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
observeViewEvents()
|
||||||
|
viewModel.onEach(VectorSettingsPushRuleNotificationViewState::isLoading) { isLoading ->
|
||||||
|
if (isLoading) {
|
||||||
|
displayLoadingView()
|
||||||
|
} else {
|
||||||
|
hideLoadingView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeViewEvents() {
|
||||||
|
viewModel.observeViewEvents {
|
||||||
|
when (it) {
|
||||||
|
is VectorSettingsPushRuleNotificationViewEvent.Failure -> refreshDisplay()
|
||||||
|
is VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated -> updatePreference(it.ruleId, it.checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindPref() {
|
||||||
|
for (preferenceKey in prefKeyToPushRuleId.keys) {
|
||||||
|
val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!!
|
||||||
|
preference.isIconSpaceReserved = false
|
||||||
|
val ruleAndKind = prefKeyToPushRuleId[preferenceKey]?.let { viewModel.getPushRuleAndKind(it) }
|
||||||
|
if (ruleAndKind == null) {
|
||||||
|
// The rule is not defined, hide the preference
|
||||||
|
preference.isVisible = false
|
||||||
|
} else {
|
||||||
|
preference.isVisible = true
|
||||||
|
updatePreference(ruleAndKind.pushRule.ruleId, viewModel.isPushRuleChecked(ruleAndKind.pushRule.ruleId))
|
||||||
|
preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
|
||||||
|
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(ruleAndKind, newValue as Boolean))
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidate() = withState(viewModel) { state ->
|
||||||
|
if (state.isLoading) {
|
||||||
|
displayLoadingView()
|
||||||
|
} else {
|
||||||
|
hideLoadingView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun refreshDisplay() {
|
||||||
|
listView?.adapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updatePreference(ruleId: String, checked: Boolean) {
|
||||||
|
val preferenceKey = prefKeyToPushRuleId.entries.find { it.value == ruleId }?.key ?: return
|
||||||
|
val preference = findPreference<VectorCheckboxPreference>(preferenceKey) ?: return
|
||||||
|
preference.isChecked = checked
|
||||||
|
}
|
||||||
|
}
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
|
||||||
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.preference.Preference
|
|
||||||
import im.vector.app.core.preference.VectorCheckboxPreference
|
|
||||||
import im.vector.app.features.settings.VectorSettingsBaseFragment
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RuleKind
|
|
||||||
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
|
|
||||||
|
|
||||||
abstract class VectorSettingsPushRuleNotificationPreferenceFragment :
|
|
||||||
VectorSettingsBaseFragment() {
|
|
||||||
|
|
||||||
abstract val prefKeyToPushRuleId: Map<String, String>
|
|
||||||
|
|
||||||
override fun bindPref() {
|
|
||||||
for (preferenceKey in prefKeyToPushRuleId.keys) {
|
|
||||||
val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!!
|
|
||||||
preference.isIconSpaceReserved = false
|
|
||||||
val ruleAndKind: PushRuleAndKind? = session.pushRuleService().getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey])
|
|
||||||
if (ruleAndKind == null) {
|
|
||||||
// The rule is not defined, hide the preference
|
|
||||||
preference.isVisible = false
|
|
||||||
} else {
|
|
||||||
preference.isVisible = true
|
|
||||||
val initialIndex = ruleAndKind.pushRule.notificationIndex
|
|
||||||
preference.isChecked = initialIndex != NotificationIndex.OFF
|
|
||||||
preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
|
|
||||||
updatePushRule(ruleAndKind.pushRule.ruleId, ruleAndKind.kind, newValue as Boolean, preference)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updatePushRule(ruleId: String, kind: RuleKind, checked: Boolean, preference: VectorCheckboxPreference) {
|
|
||||||
val newIndex = if (checked) NotificationIndex.NOISY else NotificationIndex.OFF
|
|
||||||
val standardAction = getStandardAction(ruleId, newIndex) ?: return
|
|
||||||
val enabled = standardAction != StandardActions.Disabled
|
|
||||||
val newActions = standardAction.actions
|
|
||||||
displayLoadingView()
|
|
||||||
|
|
||||||
lifecycleScope.launch {
|
|
||||||
val result = runCatching {
|
|
||||||
session.pushRuleService().updatePushRuleActions(
|
|
||||||
kind,
|
|
||||||
ruleId,
|
|
||||||
enabled,
|
|
||||||
newActions
|
|
||||||
)
|
|
||||||
}
|
|
||||||
hideLoadingView()
|
|
||||||
if (!isAdded) {
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
result.onSuccess {
|
|
||||||
preference.isChecked = checked
|
|
||||||
}
|
|
||||||
result.onFailure { failure ->
|
|
||||||
// Restore the previous value
|
|
||||||
refreshDisplay()
|
|
||||||
displayErrorDialog(failure)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refreshDisplay() {
|
|
||||||
listView?.adapter?.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
|
||||||
|
|
||||||
|
sealed interface VectorSettingsPushRuleNotificationViewAction : VectorViewModelAction {
|
||||||
|
data class UpdatePushRule(val pushRuleAndKind: PushRuleAndKind, val checked: Boolean) : VectorSettingsPushRuleNotificationViewAction
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
|
sealed interface VectorSettingsPushRuleNotificationViewEvent : VectorViewEvents {
|
||||||
|
/**
|
||||||
|
* A global push rule checked state has changed.
|
||||||
|
*
|
||||||
|
* @property ruleId the global rule id which has been updated.
|
||||||
|
* @property checked whether the global rule is checked.
|
||||||
|
* @property failure whether there has been a failure when updating the global rule (ie. a sub rule has not been updated).
|
||||||
|
*/
|
||||||
|
data class PushRuleUpdated(val ruleId: String, val checked: Boolean, val failure: Throwable? = null) : VectorSettingsPushRuleNotificationViewEvent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A failure has occurred.
|
||||||
|
*
|
||||||
|
* @property throwable the related exception, if any.
|
||||||
|
*/
|
||||||
|
data class Failure(val throwable: Throwable?) : VectorSettingsPushRuleNotificationViewEvent
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationViewEvent.Failure
|
||||||
|
import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.matrix.android.sdk.api.failure.Failure.ServerError
|
||||||
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.Action
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.RuleKind
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
|
||||||
|
|
||||||
|
private typealias ViewModel = VectorSettingsPushRuleNotificationViewModel
|
||||||
|
private typealias ViewState = VectorSettingsPushRuleNotificationViewState
|
||||||
|
|
||||||
|
class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
|
||||||
|
@Assisted initialState: ViewState,
|
||||||
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
|
) : VectorViewModel<VectorSettingsPushRuleNotificationViewState,
|
||||||
|
VectorSettingsPushRuleNotificationViewAction,
|
||||||
|
VectorSettingsPushRuleNotificationViewEvent>(initialState) {
|
||||||
|
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory : MavericksAssistedViewModelFactory<ViewModel, ViewState> {
|
||||||
|
override fun create(initialState: ViewState): ViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MavericksViewModelFactory<ViewModel, ViewState> by hiltMavericksViewModelFactory()
|
||||||
|
|
||||||
|
override fun handle(action: VectorSettingsPushRuleNotificationViewAction) {
|
||||||
|
when (action) {
|
||||||
|
is VectorSettingsPushRuleNotificationViewAction.UpdatePushRule -> handleUpdatePushRule(action.pushRuleAndKind, action.checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPushRuleAndKind(ruleId: String): PushRuleAndKind? {
|
||||||
|
return activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.getPushRules()?.findDefaultRule(ruleId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isPushRuleChecked(ruleId: String): Boolean {
|
||||||
|
val rulesGroup = listOf(ruleId) + RuleIds.getSyncedRules(ruleId)
|
||||||
|
return rulesGroup.mapNotNull { getPushRuleAndKind(it) }.any { it.pushRule.notificationIndex != NotificationIndex.OFF }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleUpdatePushRule(pushRuleAndKind: PushRuleAndKind, checked: Boolean) {
|
||||||
|
val ruleId = pushRuleAndKind.pushRule.ruleId
|
||||||
|
val kind = pushRuleAndKind.kind
|
||||||
|
val newIndex = if (checked) NotificationIndex.NOISY else NotificationIndex.OFF
|
||||||
|
val standardAction = getStandardAction(ruleId, newIndex) ?: return
|
||||||
|
val enabled = standardAction != StandardActions.Disabled
|
||||||
|
val newActions = standardAction.actions
|
||||||
|
setState { copy(isLoading = true) }
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
val rulesToUpdate = listOf(ruleId) + RuleIds.getSyncedRules(ruleId)
|
||||||
|
val results = rulesToUpdate.map { ruleId ->
|
||||||
|
runCatching {
|
||||||
|
updatePushRule(kind, ruleId, enabled, newActions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setState { copy(isLoading = false) }
|
||||||
|
val failure = results.firstNotNullOfOrNull { result ->
|
||||||
|
// If the failure is a rule not found error, do not consider it
|
||||||
|
result.exceptionOrNull()?.takeUnless { it is ServerError && it.error.code == MatrixError.M_NOT_FOUND }
|
||||||
|
}
|
||||||
|
val newChecked = if (checked) {
|
||||||
|
// If any rule is checked, the global rule is checked
|
||||||
|
results.any { it.isSuccess }
|
||||||
|
} else {
|
||||||
|
// If any rule has not been unchecked, the global rule remains checked
|
||||||
|
failure != null
|
||||||
|
}
|
||||||
|
if (results.any { it.isSuccess }) {
|
||||||
|
_viewEvents.post(PushRuleUpdated(ruleId, newChecked, failure))
|
||||||
|
} else {
|
||||||
|
_viewEvents.post(Failure(failure))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun updatePushRule(kind: RuleKind, ruleId: String, enable: Boolean, newActions: List<Action>?) {
|
||||||
|
activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions(
|
||||||
|
kind = kind,
|
||||||
|
ruleId = ruleId,
|
||||||
|
enable = enable,
|
||||||
|
actions = newActions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.MavericksState
|
||||||
|
|
||||||
|
data class VectorSettingsPushRuleNotificationViewState(
|
||||||
|
val isLoading: Boolean = false,
|
||||||
|
) : MavericksState
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.advanced
|
||||||
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
@ -23,10 +23,15 @@ import im.vector.app.core.preference.PushRulePreference
|
|||||||
import im.vector.app.core.preference.VectorPreference
|
import im.vector.app.core.preference.VectorPreference
|
||||||
import im.vector.app.core.utils.toast
|
import im.vector.app.core.utils.toast
|
||||||
import im.vector.app.features.settings.VectorSettingsBaseFragment
|
import im.vector.app.features.settings.VectorSettingsBaseFragment
|
||||||
|
import im.vector.app.features.settings.notifications.NotificationIndex
|
||||||
|
import im.vector.app.features.settings.notifications.StandardActions
|
||||||
|
import im.vector.app.features.settings.notifications.getStandardAction
|
||||||
|
import im.vector.app.features.settings.notifications.notificationIndex
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
||||||
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
|
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
|
||||||
|
|
||||||
|
// TODO This fragment seems not used anymore, we can probably delete it
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class VectorSettingsAdvancedNotificationPreferenceFragment :
|
class VectorSettingsAdvancedNotificationPreferenceFragment :
|
||||||
VectorSettingsBaseFragment() {
|
VectorSettingsBaseFragment() {
|
||||||
@ -39,7 +44,7 @@ class VectorSettingsAdvancedNotificationPreferenceFragment :
|
|||||||
for (preferenceKey in prefKeyToPushRuleId.keys) {
|
for (preferenceKey in prefKeyToPushRuleId.keys) {
|
||||||
val preference = findPreference<VectorPreference>(preferenceKey)
|
val preference = findPreference<VectorPreference>(preferenceKey)
|
||||||
if (preference is PushRulePreference) {
|
if (preference is PushRulePreference) {
|
||||||
val ruleAndKind: PushRuleAndKind? = session.pushRuleService().getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey])
|
val ruleAndKind: PushRuleAndKind? = prefKeyToPushRuleId[preferenceKey]?.let { session.pushRuleService().getPushRules().findDefaultRule(it) }
|
||||||
|
|
||||||
if (ruleAndKind == null) {
|
if (ruleAndKind == null) {
|
||||||
// The rule is not defined, hide the preference
|
// The rule is not defined, hide the preference
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,16 +14,17 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.defaults
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.preference.VectorPreferenceCategory
|
import im.vector.app.core.preference.VectorPreferenceCategory
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
|
import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationFragment
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
||||||
|
|
||||||
class VectorSettingsDefaultNotificationPreferenceFragment :
|
class VectorSettingsDefaultNotificationFragment :
|
||||||
VectorSettingsPushRuleNotificationPreferenceFragment() {
|
VectorSettingsPushRuleNotificationFragment() {
|
||||||
|
|
||||||
override var titleRes: Int = R.string.settings_notification_default
|
override var titleRes: Int = R.string.settings_notification_default
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.keywordandmentions
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -26,6 +26,10 @@ import im.vector.app.core.preference.VectorCheckboxPreference
|
|||||||
import im.vector.app.core.preference.VectorPreference
|
import im.vector.app.core.preference.VectorPreference
|
||||||
import im.vector.app.core.preference.VectorPreferenceCategory
|
import im.vector.app.core.preference.VectorPreferenceCategory
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
|
import im.vector.app.features.settings.notifications.NotificationIndex
|
||||||
|
import im.vector.app.features.settings.notifications.StandardActions
|
||||||
|
import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationFragment
|
||||||
|
import im.vector.app.features.settings.notifications.getStandardAction
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -34,8 +38,8 @@ import org.matrix.android.sdk.api.session.pushrules.RuleKind
|
|||||||
import org.matrix.android.sdk.api.session.pushrules.rest.PushRule
|
import org.matrix.android.sdk.api.session.pushrules.rest.PushRule
|
||||||
import org.matrix.android.sdk.api.session.pushrules.toJson
|
import org.matrix.android.sdk.api.session.pushrules.toJson
|
||||||
|
|
||||||
class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment :
|
class VectorSettingsKeywordAndMentionsNotificationFragment :
|
||||||
VectorSettingsPushRuleNotificationPreferenceFragment() {
|
VectorSettingsPushRuleNotificationFragment() {
|
||||||
|
|
||||||
override var titleRes: Int = R.string.settings_notification_mentions_and_keywords
|
override var titleRes: Int = R.string.settings_notification_mentions_and_keywords
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,14 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.other
|
||||||
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.preference.VectorPreferenceCategory
|
import im.vector.app.core.preference.VectorPreferenceCategory
|
||||||
|
import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationFragment
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
||||||
|
|
||||||
class VectorSettingsOtherNotificationPreferenceFragment :
|
class VectorSettingsOtherNotificationFragment :
|
||||||
VectorSettingsPushRuleNotificationPreferenceFragment() {
|
VectorSettingsPushRuleNotificationFragment() {
|
||||||
|
|
||||||
override var titleRes: Int = R.string.settings_notification_other
|
override var titleRes: Int = R.string.settings_notification_other
|
||||||
|
|
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.troubleshoot
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.usecase
|
||||||
|
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.usecase
|
||||||
|
|
||||||
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications.usecase
|
||||||
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnifiedPushHelper
|
@ -25,21 +25,21 @@
|
|||||||
android:key="SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY"
|
android:key="SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:title="@string/settings_notification_default"
|
android:title="@string/settings_notification_default"
|
||||||
app:fragment="im.vector.app.features.settings.notifications.VectorSettingsDefaultNotificationPreferenceFragment" />
|
app:fragment="im.vector.app.features.settings.notifications.defaults.VectorSettingsDefaultNotificationFragment" />
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorPreference
|
<im.vector.app.core.preference.VectorPreference
|
||||||
android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
|
android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
|
||||||
android:key="SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY"
|
android:key="SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:title="@string/settings_notification_mentions_and_keywords"
|
android:title="@string/settings_notification_mentions_and_keywords"
|
||||||
app:fragment="im.vector.app.features.settings.notifications.VectorSettingsKeywordAndMentionsNotificationPreferenceFragment" />
|
app:fragment="im.vector.app.features.settings.notifications.keywordandmentions.VectorSettingsKeywordAndMentionsNotificationFragment" />
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorPreference
|
<im.vector.app.core.preference.VectorPreference
|
||||||
android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
|
android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
|
||||||
android:key="SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY"
|
android:key="SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:title="@string/settings_notification_other"
|
android:title="@string/settings_notification_other"
|
||||||
app:fragment="im.vector.app.features.settings.notifications.VectorSettingsOtherNotificationPreferenceFragment" />
|
app:fragment="im.vector.app.features.settings.notifications.other.VectorSettingsOtherNotificationFragment" />
|
||||||
|
|
||||||
</im.vector.app.core.preference.VectorPreferenceCategory>
|
</im.vector.app.core.preference.VectorPreferenceCategory>
|
||||||
|
|
||||||
@ -119,7 +119,7 @@
|
|||||||
<im.vector.app.core.preference.VectorPreference
|
<im.vector.app.core.preference.VectorPreference
|
||||||
android:key="SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY"
|
android:key="SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY"
|
||||||
android:title="@string/settings_notification_troubleshoot"
|
android:title="@string/settings_notification_troubleshoot"
|
||||||
app:fragment="im.vector.app.features.settings.notifications.VectorSettingsNotificationsTroubleshootFragment" />
|
app:fragment="im.vector.app.features.settings.notifications.troubleshoot.VectorSettingsNotificationsTroubleshootFragment" />
|
||||||
|
|
||||||
</im.vector.app.core.preference.VectorPreferenceCategory>
|
</im.vector.app.core.preference.VectorPreferenceCategory>
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<im.vector.app.core.preference.VectorPreference
|
<im.vector.app.core.preference.VectorPreference
|
||||||
android:icon="@drawable/ic_settings_root_notification"
|
android:icon="@drawable/ic_settings_root_notification"
|
||||||
android:title="@string/settings_notifications"
|
android:title="@string/settings_notifications"
|
||||||
app:fragment="im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceFragment"
|
app:fragment="im.vector.app.features.settings.notifications.VectorSettingsNotificationFragment"
|
||||||
app:isPreferenceVisible="@bool/settings_root_notification_visible" />
|
app:isPreferenceVisible="@bool/settings_root_notification_visible" />
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorPreference
|
<im.vector.app.core.preference.VectorPreference
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.DisableNotificationsForCurrentSessionUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
|
||||||
import im.vector.app.test.fakes.FakePushersManager
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
import io.mockk.coJustRun
|
import io.mockk.coJustRun
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
|
@ -18,6 +18,8 @@ package im.vector.app.features.settings.notifications
|
|||||||
|
|
||||||
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.EnableNotificationsForCurrentSessionUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
|
||||||
import im.vector.app.test.fakes.FakePushersManager
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
import io.mockk.coJustRun
|
import io.mockk.coJustRun
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
|
@ -19,6 +19,7 @@ package im.vector.app.features.settings.notifications
|
|||||||
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanToggleNotificationsViaPusherUseCase
|
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanToggleNotificationsViaPusherUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.DeleteNotificationSettingsAccountDataUseCase
|
import im.vector.app.features.settings.devices.v2.notification.DeleteNotificationSettingsAccountDataUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.SetNotificationSettingsAccountDataUseCase
|
import im.vector.app.features.settings.devices.v2.notification.SetNotificationSettingsAccountDataUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
|
||||||
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
import im.vector.app.test.fakes.FakeUnifiedPushHelper
|
import im.vector.app.test.fakes.FakeUnifiedPushHelper
|
||||||
import im.vector.app.test.fixtures.PusherFixture
|
import im.vector.app.test.fixtures.PusherFixture
|
||||||
|
@ -22,6 +22,9 @@ import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
|||||||
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
import im.vector.app.features.settings.VectorPreferences.Companion.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY
|
import im.vector.app.features.settings.VectorPreferences.Companion.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.DisableNotificationsForCurrentSessionUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.EnableNotificationsForCurrentSessionUseCase
|
||||||
|
import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
|
||||||
import im.vector.app.test.fakes.FakePushersManager
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
import im.vector.app.test.fakes.FakeVectorPreferences
|
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||||
import im.vector.app.test.test
|
import im.vector.app.test.test
|
||||||
@ -35,7 +38,7 @@ import io.mockk.mockk
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class VectorSettingsNotificationPreferenceViewModelTest {
|
class VectorSettingsNotificationViewModelTest {
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher)
|
val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher)
|
||||||
@ -49,7 +52,7 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
private val fakeEnsureFcmTokenIsRetrievedUseCase = mockk<EnsureFcmTokenIsRetrievedUseCase>()
|
private val fakeEnsureFcmTokenIsRetrievedUseCase = mockk<EnsureFcmTokenIsRetrievedUseCase>()
|
||||||
private val fakeToggleNotificationsForCurrentSessionUseCase = mockk<ToggleNotificationsForCurrentSessionUseCase>()
|
private val fakeToggleNotificationsForCurrentSessionUseCase = mockk<ToggleNotificationsForCurrentSessionUseCase>()
|
||||||
|
|
||||||
private fun createViewModel() = VectorSettingsNotificationPreferenceViewModel(
|
private fun createViewModel() = VectorSettingsNotificationViewModel(
|
||||||
initialState = VectorDummyViewState(),
|
initialState = VectorDummyViewState(),
|
||||||
pushersManager = fakePushersManager.instance,
|
pushersManager = fakePushersManager.instance,
|
||||||
vectorPreferences = fakeVectorPreferences.instance,
|
vectorPreferences = fakeVectorPreferences.instance,
|
||||||
@ -65,7 +68,7 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
fun `given view model init when notifications are enabled in preferences then view event is posted`() {
|
fun `given view model init when notifications are enabled in preferences then view event is posted`() {
|
||||||
// Given
|
// Given
|
||||||
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(true)
|
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(true)
|
||||||
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled
|
val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled
|
||||||
val viewModel = createViewModel()
|
val viewModel = createViewModel()
|
||||||
|
|
||||||
// When
|
// When
|
||||||
@ -82,7 +85,7 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
fun `given view model init when notifications are disabled in preferences then view event is posted`() {
|
fun `given view model init when notifications are disabled in preferences then view event is posted`() {
|
||||||
// Given
|
// Given
|
||||||
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(false)
|
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(false)
|
||||||
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled
|
val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled
|
||||||
val viewModel = createViewModel()
|
val viewModel = createViewModel()
|
||||||
|
|
||||||
// When
|
// When
|
||||||
@ -99,9 +102,9 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
fun `given DisableNotificationsForDevice action when handling action then disable use case is called`() {
|
fun `given DisableNotificationsForDevice action when handling action then disable use case is called`() {
|
||||||
// Given
|
// Given
|
||||||
val viewModel = createViewModel()
|
val viewModel = createViewModel()
|
||||||
val action = VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice
|
val action = VectorSettingsNotificationViewAction.DisableNotificationsForDevice
|
||||||
coJustRun { fakeDisableNotificationsForCurrentSessionUseCase.execute() }
|
coJustRun { fakeDisableNotificationsForCurrentSessionUseCase.execute() }
|
||||||
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled
|
val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled
|
||||||
|
|
||||||
// When
|
// When
|
||||||
val viewModelTest = viewModel.test()
|
val viewModelTest = viewModel.test()
|
||||||
@ -121,10 +124,10 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
// Given
|
// Given
|
||||||
val viewModel = createViewModel()
|
val viewModel = createViewModel()
|
||||||
val aDistributor = "aDistributor"
|
val aDistributor = "aDistributor"
|
||||||
val action = VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(aDistributor)
|
val action = VectorSettingsNotificationViewAction.EnableNotificationsForDevice(aDistributor)
|
||||||
coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
|
coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
|
||||||
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success
|
||||||
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled
|
val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled
|
||||||
|
|
||||||
// When
|
// When
|
||||||
val viewModelTest = viewModel.test()
|
val viewModelTest = viewModel.test()
|
||||||
@ -144,10 +147,10 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
// Given
|
// Given
|
||||||
val viewModel = createViewModel()
|
val viewModel = createViewModel()
|
||||||
val aDistributor = "aDistributor"
|
val aDistributor = "aDistributor"
|
||||||
val action = VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(aDistributor)
|
val action = VectorSettingsNotificationViewAction.EnableNotificationsForDevice(aDistributor)
|
||||||
coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
|
coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
|
||||||
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor
|
||||||
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor
|
val expectedEvent = VectorSettingsNotificationViewEvent.AskUserForPushDistributor
|
||||||
|
|
||||||
// When
|
// When
|
||||||
val viewModelTest = viewModel.test()
|
val viewModelTest = viewModel.test()
|
||||||
@ -167,14 +170,14 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
// Given
|
// Given
|
||||||
val viewModel = createViewModel()
|
val viewModel = createViewModel()
|
||||||
val aDistributor = "aDistributor"
|
val aDistributor = "aDistributor"
|
||||||
val action = VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(aDistributor)
|
val action = VectorSettingsNotificationViewAction.RegisterPushDistributor(aDistributor)
|
||||||
coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
||||||
coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
|
coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
|
||||||
val areNotificationsEnabled = true
|
val areNotificationsEnabled = true
|
||||||
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(areNotificationsEnabled)
|
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(areNotificationsEnabled)
|
||||||
coJustRun { fakeToggleNotificationsForCurrentSessionUseCase.execute(any()) }
|
coJustRun { fakeToggleNotificationsForCurrentSessionUseCase.execute(any()) }
|
||||||
justRun { fakeEnsureFcmTokenIsRetrievedUseCase.execute(any(), any()) }
|
justRun { fakeEnsureFcmTokenIsRetrievedUseCase.execute(any(), any()) }
|
||||||
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged
|
val expectedEvent = VectorSettingsNotificationViewEvent.NotificationMethodChanged
|
||||||
|
|
||||||
// When
|
// When
|
||||||
val viewModelTest = viewModel.test()
|
val viewModelTest = viewModel.test()
|
||||||
@ -197,10 +200,10 @@ class VectorSettingsNotificationPreferenceViewModelTest {
|
|||||||
// Given
|
// Given
|
||||||
val viewModel = createViewModel()
|
val viewModel = createViewModel()
|
||||||
val aDistributor = "aDistributor"
|
val aDistributor = "aDistributor"
|
||||||
val action = VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(aDistributor)
|
val action = VectorSettingsNotificationViewAction.RegisterPushDistributor(aDistributor)
|
||||||
coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor
|
coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor
|
||||||
coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
|
coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
|
||||||
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor
|
val expectedEvent = VectorSettingsNotificationViewEvent.AskUserForPushDistributor
|
||||||
|
|
||||||
// When
|
// When
|
||||||
val viewModelTest = viewModel.test()
|
val viewModelTest = viewModel.test()
|
@ -0,0 +1,258 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.test.MavericksTestRule
|
||||||
|
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
|
import im.vector.app.test.test
|
||||||
|
import im.vector.app.test.testDispatcher
|
||||||
|
import io.mockk.coVerifyOrder
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.unmockkAll
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.shouldBe
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
|
||||||
|
|
||||||
|
internal class VectorSettingsPushRuleNotificationViewModelTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher)
|
||||||
|
|
||||||
|
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
|
||||||
|
private val fakePushRuleService = fakeActiveSessionHolder.fakeSession.fakePushRuleService
|
||||||
|
|
||||||
|
private val initialState = VectorSettingsPushRuleNotificationViewState()
|
||||||
|
private fun createViewModel() = VectorSettingsPushRuleNotificationViewModel(
|
||||||
|
initialState = initialState,
|
||||||
|
activeSessionHolder = fakeActiveSessionHolder.instance,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
mockkStatic("im.vector.app.features.settings.notifications.NotificationIndexKt")
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
unmockkAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a ruleId, when the rule is checked or unchecked with no error, then the expected view event is posted`() = runTest {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
|
||||||
|
val firstRuleId = RuleIds.RULE_ID_ONE_TO_ONE_ROOM
|
||||||
|
val secondRuleId = RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsSucceed()
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(givenARuleId(firstRuleId), true))
|
||||||
|
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(givenARuleId(secondRuleId), false))
|
||||||
|
|
||||||
|
// Then
|
||||||
|
coVerifyOrder {
|
||||||
|
// first rule id
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), firstRuleId, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_ONE_TO_ONE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_ONE_TO_ONE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE, any(), any())
|
||||||
|
|
||||||
|
// second rule id
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), secondRuleId, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_UNSTABLE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_UNSTABLE, any(), any())
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelTest
|
||||||
|
.assertStatesChanges(
|
||||||
|
initialState,
|
||||||
|
{ copy(isLoading = true) },
|
||||||
|
{ copy(isLoading = false) },
|
||||||
|
{ copy(isLoading = true) },
|
||||||
|
{ copy(isLoading = false) },
|
||||||
|
)
|
||||||
|
.assertEvents(
|
||||||
|
VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated(RuleIds.RULE_ID_ONE_TO_ONE_ROOM, true),
|
||||||
|
VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated(RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, false),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a ruleId, when the rule is checked with an error, then expected view event is posted`() = runTest {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val failure = mockk<Throwable>()
|
||||||
|
|
||||||
|
val firstRuleId = RuleIds.RULE_ID_ONE_TO_ONE_ROOM
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsSucceed()
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE, failure)
|
||||||
|
|
||||||
|
val secondRuleId = RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(secondRuleId, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_START, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_START_UNSTABLE, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_END, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_END_UNSTABLE, failure)
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
// One rule failed to update
|
||||||
|
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(givenARuleId(firstRuleId), true))
|
||||||
|
// All the rules failed to update
|
||||||
|
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(givenARuleId(secondRuleId), true))
|
||||||
|
|
||||||
|
// Then
|
||||||
|
coVerifyOrder {
|
||||||
|
// first rule id
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), firstRuleId, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_ONE_TO_ONE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_ONE_TO_ONE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE, any(), any())
|
||||||
|
|
||||||
|
// second rule id
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), secondRuleId, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_UNSTABLE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_UNSTABLE, any(), any())
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelTest
|
||||||
|
.assertStatesChanges(
|
||||||
|
initialState,
|
||||||
|
{ copy(isLoading = true) },
|
||||||
|
{ copy(isLoading = false) },
|
||||||
|
{ copy(isLoading = true) },
|
||||||
|
{ copy(isLoading = false) },
|
||||||
|
)
|
||||||
|
.assertEvents(
|
||||||
|
VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated(RuleIds.RULE_ID_ONE_TO_ONE_ROOM, true, failure),
|
||||||
|
VectorSettingsPushRuleNotificationViewEvent.Failure(failure),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a ruleId, when the rule is unchecked with an error, then the expected view event is posted`() = runTest {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val failure = mockk<Throwable>()
|
||||||
|
|
||||||
|
val firstRuleId = RuleIds.RULE_ID_ONE_TO_ONE_ROOM
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsSucceed()
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE, failure)
|
||||||
|
|
||||||
|
val secondRuleId = RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(secondRuleId, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_START, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_START_UNSTABLE, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_END, failure)
|
||||||
|
fakePushRuleService.givenUpdatePushRuleActionsFail(RuleIds.RULE_ID_POLL_END_UNSTABLE, failure)
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
// One rule failed to update
|
||||||
|
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(givenARuleId(firstRuleId), false))
|
||||||
|
// All the rules failed to update
|
||||||
|
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(givenARuleId(secondRuleId), false))
|
||||||
|
|
||||||
|
// Then
|
||||||
|
coVerifyOrder {
|
||||||
|
// first rule id
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), firstRuleId, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_ONE_TO_ONE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_ONE_TO_ONE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE, any(), any())
|
||||||
|
|
||||||
|
// second rule id
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), secondRuleId, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_START_UNSTABLE, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END, any(), any())
|
||||||
|
fakePushRuleService.updatePushRuleActions(any(), RuleIds.RULE_ID_POLL_END_UNSTABLE, any(), any())
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelTest
|
||||||
|
.assertStatesChanges(
|
||||||
|
initialState,
|
||||||
|
{ copy(isLoading = true) },
|
||||||
|
{ copy(isLoading = false) },
|
||||||
|
{ copy(isLoading = true) },
|
||||||
|
{ copy(isLoading = false) },
|
||||||
|
)
|
||||||
|
.assertEvents(
|
||||||
|
// The global rule remains checked if all the rules are not unchecked
|
||||||
|
VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated(RuleIds.RULE_ID_ONE_TO_ONE_ROOM, true, failure),
|
||||||
|
VectorSettingsPushRuleNotificationViewEvent.Failure(failure),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a rule id, when requesting the check state, returns the expected value according to the related rules`() {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val firstRuleId = RuleIds.RULE_ID_ONE_TO_ONE_ROOM
|
||||||
|
givenARuleId(firstRuleId, NotificationIndex.OFF)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_START_ONE_TO_ONE, NotificationIndex.OFF)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_START_ONE_TO_ONE_UNSTABLE, NotificationIndex.SILENT)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_END_ONE_TO_ONE, NotificationIndex.NOISY)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_END_ONE_TO_ONE_UNSTABLE, NotificationIndex.OFF)
|
||||||
|
|
||||||
|
val secondRuleId = RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS
|
||||||
|
givenARuleId(secondRuleId, NotificationIndex.OFF)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_START, NotificationIndex.OFF)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_START_UNSTABLE, NotificationIndex.OFF)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_END, NotificationIndex.OFF)
|
||||||
|
givenARuleId(RuleIds.RULE_ID_POLL_END_UNSTABLE, NotificationIndex.OFF)
|
||||||
|
|
||||||
|
// When
|
||||||
|
val firstResult = viewModel.isPushRuleChecked(firstRuleId)
|
||||||
|
val secondResult = viewModel.isPushRuleChecked(secondRuleId)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
firstResult shouldBe true
|
||||||
|
secondResult shouldBe false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun givenARuleId(ruleId: String, notificationIndex: NotificationIndex = NotificationIndex.NOISY): PushRuleAndKind {
|
||||||
|
val ruleAndKind = mockk<PushRuleAndKind> {
|
||||||
|
every { pushRule.ruleId } returns ruleId
|
||||||
|
every { pushRule.notificationIndex } returns notificationIndex
|
||||||
|
every { kind } returns mockk()
|
||||||
|
}
|
||||||
|
|
||||||
|
every { fakePushRuleService.getPushRules().findDefaultRule(ruleId) } returns ruleAndKind
|
||||||
|
|
||||||
|
return ruleAndKind
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coJustRun
|
||||||
|
import io.mockk.mockk
|
||||||
|
import org.matrix.android.sdk.api.session.pushrules.PushRuleService
|
||||||
|
|
||||||
|
class FakePushRuleService : PushRuleService by mockk(relaxed = true) {
|
||||||
|
|
||||||
|
fun givenUpdatePushRuleActionsSucceed(ruleId: String? = null) {
|
||||||
|
coJustRun { updatePushRuleActions(any(), ruleId ?: any(), any(), any()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun givenUpdatePushRuleActionsFail(ruleId: String? = null, failure: Throwable = mockk()) {
|
||||||
|
coEvery { updatePushRuleActions(any(), ruleId ?: any(), any(), any()) }.throws(failure)
|
||||||
|
}
|
||||||
|
}
|
@ -41,10 +41,11 @@ class FakeSession(
|
|||||||
val fakeHomeServerCapabilitiesService: FakeHomeServerCapabilitiesService = FakeHomeServerCapabilitiesService(),
|
val fakeHomeServerCapabilitiesService: FakeHomeServerCapabilitiesService = FakeHomeServerCapabilitiesService(),
|
||||||
val fakeSharedSecretStorageService: FakeSharedSecretStorageService = FakeSharedSecretStorageService(),
|
val fakeSharedSecretStorageService: FakeSharedSecretStorageService = FakeSharedSecretStorageService(),
|
||||||
val fakeRoomService: FakeRoomService = FakeRoomService(),
|
val fakeRoomService: FakeRoomService = FakeRoomService(),
|
||||||
|
val fakePushRuleService: FakePushRuleService = FakePushRuleService(),
|
||||||
val fakePushersService: FakePushersService = FakePushersService(),
|
val fakePushersService: FakePushersService = FakePushersService(),
|
||||||
val fakeUserService: FakeUserService = FakeUserService(),
|
val fakeUserService: FakeUserService = FakeUserService(),
|
||||||
private val fakeEventService: FakeEventService = FakeEventService(),
|
private val fakeEventService: FakeEventService = FakeEventService(),
|
||||||
val fakeSessionAccountDataService: FakeSessionAccountDataService = FakeSessionAccountDataService()
|
val fakeSessionAccountDataService: FakeSessionAccountDataService = FakeSessionAccountDataService(),
|
||||||
) : Session by mockk(relaxed = true) {
|
) : Session by mockk(relaxed = true) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -61,6 +62,7 @@ class FakeSession(
|
|||||||
override fun sharedSecretStorageService() = fakeSharedSecretStorageService
|
override fun sharedSecretStorageService() = fakeSharedSecretStorageService
|
||||||
override fun roomService() = fakeRoomService
|
override fun roomService() = fakeRoomService
|
||||||
override fun eventService() = fakeEventService
|
override fun eventService() = fakeEventService
|
||||||
|
override fun pushRuleService() = fakePushRuleService
|
||||||
override fun pushersService() = fakePushersService
|
override fun pushersService() = fakePushersService
|
||||||
override fun accountDataService() = fakeSessionAccountDataService
|
override fun accountDataService() = fakeSessionAccountDataService
|
||||||
override fun userService() = fakeUserService
|
override fun userService() = fakeUserService
|
||||||
|
Loading…
x
Reference in New Issue
Block a user