From 1f5df94c37cc7a7471b35e04e5d841bf6ef9156e Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Wed, 8 Feb 2023 09:49:59 +0100
Subject: [PATCH 1/9] Reorganize notification packages

---
 .../VectorSettingsNotificationPreferenceViewModel.kt      | 3 +++
 ...ectorSettingsPushRuleNotificationPreferenceFragment.kt | 2 +-
 ...ectorSettingsAdvancedNotificationPreferenceFragment.kt | 8 ++++++--
 ...VectorSettingsDefaultNotificationPreferenceFragment.kt | 5 +++--
 ...ngsKeywordAndMentionsNotificationPreferenceFragment.kt | 8 ++++++--
 .../VectorSettingsOtherNotificationPreferenceFragment.kt  | 5 +++--
 .../VectorSettingsNotificationsTroubleshootFragment.kt    | 2 +-
 .../DisableNotificationsForCurrentSessionUseCase.kt       | 4 ++--
 .../EnableNotificationsForCurrentSessionUseCase.kt        | 4 ++--
 .../ToggleNotificationsForCurrentSessionUseCase.kt        | 2 +-
 vector/src/main/res/xml/vector_settings_notifications.xml | 8 ++++----
 .../DisableNotificationsForCurrentSessionUseCaseTest.kt   | 2 ++
 .../EnableNotificationsForCurrentSessionUseCaseTest.kt    | 2 ++
 .../ToggleNotificationsForCurrentSessionUseCaseTest.kt    | 1 +
 .../VectorSettingsNotificationPreferenceViewModelTest.kt  | 3 +++
 15 files changed, 40 insertions(+), 19 deletions(-)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => advanced}/VectorSettingsAdvancedNotificationPreferenceFragment.kt (93%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => defaults}/VectorSettingsDefaultNotificationPreferenceFragment.kt (90%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => keywordandmentions}/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt (94%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => other}/VectorSettingsOtherNotificationPreferenceFragment.kt (88%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => troubleshoot}/VectorSettingsNotificationsTroubleshootFragment.kt (99%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => usecase}/DisableNotificationsForCurrentSessionUseCase.kt (92%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => usecase}/EnableNotificationsForCurrentSessionUseCase.kt (95%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{ => usecase}/ToggleNotificationsForCurrentSessionUseCase.kt (97%)

diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModel.kt
index 9530be599e..a1edcd93c6 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModel.kt
@@ -31,6 +31,9 @@ import im.vector.app.core.pushers.PushersManager
 import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
 import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
 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
 
 class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
index 7f856298ea..33f1b2dc6d 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
@@ -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");
  * you may not use this file except in compliance with the License.
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsAdvancedNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/advanced/VectorSettingsAdvancedNotificationPreferenceFragment.kt
similarity index 93%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsAdvancedNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/advanced/VectorSettingsAdvancedNotificationPreferenceFragment.kt
index 183d997ffb..ae7b261414 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsAdvancedNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/advanced/VectorSettingsAdvancedNotificationPreferenceFragment.kt
@@ -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");
  * 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
  * 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.preference.Preference
@@ -23,6 +23,10 @@ import im.vector.app.core.preference.PushRulePreference
 import im.vector.app.core.preference.VectorPreference
 import im.vector.app.core.utils.toast
 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 org.matrix.android.sdk.api.session.pushrules.RuleIds
 import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationPreferenceFragment.kt
similarity index 90%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationPreferenceFragment.kt
index 33ed7730eb..c63c20e579 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationPreferenceFragment.kt
@@ -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");
  * you may not use this file except in compliance with the License.
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-package im.vector.app.features.settings.notifications
+package im.vector.app.features.settings.notifications.defaults
 
 import android.os.Bundle
 import im.vector.app.R
 import im.vector.app.core.preference.VectorPreferenceCategory
 import im.vector.app.features.analytics.plan.MobileScreen
+import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationPreferenceFragment
 import org.matrix.android.sdk.api.session.pushrules.RuleIds
 
 class VectorSettingsDefaultNotificationPreferenceFragment :
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt
similarity index 94%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt
index d0a1bff50c..e16ddd502c 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt
@@ -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");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * 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.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.VectorPreferenceCategory
 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.VectorSettingsPushRuleNotificationPreferenceFragment
+import im.vector.app.features.settings.notifications.getStandardAction
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsOtherNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationPreferenceFragment.kt
similarity index 88%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsOtherNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationPreferenceFragment.kt
index 3638fb8526..bef76793dc 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsOtherNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationPreferenceFragment.kt
@@ -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");
  * you may not use this file except in compliance with the License.
@@ -14,10 +14,11 @@
  * 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.core.preference.VectorPreferenceCategory
+import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationPreferenceFragment
 import org.matrix.android.sdk.api.session.pushrules.RuleIds
 
 class VectorSettingsOtherNotificationPreferenceFragment :
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/troubleshoot/VectorSettingsNotificationsTroubleshootFragment.kt
similarity index 99%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/troubleshoot/VectorSettingsNotificationsTroubleshootFragment.kt
index c5d15e54e5..b814c981c9 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/troubleshoot/VectorSettingsNotificationsTroubleshootFragment.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * 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.content.BroadcastReceiver
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/DisableNotificationsForCurrentSessionUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/usecase/DisableNotificationsForCurrentSessionUseCase.kt
similarity index 92%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/DisableNotificationsForCurrentSessionUseCase.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/usecase/DisableNotificationsForCurrentSessionUseCase.kt
index 0c50a296f3..9ce0307820 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/DisableNotificationsForCurrentSessionUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/usecase/DisableNotificationsForCurrentSessionUseCase.kt
@@ -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");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * 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.UnregisterUnifiedPushUseCase
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/EnableNotificationsForCurrentSessionUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/usecase/EnableNotificationsForCurrentSessionUseCase.kt
similarity index 95%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/EnableNotificationsForCurrentSessionUseCase.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/usecase/EnableNotificationsForCurrentSessionUseCase.kt
index daf3890e33..2bb350b6ac 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/EnableNotificationsForCurrentSessionUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/usecase/EnableNotificationsForCurrentSessionUseCase.kt
@@ -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");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * 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.PushersManager
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/ToggleNotificationsForCurrentSessionUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/usecase/ToggleNotificationsForCurrentSessionUseCase.kt
similarity index 97%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/ToggleNotificationsForCurrentSessionUseCase.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/usecase/ToggleNotificationsForCurrentSessionUseCase.kt
index 3dc73f0a31..c717ab7657 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/ToggleNotificationsForCurrentSessionUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/usecase/ToggleNotificationsForCurrentSessionUseCase.kt
@@ -14,7 +14,7 @@
  * 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.pushers.UnifiedPushHelper
diff --git a/vector/src/main/res/xml/vector_settings_notifications.xml b/vector/src/main/res/xml/vector_settings_notifications.xml
index f4d7ff8cd5..4d6de52f16 100644
--- a/vector/src/main/res/xml/vector_settings_notifications.xml
+++ b/vector/src/main/res/xml/vector_settings_notifications.xml
@@ -25,21 +25,21 @@
             android:key="SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY"
             android:persistent="false"
             android:title="@string/settings_notification_default"
-            app:fragment="im.vector.app.features.settings.notifications.VectorSettingsDefaultNotificationPreferenceFragment" />
+            app:fragment="im.vector.app.features.settings.notifications.defaults.VectorSettingsDefaultNotificationPreferenceFragment" />
 
         <im.vector.app.core.preference.VectorPreference
             android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
             android:key="SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY"
             android:persistent="false"
             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.VectorSettingsKeywordAndMentionsNotificationPreferenceFragment" />
 
         <im.vector.app.core.preference.VectorPreference
             android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
             android:key="SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY"
             android:persistent="false"
             android:title="@string/settings_notification_other"
-            app:fragment="im.vector.app.features.settings.notifications.VectorSettingsOtherNotificationPreferenceFragment" />
+            app:fragment="im.vector.app.features.settings.notifications.other.VectorSettingsOtherNotificationPreferenceFragment" />
 
     </im.vector.app.core.preference.VectorPreferenceCategory>
 
@@ -119,7 +119,7 @@
         <im.vector.app.core.preference.VectorPreference
             android:key="SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY"
             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>
 
diff --git a/vector/src/test/java/im/vector/app/features/settings/notifications/DisableNotificationsForCurrentSessionUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/notifications/DisableNotificationsForCurrentSessionUseCaseTest.kt
index 669b20fc1a..ceb6fd9217 100644
--- a/vector/src/test/java/im/vector/app/features/settings/notifications/DisableNotificationsForCurrentSessionUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/notifications/DisableNotificationsForCurrentSessionUseCaseTest.kt
@@ -17,6 +17,8 @@
 package im.vector.app.features.settings.notifications
 
 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 io.mockk.coJustRun
 import io.mockk.coVerify
diff --git a/vector/src/test/java/im/vector/app/features/settings/notifications/EnableNotificationsForCurrentSessionUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/notifications/EnableNotificationsForCurrentSessionUseCaseTest.kt
index d58ba7645c..fa5d0a8bd1 100644
--- a/vector/src/test/java/im/vector/app/features/settings/notifications/EnableNotificationsForCurrentSessionUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/notifications/EnableNotificationsForCurrentSessionUseCaseTest.kt
@@ -18,6 +18,8 @@ package im.vector.app.features.settings.notifications
 
 import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
 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 io.mockk.coJustRun
 import io.mockk.coVerify
diff --git a/vector/src/test/java/im/vector/app/features/settings/notifications/ToggleNotificationsForCurrentSessionUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/notifications/ToggleNotificationsForCurrentSessionUseCaseTest.kt
index f49aafab8a..83a4265ace 100644
--- a/vector/src/test/java/im/vector/app/features/settings/notifications/ToggleNotificationsForCurrentSessionUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/notifications/ToggleNotificationsForCurrentSessionUseCaseTest.kt
@@ -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.DeleteNotificationSettingsAccountDataUseCase
 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.FakeUnifiedPushHelper
 import im.vector.app.test.fixtures.PusherFixture
diff --git a/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModelTest.kt
index ae36ee7600..c6755011f8 100644
--- a/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModelTest.kt
@@ -22,6 +22,9 @@ import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
 import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
 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.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.FakeVectorPreferences
 import im.vector.app.test.test

From 40119733b9e380b815dd0c026e40a65083d39a77 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Thu, 9 Feb 2023 11:32:24 +0100
Subject: [PATCH 2/9] Add ViewModel for push rules settings fragment

---
 .../app/core/di/MavericksViewModelModule.kt   |  8 ++
 ...sPushRuleNotificationPreferenceFragment.kt | 65 +++++++--------
 ...ushRuleNotificationPreferenceViewAction.kt | 24 ++++++
 ...PushRuleNotificationPreferenceViewEvent.kt | 24 ++++++
 ...PushRuleNotificationPreferenceViewModel.kt | 79 +++++++++++++++++++
 ...PushRuleNotificationPreferenceViewState.kt | 23 ++++++
 6 files changed, 191 insertions(+), 32 deletions(-)
 create mode 100644 vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewAction.kt
 create mode 100644 vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewEvent.kt
 create mode 100644 vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewModel.kt
 create mode 100644 vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewState.kt

diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
index 911bbfa4a3..22fd3abde7 100644
--- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
@@ -108,6 +108,7 @@ import im.vector.app.features.settings.labs.VectorSettingsLabsViewModel
 import im.vector.app.features.settings.legals.LegalsViewModel
 import im.vector.app.features.settings.locale.LocalePickerViewModel
 import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceViewModel
+import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationPreferenceViewModel
 import im.vector.app.features.settings.push.PushGatewaysViewModel
 import im.vector.app.features.settings.threepids.ThreePidsSettingsViewModel
 import im.vector.app.features.share.IncomingShareViewModel
@@ -694,6 +695,13 @@ interface MavericksViewModelModule {
             factory: VectorSettingsNotificationPreferenceViewModel.Factory
     ): MavericksAssistedViewModelFactory<*, *>
 
+    @Binds
+    @IntoMap
+    @MavericksViewModelKey(VectorSettingsPushRuleNotificationPreferenceViewModel::class)
+    fun vectorSettingsPushRuleNotificationPreferenceViewModelFactory(
+            factory: VectorSettingsPushRuleNotificationPreferenceViewModel.Factory
+    ): MavericksAssistedViewModelFactory<*, *>
+
     @Binds
     @IntoMap
     @MavericksViewModelKey(SetLinkViewModel::class)
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
index 33f1b2dc6d..e3ea07f9f5 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
@@ -16,19 +16,36 @@
 
 package im.vector.app.features.settings.notifications
 
-import androidx.lifecycle.lifecycleScope
+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
-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() {
 
+    private val viewModel: VectorSettingsPushRuleNotificationPreferenceViewModel by fragmentViewModel()
+
     abstract val prefKeyToPushRuleId: Map<String, String>
 
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        observeViewEvents()
+    }
+
+    private fun observeViewEvents() {
+        viewModel.observeViewEvents {
+            when (it) {
+                is VectorSettingsPushRuleNotificationPreferenceViewEvent.Failure -> refreshDisplay()
+                is VectorSettingsPushRuleNotificationPreferenceViewEvent.PushRuleUpdated -> updatePreference(it.ruleId, it.enabled)
+            }
+        }
+    }
+
     override fun bindPref() {
         for (preferenceKey in prefKeyToPushRuleId.keys) {
             val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!!
@@ -42,45 +59,29 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment :
                 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)
+                    viewModel.handle(VectorSettingsPushRuleNotificationPreferenceViewAction.UpdatePushRule(ruleAndKind, newValue as Boolean))
                     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
-                )
-            }
+    override fun invalidate() = withState(viewModel) { state ->
+        if (state.isLoading) {
+            displayLoadingView()
+        } else {
             hideLoadingView()
-            if (!isAdded) {
-                return@launch
-            }
-            result.onSuccess {
-                preference.isChecked = checked
-            }
-            result.onFailure { failure ->
-                // Restore the previous value
-                refreshDisplay()
-                displayErrorDialog(failure)
-            }
         }
     }
 
-    fun refreshDisplay() {
+    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
+    }
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewAction.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewAction.kt
new file mode 100644
index 0000000000..766b1aa730
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewAction.kt
@@ -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 VectorSettingsPushRuleNotificationPreferenceViewAction : VectorViewModelAction {
+    data class UpdatePushRule(val pushRuleAndKind: PushRuleAndKind, val checked: Boolean) : VectorSettingsPushRuleNotificationPreferenceViewAction
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewEvent.kt
new file mode 100644
index 0000000000..be8cd6c47a
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewEvent.kt
@@ -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.VectorViewEvents
+
+sealed interface VectorSettingsPushRuleNotificationPreferenceViewEvent : VectorViewEvents {
+    data class PushRuleUpdated(val ruleId: String, val enabled: Boolean) : VectorSettingsPushRuleNotificationPreferenceViewEvent
+    data class Failure(val throwable: Throwable) : VectorSettingsPushRuleNotificationPreferenceViewEvent
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewModel.kt
new file mode 100644
index 0000000000..0d2d2b9876
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewModel.kt
@@ -0,0 +1,79 @@
+/*
+ * 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 kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
+
+class VectorSettingsPushRuleNotificationPreferenceViewModel @AssistedInject constructor(
+        @Assisted initialState: VectorSettingsPushRuleNotificationPreferenceViewState,
+        private val activeSessionHolder: ActiveSessionHolder,
+) : VectorViewModel<VectorSettingsPushRuleNotificationPreferenceViewState,
+        VectorSettingsPushRuleNotificationPreferenceViewAction,
+        VectorSettingsPushRuleNotificationPreferenceViewEvent>(initialState) {
+
+    @AssistedFactory
+    interface Factory : MavericksAssistedViewModelFactory<VectorSettingsPushRuleNotificationPreferenceViewModel, VectorSettingsPushRuleNotificationPreferenceViewState> {
+        override fun create(initialState: VectorSettingsPushRuleNotificationPreferenceViewState): VectorSettingsPushRuleNotificationPreferenceViewModel
+    }
+
+    companion object : MavericksViewModelFactory<VectorSettingsPushRuleNotificationPreferenceViewModel, VectorSettingsPushRuleNotificationPreferenceViewState> by hiltMavericksViewModelFactory()
+
+    override fun handle(action: VectorSettingsPushRuleNotificationPreferenceViewAction) {
+        when (action) {
+            is VectorSettingsPushRuleNotificationPreferenceViewAction.UpdatePushRule -> handleUpdatePushRule(action.pushRuleAndKind, action.checked)
+        }
+    }
+
+    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 {
+            runCatching {
+                activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions(
+                        kind = kind,
+                        ruleId = ruleId,
+                        enable = enabled,
+                        actions = newActions
+                )
+            }.fold(
+                    onSuccess = {
+                        setState { copy(isLoading = false) }
+                        _viewEvents.post(VectorSettingsPushRuleNotificationPreferenceViewEvent.PushRuleUpdated(ruleId, checked))
+                    },
+                    onFailure = { failure ->
+                        setState { copy(isLoading = false) }
+                        _viewEvents.post(VectorSettingsPushRuleNotificationPreferenceViewEvent.Failure(failure))
+                    }
+            )
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewState.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewState.kt
new file mode 100644
index 0000000000..6f9095f1d9
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewState.kt
@@ -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 VectorSettingsPushRuleNotificationPreferenceViewState(
+        val isLoading: Boolean = false,
+): MavericksState

From 1c47983a9929855efb6c13b81b2fba1992afb429 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Thu, 9 Feb 2023 12:00:28 +0100
Subject: [PATCH 3/9] Rename notification settings objects

---
 .../app/core/di/MavericksViewModelModule.kt   | 12 +++----
 .../settings/VectorSettingsActivity.kt        |  4 +--
 ... => VectorSettingsNotificationFragment.kt} | 20 ++++++------
 ...> VectorSettingsNotificationViewAction.kt} |  8 ++---
 ...=> VectorSettingsNotificationViewEvent.kt} | 10 +++---
 ...=> VectorSettingsNotificationViewModel.kt} | 32 +++++++++----------
 ...orSettingsPushRuleNotificationFragment.kt} | 10 +++---
 ...SettingsPushRuleNotificationViewAction.kt} |  4 +--
 ...rSettingsPushRuleNotificationViewEvent.kt} |  6 ++--
 ...rSettingsPushRuleNotificationViewModel.kt} | 29 ++++++++++-------
 ...rSettingsPushRuleNotificationViewState.kt} |  2 +-
 ...torSettingsDefaultNotificationFragment.kt} |  6 ++--
 ...KeywordAndMentionsNotificationFragment.kt} |  6 ++--
 ...ectorSettingsOtherNotificationFragment.kt} |  6 ++--
 .../res/xml/vector_settings_notifications.xml |  6 ++--
 .../src/main/res/xml/vector_settings_root.xml |  2 +-
 ...ectorSettingsNotificationViewModelTest.kt} | 28 ++++++++--------
 17 files changed, 98 insertions(+), 93 deletions(-)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsNotificationPreferenceFragment.kt => VectorSettingsNotificationFragment.kt} (95%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsNotificationPreferenceViewAction.kt => VectorSettingsNotificationViewAction.kt} (80%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsNotificationPreferenceViewEvent.kt => VectorSettingsNotificationViewEvent.kt} (84%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsNotificationPreferenceViewModel.kt => VectorSettingsNotificationViewModel.kt} (77%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsPushRuleNotificationPreferenceFragment.kt => VectorSettingsPushRuleNotificationFragment.kt} (86%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsPushRuleNotificationPreferenceViewAction.kt => VectorSettingsPushRuleNotificationViewAction.kt} (82%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsPushRuleNotificationPreferenceViewEvent.kt => VectorSettingsPushRuleNotificationViewEvent.kt} (80%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsPushRuleNotificationPreferenceViewModel.kt => VectorSettingsPushRuleNotificationViewModel.kt} (65%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsPushRuleNotificationPreferenceViewState.kt => VectorSettingsPushRuleNotificationViewState.kt} (91%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/defaults/{VectorSettingsDefaultNotificationPreferenceFragment.kt => VectorSettingsDefaultNotificationFragment.kt} (92%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/{VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt => VectorSettingsKeywordAndMentionsNotificationFragment.kt} (97%)
 rename vector/src/main/java/im/vector/app/features/settings/notifications/other/{VectorSettingsOtherNotificationPreferenceFragment.kt => VectorSettingsOtherNotificationFragment.kt} (90%)
 rename vector/src/test/java/im/vector/app/features/settings/notifications/{VectorSettingsNotificationPreferenceViewModelTest.kt => VectorSettingsNotificationViewModelTest.kt} (86%)

diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
index 22fd3abde7..c78ba3643c 100644
--- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
@@ -107,8 +107,8 @@ import im.vector.app.features.settings.ignored.IgnoredUsersViewModel
 import im.vector.app.features.settings.labs.VectorSettingsLabsViewModel
 import im.vector.app.features.settings.legals.LegalsViewModel
 import im.vector.app.features.settings.locale.LocalePickerViewModel
-import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceViewModel
-import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationPreferenceViewModel
+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.threepids.ThreePidsSettingsViewModel
 import im.vector.app.features.share.IncomingShareViewModel
@@ -690,16 +690,16 @@ interface MavericksViewModelModule {
 
     @Binds
     @IntoMap
-    @MavericksViewModelKey(VectorSettingsNotificationPreferenceViewModel::class)
+    @MavericksViewModelKey(VectorSettingsNotificationViewModel::class)
     fun vectorSettingsNotificationPreferenceViewModelFactory(
-            factory: VectorSettingsNotificationPreferenceViewModel.Factory
+            factory: VectorSettingsNotificationViewModel.Factory
     ): MavericksAssistedViewModelFactory<*, *>
 
     @Binds
     @IntoMap
-    @MavericksViewModelKey(VectorSettingsPushRuleNotificationPreferenceViewModel::class)
+    @MavericksViewModelKey(VectorSettingsPushRuleNotificationViewModel::class)
     fun vectorSettingsPushRuleNotificationPreferenceViewModelFactory(
-            factory: VectorSettingsPushRuleNotificationPreferenceViewModel.Factory
+            factory: VectorSettingsPushRuleNotificationViewModel.Factory
     ): MavericksAssistedViewModelFactory<*, *>
 
     @Binds
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt
index 4a9db49c67..33557fabef 100755
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt
@@ -32,7 +32,7 @@ import im.vector.app.databinding.ActivityVectorSettingsBinding
 import im.vector.app.features.discovery.DiscoverySettingsFragment
 import im.vector.app.features.navigation.SettingsActivityPayload
 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.lib.core.utils.compat.getParcelableExtraCompat
 import org.matrix.android.sdk.api.failure.GlobalError
@@ -92,7 +92,7 @@ class VectorSettingsActivity : VectorBaseActivity<ActivityVectorSettingsBinding>
                 }
                 SettingsActivityPayload.Notifications -> {
                     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 -> {
                     replaceFragment(views.vectorSettingsPage, DiscoverySettingsFragment::class.java, payload, FRAGMENT_TAG)
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationFragment.kt
similarity index 95%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationFragment.kt
index 490a47ef61..dab7a9ed3a 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationFragment.kt
@@ -71,7 +71,7 @@ import javax.inject.Inject
 
 // Referenced in vector_settings_preferences_root.xml
 @AndroidEntryPoint
-class VectorSettingsNotificationPreferenceFragment :
+class VectorSettingsNotificationFragment :
         VectorSettingsBaseFragment(),
         BackgroundSyncModeChooserDialog.InteractionListener {
 
@@ -90,7 +90,7 @@ class VectorSettingsNotificationPreferenceFragment :
 
     private var interactionListener: VectorSettingsFragmentInteractionListener? = null
 
-    private val viewModel: VectorSettingsNotificationPreferenceViewModel by fragmentViewModel()
+    private val viewModel: VectorSettingsNotificationViewModel by fragmentViewModel()
 
     private val notificationStartForActivityResult = registerStartForActivityResult { _ ->
         // No op
@@ -116,10 +116,10 @@ class VectorSettingsNotificationPreferenceFragment :
     private fun observeViewEvents() {
         viewModel.observeViewEvents {
             when (it) {
-                VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled -> onNotificationsForDeviceEnabled()
-                VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled -> onNotificationsForDeviceDisabled()
-                is VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor()
-                VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged -> onNotificationMethodChanged()
+                VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled -> onNotificationsForDeviceEnabled()
+                VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled -> onNotificationsForDeviceDisabled()
+                is VectorSettingsNotificationViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor()
+                VectorSettingsNotificationViewEvent.NotificationMethodChanged -> onNotificationMethodChanged()
             }
         }
     }
@@ -143,9 +143,9 @@ class VectorSettingsNotificationPreferenceFragment :
         findPreference<SwitchPreference>(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
                 ?.setOnPreferenceChangeListener { _, isChecked ->
                     val action = if (isChecked as Boolean) {
-                        VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(pushDistributor = "")
+                        VectorSettingsNotificationViewAction.EnableNotificationsForDevice(pushDistributor = "")
                     } else {
-                        VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice
+                        VectorSettingsNotificationViewAction.DisableNotificationsForDevice
                     }
                     viewModel.handle(action)
                     // preference will be updated on ViewEvent reception
@@ -231,9 +231,9 @@ class VectorSettingsNotificationPreferenceFragment :
     private fun askUserToSelectPushDistributor(withUnregister: Boolean = false) {
         unifiedPushHelper.showSelectDistributorDialog(requireContext()) { selection ->
             if (withUnregister) {
-                viewModel.handle(VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(selection))
+                viewModel.handle(VectorSettingsNotificationViewAction.RegisterPushDistributor(selection))
             } else {
-                viewModel.handle(VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(selection))
+                viewModel.handle(VectorSettingsNotificationViewAction.EnableNotificationsForDevice(selection))
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewAction.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewAction.kt
similarity index 80%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewAction.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewAction.kt
index 949dc99993..4257f0a72b 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewAction.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewAction.kt
@@ -18,8 +18,8 @@ package im.vector.app.features.settings.notifications
 
 import im.vector.app.core.platform.VectorViewModelAction
 
-sealed interface VectorSettingsNotificationPreferenceViewAction : VectorViewModelAction {
-    data class EnableNotificationsForDevice(val pushDistributor: String) : VectorSettingsNotificationPreferenceViewAction
-    object DisableNotificationsForDevice : VectorSettingsNotificationPreferenceViewAction
-    data class RegisterPushDistributor(val pushDistributor: String) : VectorSettingsNotificationPreferenceViewAction
+sealed interface VectorSettingsNotificationViewAction : VectorViewModelAction {
+    data class EnableNotificationsForDevice(val pushDistributor: String) : VectorSettingsNotificationViewAction
+    object DisableNotificationsForDevice : VectorSettingsNotificationViewAction
+    data class RegisterPushDistributor(val pushDistributor: String) : VectorSettingsNotificationViewAction
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewEvent.kt
similarity index 84%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewEvent.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewEvent.kt
index b0ee107769..dd284a8bb1 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewEvent.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewEvent.kt
@@ -18,9 +18,9 @@ package im.vector.app.features.settings.notifications
 
 import im.vector.app.core.platform.VectorViewEvents
 
-sealed interface VectorSettingsNotificationPreferenceViewEvent : VectorViewEvents {
-    object NotificationsForDeviceEnabled : VectorSettingsNotificationPreferenceViewEvent
-    object NotificationsForDeviceDisabled : VectorSettingsNotificationPreferenceViewEvent
-    object AskUserForPushDistributor : VectorSettingsNotificationPreferenceViewEvent
-    object NotificationMethodChanged : VectorSettingsNotificationPreferenceViewEvent
+sealed interface VectorSettingsNotificationViewEvent : VectorViewEvents {
+    object NotificationsForDeviceEnabled : VectorSettingsNotificationViewEvent
+    object NotificationsForDeviceDisabled : VectorSettingsNotificationViewEvent
+    object AskUserForPushDistributor : VectorSettingsNotificationViewEvent
+    object NotificationMethodChanged : VectorSettingsNotificationViewEvent
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewModel.kt
similarity index 77%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModel.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewModel.kt
index a1edcd93c6..c980288d76 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewModel.kt
@@ -36,7 +36,7 @@ import im.vector.app.features.settings.notifications.usecase.EnableNotifications
 import im.vector.app.features.settings.notifications.usecase.ToggleNotificationsForCurrentSessionUseCase
 import kotlinx.coroutines.launch
 
-class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
+class VectorSettingsNotificationViewModel @AssistedInject constructor(
         @Assisted initialState: VectorDummyViewState,
         private val pushersManager: PushersManager,
         private val vectorPreferences: VectorPreferences,
@@ -46,23 +46,23 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
         private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
         private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
         private val toggleNotificationsForCurrentSessionUseCase: ToggleNotificationsForCurrentSessionUseCase,
-) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationPreferenceViewAction, VectorSettingsNotificationPreferenceViewEvent>(initialState) {
+) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationViewAction, VectorSettingsNotificationViewEvent>(initialState) {
 
     @AssistedFactory
-    interface Factory : MavericksAssistedViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> {
-        override fun create(initialState: VectorDummyViewState): VectorSettingsNotificationPreferenceViewModel
+    interface Factory : MavericksAssistedViewModelFactory<VectorSettingsNotificationViewModel, VectorDummyViewState> {
+        override fun create(initialState: VectorDummyViewState): VectorSettingsNotificationViewModel
     }
 
-    companion object : MavericksViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
+    companion object : MavericksViewModelFactory<VectorSettingsNotificationViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
 
     @VisibleForTesting
     val notificationsPreferenceListener: SharedPreferences.OnSharedPreferenceChangeListener =
             SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
                 if (key == VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY) {
                     if (vectorPreferences.areNotificationEnabledForDevice()) {
-                        _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
+                        _viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled)
                     } else {
-                        _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
+                        _viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled)
                     }
                 }
             }
@@ -80,18 +80,18 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
         super.onCleared()
     }
 
-    override fun handle(action: VectorSettingsNotificationPreferenceViewAction) {
+    override fun handle(action: VectorSettingsNotificationViewAction) {
         when (action) {
-            VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice -> handleDisableNotificationsForDevice()
-            is VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice -> handleEnableNotificationsForDevice(action.pushDistributor)
-            is VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor -> handleRegisterPushDistributor(action.pushDistributor)
+            VectorSettingsNotificationViewAction.DisableNotificationsForDevice -> handleDisableNotificationsForDevice()
+            is VectorSettingsNotificationViewAction.EnableNotificationsForDevice -> handleEnableNotificationsForDevice(action.pushDistributor)
+            is VectorSettingsNotificationViewAction.RegisterPushDistributor -> handleRegisterPushDistributor(action.pushDistributor)
         }
     }
 
     private fun handleDisableNotificationsForDevice() {
         viewModelScope.launch {
             disableNotificationsForCurrentSessionUseCase.execute()
-            _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
+            _viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled)
         }
     }
 
@@ -99,10 +99,10 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
         viewModelScope.launch {
             when (enableNotificationsForCurrentSessionUseCase.execute(distributor)) {
                 is EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor -> {
-                    _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
+                    _viewEvents.post(VectorSettingsNotificationViewEvent.AskUserForPushDistributor)
                 }
                 EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success -> {
-                    _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
+                    _viewEvents.post(VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled)
                 }
             }
         }
@@ -113,13 +113,13 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
             unregisterUnifiedPushUseCase.execute(pushersManager)
             when (registerUnifiedPushUseCase.execute(distributor)) {
                 RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
-                    _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
+                    _viewEvents.post(VectorSettingsNotificationViewEvent.AskUserForPushDistributor)
                 }
                 RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
                     val areNotificationsEnabled = vectorPreferences.areNotificationEnabledForDevice()
                     ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = areNotificationsEnabled)
                     toggleNotificationsForCurrentSessionUseCase.execute(enabled = areNotificationsEnabled)
-                    _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged)
+                    _viewEvents.post(VectorSettingsNotificationViewEvent.NotificationMethodChanged)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationFragment.kt
similarity index 86%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationFragment.kt
index e3ea07f9f5..e53e84e5b4 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationFragment.kt
@@ -25,10 +25,10 @@ import im.vector.app.core.preference.VectorCheckboxPreference
 import im.vector.app.features.settings.VectorSettingsBaseFragment
 import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
 
-abstract class VectorSettingsPushRuleNotificationPreferenceFragment :
+abstract class VectorSettingsPushRuleNotificationFragment :
         VectorSettingsBaseFragment() {
 
-    private val viewModel: VectorSettingsPushRuleNotificationPreferenceViewModel by fragmentViewModel()
+    private val viewModel: VectorSettingsPushRuleNotificationViewModel by fragmentViewModel()
 
     abstract val prefKeyToPushRuleId: Map<String, String>
 
@@ -40,8 +40,8 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment :
     private fun observeViewEvents() {
         viewModel.observeViewEvents {
             when (it) {
-                is VectorSettingsPushRuleNotificationPreferenceViewEvent.Failure -> refreshDisplay()
-                is VectorSettingsPushRuleNotificationPreferenceViewEvent.PushRuleUpdated -> updatePreference(it.ruleId, it.enabled)
+                is VectorSettingsPushRuleNotificationViewEvent.Failure -> refreshDisplay()
+                is VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated -> updatePreference(it.ruleId, it.enabled)
             }
         }
     }
@@ -59,7 +59,7 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment :
                 val initialIndex = ruleAndKind.pushRule.notificationIndex
                 preference.isChecked = initialIndex != NotificationIndex.OFF
                 preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
-                    viewModel.handle(VectorSettingsPushRuleNotificationPreferenceViewAction.UpdatePushRule(ruleAndKind, newValue as Boolean))
+                    viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(ruleAndKind, newValue as Boolean))
                     false
                 }
             }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewAction.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewAction.kt
similarity index 82%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewAction.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewAction.kt
index 766b1aa730..61bf7c5b15 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewAction.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewAction.kt
@@ -19,6 +19,6 @@ 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 VectorSettingsPushRuleNotificationPreferenceViewAction : VectorViewModelAction {
-    data class UpdatePushRule(val pushRuleAndKind: PushRuleAndKind, val checked: Boolean) : VectorSettingsPushRuleNotificationPreferenceViewAction
+sealed interface VectorSettingsPushRuleNotificationViewAction : VectorViewModelAction {
+    data class UpdatePushRule(val pushRuleAndKind: PushRuleAndKind, val checked: Boolean) : VectorSettingsPushRuleNotificationViewAction
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
similarity index 80%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewEvent.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
index be8cd6c47a..6c316623e5 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewEvent.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
@@ -18,7 +18,7 @@ package im.vector.app.features.settings.notifications
 
 import im.vector.app.core.platform.VectorViewEvents
 
-sealed interface VectorSettingsPushRuleNotificationPreferenceViewEvent : VectorViewEvents {
-    data class PushRuleUpdated(val ruleId: String, val enabled: Boolean) : VectorSettingsPushRuleNotificationPreferenceViewEvent
-    data class Failure(val throwable: Throwable) : VectorSettingsPushRuleNotificationPreferenceViewEvent
+sealed interface VectorSettingsPushRuleNotificationViewEvent : VectorViewEvents {
+    data class PushRuleUpdated(val ruleId: String, val enabled: Boolean) : VectorSettingsPushRuleNotificationViewEvent
+    data class Failure(val throwable: Throwable) : VectorSettingsPushRuleNotificationViewEvent
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
similarity index 65%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewModel.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
index 0d2d2b9876..e284a32ec0 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
@@ -24,26 +24,31 @@ 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.session.pushrules.rest.PushRuleAndKind
 
-class VectorSettingsPushRuleNotificationPreferenceViewModel @AssistedInject constructor(
-        @Assisted initialState: VectorSettingsPushRuleNotificationPreferenceViewState,
+private typealias ViewModel = VectorSettingsPushRuleNotificationViewModel
+private typealias ViewState = VectorSettingsPushRuleNotificationViewState
+
+class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
+        @Assisted initialState: ViewState,
         private val activeSessionHolder: ActiveSessionHolder,
-) : VectorViewModel<VectorSettingsPushRuleNotificationPreferenceViewState,
-        VectorSettingsPushRuleNotificationPreferenceViewAction,
-        VectorSettingsPushRuleNotificationPreferenceViewEvent>(initialState) {
+) : VectorViewModel<VectorSettingsPushRuleNotificationViewState,
+        VectorSettingsPushRuleNotificationViewAction,
+        VectorSettingsPushRuleNotificationViewEvent>(initialState) {
 
     @AssistedFactory
-    interface Factory : MavericksAssistedViewModelFactory<VectorSettingsPushRuleNotificationPreferenceViewModel, VectorSettingsPushRuleNotificationPreferenceViewState> {
-        override fun create(initialState: VectorSettingsPushRuleNotificationPreferenceViewState): VectorSettingsPushRuleNotificationPreferenceViewModel
+    interface Factory : MavericksAssistedViewModelFactory<ViewModel, ViewState> {
+        override fun create(initialState: ViewState): ViewModel
     }
 
-    companion object : MavericksViewModelFactory<VectorSettingsPushRuleNotificationPreferenceViewModel, VectorSettingsPushRuleNotificationPreferenceViewState> by hiltMavericksViewModelFactory()
+    companion object : MavericksViewModelFactory<ViewModel, ViewState> by hiltMavericksViewModelFactory()
 
-    override fun handle(action: VectorSettingsPushRuleNotificationPreferenceViewAction) {
+    override fun handle(action: VectorSettingsPushRuleNotificationViewAction) {
         when (action) {
-            is VectorSettingsPushRuleNotificationPreferenceViewAction.UpdatePushRule -> handleUpdatePushRule(action.pushRuleAndKind, action.checked)
+            is VectorSettingsPushRuleNotificationViewAction.UpdatePushRule -> handleUpdatePushRule(action.pushRuleAndKind, action.checked)
         }
     }
 
@@ -67,11 +72,11 @@ class VectorSettingsPushRuleNotificationPreferenceViewModel @AssistedInject cons
             }.fold(
                     onSuccess = {
                         setState { copy(isLoading = false) }
-                        _viewEvents.post(VectorSettingsPushRuleNotificationPreferenceViewEvent.PushRuleUpdated(ruleId, checked))
+                        _viewEvents.post(PushRuleUpdated(ruleId, checked))
                     },
                     onFailure = { failure ->
                         setState { copy(isLoading = false) }
-                        _viewEvents.post(VectorSettingsPushRuleNotificationPreferenceViewEvent.Failure(failure))
+                        _viewEvents.post(Failure(failure))
                     }
             )
         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewState.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewState.kt
similarity index 91%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewState.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewState.kt
index 6f9095f1d9..5355f4f608 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewState.kt
@@ -18,6 +18,6 @@ package im.vector.app.features.settings.notifications
 
 import com.airbnb.mvrx.MavericksState
 
-data class VectorSettingsPushRuleNotificationPreferenceViewState(
+data class VectorSettingsPushRuleNotificationViewState(
         val isLoading: Boolean = false,
 ): MavericksState
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationFragment.kt
similarity index 92%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationFragment.kt
index c63c20e579..009213ceff 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/defaults/VectorSettingsDefaultNotificationFragment.kt
@@ -20,11 +20,11 @@ import android.os.Bundle
 import im.vector.app.R
 import im.vector.app.core.preference.VectorPreferenceCategory
 import im.vector.app.features.analytics.plan.MobileScreen
-import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationPreferenceFragment
+import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationFragment
 import org.matrix.android.sdk.api.session.pushrules.RuleIds
 
-class VectorSettingsDefaultNotificationPreferenceFragment :
-        VectorSettingsPushRuleNotificationPreferenceFragment() {
+class VectorSettingsDefaultNotificationFragment :
+        VectorSettingsPushRuleNotificationFragment() {
 
     override var titleRes: Int = R.string.settings_notification_default
 
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationFragment.kt
similarity index 97%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationFragment.kt
index e16ddd502c..c408b8ea91 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/keywordandmentions/VectorSettingsKeywordAndMentionsNotificationFragment.kt
@@ -28,7 +28,7 @@ import im.vector.app.core.preference.VectorPreferenceCategory
 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.VectorSettingsPushRuleNotificationPreferenceFragment
+import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationFragment
 import im.vector.app.features.settings.notifications.getStandardAction
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -38,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.toJson
 
-class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment :
-        VectorSettingsPushRuleNotificationPreferenceFragment() {
+class VectorSettingsKeywordAndMentionsNotificationFragment :
+        VectorSettingsPushRuleNotificationFragment() {
 
     override var titleRes: Int = R.string.settings_notification_mentions_and_keywords
 
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationFragment.kt
similarity index 90%
rename from vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationPreferenceFragment.kt
rename to vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationFragment.kt
index bef76793dc..5f8ad08a80 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/other/VectorSettingsOtherNotificationFragment.kt
@@ -18,11 +18,11 @@ package im.vector.app.features.settings.notifications.other
 
 import im.vector.app.R
 import im.vector.app.core.preference.VectorPreferenceCategory
-import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationPreferenceFragment
+import im.vector.app.features.settings.notifications.VectorSettingsPushRuleNotificationFragment
 import org.matrix.android.sdk.api.session.pushrules.RuleIds
 
-class VectorSettingsOtherNotificationPreferenceFragment :
-        VectorSettingsPushRuleNotificationPreferenceFragment() {
+class VectorSettingsOtherNotificationFragment :
+        VectorSettingsPushRuleNotificationFragment() {
 
     override var titleRes: Int = R.string.settings_notification_other
 
diff --git a/vector/src/main/res/xml/vector_settings_notifications.xml b/vector/src/main/res/xml/vector_settings_notifications.xml
index 4d6de52f16..87f344fc54 100644
--- a/vector/src/main/res/xml/vector_settings_notifications.xml
+++ b/vector/src/main/res/xml/vector_settings_notifications.xml
@@ -25,21 +25,21 @@
             android:key="SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY"
             android:persistent="false"
             android:title="@string/settings_notification_default"
-            app:fragment="im.vector.app.features.settings.notifications.defaults.VectorSettingsDefaultNotificationPreferenceFragment" />
+            app:fragment="im.vector.app.features.settings.notifications.defaults.VectorSettingsDefaultNotificationFragment" />
 
         <im.vector.app.core.preference.VectorPreference
             android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
             android:key="SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY"
             android:persistent="false"
             android:title="@string/settings_notification_mentions_and_keywords"
-            app:fragment="im.vector.app.features.settings.notifications.keywordandmentions.VectorSettingsKeywordAndMentionsNotificationPreferenceFragment" />
+            app:fragment="im.vector.app.features.settings.notifications.keywordandmentions.VectorSettingsKeywordAndMentionsNotificationFragment" />
 
         <im.vector.app.core.preference.VectorPreference
             android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
             android:key="SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY"
             android:persistent="false"
             android:title="@string/settings_notification_other"
-            app:fragment="im.vector.app.features.settings.notifications.other.VectorSettingsOtherNotificationPreferenceFragment" />
+            app:fragment="im.vector.app.features.settings.notifications.other.VectorSettingsOtherNotificationFragment" />
 
     </im.vector.app.core.preference.VectorPreferenceCategory>
 
diff --git a/vector/src/main/res/xml/vector_settings_root.xml b/vector/src/main/res/xml/vector_settings_root.xml
index ffa8688cbd..59548d10cb 100644
--- a/vector/src/main/res/xml/vector_settings_root.xml
+++ b/vector/src/main/res/xml/vector_settings_root.xml
@@ -11,7 +11,7 @@
     <im.vector.app.core.preference.VectorPreference
         android:icon="@drawable/ic_settings_root_notification"
         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" />
 
     <im.vector.app.core.preference.VectorPreference
diff --git a/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewModelTest.kt
similarity index 86%
rename from vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModelTest.kt
rename to vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewModelTest.kt
index c6755011f8..ad7adc6b69 100644
--- a/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationViewModelTest.kt
@@ -38,7 +38,7 @@ import io.mockk.mockk
 import org.junit.Rule
 import org.junit.Test
 
-class VectorSettingsNotificationPreferenceViewModelTest {
+class VectorSettingsNotificationViewModelTest {
 
     @get:Rule
     val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher)
@@ -52,7 +52,7 @@ class VectorSettingsNotificationPreferenceViewModelTest {
     private val fakeEnsureFcmTokenIsRetrievedUseCase = mockk<EnsureFcmTokenIsRetrievedUseCase>()
     private val fakeToggleNotificationsForCurrentSessionUseCase = mockk<ToggleNotificationsForCurrentSessionUseCase>()
 
-    private fun createViewModel() = VectorSettingsNotificationPreferenceViewModel(
+    private fun createViewModel() = VectorSettingsNotificationViewModel(
             initialState = VectorDummyViewState(),
             pushersManager = fakePushersManager.instance,
             vectorPreferences = fakeVectorPreferences.instance,
@@ -68,7 +68,7 @@ class VectorSettingsNotificationPreferenceViewModelTest {
     fun `given view model init when notifications are enabled in preferences then view event is posted`() {
         // Given
         fakeVectorPreferences.givenAreNotificationsEnabledForDevice(true)
-        val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled
+        val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled
         val viewModel = createViewModel()
 
         // When
@@ -85,7 +85,7 @@ class VectorSettingsNotificationPreferenceViewModelTest {
     fun `given view model init when notifications are disabled in preferences then view event is posted`() {
         // Given
         fakeVectorPreferences.givenAreNotificationsEnabledForDevice(false)
-        val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled
+        val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled
         val viewModel = createViewModel()
 
         // When
@@ -102,9 +102,9 @@ class VectorSettingsNotificationPreferenceViewModelTest {
     fun `given DisableNotificationsForDevice action when handling action then disable use case is called`() {
         // Given
         val viewModel = createViewModel()
-        val action = VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice
+        val action = VectorSettingsNotificationViewAction.DisableNotificationsForDevice
         coJustRun { fakeDisableNotificationsForCurrentSessionUseCase.execute() }
-        val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled
+        val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceDisabled
 
         // When
         val viewModelTest = viewModel.test()
@@ -124,10 +124,10 @@ class VectorSettingsNotificationPreferenceViewModelTest {
         // Given
         val viewModel = createViewModel()
         val aDistributor = "aDistributor"
-        val action = VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(aDistributor)
+        val action = VectorSettingsNotificationViewAction.EnableNotificationsForDevice(aDistributor)
         coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
                 EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success
-        val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled
+        val expectedEvent = VectorSettingsNotificationViewEvent.NotificationsForDeviceEnabled
 
         // When
         val viewModelTest = viewModel.test()
@@ -147,10 +147,10 @@ class VectorSettingsNotificationPreferenceViewModelTest {
         // Given
         val viewModel = createViewModel()
         val aDistributor = "aDistributor"
-        val action = VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(aDistributor)
+        val action = VectorSettingsNotificationViewAction.EnableNotificationsForDevice(aDistributor)
         coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
                 EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor
-        val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor
+        val expectedEvent = VectorSettingsNotificationViewEvent.AskUserForPushDistributor
 
         // When
         val viewModelTest = viewModel.test()
@@ -170,14 +170,14 @@ class VectorSettingsNotificationPreferenceViewModelTest {
         // Given
         val viewModel = createViewModel()
         val aDistributor = "aDistributor"
-        val action = VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(aDistributor)
+        val action = VectorSettingsNotificationViewAction.RegisterPushDistributor(aDistributor)
         coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
         coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
         val areNotificationsEnabled = true
         fakeVectorPreferences.givenAreNotificationsEnabledForDevice(areNotificationsEnabled)
         coJustRun { fakeToggleNotificationsForCurrentSessionUseCase.execute(any()) }
         justRun { fakeEnsureFcmTokenIsRetrievedUseCase.execute(any(), any()) }
-        val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged
+        val expectedEvent = VectorSettingsNotificationViewEvent.NotificationMethodChanged
 
         // When
         val viewModelTest = viewModel.test()
@@ -200,10 +200,10 @@ class VectorSettingsNotificationPreferenceViewModelTest {
         // Given
         val viewModel = createViewModel()
         val aDistributor = "aDistributor"
-        val action = VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(aDistributor)
+        val action = VectorSettingsNotificationViewAction.RegisterPushDistributor(aDistributor)
         coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor
         coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
-        val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor
+        val expectedEvent = VectorSettingsNotificationViewEvent.AskUserForPushDistributor
 
         // When
         val viewModelTest = viewModel.test()

From 71455706cb807187b23c1a3c8fa0c0e68acd50e1 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Thu, 9 Feb 2023 17:34:59 +0100
Subject: [PATCH 4/9] Sync poll rules with messages rule

---
 .../sdk/api/session/pushrules/RuleIds.kt      | 28 +++++++++
 .../sdk/api/session/pushrules/rest/RuleSet.kt | 21 +++----
 .../notifications/PushRuleDefinitions.kt      | 13 ++++-
 ...torSettingsPushRuleNotificationFragment.kt | 16 +++--
 ...orSettingsPushRuleNotificationViewEvent.kt |  2 +-
 ...orSettingsPushRuleNotificationViewModel.kt | 58 ++++++++++++++-----
 6 files changed, 99 insertions(+), 39 deletions(-)

diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/RuleIds.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/RuleIds.kt
index 4f35fb79c3..a3755f85b7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/RuleIds.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/RuleIds.kt
@@ -47,8 +47,36 @@ object RuleIds {
     const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = ".m.rule.message"
     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
     const val RULE_ID_FALLBACK = ".m.rule.fallback"
 
     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()
+        }
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt
index 9498ed002c..9287a7828d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt
@@ -47,21 +47,14 @@ data class RuleSet(
      * @param ruleId a RULE_ID_XX value
      * @return the matched bing rule or null it doesn't exist.
      */
-    fun findDefaultRule(ruleId: String?): PushRuleAndKind? {
-        var result: PushRuleAndKind? = null
-        // sanity check
-        if (null != ruleId) {
-            if (RuleIds.RULE_ID_CONTAIN_USER_NAME == ruleId) {
-                result = findRule(content, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.CONTENT) }
-            } else {
-                // assume that the ruleId is unique.
-                result = findRule(override, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.OVERRIDE) }
-                if (null == result) {
-                    result = findRule(underride, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.UNDERRIDE) }
-                }
-            }
+    fun findDefaultRule(ruleId: String): PushRuleAndKind? {
+        return if (RuleIds.RULE_ID_CONTAIN_USER_NAME == ruleId) {
+            findRule(content, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.CONTENT) }
+        } else {
+            // assume that the ruleId is unique.
+            findRule(override, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.OVERRIDE) }
+                    ?: findRule(underride, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.UNDERRIDE) }
         }
-        return result
     }
 
     /**
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/PushRuleDefinitions.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/PushRuleDefinitions.kt
index 264da7c4a3..fff6ffe933 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/PushRuleDefinitions.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/PushRuleDefinitions.kt
@@ -38,7 +38,12 @@ fun getStandardAction(ruleId: String, index: NotificationIndex): StandardActions
                 NotificationIndex.SILENT -> StandardActions.Notify
                 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) {
                 NotificationIndex.OFF -> StandardActions.DontNotify
                 NotificationIndex.SILENT -> StandardActions.Notify
@@ -50,7 +55,11 @@ fun getStandardAction(ruleId: String, index: NotificationIndex): StandardActions
                 NotificationIndex.SILENT -> StandardActions.Notify
                 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) {
                 NotificationIndex.OFF -> StandardActions.DontNotify
                 NotificationIndex.SILENT -> StandardActions.Notify
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationFragment.kt
index e53e84e5b4..0f991867fe 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationFragment.kt
@@ -23,7 +23,6 @@ import com.airbnb.mvrx.fragmentViewModel
 import com.airbnb.mvrx.withState
 import im.vector.app.core.preference.VectorCheckboxPreference
 import im.vector.app.features.settings.VectorSettingsBaseFragment
-import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
 
 abstract class VectorSettingsPushRuleNotificationFragment :
         VectorSettingsBaseFragment() {
@@ -35,13 +34,20 @@ abstract class VectorSettingsPushRuleNotificationFragment :
     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.enabled)
+                is VectorSettingsPushRuleNotificationViewEvent.PushRuleUpdated -> updatePreference(it.ruleId, it.checked)
             }
         }
     }
@@ -50,14 +56,13 @@ abstract class VectorSettingsPushRuleNotificationFragment :
         for (preferenceKey in prefKeyToPushRuleId.keys) {
             val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!!
             preference.isIconSpaceReserved = false
-            val ruleAndKind: PushRuleAndKind? = session.pushRuleService().getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey])
+            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
-                val initialIndex = ruleAndKind.pushRule.notificationIndex
-                preference.isChecked = initialIndex != NotificationIndex.OFF
+                updatePreference(ruleAndKind.pushRule.ruleId, viewModel.isPushRuleChecked(ruleAndKind.pushRule.ruleId))
                 preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
                     viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(ruleAndKind, newValue as Boolean))
                     false
@@ -81,7 +86,6 @@ abstract class VectorSettingsPushRuleNotificationFragment :
     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
     }
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
index 6c316623e5..14d86d7ba7 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
@@ -19,6 +19,6 @@ package im.vector.app.features.settings.notifications
 import im.vector.app.core.platform.VectorViewEvents
 
 sealed interface VectorSettingsPushRuleNotificationViewEvent : VectorViewEvents {
-    data class PushRuleUpdated(val ruleId: String, val enabled: Boolean) : VectorSettingsPushRuleNotificationViewEvent
+    data class PushRuleUpdated(val ruleId: String, val checked: Boolean) : VectorSettingsPushRuleNotificationViewEvent
     data class Failure(val throwable: Throwable) : VectorSettingsPushRuleNotificationViewEvent
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
index e284a32ec0..c681576ce0 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
@@ -27,6 +27,11 @@ 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
@@ -52,6 +57,15 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
         }
     }
 
+    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
@@ -62,23 +76,35 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
         setState { copy(isLoading = true) }
 
         viewModelScope.launch {
-            runCatching {
-                activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions(
-                        kind = kind,
-                        ruleId = ruleId,
-                        enable = enabled,
-                        actions = newActions
-                )
-            }.fold(
-                    onSuccess = {
-                        setState { copy(isLoading = false) }
-                        _viewEvents.post(PushRuleUpdated(ruleId, checked))
-                    },
-                    onFailure = { failure ->
-                        setState { copy(isLoading = false) }
-                        _viewEvents.post(Failure(failure))
-                    }
+            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 { it.exceptionOrNull() }
+            if (failure == null) {
+                _viewEvents.post(PushRuleUpdated(ruleId, checked))
+            } else {
+                _viewEvents.post(Failure(failure))
+            }
+        }
+    }
+
+    private suspend fun updatePushRule(kind: RuleKind, ruleId: String, enable: Boolean, newActions: List<Action>?) {
+        try {
+            activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions(
+                    kind = kind,
+                    ruleId = ruleId,
+                    enable = enable,
+                    actions = newActions
             )
+        } catch (failure: ServerError) {
+            // Ignore the error if the rule id is not known from the server
+            if (failure.error.code != MatrixError.M_NOT_FOUND) {
+                throw failure
+            }
         }
     }
 }

From 25d49806ccff776b3f974ba9d2949a724f6ae8d5 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Fri, 10 Feb 2023 15:29:56 +0100
Subject: [PATCH 5/9] Improve view events and add unit tests

---
 ...orSettingsPushRuleNotificationViewEvent.kt |  17 +-
 ...orSettingsPushRuleNotificationViewModel.kt |  35 +--
 ...ttingsPushRuleNotificationViewModelTest.kt | 258 ++++++++++++++++++
 .../app/test/fakes/FakePushRuleService.kt     |  33 +++
 .../im/vector/app/test/fakes/FakeSession.kt   |   4 +-
 5 files changed, 328 insertions(+), 19 deletions(-)
 create mode 100644 vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt
 create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakePushRuleService.kt

diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
index 14d86d7ba7..adfc17f827 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewEvent.kt
@@ -19,6 +19,19 @@ package im.vector.app.features.settings.notifications
 import im.vector.app.core.platform.VectorViewEvents
 
 sealed interface VectorSettingsPushRuleNotificationViewEvent : VectorViewEvents {
-    data class PushRuleUpdated(val ruleId: String, val checked: Boolean) : VectorSettingsPushRuleNotificationViewEvent
-    data class Failure(val throwable: Throwable) : VectorSettingsPushRuleNotificationViewEvent
+    /**
+     * 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
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
index c681576ce0..39969ec13e 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModel.kt
@@ -83,9 +83,19 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
                 }
             }
             setState { copy(isLoading = false) }
-            val failure = results.firstNotNullOfOrNull { it.exceptionOrNull() }
-            if (failure == null) {
-                _viewEvents.post(PushRuleUpdated(ruleId, checked))
+            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))
             }
@@ -93,18 +103,11 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
     }
 
     private suspend fun updatePushRule(kind: RuleKind, ruleId: String, enable: Boolean, newActions: List<Action>?) {
-        try {
-            activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions(
-                    kind = kind,
-                    ruleId = ruleId,
-                    enable = enable,
-                    actions = newActions
-            )
-        } catch (failure: ServerError) {
-            // Ignore the error if the rule id is not known from the server
-            if (failure.error.code != MatrixError.M_NOT_FOUND) {
-                throw failure
-            }
-        }
+        activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions(
+                kind = kind,
+                ruleId = ruleId,
+                enable = enable,
+                actions = newActions
+        )
     }
 }
diff --git a/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt
new file mode 100644
index 0000000000..ff1cedee86
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt
@@ -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, then the related rules are also updated and a 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 and an error is thrown, then all the related rules are updated and an event is posted with the failure`() = 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 and an error is thrown, then all the related rules are updated and an event is posted with the failure`() = 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
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakePushRuleService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakePushRuleService.kt
new file mode 100644
index 0000000000..4560f58978
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakePushRuleService.kt
@@ -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)
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt
index a05dce9c54..1b6d3e2729 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt
@@ -41,10 +41,11 @@ class FakeSession(
         val fakeHomeServerCapabilitiesService: FakeHomeServerCapabilitiesService = FakeHomeServerCapabilitiesService(),
         val fakeSharedSecretStorageService: FakeSharedSecretStorageService = FakeSharedSecretStorageService(),
         val fakeRoomService: FakeRoomService = FakeRoomService(),
+        val fakePushRuleService: FakePushRuleService = FakePushRuleService(),
         val fakePushersService: FakePushersService = FakePushersService(),
         val fakeUserService: FakeUserService = FakeUserService(),
         private val fakeEventService: FakeEventService = FakeEventService(),
-        val fakeSessionAccountDataService: FakeSessionAccountDataService = FakeSessionAccountDataService()
+        val fakeSessionAccountDataService: FakeSessionAccountDataService = FakeSessionAccountDataService(),
 ) : Session by mockk(relaxed = true) {
 
     init {
@@ -61,6 +62,7 @@ class FakeSession(
     override fun sharedSecretStorageService() = fakeSharedSecretStorageService
     override fun roomService() = fakeRoomService
     override fun eventService() = fakeEventService
+    override fun pushRuleService() = fakePushRuleService
     override fun pushersService() = fakePushersService
     override fun accountDataService() = fakeSessionAccountDataService
     override fun userService() = fakeUserService

From c8fda158a3c04f8061af452fdff2ddc9509992d2 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Fri, 10 Feb 2023 16:33:41 +0100
Subject: [PATCH 6/9] Changelog

---
 changelog.d/8007.feature | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 changelog.d/8007.feature

diff --git a/changelog.d/8007.feature b/changelog.d/8007.feature
new file mode 100644
index 0000000000..0ae4cc49af
--- /dev/null
+++ b/changelog.d/8007.feature
@@ -0,0 +1 @@
+[Poll] Synchronize polls push rules with message push rules

From 6aa4eb5e040b2b2896f9c90fa12d8bbb5061f188 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Fri, 10 Feb 2023 16:43:40 +0100
Subject: [PATCH 7/9] Fix lint issues

---
 .../VectorSettingsPushRuleNotificationViewState.kt          | 2 +-
 .../VectorSettingsPushRuleNotificationViewModelTest.kt      | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewState.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewState.kt
index 5355f4f608..477727aee6 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewState.kt
@@ -20,4 +20,4 @@ import com.airbnb.mvrx.MavericksState
 
 data class VectorSettingsPushRuleNotificationViewState(
         val isLoading: Boolean = false,
-): MavericksState
+) : MavericksState
diff --git a/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt
index ff1cedee86..04a22bc21f 100644
--- a/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationViewModelTest.kt
@@ -59,7 +59,7 @@ internal class VectorSettingsPushRuleNotificationViewModelTest {
     }
 
     @Test
-    fun `given a ruleId, when the rule is checked or unchecked, then the related rules are also updated and a view event is posted`() = runTest {
+    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()
 
@@ -105,7 +105,7 @@ internal class VectorSettingsPushRuleNotificationViewModelTest {
     }
 
     @Test
-    fun `given a ruleId, when the rule is checked and an error is thrown, then all the related rules are updated and an event is posted with the failure`() = runTest {
+    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>()
@@ -161,7 +161,7 @@ internal class VectorSettingsPushRuleNotificationViewModelTest {
     }
 
     @Test
-    fun `given a ruleId, when the rule is unchecked and an error is thrown, then all the related rules are updated and an event is posted with the failure`() = runTest {
+    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>()

From 2cb1ea95dc4df15df662a2a2cf414f8359302c45 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Tue, 14 Feb 2023 17:06:28 +0100
Subject: [PATCH 8/9] Allow notifications for poll end event

---
 .../sdk/internal/session/pushrules/ProcessEventForPushTask.kt   | 1 +
 .../app/features/notifications/NotifiableEventResolver.kt       | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt
index 9fe93d8262..3dfac694ed 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt
@@ -57,6 +57,7 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
         val allEvents = (newJoinEvents + inviteEvents).filter { event ->
             when (event.type) {
                 in EventType.POLL_START.values,
+                in EventType.POLL_END.values,
                 in EventType.STATE_ROOM_BEACON_INFO.values,
                 EventType.MESSAGE,
                 EventType.REDACTION,
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt
index a69958ef25..14a36d9922 100644
--- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt
@@ -67,7 +67,7 @@ class NotifiableEventResolver @Inject constructor(
 ) {
 
     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? {
         val roomID = event.roomId ?: return null

From 0a0ad2d91e7e00c575da3d868c1bad7d5b6bd477 Mon Sep 17 00:00:00 2001
From: Florian Renaud <florianr@element.io>
Date: Tue, 14 Feb 2023 17:54:27 +0100
Subject: [PATCH 9/9] Add todo

---
 .../VectorSettingsAdvancedNotificationPreferenceFragment.kt    | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/advanced/VectorSettingsAdvancedNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/advanced/VectorSettingsAdvancedNotificationPreferenceFragment.kt
index ae7b261414..44d7330d39 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/advanced/VectorSettingsAdvancedNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/advanced/VectorSettingsAdvancedNotificationPreferenceFragment.kt
@@ -31,6 +31,7 @@ import kotlinx.coroutines.launch
 import org.matrix.android.sdk.api.session.pushrules.RuleIds
 import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
 
+// TODO This fragment seems not used anymore, we can probably delete it
 @AndroidEntryPoint
 class VectorSettingsAdvancedNotificationPreferenceFragment :
         VectorSettingsBaseFragment() {
@@ -43,7 +44,7 @@ class VectorSettingsAdvancedNotificationPreferenceFragment :
         for (preferenceKey in prefKeyToPushRuleId.keys) {
             val preference = findPreference<VectorPreference>(preferenceKey)
             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) {
                     // The rule is not defined, hide the preference