From d6f1f276c2f0f3624c9182407a094f531b714c3a Mon Sep 17 00:00:00 2001 From: langleyd <davidl@element.io> Date: Mon, 12 Jul 2021 14:07:27 +0100 Subject: [PATCH 01/21] Add checkbox preference, remove PushRulePreference, Split adavanced fragment to new 3 new fragments and inherit common function --- .../im/vector/app/core/di/FragmentModule.kt | 9 +- .../preference/VectorCheckboxPreference.kt | 92 +++++++++++ ...sAdvancedNotificationPreferenceFragment.kt | 105 ------------ ...ngsGlobalNotificationPreferenceFragment.kt | 38 +++++ ...dMentionsNotificationPreferenceFragment.kt | 36 +++++ ...ingsOtherNotificationPreferenceFragment.kt | 37 +++++ ...PushRuleNotificationPreferenceFragment.kt} | 150 +++++++++--------- .../layout/vector_preference_push_rule.xml | 79 --------- vector/src/main/res/values/strings.xml | 6 + ...ings_notification_advanced_preferences.xml | 67 -------- .../vector_settings_notification_global.xml | 28 ++++ ...ngs_notification_mentions_and_keywords.xml | 23 +++ .../vector_settings_notification_other.xml | 27 ++++ .../res/xml/vector_settings_notifications.xml | 21 ++- 14 files changed, 383 insertions(+), 335 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt delete mode 100644 vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt rename vector/src/main/java/im/vector/app/{core/preference/PushRulePreference.kt => features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt} (56%) mode change 100755 => 100644 delete mode 100644 vector/src/main/res/layout/vector_preference_push_rule.xml delete mode 100644 vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml create mode 100644 vector/src/main/res/xml/vector_settings_notification_global.xml create mode 100644 vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml create mode 100644 vector/src/main/res/xml/vector_settings_notification_other.xml diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 8580543022..77e7e7ad72 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -111,7 +111,6 @@ import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.app.features.roomprofile.uploads.files.RoomUploadsFilesFragment import im.vector.app.features.roomprofile.uploads.media.RoomUploadsMediaFragment -import im.vector.app.features.settings.VectorSettingsAdvancedNotificationPreferenceFragment import im.vector.app.features.settings.VectorSettingsGeneralFragment import im.vector.app.features.settings.VectorSettingsHelpAboutFragment import im.vector.app.features.settings.VectorSettingsLabsFragment @@ -390,10 +389,10 @@ interface FragmentModule { @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment - @Binds - @IntoMap - @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) - fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment +// @Binds +// @IntoMap +// @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) +// fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment @Binds @IntoMap diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt b/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt new file mode 100644 index 0000000000..fd7a2ef5c5 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.preference + +import android.animation.Animator +import android.animation.ArgbEvaluator +import android.animation.ValueAnimator +import android.content.Context +import android.graphics.Color +import android.util.AttributeSet +import android.widget.TextView +import androidx.core.animation.doOnEnd +import androidx.preference.CheckBoxPreference +import androidx.preference.PreferenceViewHolder +import im.vector.app.R +import im.vector.app.features.themes.ThemeUtils + +open class VectorCheckboxPreference : CheckBoxPreference { + // Note: @JvmOverload does not work here... + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context) : super(context) + + init { + // Set to false to remove the space when there is no icon + isIconSpaceReserved = true + } + + var isHighlighted = false + set(value) { + field = value + notifyChanged() + } + + var currentHighlightAnimator: Animator? = null + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + // display the title in multi-line to avoid ellipsis. + (holder.findViewById(android.R.id.title) as? TextView)?.isSingleLine = false + + // cancel existing animation (find a way to resume if happens during anim?) + currentHighlightAnimator?.cancel() + + val itemView = holder.itemView + if (isHighlighted) { + val colorFrom = Color.TRANSPARENT + val colorTo = ThemeUtils.getColor(itemView.context, R.attr.colorControlHighlight) + currentHighlightAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo).apply { + duration = 250 // milliseconds + addUpdateListener { animator -> + itemView.setBackgroundColor(animator.animatedValue as Int) + } + doOnEnd { + currentHighlightAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorTo, colorFrom).apply { + duration = 250 // milliseconds + addUpdateListener { animator -> + itemView.setBackgroundColor(animator.animatedValue as Int) + } + doOnEnd { + isHighlighted = false + } + start() + } + } + startDelay = 200 + start() + } + } else { + itemView.setBackgroundColor(Color.TRANSPARENT) + } + + super.onBindViewHolder(holder) + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt deleted file mode 100644 index 8d9f8d7170..0000000000 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2018 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 - -import androidx.lifecycle.lifecycleScope -import androidx.preference.Preference -import im.vector.app.R -import im.vector.app.core.preference.PushRulePreference -import im.vector.app.core.preference.VectorPreference -import im.vector.app.core.utils.toast -import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.pushrules.RuleIds -import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind -import javax.inject.Inject - -class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor() - : VectorSettingsBaseFragment() { - - override var titleRes: Int = R.string.settings_notification_advanced - - override val preferenceXmlRes = R.xml.vector_settings_notification_advanced_preferences - - override fun bindPref() { - for (preferenceKey in prefKeyToPushRuleId.keys) { - val preference = findPreference<VectorPreference>(preferenceKey) - if (preference is PushRulePreference) { - // preference.isEnabled = null != rules && isConnected && pushManager.areDeviceNotificationsAllowed() - val ruleAndKind: PushRuleAndKind? = session.getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey]) - - if (ruleAndKind == null) { - // The rule is not defined, hide the preference - preference.isVisible = false - } else { - preference.isVisible = true - preference.setPushRule(ruleAndKind) - preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> - val newRule = preference.createNewRule(newValue as Int) - if (newRule != null) { - displayLoadingView() - - lifecycleScope.launch { - val result = runCatching { - session.updatePushRuleActions(ruleAndKind.kind, - preference.ruleAndKind?.pushRule ?: ruleAndKind.pushRule, - newRule) - } - if (!isAdded) { - return@launch - } - hideLoadingView() - result.onSuccess { - preference.setPushRule(ruleAndKind.copy(pushRule = newRule)) - } - result.onFailure { failure -> - // Restore the previous value - refreshDisplay() - activity?.toast(errorFormatter.toHumanReadable(failure)) - } - } - } - false - } - } - } - } - } - - private fun refreshDisplay() { - listView?.adapter?.notifyDataSetChanged() - } - - /* ========================================================================================== - * Companion - * ========================================================================================== */ - - companion object { - // preference name <-> rule Id - private val prefKeyToPushRuleId = mapOf( - "SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_DISPLAY_NAME, - "SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_USER_NAME, - "SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ROOM, - "SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, - "SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_INVITE_ME, - "SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to RuleIds.RULE_ID_CALL, - "SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" to RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS, - "SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_ROOM_NOTIF, - "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ENCRYPTED_ROOM, - "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ENCRYPTED, - "SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" to RuleIds.RULE_ID_TOMBSTONE - ) - } -} diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt new file mode 100644 index 0000000000..a91b3c5ef7 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings + +import im.vector.app.R +import org.matrix.android.sdk.api.pushrules.RuleIds +import javax.inject.Inject + +class VectorSettingsGlobalNotificationPreferenceFragment @Inject constructor() + : VectorSettingsPushRuleNotificationPreferenceFragment() { + + override var titleRes: Int = R.string.settings_notification_global + + override val preferenceXmlRes = R.xml.vector_settings_notification_global + + override val prefKeyToPushRuleId: Map<String, String> + get() = mapOf( + "SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ROOM, + "SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, + "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ENCRYPTED_ROOM, + "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ENCRYPTED + ) +} + diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt new file mode 100644 index 0000000000..0c7ed23070 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings + +import im.vector.app.R +import org.matrix.android.sdk.api.pushrules.RuleIds +import javax.inject.Inject + +class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment @Inject constructor() + : VectorSettingsPushRuleNotificationPreferenceFragment() { + + override var titleRes: Int = R.string.settings_notification_mentions_and_keywords + + override val preferenceXmlRes = R.xml.vector_settings_notification_mentions_and_keywords + + override val prefKeyToPushRuleId: Map<String, String> + get() = mapOf( + "SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_DISPLAY_NAME, + "SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_USER_NAME, + "SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_ROOM_NOTIF + ) +} diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt new file mode 100644 index 0000000000..bf58ab27a1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings + +import im.vector.app.R +import org.matrix.android.sdk.api.pushrules.RuleIds +import javax.inject.Inject + +class VectorSettingsOtherNotificationPreferenceFragment @Inject constructor() + : VectorSettingsPushRuleNotificationPreferenceFragment() { + + override var titleRes: Int = R.string.settings_notification_other + + override val preferenceXmlRes = R.xml.vector_settings_notification_other + + override val prefKeyToPushRuleId: Map<String, String> + get() = mapOf( + "SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_INVITE_ME, + "SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to RuleIds.RULE_ID_CALL, + "SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" to RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS, + "SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" to RuleIds.RULE_ID_TOMBSTONE + ) +} diff --git a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt old mode 100755 new mode 100644 similarity index 56% rename from vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt rename to vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt index c3e324b64a..2f274ce904 --- a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018 New Vector Ltd + * Copyright (c) 2021 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,43 +14,39 @@ * limitations under the License. */ -package im.vector.app.core.preference +package im.vector.app.features.settings -import android.content.Context -import android.util.AttributeSet -import android.view.View -import android.widget.RadioGroup -import androidx.preference.PreferenceViewHolder -import im.vector.app.R +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import im.vector.app.core.preference.VectorCheckboxPreference +import im.vector.app.core.utils.toast +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.pushrules.Action import org.matrix.android.sdk.api.pushrules.RuleIds import org.matrix.android.sdk.api.pushrules.RuleSetKey import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind -class PushRulePreference : VectorPreference { +abstract class VectorSettingsPushRuleNotificationPreferenceFragment + : VectorSettingsBaseFragment() { - /** - * @return the selected push rule and its kind - */ - var ruleAndKind: PushRuleAndKind? = null - private set - constructor(context: Context) : super(context) + fun indexFromBooleanPreference(pushRuleOn: Boolean): Int { + return if (pushRuleOn) { + NOTIFICATION_NOISY_INDEX + } else { + NOTIFICATION_OFF_INDEX + } + } - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - - constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) - - init { - layoutResource = R.layout.vector_preference_push_rule + fun booleanPreferenceFromIndex(index: Int): Boolean { + return index != NOTIFICATION_OFF_INDEX } /** * @return the bing rule status index */ - private val ruleStatusIndex: Int - get() { + fun ruleStatusIndexFor(ruleAndKind: PushRuleAndKind? ): Int { val safeRule = ruleAndKind?.pushRule ?: return NOTIFICATION_OFF_INDEX if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { @@ -78,36 +74,16 @@ class PushRulePreference : VectorPreference { return NOTIFICATION_OFF_INDEX } - /** - * Update the push rule. - * - * @param pushRule - */ - fun setPushRule(pushRuleAndKind: PushRuleAndKind?) { - ruleAndKind = pushRuleAndKind - refreshSummary() - } - - /** - * Refresh the summary - */ - private fun refreshSummary() { - summary = context.getString(when (ruleStatusIndex) { - NOTIFICATION_OFF_INDEX -> R.string.notification_off - NOTIFICATION_SILENT_INDEX -> R.string.notification_silent - else -> R.string.notification_noisy - }) - } - /** * Create a push rule with the updated required at index. * * @param index index * @return a push rule with the updated flags / null if there is no update */ - fun createNewRule(index: Int): PushRule? { + fun createNewRule(ruleAndKind: PushRuleAndKind?, index: Int): PushRule? { val safeRule = ruleAndKind?.pushRule ?: return null - val safeKind = ruleAndKind?.kind ?: return null + val safeKind = ruleAndKind.kind + val ruleStatusIndex = ruleStatusIndexFor(ruleAndKind) return if (index != ruleStatusIndex) { if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { @@ -126,7 +102,7 @@ class PushRulePreference : VectorPreference { .setNotify(true) .setNotificationSound() } - else -> safeRule + else -> safeRule } } else { if (NOTIFICATION_OFF_INDEX == index) { @@ -160,43 +136,67 @@ class PushRulePreference : VectorPreference { } } - override fun onBindViewHolder(holder: PreferenceViewHolder) { - super.onBindViewHolder(holder) - holder.findViewById(android.R.id.summary)?.visibility = View.GONE - holder.itemView.setOnClickListener(null) - holder.itemView.setOnLongClickListener(null) + override fun bindPref() { + for (preferenceKey in prefKeyToPushRuleId.keys) { + val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!! + // preference.isEnabled = null != rules && isConnected && pushManager.areDeviceNotificationsAllowed() + val ruleAndKind: PushRuleAndKind? = session.getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey]) - val radioGroup = holder.findViewById(R.id.bingPreferenceRadioGroup) as? RadioGroup - radioGroup?.setOnCheckedChangeListener(null) + if (ruleAndKind == null) { + // The rule is not defined, hide the preference + preference.isVisible = false + } else { + preference.isVisible = true - when (ruleStatusIndex) { - NOTIFICATION_OFF_INDEX -> { - radioGroup?.check(R.id.bingPreferenceRadioBingRuleOff) - } - NOTIFICATION_SILENT_INDEX -> { - radioGroup?.check(R.id.bingPreferenceRadioBingRuleSilent) - } - else -> { - radioGroup?.check(R.id.bingPreferenceRadioBingRuleNoisy) - } - } + val index = ruleStatusIndexFor(ruleAndKind) + val boolPreference = booleanPreferenceFromIndex(index) + preference.isChecked = boolPreference + preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + val newIndex = indexFromBooleanPreference(newValue as Boolean) + val newRule = createNewRule(ruleAndKind, newIndex) - radioGroup?.setOnCheckedChangeListener { _, checkedId -> - when (checkedId) { - R.id.bingPreferenceRadioBingRuleOff -> { - onPreferenceChangeListener?.onPreferenceChange(this, NOTIFICATION_OFF_INDEX) - } - R.id.bingPreferenceRadioBingRuleSilent -> { - onPreferenceChangeListener?.onPreferenceChange(this, NOTIFICATION_SILENT_INDEX) - } - R.id.bingPreferenceRadioBingRuleNoisy -> { - onPreferenceChangeListener?.onPreferenceChange(this, NOTIFICATION_NOISY_INDEX) + if (newRule != null) { + displayLoadingView() + + lifecycleScope.launch { + val result = runCatching { + session.updatePushRuleActions( + ruleAndKind.kind, + ruleAndKind.pushRule, + newRule + ) + } + if (!isAdded) { + return@launch + } + hideLoadingView() + result.onSuccess { + preference.isChecked = newValue + } + result.onFailure { failure -> + // Restore the previous value + refreshDisplay() + activity?.toast(errorFormatter.toHumanReadable(failure)) + } + } + } + false } } } } + private fun refreshDisplay() { + listView?.adapter?.notifyDataSetChanged() + } + + /* ========================================================================================== + * Companion + * ========================================================================================== */ + + abstract val prefKeyToPushRuleId: Map<String, String> + companion object { // index in mRuleStatuses diff --git a/vector/src/main/res/layout/vector_preference_push_rule.xml b/vector/src/main/res/layout/vector_preference_push_rule.xml deleted file mode 100644 index 5242bfdf85..0000000000 --- a/vector/src/main/res/layout/vector_preference_push_rule.xml +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="?android:attr/selectableItemBackground" - android:baselineAligned="false" - android:clipToPadding="false" - android:gravity="center_vertical" - android:minHeight="?android:attr/listPreferredItemHeightSmall" - android:orientation="vertical" - android:paddingStart="?android:attr/listPreferredItemPaddingLeft" - android:paddingEnd="?android:attr/listPreferredItemPaddingRight"> - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="16dp"> - - <TextView - android:id="@android:id/title" - style="@style/Widget.Vector.TextView.Body" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ellipsize="marquee" - android:singleLine="true" - android:textAppearance="?textAppearanceListItem" - android:textColor="?vctr_content_primary" - tools:text="Title" /> - - <TextView - android:id="@android:id/summary" - style="@style/Widget.Vector.TextView.Body" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_below="@android:id/title" - android:layout_alignStart="@android:id/title" - android:maxLines="2" - android:paddingTop="6dp" - android:textAppearance="?textAppearanceListItemSecondary" - android:textColor="?vctr_content_secondary" - tools:text="Summary" - tools:visibility="visible" /> - - </RelativeLayout> - - <RadioGroup - android:id="@+id/bingPreferenceRadioGroup" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical|end" - android:orientation="horizontal" - android:paddingTop="6dp" - android:paddingBottom="16dp"> - - <RadioButton - android:id="@+id/bingPreferenceRadioBingRuleOff" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/notification_off" - tools:checked="true" /> - - <RadioButton - android:id="@+id/bingPreferenceRadioBingRuleSilent" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/notification_silent" /> - - <RadioButton - android:id="@+id/bingPreferenceRadioBingRuleNoisy" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/notification_noisy" /> - - </RadioGroup> - -</LinearLayout> - - diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 0159c98c20..154d5619b4 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1075,6 +1075,12 @@ <string name="settings_notification_advanced">Advanced Notification Settings</string> <string name="settings_notification_by_event">Notification importance by event</string> + <string name="settings_notification_global">Global Notifications</string> + <string name="settings_notification_mentions_and_keywords">Mentions and Keywords</string> + <string name="settings_notification_other">Other</string> + + <string name="settings_notification_notify_me_for">Notify me for</string> + <string name="settings_notification_privacy">Notification privacy</string> <string name="settings_notification_troubleshoot">Troubleshoot Notifications</string> <string name="settings_troubleshoot_diagnostic">Troubleshooting diagnostics</string> diff --git a/vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml b/vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml deleted file mode 100644 index 4e9a9b07bf..0000000000 --- a/vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - - <im.vector.app.core.preference.VectorPreferenceCategory - android:key="SETTINGS_NOTIFICATION_LEVEL" - android:title="@string/settings_notification_by_event"> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_containing_my_display_name" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_containing_my_user_name" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_messages_at_room" /> - - <!-- TODO Support message with keywords rule --> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_messages_in_one_to_one" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_messages_in_e2e_one_to_one" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_messages_in_group_chat" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_messages_in_e2e_group_chat" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_invited_to_room" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_call_invitations" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" - android:persistent="false" - android:title="@string/settings_messages_sent_by_bot" /> - - <im.vector.app.core.preference.PushRulePreference - android:key="SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" - android:persistent="false" - android:title="@string/settings_when_rooms_are_upgraded" /> - - </im.vector.app.core.preference.VectorPreferenceCategory> - -</androidx.preference.PreferenceScreen> diff --git a/vector/src/main/res/xml/vector_settings_notification_global.xml b/vector/src/main/res/xml/vector_settings_notification_global.xml new file mode 100644 index 0000000000..787419bd55 --- /dev/null +++ b/vector/src/main/res/xml/vector_settings_notification_global.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <im.vector.app.core.preference.VectorPreferenceCategory + android:key="SETTINGS_OTHER" + android:title="@string/settings_notification_notify_me_for"> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_one_to_one" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_e2e_one_to_one" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_group_chat" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_e2e_group_chat" /> + + </im.vector.app.core.preference.VectorPreferenceCategory> +</PreferenceScreen> \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml b/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml new file mode 100644 index 0000000000..c84bf53faa --- /dev/null +++ b/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <im.vector.app.core.preference.VectorPreferenceCategory + android:key="SETTINGS_KEYWORDS_AND_MENTIONS" + android:title="@string/settings_notification_notify_me_for"> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_containing_my_display_name" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_containing_my_user_name" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_at_room" /> + + </im.vector.app.core.preference.VectorPreferenceCategory> +</PreferenceScreen> \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_notification_other.xml b/vector/src/main/res/xml/vector_settings_notification_other.xml new file mode 100644 index 0000000000..e1119e7c16 --- /dev/null +++ b/vector/src/main/res/xml/vector_settings_notification_other.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <im.vector.app.core.preference.VectorPreferenceCategory + android:key="SETTINGS_OTHER" + android:title="@string/settings_notification_notify_me_for"> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_invited_to_room" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_call_invitations" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_sent_by_bot" /> + + <im.vector.app.core.preference.VectorCheckboxPreference + android:key="SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" + android:persistent="false" + android:title="@string/settings_when_rooms_are_upgraded" /> + </im.vector.app.core.preference.VectorPreferenceCategory> +</PreferenceScreen> \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_notifications.xml b/vector/src/main/res/xml/vector_settings_notifications.xml index 983ddf36f2..35e21ca320 100644 --- a/vector/src/main/res/xml/vector_settings_notifications.xml +++ b/vector/src/main/res/xml/vector_settings_notifications.xml @@ -22,11 +22,24 @@ <im.vector.app.core.preference.VectorPreference android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY" - android:key="SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY" + android:key="SETTINGS_NOTIFICATION_GLOBAL_PREFERENCE_KEY" android:persistent="false" - android:summary="@string/settings_notification_advanced_summary" - android:title="@string/settings_notification_advanced" - app:fragment="im.vector.app.features.settings.VectorSettingsAdvancedNotificationPreferenceFragment" /> + android:title="@string/settings_notification_global" + app:fragment="im.vector.app.features.settings.VectorSettingsGlobalNotificationPreferenceFragment" /> + +<!-- <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.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.VectorSettingsOtherNotificationPreferenceFragment" />--> </im.vector.app.core.preference.VectorPreferenceCategory> From 7e156d372f7c1573e66c41d6a02aa17cbdf6e876 Mon Sep 17 00:00:00 2001 From: langleyd <davidl@element.io> Date: Mon, 12 Jul 2021 14:08:35 +0100 Subject: [PATCH 02/21] Add checkbox preference, remove PushRulePreference, Split adavanced fragment to new 3 new fragments and inherit common function --- .../im/vector/app/core/di/FragmentModule.kt | 5 -- .../preference/VectorCheckboxPreference.kt | 47 ------------------- ...ngsGlobalNotificationPreferenceFragment.kt | 3 +- ...dMentionsNotificationPreferenceFragment.kt | 4 +- ...ingsOtherNotificationPreferenceFragment.kt | 3 +- .../res/xml/vector_settings_notifications.xml | 24 +++++----- 6 files changed, 16 insertions(+), 70 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 77e7e7ad72..7d50dbdcb5 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -389,11 +389,6 @@ interface FragmentModule { @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment -// @Binds -// @IntoMap -// @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) -// fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment - @Binds @IntoMap @FragmentKey(VectorSettingsNotificationPreferenceFragment::class) diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt b/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt index fd7a2ef5c5..b66ea77bdd 100644 --- a/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt @@ -16,18 +16,11 @@ package im.vector.app.core.preference -import android.animation.Animator -import android.animation.ArgbEvaluator -import android.animation.ValueAnimator import android.content.Context -import android.graphics.Color import android.util.AttributeSet import android.widget.TextView -import androidx.core.animation.doOnEnd import androidx.preference.CheckBoxPreference import androidx.preference.PreferenceViewHolder -import im.vector.app.R -import im.vector.app.features.themes.ThemeUtils open class VectorCheckboxPreference : CheckBoxPreference { // Note: @JvmOverload does not work here... @@ -44,49 +37,9 @@ open class VectorCheckboxPreference : CheckBoxPreference { isIconSpaceReserved = true } - var isHighlighted = false - set(value) { - field = value - notifyChanged() - } - - var currentHighlightAnimator: Animator? = null - override fun onBindViewHolder(holder: PreferenceViewHolder) { // display the title in multi-line to avoid ellipsis. (holder.findViewById(android.R.id.title) as? TextView)?.isSingleLine = false - - // cancel existing animation (find a way to resume if happens during anim?) - currentHighlightAnimator?.cancel() - - val itemView = holder.itemView - if (isHighlighted) { - val colorFrom = Color.TRANSPARENT - val colorTo = ThemeUtils.getColor(itemView.context, R.attr.colorControlHighlight) - currentHighlightAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo).apply { - duration = 250 // milliseconds - addUpdateListener { animator -> - itemView.setBackgroundColor(animator.animatedValue as Int) - } - doOnEnd { - currentHighlightAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorTo, colorFrom).apply { - duration = 250 // milliseconds - addUpdateListener { animator -> - itemView.setBackgroundColor(animator.animatedValue as Int) - } - doOnEnd { - isHighlighted = false - } - start() - } - } - startDelay = 200 - start() - } - } else { - itemView.setBackgroundColor(Color.TRANSPARENT) - } - super.onBindViewHolder(holder) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt index a91b3c5ef7..7e6f51f0b6 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt @@ -18,9 +18,8 @@ package im.vector.app.features.settings import im.vector.app.R import org.matrix.android.sdk.api.pushrules.RuleIds -import javax.inject.Inject -class VectorSettingsGlobalNotificationPreferenceFragment @Inject constructor() +class VectorSettingsGlobalNotificationPreferenceFragment : VectorSettingsPushRuleNotificationPreferenceFragment() { override var titleRes: Int = R.string.settings_notification_global diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt index 0c7ed23070..2bf0a7c0ed 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt @@ -18,9 +18,9 @@ package im.vector.app.features.settings import im.vector.app.R import org.matrix.android.sdk.api.pushrules.RuleIds -import javax.inject.Inject -class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment @Inject constructor() + +class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment : VectorSettingsPushRuleNotificationPreferenceFragment() { override var titleRes: Int = R.string.settings_notification_mentions_and_keywords diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt index bf58ab27a1..64d5cda638 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsOtherNotificationPreferenceFragment.kt @@ -18,9 +18,8 @@ package im.vector.app.features.settings import im.vector.app.R import org.matrix.android.sdk.api.pushrules.RuleIds -import javax.inject.Inject -class VectorSettingsOtherNotificationPreferenceFragment @Inject constructor() +class VectorSettingsOtherNotificationPreferenceFragment : VectorSettingsPushRuleNotificationPreferenceFragment() { 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 35e21ca320..d19945cd46 100644 --- a/vector/src/main/res/xml/vector_settings_notifications.xml +++ b/vector/src/main/res/xml/vector_settings_notifications.xml @@ -27,19 +27,19 @@ android:title="@string/settings_notification_global" app:fragment="im.vector.app.features.settings.VectorSettingsGlobalNotificationPreferenceFragment" /> -<!-- <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.VectorSettingsKeywordAndMentionsNotificationPreferenceFragment" />--> + <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.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.VectorSettingsOtherNotificationPreferenceFragment" />--> + <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.VectorSettingsOtherNotificationPreferenceFragment" /> </im.vector.app.core.preference.VectorPreferenceCategory> From 727ce7272a58d33efcce6375d8e726933758f4e4 Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Mon, 12 Jul 2021 18:38:56 +0100 Subject: [PATCH 03/21] update translations --- .../troubleshoot/TestPushRulesSettings.kt | 5 ----- vector/src/main/res/values/strings.xml | 20 +++++++++---------- .../vector_settings_notification_global.xml | 8 ++++---- ...ngs_notification_mentions_and_keywords.xml | 4 ++-- .../vector_settings_notification_other.xml | 6 +++--- 5 files changed, 19 insertions(+), 24 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt index 8dcf9ab6ce..eea5705b7a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt @@ -35,11 +35,6 @@ class TestPushRulesSettings @Inject constructor(private val activeSessionHolder: RuleIds.RULE_ID_ONE_TO_ONE_ROOM, RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS) - val ruleSettingsName = arrayOf(R.string.settings_containing_my_display_name, - R.string.settings_containing_my_user_name, - R.string.settings_messages_in_one_to_one, - R.string.settings_messages_in_group_chat) - override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) { val session = activeSessionHolder.getSafeActiveSession() ?: return val pushRules = session.getPushRules().getAllRules() diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 154d5619b4..a80ed06186 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1190,13 +1190,17 @@ <string name="settings_system_preferences_summary">Choose LED color, vibration, sound…</string> - <string name="settings_containing_my_display_name">Msgs containing my display name</string> - <string name="settings_containing_my_user_name">Msgs containing my user name</string> - <string name="settings_messages_in_one_to_one">Msgs in one-to-one chats</string> - <string name="settings_messages_in_group_chat">Msgs in group chats</string> - <string name="settings_invited_to_room">When I’m invited to a room</string> + <string name="settings_messages_containing_display_name">Messages containing my display name</string> + <string name="settings_messages_containing_username">Messages containing my username</string> + <string name="settings_messages_direct_messages">Direct messages</string> + <string name="settings_encrypted_direct_messages">Encrypted direct messages</string> + <string name="settings_group_messages">Group messages</string> + <string name="settings_encrypted_group_messages">Encrypted group messages</string> + <string name="settings_messages_at_room">Messages containing @room</string> + <string name="settings_room_invitations">Room invitations</string> <string name="settings_call_invitations">Call invitations</string> - <string name="settings_messages_sent_by_bot">Messages sent by bot</string> + <string name="settings_messages_by_bot">Messages by bot</string> + <string name="settings_room_upgrades">Room upgrades</string> <string name="settings_background_sync">Background synchronization</string> <string name="settings_background_fdroid_sync_mode">Background Sync Mode</string> @@ -2948,10 +2952,6 @@ <string name="error_failed_to_import_keys">Failed to import keys</string> <string name="settings_notification_configuration">Notifications configuration</string> - <string name="settings_messages_at_room">Messages containing @room</string> - <string name="settings_messages_in_e2e_one_to_one">Encrypted messages in one-to-one chats</string> - <string name="settings_messages_in_e2e_group_chat">Encrypted messages in group chats</string> - <string name="settings_when_rooms_are_upgraded">When rooms are upgraded</string> <string name="settings_troubleshoot_title">Troubleshoot</string> <string name="settings_notification_advanced_summary">Set notification importance by event</string> diff --git a/vector/src/main/res/xml/vector_settings_notification_global.xml b/vector/src/main/res/xml/vector_settings_notification_global.xml index 787419bd55..70defb32c4 100644 --- a/vector/src/main/res/xml/vector_settings_notification_global.xml +++ b/vector/src/main/res/xml/vector_settings_notification_global.xml @@ -7,22 +7,22 @@ <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_messages_in_one_to_one" /> + android:title="@string/settings_messages_direct_messages" /> <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_messages_in_e2e_one_to_one" /> + android:title="@string/settings_encrypted_direct_messages" /> <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_messages_in_group_chat" /> + android:title="@string/settings_group_messages" /> <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_messages_in_e2e_group_chat" /> + android:title="@string/settings_encrypted_group_messages" /> </im.vector.app.core.preference.VectorPreferenceCategory> </PreferenceScreen> \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml b/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml index c84bf53faa..18de36cb52 100644 --- a/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml +++ b/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml @@ -7,12 +7,12 @@ <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_containing_my_display_name" /> + android:title="@string/settings_messages_containing_display_name" /> <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_containing_my_user_name" /> + android:title="@string/settings_messages_containing_username" /> <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" diff --git a/vector/src/main/res/xml/vector_settings_notification_other.xml b/vector/src/main/res/xml/vector_settings_notification_other.xml index e1119e7c16..ad2b5194f0 100644 --- a/vector/src/main/res/xml/vector_settings_notification_other.xml +++ b/vector/src/main/res/xml/vector_settings_notification_other.xml @@ -7,7 +7,7 @@ <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_invited_to_room" /> + android:title="@string/settings_room_invitations" /> <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" @@ -17,11 +17,11 @@ <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_messages_sent_by_bot" /> + android:title="@string/settings_messages_by_bot" /> <im.vector.app.core.preference.VectorCheckboxPreference android:key="SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" android:persistent="false" - android:title="@string/settings_when_rooms_are_upgraded" /> + android:title="@string/settings_room_upgrades" /> </im.vector.app.core.preference.VectorPreferenceCategory> </PreferenceScreen> \ No newline at end of file From a3204fdad954650df2f6c00c4803cea2b7c1f88d Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Tue, 13 Jul 2021 21:22:56 +0100 Subject: [PATCH 04/21] add resValue to enable feature, put back old code --- vector/build.gradle | 3 + .../im/vector/app/core/di/FragmentModule.kt | 6 + .../app/core/preference/PushRulePreference.kt | 207 ++++++++++++++++++ ...sAdvancedNotificationPreferenceFragment.kt | 105 +++++++++ ...sPushRuleNotificationPreferenceFragment.kt | 181 +++++---------- .../layout/vector_preference_push_rule.xml | 78 +++++++ vector/src/main/res/values/strings.xml | 9 + ...ings_notification_advanced_preferences.xml | 67 ++++++ .../res/xml/vector_settings_notifications.xml | 18 +- 9 files changed, 548 insertions(+), 126 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt create mode 100644 vector/src/main/res/layout/vector_preference_push_rule.xml create mode 100644 vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml diff --git a/vector/build.gradle b/vector/build.gradle index 8e8e5bc3dc..7003ab1834 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -142,6 +142,9 @@ android { resValue "bool", "useLoginV1", "true" resValue "bool", "useLoginV2", "false" + resValue "bool", "useNotificationSettingsV1", "true" + resValue "bool", "useNotificationSettingsV2", "false" + buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping" // If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity. diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 7d50dbdcb5..7da26a3ea1 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -111,6 +111,7 @@ import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.app.features.roomprofile.uploads.files.RoomUploadsFilesFragment import im.vector.app.features.roomprofile.uploads.media.RoomUploadsMediaFragment +import im.vector.app.features.settings.VectorSettingsAdvancedNotificationPreferenceFragment import im.vector.app.features.settings.VectorSettingsGeneralFragment import im.vector.app.features.settings.VectorSettingsHelpAboutFragment import im.vector.app.features.settings.VectorSettingsLabsFragment @@ -384,6 +385,11 @@ interface FragmentModule { @FragmentKey(PushGatewaysFragment::class) fun bindPushGatewaysFragment(fragment: PushGatewaysFragment): Fragment + @Binds + @IntoMap + @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) + fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment + @Binds @IntoMap @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) diff --git a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt new file mode 100644 index 0000000000..c3e324b64a --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt @@ -0,0 +1,207 @@ +/* + * Copyright 2018 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.core.preference + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.widget.RadioGroup +import androidx.preference.PreferenceViewHolder +import im.vector.app.R +import org.matrix.android.sdk.api.pushrules.Action +import org.matrix.android.sdk.api.pushrules.RuleIds +import org.matrix.android.sdk.api.pushrules.RuleSetKey +import org.matrix.android.sdk.api.pushrules.rest.PushRule +import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind + +class PushRulePreference : VectorPreference { + + /** + * @return the selected push rule and its kind + */ + var ruleAndKind: PushRuleAndKind? = null + private set + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) + + init { + layoutResource = R.layout.vector_preference_push_rule + } + + /** + * @return the bing rule status index + */ + private val ruleStatusIndex: Int + get() { + val safeRule = ruleAndKind?.pushRule ?: return NOTIFICATION_OFF_INDEX + + if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + if (safeRule.shouldNotNotify()) { + return if (safeRule.enabled) { + NOTIFICATION_OFF_INDEX + } else { + NOTIFICATION_SILENT_INDEX + } + } else if (safeRule.shouldNotify()) { + return NOTIFICATION_NOISY_INDEX + } + } + + if (safeRule.enabled) { + return if (safeRule.shouldNotNotify()) { + NOTIFICATION_OFF_INDEX + } else if (safeRule.getNotificationSound() != null) { + NOTIFICATION_NOISY_INDEX + } else { + NOTIFICATION_SILENT_INDEX + } + } + + return NOTIFICATION_OFF_INDEX + } + + /** + * Update the push rule. + * + * @param pushRule + */ + fun setPushRule(pushRuleAndKind: PushRuleAndKind?) { + ruleAndKind = pushRuleAndKind + refreshSummary() + } + + /** + * Refresh the summary + */ + private fun refreshSummary() { + summary = context.getString(when (ruleStatusIndex) { + NOTIFICATION_OFF_INDEX -> R.string.notification_off + NOTIFICATION_SILENT_INDEX -> R.string.notification_silent + else -> R.string.notification_noisy + }) + } + + /** + * Create a push rule with the updated required at index. + * + * @param index index + * @return a push rule with the updated flags / null if there is no update + */ + fun createNewRule(index: Int): PushRule? { + val safeRule = ruleAndKind?.pushRule ?: return null + val safeKind = ruleAndKind?.kind ?: return null + + return if (index != ruleStatusIndex) { + if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + when (index) { + NOTIFICATION_OFF_INDEX -> { + safeRule.copy(enabled = true) + .setNotify(false) + .removeNotificationSound() + } + NOTIFICATION_SILENT_INDEX -> { + safeRule.copy(enabled = false) + .setNotify(false) + } + NOTIFICATION_NOISY_INDEX -> { + safeRule.copy(enabled = true) + .setNotify(true) + .setNotificationSound() + } + else -> safeRule + } + } else { + if (NOTIFICATION_OFF_INDEX == index) { + if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + safeRule.setNotify(false) + } else { + safeRule.copy(enabled = false) + } + } else { + val newRule = safeRule.copy(enabled = true) + .setNotify(true) + .setHighlight(safeKind != RuleSetKey.UNDERRIDE + && safeRule.ruleId != RuleIds.RULE_ID_INVITE_ME + && NOTIFICATION_NOISY_INDEX == index) + + if (NOTIFICATION_NOISY_INDEX == index) { + newRule.setNotificationSound( + if (safeRule.ruleId == RuleIds.RULE_ID_CALL) { + Action.ACTION_OBJECT_VALUE_VALUE_RING + } else { + Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT + } + ) + } else { + newRule.removeNotificationSound() + } + } + } + } else { + safeRule + } + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + holder.findViewById(android.R.id.summary)?.visibility = View.GONE + holder.itemView.setOnClickListener(null) + holder.itemView.setOnLongClickListener(null) + + val radioGroup = holder.findViewById(R.id.bingPreferenceRadioGroup) as? RadioGroup + radioGroup?.setOnCheckedChangeListener(null) + + when (ruleStatusIndex) { + NOTIFICATION_OFF_INDEX -> { + radioGroup?.check(R.id.bingPreferenceRadioBingRuleOff) + } + NOTIFICATION_SILENT_INDEX -> { + radioGroup?.check(R.id.bingPreferenceRadioBingRuleSilent) + } + else -> { + radioGroup?.check(R.id.bingPreferenceRadioBingRuleNoisy) + } + } + + radioGroup?.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.bingPreferenceRadioBingRuleOff -> { + onPreferenceChangeListener?.onPreferenceChange(this, NOTIFICATION_OFF_INDEX) + } + R.id.bingPreferenceRadioBingRuleSilent -> { + onPreferenceChangeListener?.onPreferenceChange(this, NOTIFICATION_SILENT_INDEX) + } + R.id.bingPreferenceRadioBingRuleNoisy -> { + onPreferenceChangeListener?.onPreferenceChange(this, NOTIFICATION_NOISY_INDEX) + } + } + } + } + + companion object { + + // index in mRuleStatuses + private const val NOTIFICATION_OFF_INDEX = 0 + private const val NOTIFICATION_SILENT_INDEX = 1 + private const val NOTIFICATION_NOISY_INDEX = 2 + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt new file mode 100644 index 0000000000..8d9f8d7170 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt @@ -0,0 +1,105 @@ +/* + * Copyright 2018 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 + +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import im.vector.app.R +import im.vector.app.core.preference.PushRulePreference +import im.vector.app.core.preference.VectorPreference +import im.vector.app.core.utils.toast +import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.pushrules.RuleIds +import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind +import javax.inject.Inject + +class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor() + : VectorSettingsBaseFragment() { + + override var titleRes: Int = R.string.settings_notification_advanced + + override val preferenceXmlRes = R.xml.vector_settings_notification_advanced_preferences + + override fun bindPref() { + for (preferenceKey in prefKeyToPushRuleId.keys) { + val preference = findPreference<VectorPreference>(preferenceKey) + if (preference is PushRulePreference) { + // preference.isEnabled = null != rules && isConnected && pushManager.areDeviceNotificationsAllowed() + val ruleAndKind: PushRuleAndKind? = session.getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey]) + + if (ruleAndKind == null) { + // The rule is not defined, hide the preference + preference.isVisible = false + } else { + preference.isVisible = true + preference.setPushRule(ruleAndKind) + preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + val newRule = preference.createNewRule(newValue as Int) + if (newRule != null) { + displayLoadingView() + + lifecycleScope.launch { + val result = runCatching { + session.updatePushRuleActions(ruleAndKind.kind, + preference.ruleAndKind?.pushRule ?: ruleAndKind.pushRule, + newRule) + } + if (!isAdded) { + return@launch + } + hideLoadingView() + result.onSuccess { + preference.setPushRule(ruleAndKind.copy(pushRule = newRule)) + } + result.onFailure { failure -> + // Restore the previous value + refreshDisplay() + activity?.toast(errorFormatter.toHumanReadable(failure)) + } + } + } + false + } + } + } + } + } + + private fun refreshDisplay() { + listView?.adapter?.notifyDataSetChanged() + } + + /* ========================================================================================== + * Companion + * ========================================================================================== */ + + companion object { + // preference name <-> rule Id + private val prefKeyToPushRuleId = mapOf( + "SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_DISPLAY_NAME, + "SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_USER_NAME, + "SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ROOM, + "SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, + "SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_INVITE_ME, + "SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to RuleIds.RULE_ID_CALL, + "SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" to RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS, + "SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_ROOM_NOTIF, + "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ENCRYPTED_ROOM, + "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ENCRYPTED, + "SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" to RuleIds.RULE_ID_TOMBSTONE + ) + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt index 2f274ce904..6683cf3038 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt @@ -30,105 +30,58 @@ import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind abstract class VectorSettingsPushRuleNotificationPreferenceFragment : VectorSettingsBaseFragment() { - - fun indexFromBooleanPreference(pushRuleOn: Boolean): Int { - return if (pushRuleOn) { - NOTIFICATION_NOISY_INDEX - } else { - NOTIFICATION_OFF_INDEX - } - } - - fun booleanPreferenceFromIndex(index: Int): Boolean { - return index != NOTIFICATION_OFF_INDEX - } - /** - * @return the bing rule status index + * @return the bing rule status boolean */ - fun ruleStatusIndexFor(ruleAndKind: PushRuleAndKind? ): Int { - val safeRule = ruleAndKind?.pushRule ?: return NOTIFICATION_OFF_INDEX - - if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { - if (safeRule.shouldNotNotify()) { - return if (safeRule.enabled) { - NOTIFICATION_OFF_INDEX - } else { - NOTIFICATION_SILENT_INDEX - } - } else if (safeRule.shouldNotify()) { - return NOTIFICATION_NOISY_INDEX - } - } - - if (safeRule.enabled) { - return if (safeRule.shouldNotNotify()) { - NOTIFICATION_OFF_INDEX - } else if (safeRule.getNotificationSound() != null) { - NOTIFICATION_NOISY_INDEX - } else { - NOTIFICATION_SILENT_INDEX - } - } - - return NOTIFICATION_OFF_INDEX + fun ruleStatusIndexFor(ruleAndKind: PushRuleAndKind): Boolean { + val rule = ruleAndKind.pushRule + if (rule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + return rule.shouldNotify() || rule.shouldNotNotify() && !rule.enabled } + return rule.enabled && !rule.shouldNotNotify() + } /** * Create a push rule with the updated required at index. * - * @param index index - * @return a push rule with the updated flags / null if there is no update + * @param status boolean checkbox status + * @return a push rule with the updated flags */ - fun createNewRule(ruleAndKind: PushRuleAndKind?, index: Int): PushRule? { - val safeRule = ruleAndKind?.pushRule ?: return null + fun createNewRule(ruleAndKind: PushRuleAndKind, status: Boolean): PushRule { + val safeRule = ruleAndKind.pushRule val safeKind = ruleAndKind.kind val ruleStatusIndex = ruleStatusIndexFor(ruleAndKind) - return if (index != ruleStatusIndex) { + return if (status != ruleStatusIndex) { if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { - when (index) { - NOTIFICATION_OFF_INDEX -> { - safeRule.copy(enabled = true) - .setNotify(false) - .removeNotificationSound() - } - NOTIFICATION_SILENT_INDEX -> { - safeRule.copy(enabled = false) - .setNotify(false) - } - NOTIFICATION_NOISY_INDEX -> { - safeRule.copy(enabled = true) - .setNotify(true) - .setNotificationSound() - } - else -> safeRule + if (status) { + safeRule.copy(enabled = true) + .setNotify(true) + .setNotificationSound() + } else { + safeRule.copy(enabled = true) + .setNotify(false) + .removeNotificationSound() } } else { - if (NOTIFICATION_OFF_INDEX == index) { + if (status) { + safeRule.copy(enabled = true) + .setNotify(true) + .setHighlight(safeKind != RuleSetKey.UNDERRIDE + && safeRule.ruleId != RuleIds.RULE_ID_INVITE_ME) + .setNotificationSound( + if (safeRule.ruleId == RuleIds.RULE_ID_CALL) { + Action.ACTION_OBJECT_VALUE_VALUE_RING + } else { + Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT + } + ) + } else { if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { safeRule.setNotify(false) } else { safeRule.copy(enabled = false) } - } else { - val newRule = safeRule.copy(enabled = true) - .setNotify(true) - .setHighlight(safeKind != RuleSetKey.UNDERRIDE - && safeRule.ruleId != RuleIds.RULE_ID_INVITE_ME - && NOTIFICATION_NOISY_INDEX == index) - - if (NOTIFICATION_NOISY_INDEX == index) { - newRule.setNotificationSound( - if (safeRule.ruleId == RuleIds.RULE_ID_CALL) { - Action.ACTION_OBJECT_VALUE_VALUE_RING - } else { - Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT - } - ) - } else { - newRule.removeNotificationSound() - } } } } else { @@ -136,51 +89,44 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment } } - override fun bindPref() { for (preferenceKey in prefKeyToPushRuleId.keys) { val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!! - // preference.isEnabled = null != rules && isConnected && pushManager.areDeviceNotificationsAllowed() val ruleAndKind: PushRuleAndKind? = session.getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey]) - if (ruleAndKind == null) { // The rule is not defined, hide the preference preference.isVisible = false } else { + var oldRuleAndKind: PushRuleAndKind = ruleAndKind preference.isVisible = true - - val index = ruleStatusIndexFor(ruleAndKind) - val boolPreference = booleanPreferenceFromIndex(index) - preference.isChecked = boolPreference + preference.isChecked = ruleStatusIndexFor(ruleAndKind) preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> - val newIndex = indexFromBooleanPreference(newValue as Boolean) - val newRule = createNewRule(ruleAndKind, newIndex) + val newRule = createNewRule(ruleAndKind, newValue as Boolean) + displayLoadingView() - if (newRule != null) { - displayLoadingView() - - lifecycleScope.launch { - val result = runCatching { - session.updatePushRuleActions( - ruleAndKind.kind, - ruleAndKind.pushRule, - newRule - ) - } - if (!isAdded) { - return@launch - } - hideLoadingView() - result.onSuccess { - preference.isChecked = newValue - } - result.onFailure { failure -> - // Restore the previous value - refreshDisplay() - activity?.toast(errorFormatter.toHumanReadable(failure)) - } + lifecycleScope.launch { + val result = runCatching { + session.updatePushRuleActions( + oldRuleAndKind.kind, + oldRuleAndKind.pushRule, + newRule + ) + } + if (!isAdded) { + return@launch + } + hideLoadingView() + result.onSuccess { + oldRuleAndKind = oldRuleAndKind.copy(pushRule = newRule) + preference.isChecked = newValue + } + result.onFailure { failure -> + // Restore the previous value + refreshDisplay() + activity?.toast(errorFormatter.toHumanReadable(failure)) } } + false } } @@ -191,17 +137,6 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment listView?.adapter?.notifyDataSetChanged() } - /* ========================================================================================== - * Companion - * ========================================================================================== */ - abstract val prefKeyToPushRuleId: Map<String, String> - companion object { - - // index in mRuleStatuses - private const val NOTIFICATION_OFF_INDEX = 0 - private const val NOTIFICATION_SILENT_INDEX = 1 - private const val NOTIFICATION_NOISY_INDEX = 2 - } } diff --git a/vector/src/main/res/layout/vector_preference_push_rule.xml b/vector/src/main/res/layout/vector_preference_push_rule.xml new file mode 100644 index 0000000000..3da5c81410 --- /dev/null +++ b/vector/src/main/res/layout/vector_preference_push_rule.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" + android:baselineAligned="false" + android:clipToPadding="false" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:orientation="vertical" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight"> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="16dp"> + + <TextView + android:id="@android:id/title" + style="@style/Widget.Vector.TextView.Body" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:singleLine="true" + android:textAppearance="?textAppearanceListItem" + android:textColor="?vctr_content_primary" + tools:text="Title" /> + + <TextView + android:id="@android:id/summary" + style="@style/Widget.Vector.TextView.Body" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@android:id/title" + android:layout_alignStart="@android:id/title" + android:maxLines="2" + android:paddingTop="6dp" + android:textAppearance="?textAppearanceListItemSecondary" + android:textColor="?vctr_content_secondary" + tools:text="Summary" + tools:visibility="visible" /> + + </RelativeLayout> + + <RadioGroup + android:id="@+id/bingPreferenceRadioGroup" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical|end" + android:orientation="horizontal" + android:paddingTop="6dp" + android:paddingBottom="16dp"> + + <RadioButton + android:id="@+id/bingPreferenceRadioBingRuleOff" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/notification_off" + tools:checked="true" /> + + <RadioButton + android:id="@+id/bingPreferenceRadioBingRuleSilent" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/notification_silent" /> + + <RadioButton + android:id="@+id/bingPreferenceRadioBingRuleNoisy" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/notification_noisy" /> + + </RadioGroup> + +</LinearLayout> + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index a80ed06186..7f93cd3957 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1189,6 +1189,15 @@ <string name="settings_silent_notifications_preferences">Configure Silent Notifications</string> <string name="settings_system_preferences_summary">Choose LED color, vibration, sound…</string> + <string name="settings_messages_in_e2e_one_to_one">Encrypted messages in one-to-one chats</string> + <string name="settings_messages_in_e2e_group_chat">Encrypted messages in group chats</string> + <string name="settings_when_rooms_are_upgraded">When rooms are upgraded</string> + <string name="settings_containing_my_display_name">Msgs containing my display name</string> + <string name="settings_containing_my_user_name">Msgs containing my user name</string> + <string name="settings_messages_in_one_to_one">Msgs in one-to-one chats</string> + <string name="settings_messages_in_group_chat">Msgs in group chats</string> + <string name="settings_invited_to_room">When I’m invited to a room</string> + <string name="settings_messages_sent_by_bot">Messages sent by bot</string> <string name="settings_messages_containing_display_name">Messages containing my display name</string> <string name="settings_messages_containing_username">Messages containing my username</string> diff --git a/vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml b/vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml new file mode 100644 index 0000000000..436858ac05 --- /dev/null +++ b/vector/src/main/res/xml/vector_settings_notification_advanced_preferences.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <im.vector.app.core.preference.VectorPreferenceCategory + android:key="SETTINGS_NOTIFICATION_LEVEL" + android:title="@string/settings_notification_by_event"> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_containing_my_display_name" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_containing_my_user_name" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_at_room" /> + + <!-- TODO Support message with keywords rule --> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_one_to_one" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_e2e_one_to_one" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_group_chat" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_in_e2e_group_chat" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_invited_to_room" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_call_invitations" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" + android:persistent="false" + android:title="@string/settings_messages_sent_by_bot" /> + + <im.vector.app.core.preference.PushRulePreference + android:key="SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" + android:persistent="false" + android:title="@string/settings_when_rooms_are_upgraded" /> + + </im.vector.app.core.preference.VectorPreferenceCategory> + +</androidx.preference.PreferenceScreen> \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_notifications.xml b/vector/src/main/res/xml/vector_settings_notifications.xml index d19945cd46..c9668bcd4d 100644 --- a/vector/src/main/res/xml/vector_settings_notifications.xml +++ b/vector/src/main/res/xml/vector_settings_notifications.xml @@ -20,26 +20,38 @@ <!--android:key="SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY"--> <!--android:title="@string/settings_turn_screen_on" />--> + <im.vector.app.core.preference.VectorPreference + android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY" + android:key="SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY" + android:persistent="false" + android:summary="@string/settings_notification_advanced_summary" + android:title="@string/settings_notification_advanced" + app:fragment="im.vector.app.features.settings.VectorSettingsAdvancedNotificationPreferenceFragment" + app:isPreferenceVisible="@bool/useNotificationSettingsV1" /> + <im.vector.app.core.preference.VectorPreference android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY" android:key="SETTINGS_NOTIFICATION_GLOBAL_PREFERENCE_KEY" android:persistent="false" android:title="@string/settings_notification_global" - app:fragment="im.vector.app.features.settings.VectorSettingsGlobalNotificationPreferenceFragment" /> + app:fragment="im.vector.app.features.settings.VectorSettingsGlobalNotificationPreferenceFragment" + app:isPreferenceVisible="@bool/useNotificationSettingsV2"/> <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.VectorSettingsKeywordAndMentionsNotificationPreferenceFragment" /> + app:fragment="im.vector.app.features.settings.VectorSettingsKeywordAndMentionsNotificationPreferenceFragment" + app:isPreferenceVisible="@bool/useNotificationSettingsV2"/> <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.VectorSettingsOtherNotificationPreferenceFragment" /> + app:fragment="im.vector.app.features.settings.VectorSettingsOtherNotificationPreferenceFragment" + app:isPreferenceVisible="@bool/useNotificationSettingsV2"/> </im.vector.app.core.preference.VectorPreferenceCategory> From 5044b21545fe0588f5d269f7740dc67d0db36d13 Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Wed, 14 Jul 2021 11:49:16 +0100 Subject: [PATCH 05/21] add changelog, checks/tests --- changelog.d/3646.feature | 1 + vector/build.gradle | 1 + .../VectorSettingsGlobalNotificationPreferenceFragment.kt | 1 - ...ettingsKeywordAndMentionsNotificationPreferenceFragment.kt | 1 - .../VectorSettingsPushRuleNotificationPreferenceFragment.kt | 1 - .../src/main/res/xml/vector_settings_notification_global.xml | 4 ++-- .../vector_settings_notification_mentions_and_keywords.xml | 4 ++-- .../src/main/res/xml/vector_settings_notification_other.xml | 4 ++-- 8 files changed, 8 insertions(+), 9 deletions(-) create mode 100644 changelog.d/3646.feature diff --git a/changelog.d/3646.feature b/changelog.d/3646.feature new file mode 100644 index 0000000000..ba2e870052 --- /dev/null +++ b/changelog.d/3646.feature @@ -0,0 +1 @@ +Reorganise Advanced Notifications in to Global Notifications, Keywords and Mentions, Other (This feature is hidden in the release ui until a future release date.) \ No newline at end of file diff --git a/vector/build.gradle b/vector/build.gradle index eaf70e50b1..dabdcfb4dc 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -142,6 +142,7 @@ android { resValue "bool", "useLoginV1", "true" resValue "bool", "useLoginV2", "false" + // NotificationSettingsV2 is disabled. To be released in conjunction with iOS/Web resValue "bool", "useNotificationSettingsV1", "true" resValue "bool", "useNotificationSettingsV2", "false" diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt index 7e6f51f0b6..b9ac089158 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGlobalNotificationPreferenceFragment.kt @@ -34,4 +34,3 @@ class VectorSettingsGlobalNotificationPreferenceFragment "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ENCRYPTED ) } - diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt index 2bf0a7c0ed..b2a1d26fc8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt @@ -19,7 +19,6 @@ package im.vector.app.features.settings import im.vector.app.R import org.matrix.android.sdk.api.pushrules.RuleIds - class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment : VectorSettingsPushRuleNotificationPreferenceFragment() { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt index 6683cf3038..705d90a8c9 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt @@ -138,5 +138,4 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment } abstract val prefKeyToPushRuleId: Map<String, String> - } diff --git a/vector/src/main/res/xml/vector_settings_notification_global.xml b/vector/src/main/res/xml/vector_settings_notification_global.xml index 70defb32c4..64d0c131b7 100644 --- a/vector/src/main/res/xml/vector_settings_notification_global.xml +++ b/vector/src/main/res/xml/vector_settings_notification_global.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <im.vector.app.core.preference.VectorPreferenceCategory android:key="SETTINGS_OTHER" android:title="@string/settings_notification_notify_me_for"> @@ -25,4 +25,4 @@ android:title="@string/settings_encrypted_group_messages" /> </im.vector.app.core.preference.VectorPreferenceCategory> -</PreferenceScreen> \ No newline at end of file +</androidx.preference.PreferenceScreen> \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml b/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml index 18de36cb52..be89c86cb1 100644 --- a/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml +++ b/vector/src/main/res/xml/vector_settings_notification_mentions_and_keywords.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <im.vector.app.core.preference.VectorPreferenceCategory android:key="SETTINGS_KEYWORDS_AND_MENTIONS" android:title="@string/settings_notification_notify_me_for"> @@ -20,4 +20,4 @@ android:title="@string/settings_messages_at_room" /> </im.vector.app.core.preference.VectorPreferenceCategory> -</PreferenceScreen> \ No newline at end of file +</androidx.preference.PreferenceScreen> \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_notification_other.xml b/vector/src/main/res/xml/vector_settings_notification_other.xml index ad2b5194f0..b15329635c 100644 --- a/vector/src/main/res/xml/vector_settings_notification_other.xml +++ b/vector/src/main/res/xml/vector_settings_notification_other.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <im.vector.app.core.preference.VectorPreferenceCategory android:key="SETTINGS_OTHER" android:title="@string/settings_notification_notify_me_for"> @@ -24,4 +24,4 @@ android:persistent="false" android:title="@string/settings_room_upgrades" /> </im.vector.app.core.preference.VectorPreferenceCategory> -</PreferenceScreen> \ No newline at end of file +</androidx.preference.PreferenceScreen> \ No newline at end of file From f0d5950b13e3c79966812ed284ee1f4e7056292d Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Wed, 14 Jul 2021 11:59:00 +0100 Subject: [PATCH 06/21] fix unncessary reformatting and function description --- .../src/main/java/im/vector/app/core/di/FragmentModule.kt | 8 ++++---- ...ectorSettingsPushRuleNotificationPreferenceFragment.kt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 7da26a3ea1..8580543022 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -387,13 +387,13 @@ interface FragmentModule { @Binds @IntoMap - @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) - fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment + @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) + fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment @Binds @IntoMap - @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) - fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment + @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) + fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment @Binds @IntoMap diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt index 705d90a8c9..9aa6bf2f9f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPushRuleNotificationPreferenceFragment.kt @@ -42,7 +42,7 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment } /** - * Create a push rule with the updated required at index. + * Create a push rule with the updated checkbox status. * * @param status boolean checkbox status * @return a push rule with the updated flags From 73bf50b93c37f190725ff30990899e8f7346f95d Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Tue, 27 Jul 2021 20:21:40 +0100 Subject: [PATCH 07/21] rename global -> default, address comments --- .../preference/VectorCheckboxPreference.kt | 2 +- ...sDefaultNotificationPreferenceFragment.kt} | 9 ++++--- ...dMentionsNotificationPreferenceFragment.kt | 3 +-- ...ingsOtherNotificationPreferenceFragment.kt | 3 +-- ...sPushRuleNotificationPreferenceFragment.kt | 24 ++++++++++--------- vector/src/main/res/values/strings.xml | 2 +- ... vector_settings_notification_default.xml} | 2 +- .../res/xml/vector_settings_notifications.xml | 6 ++--- 8 files changed, 25 insertions(+), 26 deletions(-) rename vector/src/main/java/im/vector/app/features/settings/notifications/{VectorSettingsGlobalNotificationPreferenceFragment.kt => VectorSettingsDefaultNotificationPreferenceFragment.kt} (89%) rename vector/src/main/res/xml/{vector_settings_notification_global.xml => vector_settings_notification_default.xml} (94%) diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt b/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt index b66ea77bdd..13b65e11b4 100644 --- a/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/VectorCheckboxPreference.kt @@ -22,7 +22,7 @@ import android.widget.TextView import androidx.preference.CheckBoxPreference import androidx.preference.PreferenceViewHolder -open class VectorCheckboxPreference : CheckBoxPreference { +class VectorCheckboxPreference : CheckBoxPreference { // Note: @JvmOverload does not work here... constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsGlobalNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt similarity index 89% rename from vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsGlobalNotificationPreferenceFragment.kt rename to vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt index 7fe4c4b87d..7d6b74b093 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsGlobalNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt @@ -19,15 +19,14 @@ package im.vector.app.features.settings.notifications import im.vector.app.R import org.matrix.android.sdk.api.pushrules.RuleIds -class VectorSettingsGlobalNotificationPreferenceFragment +class VectorSettingsDefaultNotificationPreferenceFragment : VectorSettingsPushRuleNotificationPreferenceFragment() { - override var titleRes: Int = R.string.settings_notification_global + override var titleRes: Int = R.string.settings_notification_default - override val preferenceXmlRes = R.xml.vector_settings_notification_global + override val preferenceXmlRes = R.xml.vector_settings_notification_default - override val prefKeyToPushRuleId: Map<String, String> - get() = mapOf( + override val prefKeyToPushRuleId = mapOf( "SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ROOM, "SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ENCRYPTED_ROOM, 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/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt index 149b176e09..37acc1d898 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/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt @@ -26,8 +26,7 @@ class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment override val preferenceXmlRes = R.xml.vector_settings_notification_mentions_and_keywords - override val prefKeyToPushRuleId: Map<String, String> - get() = mapOf( + override val prefKeyToPushRuleId = mapOf( "SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_DISPLAY_NAME, "SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_USER_NAME, "SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_ROOM_NOTIF 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/VectorSettingsOtherNotificationPreferenceFragment.kt index db25d46e10..42203fb613 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/VectorSettingsOtherNotificationPreferenceFragment.kt @@ -26,8 +26,7 @@ class VectorSettingsOtherNotificationPreferenceFragment override val preferenceXmlRes = R.xml.vector_settings_notification_other - override val prefKeyToPushRuleId: Map<String, String> - get() = mapOf( + override val prefKeyToPushRuleId = mapOf( "SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_INVITE_ME, "SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to RuleIds.RULE_ID_CALL, "SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" to RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS, 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 4e3d8692b7..7f5ed0084d 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 @@ -31,16 +31,7 @@ import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind abstract class VectorSettingsPushRuleNotificationPreferenceFragment : VectorSettingsBaseFragment() { - /** - * @return the bing rule status boolean - */ - fun ruleStatusIndexFor(ruleAndKind: PushRuleAndKind): Boolean { - val rule = ruleAndKind.pushRule - if (rule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { - return rule.shouldNotify() || rule.shouldNotNotify() && !rule.enabled - } - return rule.enabled && !rule.shouldNotNotify() - } + abstract val prefKeyToPushRuleId: Map<String, String> /** * Create a push rule with the updated checkbox status. @@ -90,6 +81,18 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment } } + /** + * @return the bing rule status boolean + */ + private fun ruleStatusIndexFor(ruleAndKind: PushRuleAndKind): Boolean { + val rule = ruleAndKind.pushRule + if (rule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + return rule.shouldNotify() || rule.shouldNotNotify() && !rule.enabled + } + return rule.enabled && !rule.shouldNotNotify() + } + + override fun bindPref() { for (preferenceKey in prefKeyToPushRuleId.keys) { val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!! @@ -139,5 +142,4 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment listView?.adapter?.notifyDataSetChanged() } - abstract val prefKeyToPushRuleId: Map<String, String> } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 38a2c21f0c..3ead8b009e 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1087,7 +1087,7 @@ <string name="settings_notification_advanced">Advanced Notification Settings</string> <string name="settings_notification_by_event">Notification importance by event</string> - <string name="settings_notification_global">Global Notifications</string> + <string name="settings_notification_default">Default Notifications</string> <string name="settings_notification_mentions_and_keywords">Mentions and Keywords</string> <string name="settings_notification_other">Other</string> diff --git a/vector/src/main/res/xml/vector_settings_notification_global.xml b/vector/src/main/res/xml/vector_settings_notification_default.xml similarity index 94% rename from vector/src/main/res/xml/vector_settings_notification_global.xml rename to vector/src/main/res/xml/vector_settings_notification_default.xml index 64d0c131b7..fb565d2230 100644 --- a/vector/src/main/res/xml/vector_settings_notification_global.xml +++ b/vector/src/main/res/xml/vector_settings_notification_default.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <im.vector.app.core.preference.VectorPreferenceCategory - android:key="SETTINGS_OTHER" + android:key="SETTINGS_DEFAULT" android:title="@string/settings_notification_notify_me_for"> <im.vector.app.core.preference.VectorCheckboxPreference diff --git a/vector/src/main/res/xml/vector_settings_notifications.xml b/vector/src/main/res/xml/vector_settings_notifications.xml index 58be182138..1d184ad650 100644 --- a/vector/src/main/res/xml/vector_settings_notifications.xml +++ b/vector/src/main/res/xml/vector_settings_notifications.xml @@ -31,10 +31,10 @@ <im.vector.app.core.preference.VectorPreference android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY" - android:key="SETTINGS_NOTIFICATION_GLOBAL_PREFERENCE_KEY" + android:key="SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY" android:persistent="false" - android:title="@string/settings_notification_global" - app:fragment="im.vector.app.features.settings.notifications.VectorSettingsGlobalNotificationPreferenceFragment" + android:title="@string/settings_notification_default" + app:fragment="im.vector.app.features.settings.notifications.VectorSettingsDefaultNotificationPreferenceFragment" app:isPreferenceVisible="@bool/useNotificationSettingsV2"/> <im.vector.app.core.preference.VectorPreference From 60b351cddda21fda655f4603f7a03c3c60f55504 Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Tue, 27 Jul 2021 20:36:41 +0100 Subject: [PATCH 08/21] fic towncrier text --- changelog.d/3646.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/3646.feature b/changelog.d/3646.feature index ba2e870052..c44a5fa58f 100644 --- a/changelog.d/3646.feature +++ b/changelog.d/3646.feature @@ -1 +1 @@ -Reorganise Advanced Notifications in to Global Notifications, Keywords and Mentions, Other (This feature is hidden in the release ui until a future release date.) \ No newline at end of file +Reorganise Advanced Notifications in to Default Notifications, Keywords and Mentions, Other (This feature is hidden in the release ui until a future release date.) \ No newline at end of file From 7405d501f6d7020abefce27e301309d834c55608 Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Tue, 27 Jul 2021 20:38:13 +0100 Subject: [PATCH 09/21] lint --- .../app/features/settings/notifications/NotificationIndex.kt | 1 - .../app/features/settings/notifications/PushRuleDefinitions.kt | 2 -- 2 files changed, 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt index 678a4e14c2..10bf6f7762 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt @@ -39,7 +39,6 @@ val PushRule.notificationIndex: NotificationIndex? get() = ruleMatches(this, targetRule) } - private fun ruleMatches(rule: PushRule, targetRule: PushRule): Boolean { // Rules match if both are disabled, or if both are enabled and their highlight/sound/notify actions match up. return (!rule.enabled && !targetRule.enabled) 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 f3bac188a2..dd9077508e 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 @@ -17,8 +17,6 @@ package im.vector.app.features.settings.notifications import org.matrix.android.sdk.api.pushrules.RuleIds -import org.matrix.android.sdk.api.pushrules.rest.PushRule -import org.matrix.android.sdk.api.pushrules.toJson fun getStandardAction(ruleId: String, index: NotificationIndex): StandardActions? { return when (ruleId) { From 886bd3cc8f06b097723702e5aac849ef70556acb Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Wed, 28 Jul 2021 09:34:15 +0100 Subject: [PATCH 10/21] lint --- .../VectorSettingsPushRuleNotificationPreferenceFragment.kt | 2 -- 1 file changed, 2 deletions(-) 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 7f5ed0084d..8019ac4f53 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 @@ -92,7 +92,6 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment return rule.enabled && !rule.shouldNotNotify() } - override fun bindPref() { for (preferenceKey in prefKeyToPushRuleId.keys) { val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!! @@ -141,5 +140,4 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment private fun refreshDisplay() { listView?.adapter?.notifyDataSetChanged() } - } From 756ff3d93805f79ec50467ffb4ac5ae4001d2241 Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Tue, 10 Aug 2021 10:54:13 +0100 Subject: [PATCH 11/21] cleanup unused code and add comments for clarity --- .../notifications/NotificationIndex.kt | 7 +++ ...sAdvancedNotificationPreferenceFragment.kt | 1 - ...sPushRuleNotificationPreferenceFragment.kt | 63 ------------------- 3 files changed, 7 insertions(+), 64 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt index 10bf6f7762..27f9302c45 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt @@ -29,6 +29,10 @@ enum class NotificationIndex(val index: Int) { } } +/** + * Given a push rule determine the NotificationIndex by comparing it to the static push rule definitions. + * Used when determining the selected state of the PushRulePreference. + */ val PushRule.notificationIndex: NotificationIndex? get() = NotificationIndex.values().firstOrNull { // Get the actions for the index @@ -39,6 +43,9 @@ val PushRule.notificationIndex: NotificationIndex? get() = ruleMatches(this, targetRule) } +/** + * A check to determine if two push rules should be considered a match. + */ private fun ruleMatches(rule: PushRule, targetRule: PushRule): Boolean { // Rules match if both are disabled, or if both are enabled and their highlight/sound/notify actions match up. return (!rule.enabled && !targetRule.enabled) 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/VectorSettingsAdvancedNotificationPreferenceFragment.kt index 5ffb4d854d..93a788f528 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/VectorSettingsAdvancedNotificationPreferenceFragment.kt @@ -38,7 +38,6 @@ class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor() for (preferenceKey in prefKeyToPushRuleId.keys) { val preference = findPreference<VectorPreference>(preferenceKey) if (preference is PushRulePreference) { - // preference.isEnabled = null != rules && isConnected && pushManager.areDeviceNotificationsAllowed() val ruleAndKind: PushRuleAndKind? = session.getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey]) if (ruleAndKind == null) { 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 8019ac4f53..6f28876e1d 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 @@ -22,10 +22,6 @@ import im.vector.app.core.preference.VectorCheckboxPreference import im.vector.app.core.utils.toast import im.vector.app.features.settings.VectorSettingsBaseFragment import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.pushrules.Action -import org.matrix.android.sdk.api.pushrules.RuleIds -import org.matrix.android.sdk.api.pushrules.RuleSetKey -import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind abstract class VectorSettingsPushRuleNotificationPreferenceFragment @@ -33,65 +29,6 @@ abstract class VectorSettingsPushRuleNotificationPreferenceFragment abstract val prefKeyToPushRuleId: Map<String, String> - /** - * Create a push rule with the updated checkbox status. - * - * @param status boolean checkbox status - * @return a push rule with the updated flags - */ - fun createNewRule(ruleAndKind: PushRuleAndKind, status: Boolean): PushRule { - val safeRule = ruleAndKind.pushRule - val safeKind = ruleAndKind.kind - val ruleStatusIndex = ruleStatusIndexFor(ruleAndKind) - - return if (status != ruleStatusIndex) { - if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { - if (status) { - safeRule.copy(enabled = true) - .setNotify(true) - .setNotificationSound() - } else { - safeRule.copy(enabled = true) - .setNotify(false) - .removeNotificationSound() - } - } else { - if (status) { - safeRule.copy(enabled = true) - .setNotify(true) - .setHighlight(safeKind != RuleSetKey.UNDERRIDE - && safeRule.ruleId != RuleIds.RULE_ID_INVITE_ME) - .setNotificationSound( - if (safeRule.ruleId == RuleIds.RULE_ID_CALL) { - Action.ACTION_OBJECT_VALUE_VALUE_RING - } else { - Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT - } - ) - } else { - if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { - safeRule.setNotify(false) - } else { - safeRule.copy(enabled = false) - } - } - } - } else { - safeRule - } - } - - /** - * @return the bing rule status boolean - */ - private fun ruleStatusIndexFor(ruleAndKind: PushRuleAndKind): Boolean { - val rule = ruleAndKind.pushRule - if (rule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { - return rule.shouldNotify() || rule.shouldNotNotify() && !rule.enabled - } - return rule.enabled && !rule.shouldNotNotify() - } - override fun bindPref() { for (preferenceKey in prefKeyToPushRuleId.keys) { val preference = findPreference<VectorCheckboxPreference>(preferenceKey)!! From bf9a22c1b03cc87946deeeaeae466256a77fa2b4 Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Tue, 10 Aug 2021 13:59:39 +0300 Subject: [PATCH 12/21] Fix flickering lock view. --- .../home/room/detail/composer/VoiceMessageRecorderView.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index 48195dc8f1..00ab67656c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -220,6 +220,9 @@ class VoiceMessageRecorderView @JvmOverloads constructor( } RecordingState.STARTED -> { showRecordingViews() + val translationAmount = distanceX.coerceAtMost(distanceToCancel) + views.voiceMessageMicButton.translationX = -translationAmount * rtlXMultiplier + views.voiceMessageSlideToCancel.translationX = -translationAmount / 2 * rtlXMultiplier } RecordingState.NONE -> Timber.d("VoiceMessageRecorderView shouldn't be in NONE state while moving.") RecordingState.PLAYBACK -> Timber.d("VoiceMessageRecorderView shouldn't be in PLAYBACK state while moving.") @@ -235,7 +238,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor( if (recordingState == RecordingState.STARTED) { // Determine if cancelling or locking for the first move action. if (((currentX < firstX && rtlXMultiplier == 1) || (currentX > firstX && rtlXMultiplier == -1)) - && distanceX > distanceY) { + && distanceX > distanceY && distanceX > lastDistanceX) { recordingState = RecordingState.CANCELLING } else if (currentY < firstY && distanceY > distanceX) { recordingState = RecordingState.LOCKING From a0730943b494bca4ca97c35aeddbce001ab36b79 Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Tue, 10 Aug 2021 14:17:33 +0300 Subject: [PATCH 13/21] Dynamically set content description of play/pause button. --- .../home/room/detail/composer/VoiceMessageRecorderView.kt | 2 ++ .../home/room/detail/timeline/item/MessageVoiceItem.kt | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index 00ab67656c..50d8d8e867 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -510,12 +510,14 @@ class VoiceMessageRecorderView @JvmOverloads constructor( } is VoiceMessagePlaybackTracker.Listener.State.Playing -> { views.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause) + views.voicePlaybackControlButton.contentDescription = context.getString(R.string.a11y_pause_voice_message) val formattedTimerText = DateUtils.formatElapsedTime((state.playbackTime / 1000).toLong()) views.voicePlaybackTime.text = formattedTimerText } is VoiceMessagePlaybackTracker.Listener.State.Paused, is VoiceMessagePlaybackTracker.Listener.State.Idle -> { views.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + views.voicePlaybackControlButton.contentDescription = context.getString(R.string.a11y_play_voice_message) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt index dc204da291..fb7d0cabd5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt @@ -71,6 +71,7 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, izLocalFile, holder.progressLayout) } else { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_cross) + holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.error_voice_message_unable_to_play) holder.progressLayout.isVisible = false } @@ -98,16 +99,19 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { private fun renderIdleState(holder: Holder) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_play_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(duration) } private fun renderPlayingState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Playing) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause) + holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_pause_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) } private fun renderPausedState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Paused) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_play_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) } From bf1db5dcf9af1f8591627e4495ec8927aa8eee3e Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Tue, 10 Aug 2021 14:36:01 +0300 Subject: [PATCH 14/21] Remove content description of mic button if it is not visible. --- .../room/detail/composer/VoiceMessageRecorderView.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index 50d8d8e867..033020bbce 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -20,6 +20,7 @@ import android.content.Context import android.text.format.DateUtils import android.util.AttributeSet import android.view.MotionEvent +import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isInvisible import androidx.core.view.isVisible @@ -87,6 +88,15 @@ class VoiceMessageRecorderView @JvmOverloads constructor( initListeners() } + override fun onVisibilityChanged(changedView: View, visibility: Int) { + super.onVisibilityChanged(changedView, visibility) + if (changedView == this && visibility == VISIBLE) { + views.voiceMessageMicButton.contentDescription = context.getString(R.string.a11y_start_voice_message) + } else { + views.voiceMessageMicButton.contentDescription = "" + } + } + fun initVoiceRecordingViews() { recordingState = RecordingState.NONE From 296a1c47702a5228c612df2c98c02e01bc75208f Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Tue, 10 Aug 2021 14:43:16 +0300 Subject: [PATCH 15/21] Vibrate when the recording is canceled. --- .../home/room/detail/composer/VoiceMessageRecorderView.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index 033020bbce..f059d4285e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -428,6 +428,10 @@ class VoiceMessageRecorderView @JvmOverloads constructor( if (recordingState == RecordingState.CANCELLED || recordingState == RecordingState.NONE) { hideToast() } + + if (isCancelled.orFalse()) { + vibrate(context) + } } private fun resetMicButtonUi() { From 0cd0484b41bd714502a063ca516ce7722f3c8a3e Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Tue, 10 Aug 2021 14:54:03 +0300 Subject: [PATCH 16/21] Fix flickering between locking states. --- .../home/room/detail/composer/VoiceMessageRecorderView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index f059d4285e..96a066b295 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -250,7 +250,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor( if (((currentX < firstX && rtlXMultiplier == 1) || (currentX > firstX && rtlXMultiplier == -1)) && distanceX > distanceY && distanceX > lastDistanceX) { recordingState = RecordingState.CANCELLING - } else if (currentY < firstY && distanceY > distanceX) { + } else if (currentY < firstY && distanceY > distanceX && distanceY > lastDistanceY) { recordingState = RecordingState.LOCKING } } else if (recordingState == RecordingState.CANCELLING) { From 9f4a45911656c0f873027fc4c83958b62057444d Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Tue, 10 Aug 2021 15:40:04 +0300 Subject: [PATCH 17/21] Fix cannot draw waveform while recording after onPause. --- .../vector/app/features/home/room/detail/RoomDetailFragment.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 6a8b4fa863..c37f1840ac 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -1044,6 +1044,9 @@ class RoomDetailFragment @Inject constructor( notificationDrawerManager.setCurrentRoom(roomDetailArgs.roomId) roomDetailPendingActionStore.data?.let { handlePendingAction(it) } roomDetailPendingActionStore.data = null + + // Removed listeners should be set again + setupVoiceMessageView() } private fun handlePendingAction(roomDetailPendingAction: RoomDetailPendingAction) { From 5cc9c6231b372143d326369ffc0f6bea043ebfbe Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Tue, 10 Aug 2021 15:44:09 +0300 Subject: [PATCH 18/21] Changelog added. --- changelog.d/3798.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/3798.bugfix diff --git a/changelog.d/3798.bugfix b/changelog.d/3798.bugfix new file mode 100644 index 0000000000..92374d94d6 --- /dev/null +++ b/changelog.d/3798.bugfix @@ -0,0 +1 @@ +Voice Message - UI Improvements \ No newline at end of file From 45077c69f771951fc9924b8cd8b017b847b81cd6 Mon Sep 17 00:00:00 2001 From: David Langley <langley.dave@gmail.com> Date: Wed, 11 Aug 2021 09:59:23 +0100 Subject: [PATCH 19/21] remove NotificationIndex Int index --- .../settings/notifications/NotificationIndex.kt | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt index 27f9302c45..29d316bb76 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt @@ -19,14 +19,10 @@ package im.vector.app.features.settings.notifications import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.pushrules.toJson -enum class NotificationIndex(val index: Int) { - OFF(0), - SILENT(1), - NOISY(2); - - companion object { - fun fromInt(index: Int) = values().first { it.index == index } - } +enum class NotificationIndex { + OFF, + SILENT, + NOISY; } /** From c2401e04b4966a76de2b058f1583431d69ee2134 Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Wed, 11 Aug 2021 14:54:29 +0300 Subject: [PATCH 20/21] Fix collapsing mic and send buttons. --- .../vector/app/features/home/room/detail/RoomDetailFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index c37f1840ac..e50d6c8df3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -1321,7 +1321,6 @@ class RoomDetailFragment @Inject constructor( if (text.isNotBlank()) { // We collapse ASAP, if not there will be a slight annoying delay views.composerLayout.collapse(true) - views.voiceMessageRecorderView.isVisible = vectorPreferences.labsUseVoiceMessage() lockSendButton = true roomDetailViewModel.handle(RoomDetailAction.SendMessage(text, vectorPreferences.isMarkdownEnabled())) emojiPopup.dismiss() From a8f4b318c18c067e9d63edfc2d87f7bf9745c5e5 Mon Sep 17 00:00:00 2001 From: Onuray Sahin <onurays@element.io> Date: Wed, 11 Aug 2021 14:59:21 +0300 Subject: [PATCH 21/21] Fix tice vibration after cancelling the voice record. --- .../home/room/detail/composer/VoiceMessageRecorderView.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index 96a066b295..47e72b46f7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -219,6 +219,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor( } RecordingState.CANCELLED -> { hideRecordingViews(isCancelled = true) + vibrate(context) } RecordingState.LOCKED -> { if (isRecordingStateChanged) { // Do not update views if it was already in locked state. @@ -428,10 +429,6 @@ class VoiceMessageRecorderView @JvmOverloads constructor( if (recordingState == RecordingState.CANCELLED || recordingState == RecordingState.NONE) { hideToast() } - - if (isCancelled.orFalse()) { - vibrate(context) - } } private fun resetMicButtonUi() {