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

View file

@ -17,8 +17,7 @@
package im.vector.app.features.settings.notifications
import im.vector.app.core.platform.VectorViewModelAction
import org.matrix.android.sdk.api.session.pushrules.rest.PushRuleAndKind
sealed interface VectorSettingsPushRuleNotificationViewAction : VectorViewModelAction {
data class UpdatePushRule(val pushRuleAndKind: PushRuleAndKind, val checked: Boolean) : VectorSettingsPushRuleNotificationViewAction
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.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
@ -30,6 +29,7 @@ import im.vector.app.features.settings.notifications.usecase.GetPushRulesOnInval
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.Session
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.RuleIds
@ -43,7 +43,7 @@ private typealias ViewState = VectorSettingsPushRuleNotificationViewState
class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
@Assisted initialState: ViewState,
private val activeSessionHolder: ActiveSessionHolder,
private val session: Session,
private val getPushRulesOnInvalidStateUseCase: GetPushRulesOnInvalidStateUseCase,
) : VectorViewModel<VectorSettingsPushRuleNotificationViewState,
VectorSettingsPushRuleNotificationViewAction,
@ -57,24 +57,27 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
companion object : MavericksViewModelFactory<ViewModel, ViewState> by hiltMavericksViewModelFactory()
init {
val session = activeSessionHolder.getSafeActiveSession()
session?.flow()
?.liveUserAccountData(UserAccountDataTypes.TYPE_PUSH_RULES)
?.unwrap()
?.setOnEach {
session.flow()
.liveUserAccountData(UserAccountDataTypes.TYPE_PUSH_RULES)
.unwrap()
.setOnEach {
val allRules = session.pushRuleService().getPushRules().getAllRules()
val rulesOnError = getPushRulesOnInvalidStateUseCase.execute(session).map { it.ruleId }.toSet()
copy(rulesOnError = rulesOnError)
copy(
allRules = allRules,
rulesOnError = rulesOnError
)
}
}
override fun handle(action: VectorSettingsPushRuleNotificationViewAction) {
when (action) {
is VectorSettingsPushRuleNotificationViewAction.UpdatePushRule -> handleUpdatePushRule(action.pushRuleAndKind, action.checked)
is VectorSettingsPushRuleNotificationViewAction.UpdatePushRule -> handleUpdatePushRule(action.ruleId, action.checked)
}
}
fun getPushRuleAndKind(ruleId: String): PushRuleAndKind? {
return activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.getPushRules()?.findDefaultRule(ruleId)
return session.pushRuleService().getPushRules().findDefaultRule(ruleId)
}
fun isPushRuleChecked(ruleId: String): Boolean {
@ -82,9 +85,8 @@ class VectorSettingsPushRuleNotificationViewModel @AssistedInject constructor(
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
private fun handleUpdatePushRule(ruleId: String, checked: Boolean) {
val kind = getPushRuleAndKind(ruleId)?.kind ?: return
val newIndex = if (checked) NotificationIndex.NOISY else NotificationIndex.OFF
val standardAction = getStandardAction(ruleId, newIndex) ?: return
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>?) {
activeSessionHolder.getSafeActiveSession()?.pushRuleService()?.updatePushRuleActions(
session.pushRuleService().updatePushRuleActions(
kind = kind,
ruleId = ruleId,
enable = enable,

View file

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