Refresh push rules settings on account data changes

This commit is contained in:
Florian Renaud 2023-02-17 17:38:47 +01:00
parent 8f56f9de46
commit 13866c62bf
4 changed files with 40 additions and 36 deletions

View file

@ -36,6 +36,7 @@ abstract class VectorSettingsPushRuleNotificationFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
observeViewEvents() observeViewEvents()
viewModel.onEach(VectorSettingsPushRuleNotificationViewState::allRules) { refreshPreferences() }
viewModel.onEach(VectorSettingsPushRuleNotificationViewState::isLoading) { updateLoadingView(it) } viewModel.onEach(VectorSettingsPushRuleNotificationViewState::isLoading) { updateLoadingView(it) }
viewModel.onEach(VectorSettingsPushRuleNotificationViewState::rulesOnError) { refreshErrors(it) } viewModel.onEach(VectorSettingsPushRuleNotificationViewState::rulesOnError) { refreshErrors(it) }
} }
@ -55,18 +56,11 @@ abstract class VectorSettingsPushRuleNotificationFragment :
} }
override fun bindPref() { override fun bindPref() {
for (preferenceKey in prefKeyToPushRuleId.keys) { prefKeyToPushRuleId.forEach { (preferenceKey, ruleId) ->
val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!! findPreference<VectorCheckboxPreference>(preferenceKey)?.apply {
preference.isIconSpaceReserved = false isIconSpaceReserved = false
val ruleAndKind = prefKeyToPushRuleId[preferenceKey]?.let { viewModel.getPushRuleAndKind(it) } onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
if (ruleAndKind == null) { viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(ruleId, newValue as Boolean))
// The rule is not defined, hide the preference
preference.isVisible = false
} else {
preference.isVisible = true
updatePreference(ruleAndKind.pushRule.ruleId, viewModel.isPushRuleChecked(ruleAndKind.pushRule.ruleId))
preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
viewModel.handle(VectorSettingsPushRuleNotificationViewAction.UpdatePushRule(ruleAndKind, newValue as Boolean))
false false
} }
} }
@ -81,16 +75,21 @@ abstract class VectorSettingsPushRuleNotificationFragment :
} }
} }
private fun refreshPreferences() {
prefKeyToPushRuleId.values.forEach { ruleId -> updatePreference(ruleId, viewModel.isPushRuleChecked(ruleId)) }
}
private fun refreshErrors(rulesWithError: Set<String>) { private fun refreshErrors(rulesWithError: Set<String>) {
if (withState(viewModel, VectorSettingsPushRuleNotificationViewState::isLoading)) return if (withState(viewModel, VectorSettingsPushRuleNotificationViewState::isLoading)) return
prefKeyToPushRuleId.forEach { (preferenceKey, ruleId) -> prefKeyToPushRuleId.forEach { (preferenceKey, ruleId) ->
val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!! findPreference<VectorCheckboxPreference>(preferenceKey)?.apply {
if (ruleId in rulesWithError) { if (ruleId in rulesWithError) {
preference.summaryTextColor = context?.let { ThemeUtils.getColor(it, R.attr.colorError) } summaryTextColor = ThemeUtils.getColor(context, R.attr.colorError)
preference.setSummary(R.string.settings_notification_error_on_update) setSummary(R.string.settings_notification_error_on_update)
} else { } else {
preference.summaryTextColor = null summaryTextColor = null
preference.summary = null summary = null
}
} }
} }
} }
@ -102,6 +101,8 @@ abstract class VectorSettingsPushRuleNotificationFragment :
private fun updatePreference(ruleId: String, checked: Boolean) { private fun updatePreference(ruleId: String, checked: Boolean) {
val preferenceKey = prefKeyToPushRuleId.entries.find { it.value == ruleId }?.key ?: return val preferenceKey = prefKeyToPushRuleId.entries.find { it.value == ruleId }?.key ?: return
val preference = findPreference<VectorCheckboxPreference>(preferenceKey) ?: return val preference = findPreference<VectorCheckboxPreference>(preferenceKey) ?: return
val ruleIds = withState(viewModel) { state -> state.allRules.map { it.ruleId } }
preference.isVisible = ruleId in ruleIds
preference.isChecked = checked preference.isChecked = checked
} }

View file

@ -17,8 +17,7 @@
package im.vector.app.features.settings.notifications package im.vector.app.features.settings.notifications
import im.vector.app.core.platform.VectorViewModelAction import im.vector.app.core.platform.VectorViewModelAction
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
sealed interface VectorSettingsPushRuleNotificationViewAction : VectorViewModelAction { sealed interface VectorSettingsPushRuleNotificationViewAction : VectorViewModelAction {
data class UpdatePushRule(val pushRuleAndKind: PushRuleAndKind, val checked: Boolean) : VectorSettingsPushRuleNotificationViewAction data class UpdatePushRule(val ruleId: String, val checked: Boolean) : VectorSettingsPushRuleNotificationViewAction
} }

View file

@ -20,7 +20,6 @@ import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
@ -30,6 +29,7 @@ import im.vector.app.features.settings.notifications.usecase.GetPushRulesOnInval
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.failure.Failure.ServerError import org.matrix.android.sdk.api.failure.Failure.ServerError
import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.failure.MatrixError
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
import org.matrix.android.sdk.api.session.pushrules.Action 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.RuleIds
@ -43,7 +43,7 @@ private typealias ViewState = VectorSettingsPushRuleNotificationViewState
class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor( class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
@Assisted initialState: ViewState, @Assisted initialState: ViewState,
private val activeSessionHolder: ActiveSessionHolder, private val session: Session,
private val getPushRulesOnInvalidStateUseCase: GetPushRulesOnInvalidStateUseCase, private val getPushRulesOnInvalidStateUseCase: GetPushRulesOnInvalidStateUseCase,
) : VectorViewModel<VectorSettingsPushRuleNotificationViewState, ) : VectorViewModel<VectorSettingsPushRuleNotificationViewState,
VectorSettingsPushRuleNotificationViewAction, VectorSettingsPushRuleNotificationViewAction,
@ -57,24 +57,27 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
companion object : MavericksViewModelFactory<ViewModel, ViewState> by hiltMavericksViewModelFactory() companion object : MavericksViewModelFactory<ViewModel, ViewState> by hiltMavericksViewModelFactory()
init { init {
val session = activeSessionHolder.getSafeActiveSession() session.flow()
session?.flow() .liveUserAccountData(UserAccountDataTypes.TYPE_PUSH_RULES)
?.liveUserAccountData(UserAccountDataTypes.TYPE_PUSH_RULES) .unwrap()
?.unwrap() .setOnEach {
?.setOnEach { val allRules = session.pushRuleService().getPushRules().getAllRules()
val rulesOnError = getPushRulesOnInvalidStateUseCase.execute(session).map { it.ruleId }.toSet() val rulesOnError = getPushRulesOnInvalidStateUseCase.execute(session).map { it.ruleId }.toSet()
copy(rulesOnError = rulesOnError) copy(
allRules = allRules,
rulesOnError = rulesOnError
)
} }
} }
override fun handle(action: VectorSettingsPushRuleNotificationViewAction) { override fun handle(action: VectorSettingsPushRuleNotificationViewAction) {
when (action) { when (action) {
is VectorSettingsPushRuleNotificationViewAction.UpdatePushRule -> handleUpdatePushRule(action.pushRuleAndKind, action.checked) is VectorSettingsPushRuleNotificationViewAction.UpdatePushRule -> handleUpdatePushRule(action.ruleId, action.checked)
} }
} }
fun getPushRuleAndKind(ruleId: String): PushRuleAndKind? { fun getPushRuleAndKind(ruleId: String): PushRuleAndKind? {
return activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.getPushRules()?.findDefaultRule(ruleId) return session.pushRuleService().getPushRules().findDefaultRule(ruleId)
} }
fun isPushRuleChecked(ruleId: String): Boolean { fun isPushRuleChecked(ruleId: String): Boolean {
@ -82,9 +85,8 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
return rulesGroup.mapNotNull { getPushRuleAndKind(it) }.any { it.pushRule.notificationIndex != NotificationIndex.OFF } return rulesGroup.mapNotNull { getPushRuleAndKind(it) }.any { it.pushRule.notificationIndex != NotificationIndex.OFF }
} }
private fun handleUpdatePushRule(pushRuleAndKind: PushRuleAndKind, checked: Boolean) { private fun handleUpdatePushRule(ruleId: String, checked: Boolean) {
val ruleId = pushRuleAndKind.pushRule.ruleId val kind = getPushRuleAndKind(ruleId)?.kind ?: return
val kind = pushRuleAndKind.kind
val newIndex = if (checked) NotificationIndex.NOISY else NotificationIndex.OFF val newIndex = if (checked) NotificationIndex.NOISY else NotificationIndex.OFF
val standardAction = getStandardAction(ruleId, newIndex) ?: return val standardAction = getStandardAction(ruleId, newIndex) ?: return
val enabled = standardAction != StandardActions.Disabled val enabled = standardAction != StandardActions.Disabled
@ -129,7 +131,7 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
} }
private suspend fun updatePushRule(kind: RuleKind, ruleId: String, enable: Boolean, newActions: List<Action>?) { private suspend fun updatePushRule(kind: RuleKind, ruleId: String, enable: Boolean, newActions: List<Action>?) {
activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions( session.pushRuleService().updatePushRuleActions(
kind = kind, kind = kind,
ruleId = ruleId, ruleId = ruleId,
enable = enable, enable = enable,

View file

@ -17,8 +17,10 @@
package im.vector.app.features.settings.notifications package im.vector.app.features.settings.notifications
import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksState
import org.matrix.android.sdk.api.session.pushrules.rest.PushRule
data class VectorSettingsPushRuleNotificationViewState( data class VectorSettingsPushRuleNotificationViewState(
val isLoading: Boolean = false, val isLoading: Boolean = false,
val rulesOnError: Set<String> = emptySet() val allRules: List<PushRule> = emptyList(),
val rulesOnError: Set<String> = emptySet(),
) : MavericksState ) : MavericksState