Merge pull request #1090 from vector-im/feature/notif

Restore the push rule settings
This commit is contained in:
Benoit Marty 2020-03-06 14:43:33 +01:00 committed by GitHub
commit 147766176c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 619 additions and 394 deletions

View File

@ -19,6 +19,7 @@
<w>msisdn</w> <w>msisdn</w>
<w>pbkdf</w> <w>pbkdf</w>
<w>pkcs</w> <w>pkcs</w>
<w>riotx</w>
<w>signin</w> <w>signin</w>
<w>signout</w> <w>signout</w>
<w>signup</w> <w>signup</w>

View File

@ -10,6 +10,7 @@ Improvements 🙌:
- Detect spaces in password if user fail to login (#1038) - Detect spaces in password if user fail to login (#1038)
- FTUE: do not display a different color when encrypting message when not in developer mode. - FTUE: do not display a different color when encrypting message when not in developer mode.
- Open room member profile from avatar of the room member state event (#935) - Open room member profile from avatar of the room member state event (#935)
- Restore the push rules configuration in the settings
Bugfix 🐛: Bugfix 🐛:
- Fix crash on attachment preview screen (#1088) - Fix crash on attachment preview screen (#1088)
@ -20,7 +21,7 @@ Translations 🗣:
- -
SDK API changes ⚠️: SDK API changes ⚠️:
- - PushRuleService.getPushRules() now returns a RuleSet. Use getAllRules() on this object to get all the rules.
Build 🧱: Build 🧱:
- Upgrade ktlint to version 0.36.0 - Upgrade ktlint to version 0.36.0

View File

@ -17,25 +17,24 @@ package im.vector.matrix.android.api.pushrules
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.pushrules.rest.PushRule import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.pushrules.rest.RuleSet
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
interface PushRuleService { interface PushRuleService {
/** /**
* Fetch the push rules from the server * Fetch the push rules from the server
*/ */
fun fetchPushRules(scope: String = RuleScope.GLOBAL) fun fetchPushRules(scope: String = RuleScope.GLOBAL)
// TODO get push rule set fun getPushRules(scope: String = RuleScope.GLOBAL): RuleSet
fun getPushRules(scope: String = RuleScope.GLOBAL): List<PushRule>
// TODO update rule
fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>): Cancelable fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>): Cancelable
fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable
fun updatePushRuleActions(kind: RuleKind, oldPushRule: PushRule, newPushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable
fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable
fun addPushRuleListener(listener: PushRuleListener) fun addPushRuleListener(listener: PushRuleListener)

View File

@ -20,6 +20,7 @@ import com.squareup.moshi.JsonClass
/** /**
* All push rulesets for a user. * All push rulesets for a user.
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
internal data class GetPushRulesResponse( internal data class GetPushRulesResponse(
@ -27,11 +28,11 @@ internal data class GetPushRulesResponse(
* Global rules, account level applying to all devices * Global rules, account level applying to all devices
*/ */
@Json(name = "global") @Json(name = "global")
val global: Ruleset, val global: RuleSet,
/** /**
* Device specific rules, apply only to current device * Device specific rules, apply only to current device
*/ */
@Json(name = "device") @Json(name = "device")
val device: Ruleset? = null val device: RuleSet? = null
) )

View File

@ -24,21 +24,27 @@ import im.vector.matrix.android.api.pushrules.RoomMemberCountCondition
import im.vector.matrix.android.api.pushrules.SenderNotificationPermissionCondition import im.vector.matrix.android.api.pushrules.SenderNotificationPermissionCondition
import timber.log.Timber import timber.log.Timber
/**
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules
*/
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class PushCondition( data class PushCondition(
/** /**
* Required. The kind of condition to apply. * Required. The kind of condition to apply.
*/ */
@Json(name = "kind")
val kind: String, val kind: String,
/** /**
* Required for event_match conditions. The dot- separated field of the event to match. * Required for event_match conditions. The dot- separated field of the event to match.
*/ */
@Json(name = "key")
val key: String? = null, val key: String? = null,
/** /**
* Required for event_match conditions. * Required for event_match conditions.
*/ */
@Json(name = "pattern")
val pattern: String? = null, val pattern: String? = null,
/** /**
@ -47,7 +53,8 @@ data class PushCondition(
* A prefix of < matches rooms where the member count is strictly less than the given number and so forth. * A prefix of < matches rooms where the member count is strictly less than the given number and so forth.
* If no prefix is present, this parameter defaults to ==. * If no prefix is present, this parameter defaults to ==.
*/ */
@Json(name = "is") val iz: String? = null @Json(name = "is")
val iz: String? = null
) { ) {
fun asExecutableCondition(): Condition? { fun asExecutableCondition(): Condition? {

View File

@ -18,31 +18,158 @@ package im.vector.matrix.android.api.pushrules.rest
import com.squareup.moshi.Json import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.pushrules.Action
import im.vector.matrix.android.api.pushrules.getActions
import im.vector.matrix.android.api.pushrules.toJson
/**
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules
*/
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class PushRule( data class PushRule(
/** /**
* Required. The actions to perform when this rule is matched. * Required. The actions to perform when this rule is matched.
*/ */
@Json(name = "actions")
val actions: List<Any>, val actions: List<Any>,
/** /**
* Required. Whether this is a default rule, or has been set explicitly. * Required. Whether this is a default rule, or has been set explicitly.
*/ */
@Json(name = "default")
val default: Boolean? = false, val default: Boolean? = false,
/** /**
* Required. Whether the push rule is enabled or not. * Required. Whether the push rule is enabled or not.
*/ */
@Json(name = "enabled")
val enabled: Boolean, val enabled: Boolean,
/** /**
* Required. The ID of this rule. * Required. The ID of this rule.
*/ */
@Json(name = "rule_id") val ruleId: String, @Json(name = "rule_id")
val ruleId: String,
/** /**
* The conditions that must hold true for an event in order for a rule to be applied to an event * The conditions that must hold true for an event in order for a rule to be applied to an event
*/ */
@Json(name = "conditions")
val conditions: List<PushCondition>? = null, val conditions: List<PushCondition>? = null,
/** /**
* The glob-style pattern to match against. Only applicable to content rules. * The glob-style pattern to match against. Only applicable to content rules.
*/ */
@Json(name = "pattern")
val pattern: String? = null val pattern: String? = null
) ) {
/**
* Add the default notification sound.
*/
fun setNotificationSound(): PushRule {
return setNotificationSound(ACTION_VALUE_DEFAULT)
}
fun getNotificationSound(): String? {
return (getActions().firstOrNull { it is Action.Sound } as? Action.Sound)?.sound
}
/**
* Set the notification sound
*
* @param sound notification sound
*/
fun setNotificationSound(sound: String): PushRule {
return copy(
actions = (getActions().filter { it !is Action.Sound } + Action.Sound(sound)).toJson()
)
}
/**
* Remove the notification sound
*/
fun removeNotificationSound(): PushRule {
return copy(
actions = getActions().filter { it !is Action.Sound }.toJson()
)
}
/**
* Set the highlight status.
*
* @param highlight the highlight status
*/
fun setHighlight(highlight: Boolean): PushRule {
return copy(
actions = (getActions().filter { it !is Action.Highlight } + Action.Highlight(highlight)).toJson()
)
}
/**
* Set the notification status.
*
* @param notify true to notify
*/
fun setNotify(notify: Boolean): PushRule {
val mutableActions = actions.toMutableList()
mutableActions.remove(ACTION_DONT_NOTIFY)
mutableActions.remove(ACTION_NOTIFY)
if (notify) {
mutableActions.add(ACTION_NOTIFY)
} else {
mutableActions.add(ACTION_DONT_NOTIFY)
}
return copy(actions = mutableActions)
}
/**
* Return true if the rule should highlight the event.
*
* @return true if the rule should play sound
*/
fun shouldNotify() = actions.contains(ACTION_NOTIFY)
/**
* Return true if the rule should not highlight the event.
*
* @return true if the rule should not play sound
*/
fun shouldNotNotify() = actions.contains(ACTION_DONT_NOTIFY)
companion object {
/* ==========================================================================================
* Rule id
* ========================================================================================== */
const val RULE_ID_DISABLE_ALL = ".m.rule.master"
const val RULE_ID_CONTAIN_USER_NAME = ".m.rule.contains_user_name"
const val RULE_ID_CONTAIN_DISPLAY_NAME = ".m.rule.contains_display_name"
const val RULE_ID_ONE_TO_ONE_ROOM = ".m.rule.room_one_to_one"
const val RULE_ID_INVITE_ME = ".m.rule.invite_for_me"
const val RULE_ID_PEOPLE_JOIN_LEAVE = ".m.rule.member_event"
const val RULE_ID_CALL = ".m.rule.call"
const val RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS = ".m.rule.suppress_notices"
const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = ".m.rule.message"
const val RULE_ID_AT_ROOMS = ".m.rule.roomnotif"
const val RULE_ID_TOMBSTONE = ".m.rule.tombstone"
const val RULE_ID_E2E_ONE_TO_ONE_ROOM = ".m.rule.encrypted_room_one_to_one"
const val RULE_ID_E2E_GROUP = ".m.rule.encrypted"
const val RULE_ID_REACTION = ".m.rule.reaction"
const val RULE_ID_FALLBACK = ".m.rule.fallback"
/* ==========================================================================================
* Actions
* ========================================================================================== */
const val ACTION_NOTIFY = "notify"
const val ACTION_DONT_NOTIFY = "dont_notify"
const val ACTION_COALESCE = "coalesce"
const val ACTION_SET_TWEAK_SOUND_VALUE = "sound"
const val ACTION_SET_TWEAK_HIGHLIGHT_VALUE = "highlight"
const val ACTION_PARAMETER_SET_TWEAK = "set_tweak"
const val ACTION_PARAMETER_VALUE = "value"
const val ACTION_VALUE_DEFAULT = "default"
const val ACTION_VALUE_RING = "ring"
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2019 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.matrix.android.api.pushrules.rest
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.pushrules.RuleSetKey
/**
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules
*/
@JsonClass(generateAdapter = true)
data class RuleSet(
@Json(name = "content")
val content: List<PushRule>? = null,
@Json(name = "override")
val override: List<PushRule>? = null,
@Json(name = "room")
val room: List<PushRule>? = null,
@Json(name = "sender")
val sender: List<PushRule>? = null,
@Json(name = "underride")
val underride: List<PushRule>? = null
) {
fun getAllRules(): List<PushRule> {
// Ref. for the order: https://matrix.org/docs/spec/client_server/latest#push-rules
return override.orEmpty() + content.orEmpty() + room.orEmpty() + sender.orEmpty() + underride.orEmpty()
}
/**
* Find a rule from its ruleID.
*
* @param ruleId a RULE_ID_XX value
* @return the matched bing rule or null it doesn't exist.
*/
fun findDefaultRule(ruleId: String?): PushRuleAndKind? {
var result: PushRuleAndKind? = null
// sanity check
if (null != ruleId) {
if (PushRule.RULE_ID_CONTAIN_USER_NAME == ruleId) {
result = findRule(content, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.CONTENT) }
} else {
// assume that the ruleId is unique.
result = findRule(override, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.OVERRIDE) }
if (null == result) {
result = findRule(underride, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.UNDERRIDE) }
}
}
}
return result
}
/**
* Find a rule from its rule Id.
*
* @param rules the rules list.
* @param ruleId the rule Id.
* @return the bing rule if it exists, else null.
*/
private fun findRule(rules: List<PushRule>?, ruleId: String): PushRule? {
return rules?.firstOrNull { it.ruleId == ruleId }
}
}
data class PushRuleAndKind(
val pushRule: PushRule,
val kind: RuleSetKey
)

View File

@ -1,27 +0,0 @@
/*
* Copyright 2019 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.matrix.android.api.pushrules.rest
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class Ruleset(
val content: List<PushRule>? = null,
val override: List<PushRule>? = null,
val room: List<PushRule>? = null,
val sender: List<PushRule>? = null,
val underride: List<PushRule>? = null
)

View File

@ -22,6 +22,7 @@ import im.vector.matrix.android.api.pushrules.RuleKind
import im.vector.matrix.android.api.pushrules.RuleSetKey import im.vector.matrix.android.api.pushrules.RuleSetKey
import im.vector.matrix.android.api.pushrules.getActions import im.vector.matrix.android.api.pushrules.getActions
import im.vector.matrix.android.api.pushrules.rest.PushRule import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.pushrules.rest.RuleSet
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.mapper.PushRulesMapper import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
@ -31,6 +32,7 @@ import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask
import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask
import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask
import im.vector.matrix.android.internal.session.pushers.UpdatePushRuleActionsTask
import im.vector.matrix.android.internal.session.pushers.UpdatePushRuleEnableStatusTask import im.vector.matrix.android.internal.session.pushers.UpdatePushRuleEnableStatusTask
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
@ -42,6 +44,7 @@ internal class DefaultPushRuleService @Inject constructor(
private val getPushRulesTask: GetPushRulesTask, private val getPushRulesTask: GetPushRulesTask,
private val updatePushRuleEnableStatusTask: UpdatePushRuleEnableStatusTask, private val updatePushRuleEnableStatusTask: UpdatePushRuleEnableStatusTask,
private val addPushRuleTask: AddPushRuleTask, private val addPushRuleTask: AddPushRuleTask,
private val updatePushRuleActionsTask: UpdatePushRuleActionsTask,
private val removePushRuleTask: RemovePushRuleTask, private val removePushRuleTask: RemovePushRuleTask,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val monarchy: Monarchy private val monarchy: Monarchy
@ -55,7 +58,7 @@ internal class DefaultPushRuleService @Inject constructor(
.executeBy(taskExecutor) .executeBy(taskExecutor)
} }
override fun getPushRules(scope: String): List<PushRule> { override fun getPushRules(scope: String): RuleSet {
var contentRules: List<PushRule> = emptyList() var contentRules: List<PushRule> = emptyList()
var overrideRules: List<PushRule> = emptyList() var overrideRules: List<PushRule> = emptyList()
var roomRules: List<PushRule> = emptyList() var roomRules: List<PushRule> = emptyList()
@ -90,8 +93,13 @@ internal class DefaultPushRuleService @Inject constructor(
} }
} }
// Ref. for the order: https://matrix.org/docs/spec/client_server/latest#push-rules return RuleSet(
return overrideRules + contentRules + roomRules + senderRules + underrideRules content = contentRules,
override = overrideRules,
room = roomRules,
sender = senderRules,
underride = underrideRules
)
} }
override fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>): Cancelable { override fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>): Cancelable {
@ -111,6 +119,14 @@ internal class DefaultPushRuleService @Inject constructor(
.executeBy(taskExecutor) .executeBy(taskExecutor)
} }
override fun updatePushRuleActions(kind: RuleKind, oldPushRule: PushRule, newPushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable {
return updatePushRuleActionsTask
.configureWith(UpdatePushRuleActionsTask.Params(kind, oldPushRule, newPushRule)) {
this.callback = callback
}
.executeBy(taskExecutor)
}
override fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable { override fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable {
return removePushRuleTask return removePushRuleTask
.configureWith(RemovePushRuleTask.Params(kind, pushRule)) { .configureWith(RemovePushRuleTask.Params(kind, pushRule)) {

View File

@ -47,6 +47,7 @@ internal interface PushRulesApi {
/** /**
* Update the ruleID action * Update the ruleID action
* Ref: https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-pushrules-scope-kind-ruleid-actions
* *
* @param kind the notification kind (sender, room...) * @param kind the notification kind (sender, room...)
* @param ruleId the ruleId * @param ruleId the ruleId

View File

@ -72,6 +72,9 @@ internal abstract class PushersModule {
@Binds @Binds
abstract fun bindAddPushRuleTask(task: DefaultAddPushRuleTask): AddPushRuleTask abstract fun bindAddPushRuleTask(task: DefaultAddPushRuleTask): AddPushRuleTask
@Binds
abstract fun bindUpdatePushRuleActionTask(task: DefaultUpdatePushRuleActionsTask): UpdatePushRuleActionsTask
@Binds @Binds
abstract fun bindRemovePushRuleTask(task: DefaultRemovePushRuleTask): RemovePushRuleTask abstract fun bindRemovePushRuleTask(task: DefaultRemovePushRuleTask): RemovePushRuleTask

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2020 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.matrix.android.internal.session.pushers
import im.vector.matrix.android.api.pushrules.RuleKind
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject
internal interface UpdatePushRuleActionsTask : Task<UpdatePushRuleActionsTask.Params, Unit> {
data class Params(
val kind: RuleKind,
val oldPushRule: PushRule,
val newPushRule: PushRule
)
}
internal class DefaultUpdatePushRuleActionsTask @Inject constructor(
private val pushRulesApi: PushRulesApi,
private val eventBus: EventBus
) : UpdatePushRuleActionsTask {
override suspend fun execute(params: UpdatePushRuleActionsTask.Params) {
if (params.oldPushRule.enabled != params.newPushRule.enabled) {
// First change enabled state
executeRequest<Unit>(eventBus) {
apiCall = pushRulesApi.updateEnableRuleStatus(params.kind.value, params.newPushRule.ruleId, params.newPushRule.enabled)
}
}
if (params.newPushRule.enabled) {
// Also ensure the actions are up to date
val body = mapOf("actions" to params.newPushRule.actions)
executeRequest<Unit>(eventBus) {
apiCall = pushRulesApi.updateRuleActions(params.kind.value, params.newPushRule.ruleId, body)
}
}
}
}

View File

@ -120,7 +120,7 @@ internal class SyncResponseHandler @Inject constructor(private val monarchy: Mon
return return
} // nothing on initial sync } // nothing on initial sync
val rules = pushRuleService.getPushRules(RuleScope.GLOBAL) val rules = pushRuleService.getPushRules(RuleScope.GLOBAL).getAllRules()
processEventForPushTask.execute(ProcessEventForPushTask.Params(roomsSyncResponse, rules)) processEventForPushTask.execute(ProcessEventForPushTask.Params(roomsSyncResponse, rules))
Timber.v("[PushRules] <-- Push task scheduled") Timber.v("[PushRules] <-- Push task scheduled")
} }

View File

@ -20,7 +20,7 @@ import im.vector.riotx.fdroid.features.settings.troubleshoot.TestAutoStartBoot
import im.vector.riotx.fdroid.features.settings.troubleshoot.TestBackgroundRestrictions import im.vector.riotx.fdroid.features.settings.troubleshoot.TestBackgroundRestrictions
import im.vector.riotx.features.settings.troubleshoot.NotificationTroubleshootTestManager import im.vector.riotx.features.settings.troubleshoot.NotificationTroubleshootTestManager
import im.vector.riotx.features.settings.troubleshoot.TestAccountSettings import im.vector.riotx.features.settings.troubleshoot.TestAccountSettings
import im.vector.riotx.features.settings.troubleshoot.TestBingRulesSettings import im.vector.riotx.features.settings.troubleshoot.TestPushRulesSettings
import im.vector.riotx.features.settings.troubleshoot.TestDeviceSettings import im.vector.riotx.features.settings.troubleshoot.TestDeviceSettings
import im.vector.riotx.features.settings.troubleshoot.TestSystemSettings import im.vector.riotx.features.settings.troubleshoot.TestSystemSettings
import javax.inject.Inject import javax.inject.Inject
@ -28,7 +28,7 @@ import javax.inject.Inject
class NotificationTroubleshootTestManagerFactory @Inject constructor(private val testSystemSettings: TestSystemSettings, class NotificationTroubleshootTestManagerFactory @Inject constructor(private val testSystemSettings: TestSystemSettings,
private val testAccountSettings: TestAccountSettings, private val testAccountSettings: TestAccountSettings,
private val testDeviceSettings: TestDeviceSettings, private val testDeviceSettings: TestDeviceSettings,
private val testBingRulesSettings: TestBingRulesSettings, private val testPushRulesSettings: TestPushRulesSettings,
private val testAutoStartBoot: TestAutoStartBoot, private val testAutoStartBoot: TestAutoStartBoot,
private val testBackgroundRestrictions: TestBackgroundRestrictions) { private val testBackgroundRestrictions: TestBackgroundRestrictions) {
@ -37,7 +37,7 @@ class NotificationTroubleshootTestManagerFactory @Inject constructor(private val
mgr.addTest(testSystemSettings) mgr.addTest(testSystemSettings)
mgr.addTest(testAccountSettings) mgr.addTest(testAccountSettings)
mgr.addTest(testDeviceSettings) mgr.addTest(testDeviceSettings)
mgr.addTest(testBingRulesSettings) mgr.addTest(testPushRulesSettings)
mgr.addTest(testAutoStartBoot) mgr.addTest(testAutoStartBoot)
mgr.addTest(testBackgroundRestrictions) mgr.addTest(testBackgroundRestrictions)
return mgr return mgr

View File

@ -25,13 +25,13 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner
import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage import com.google.firebase.messaging.RemoteMessage
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.riotx.BuildConfig import im.vector.riotx.BuildConfig
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.extensions.vectorComponent import im.vector.riotx.core.extensions.vectorComponent
import im.vector.riotx.core.preference.BingRule
import im.vector.riotx.core.pushers.PushersManager import im.vector.riotx.core.pushers.PushersManager
import im.vector.riotx.features.badge.BadgeProxy import im.vector.riotx.features.badge.BadgeProxy
import im.vector.riotx.features.notifications.NotifiableEventResolver import im.vector.riotx.features.notifications.NotifiableEventResolver
@ -196,7 +196,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
description = "", description = "",
type = null, type = null,
timestamp = System.currentTimeMillis(), timestamp = System.currentTimeMillis(),
soundName = BingRule.ACTION_VALUE_DEFAULT, soundName = PushRule.ACTION_VALUE_DEFAULT,
isPushGatewayEvent = true isPushGatewayEvent = true
) )
notificationDrawerManager.onNotifiableEventReceived(simpleNotifiableEvent) notificationDrawerManager.onNotifiableEventReceived(simpleNotifiableEvent)

View File

@ -18,8 +18,8 @@ package im.vector.riotx.push.fcm
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import im.vector.riotx.features.settings.troubleshoot.NotificationTroubleshootTestManager import im.vector.riotx.features.settings.troubleshoot.NotificationTroubleshootTestManager
import im.vector.riotx.features.settings.troubleshoot.TestAccountSettings import im.vector.riotx.features.settings.troubleshoot.TestAccountSettings
import im.vector.riotx.features.settings.troubleshoot.TestBingRulesSettings
import im.vector.riotx.features.settings.troubleshoot.TestDeviceSettings import im.vector.riotx.features.settings.troubleshoot.TestDeviceSettings
import im.vector.riotx.features.settings.troubleshoot.TestPushRulesSettings
import im.vector.riotx.features.settings.troubleshoot.TestSystemSettings import im.vector.riotx.features.settings.troubleshoot.TestSystemSettings
import im.vector.riotx.gplay.features.settings.troubleshoot.TestFirebaseToken import im.vector.riotx.gplay.features.settings.troubleshoot.TestFirebaseToken
import im.vector.riotx.gplay.features.settings.troubleshoot.TestPlayServices import im.vector.riotx.gplay.features.settings.troubleshoot.TestPlayServices
@ -29,7 +29,7 @@ import javax.inject.Inject
class NotificationTroubleshootTestManagerFactory @Inject constructor(private val testSystemSettings: TestSystemSettings, class NotificationTroubleshootTestManagerFactory @Inject constructor(private val testSystemSettings: TestSystemSettings,
private val testAccountSettings: TestAccountSettings, private val testAccountSettings: TestAccountSettings,
private val testDeviceSettings: TestDeviceSettings, private val testDeviceSettings: TestDeviceSettings,
private val testBingRulesSettings: TestBingRulesSettings, private val testBingRulesSettings: TestPushRulesSettings,
private val testPlayServices: TestPlayServices, private val testPlayServices: TestPlayServices,
private val testFirebaseToken: TestFirebaseToken, private val testFirebaseToken: TestFirebaseToken,
private val testTokenRegistration: TestTokenRegistration) { private val testTokenRegistration: TestTokenRegistration) {

View File

@ -22,49 +22,17 @@ import android.view.View
import android.widget.RadioGroup import android.widget.RadioGroup
import android.widget.TextView import android.widget.TextView
import androidx.preference.PreferenceViewHolder import androidx.preference.PreferenceViewHolder
import im.vector.matrix.android.api.pushrules.RuleSetKey
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.pushrules.rest.PushRuleAndKind
import im.vector.riotx.R import im.vector.riotx.R
// TODO Replace by real Bingrule class, then delete class PushRulePreference : VectorPreference {
@Suppress("UNUSED_PARAMETER")
class BingRule(rule: BingRule) {
fun shouldNotNotify() = false
fun shouldNotify() = false
fun setNotify(b: Boolean) {
}
fun setHighlight(b: Boolean) {
}
fun removeNotificationSound() {
}
val ruleId: CharSequence? = null
var isEnabled = false
var notificationSound: String? = null
val kind: CharSequence? = null
companion object {
const val RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS = "TODO"
const val ACTION_VALUE_DEFAULT = "TODO"
const val KIND_UNDERRIDE = "TODO"
const val RULE_ID_INVITE_ME = "TODO"
const val RULE_ID_CALL = "TODO"
const val ACTION_VALUE_RING = "TODO"
const val RULE_ID_DISABLE_ALL = "TODO"
const val ACTION_DONT_NOTIFY = "TODO"
const val RULE_ID_CONTAIN_DISPLAY_NAME = "TODO"
const val RULE_ID_CONTAIN_USER_NAME = "TODO"
const val RULE_ID_ONE_TO_ONE_ROOM = "TODO"
const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = "TODO"
}
}
class BingRulePreference : VectorPreference {
/** /**
* @return the selected bing rule * @return the selected push rule and its kind
*/ */
var rule: BingRule? = null var ruleAndKind: PushRuleAndKind? = null
private set private set
constructor(context: Context) : super(context) constructor(context: Context) : super(context)
@ -74,35 +42,35 @@ class BingRulePreference : VectorPreference {
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
init { init {
layoutResource = R.layout.vector_preference_bing_rule layoutResource = R.layout.vector_preference_push_rule
} }
/** /**
* @return the bing rule status index * @return the bing rule status index
*/ */
val ruleStatusIndex: Int private val ruleStatusIndex: Int
get() { get() {
if (null != rule) { val safeRule = ruleAndKind?.pushRule ?: return NOTIFICATION_OFF_INDEX
if (rule!!.ruleId == BingRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
if (rule!!.shouldNotNotify()) {
return if (rule!!.isEnabled) {
NOTIFICATION_OFF_INDEX
} else {
NOTIFICATION_SILENT_INDEX
}
} else if (rule!!.shouldNotify()) {
return NOTIFICATION_NOISY_INDEX
}
}
if (rule!!.isEnabled) { if (safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
return if (rule!!.shouldNotNotify()) { if (safeRule.shouldNotNotify()) {
return if (safeRule.enabled) {
NOTIFICATION_OFF_INDEX NOTIFICATION_OFF_INDEX
} else if (null != rule!!.notificationSound) {
NOTIFICATION_NOISY_INDEX
} else { } else {
NOTIFICATION_SILENT_INDEX 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
} }
} }
@ -110,12 +78,12 @@ class BingRulePreference : VectorPreference {
} }
/** /**
* Update the bing rule. * Update the push rule.
* *
* @param aBingRule * @param pushRule
*/ */
fun setBingRule(aBingRule: BingRule) { fun setPushRule(pushRuleAndKind: PushRuleAndKind?) {
rule = aBingRule ruleAndKind = pushRuleAndKind
refreshSummary() refreshSummary()
} }
@ -131,63 +99,64 @@ class BingRulePreference : VectorPreference {
} }
/** /**
* Create a bing rule with the updated required at index. * Create a push rule with the updated required at index.
* *
* @param index index * @param index index
* @return a bing rule with the updated flags / null if there is no update * @return a push rule with the updated flags / null if there is no update
*/ */
fun createRule(index: Int): BingRule? { fun createNewRule(index: Int): PushRule? {
var rule: BingRule? = null val safeRule = ruleAndKind?.pushRule ?: return null
val safeKind = ruleAndKind?.kind ?: return null
if (null != this.rule && index != ruleStatusIndex) { return if (index != ruleStatusIndex) {
rule = BingRule(this.rule!!) if (safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
if (rule.ruleId == BingRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
when (index) { when (index) {
NOTIFICATION_OFF_INDEX -> { NOTIFICATION_OFF_INDEX -> {
rule.isEnabled = true safeRule.copy(enabled = true)
rule.setNotify(false) .setNotify(false)
.removeNotificationSound()
} }
NOTIFICATION_SILENT_INDEX -> { NOTIFICATION_SILENT_INDEX -> {
rule.isEnabled = false safeRule.copy(enabled = false)
rule.setNotify(false) .setNotify(false)
} }
NOTIFICATION_NOISY_INDEX -> { NOTIFICATION_NOISY_INDEX -> {
rule.isEnabled = true safeRule.copy(enabled = true)
rule.setNotify(true) .setNotify(true)
rule.notificationSound = BingRule.ACTION_VALUE_DEFAULT .setNotificationSound()
} }
} else -> safeRule
return rule
}
if (NOTIFICATION_OFF_INDEX == index) {
if (this.rule!!.kind == BingRule.KIND_UNDERRIDE
|| rule.ruleId == BingRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
rule.setNotify(false)
} else {
rule.isEnabled = false
} }
} else { } else {
rule.isEnabled = true if (NOTIFICATION_OFF_INDEX == index) {
rule.setNotify(true) if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
rule.setHighlight(this.rule!!.kind != BingRule.KIND_UNDERRIDE safeRule.setNotify(false)
&& rule.ruleId != BingRule.RULE_ID_INVITE_ME
&& NOTIFICATION_NOISY_INDEX == index)
if (NOTIFICATION_NOISY_INDEX == index) {
rule.notificationSound = if (rule.ruleId == BingRule.RULE_ID_CALL) {
BingRule.ACTION_VALUE_RING
} else { } else {
BingRule.ACTION_VALUE_DEFAULT safeRule.copy(enabled = false)
} }
} else { } else {
rule.removeNotificationSound() val newRule = safeRule.copy(enabled = true)
.setNotify(true)
.setHighlight(safeKind != RuleSetKey.UNDERRIDE
&& safeRule.ruleId != PushRule.RULE_ID_INVITE_ME
&& NOTIFICATION_NOISY_INDEX == index)
if (NOTIFICATION_NOISY_INDEX == index) {
newRule.setNotificationSound(
if (safeRule.ruleId == PushRule.RULE_ID_CALL) {
PushRule.ACTION_VALUE_RING
} else {
PushRule.ACTION_VALUE_DEFAULT
}
)
} else {
newRule.removeNotificationSound()
}
} }
} }
} else {
safeRule
} }
return rule
} }
override fun onBindViewHolder(holder: PreferenceViewHolder) { override fun onBindViewHolder(holder: PreferenceViewHolder) {

View File

@ -423,9 +423,9 @@ class NotificationUtils @Inject constructor(private val context: Context,
// 'importance' which is set in the NotificationChannel. The integers representing // 'importance' which is set in the NotificationChannel. The integers representing
// 'priority' are different from 'importance', so make sure you don't mix them. // 'priority' are different from 'importance', so make sure you don't mix them.
.apply { .apply {
priority = NotificationCompat.PRIORITY_DEFAULT
if (roomInfo.shouldBing) { if (roomInfo.shouldBing) {
// Compat // Compat
priority = NotificationCompat.PRIORITY_DEFAULT
vectorPreferences.getNotificationRingTone()?.let { vectorPreferences.getNotificationRingTone()?.let {
setSound(it) setSound(it)
} }

View File

@ -35,7 +35,6 @@ import javax.inject.Inject
class VectorPreferences @Inject constructor(private val context: Context) { class VectorPreferences @Inject constructor(private val context: Context) {
companion object { companion object {
const val SETTINGS_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY = "SETTINGS_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY_2"
const val SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY = "SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY" const val SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY = "SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY"
const val SETTINGS_VERSION_PREFERENCE_KEY = "SETTINGS_VERSION_PREFERENCE_KEY" const val SETTINGS_VERSION_PREFERENCE_KEY = "SETTINGS_VERSION_PREFERENCE_KEY"
const val SETTINGS_SDK_VERSION_PREFERENCE_KEY = "SETTINGS_SDK_VERSION_PREFERENCE_KEY" const val SETTINGS_SDK_VERSION_PREFERENCE_KEY = "SETTINGS_SDK_VERSION_PREFERENCE_KEY"
@ -46,7 +45,6 @@ class VectorPreferences @Inject constructor(private val context: Context) {
const val SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY = "SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY" const val SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY = "SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY"
const val SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY = "SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY" const val SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY = "SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY"
const val SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY"
const val SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY" const val SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY"
const val SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY" const val SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
const val SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY" const val SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
@ -106,7 +104,6 @@ class VectorPreferences @Inject constructor(private val context: Context) {
const val SETTINGS_GROUPS_FLAIR_KEY = "SETTINGS_GROUPS_FLAIR_KEY" const val SETTINGS_GROUPS_FLAIR_KEY = "SETTINGS_GROUPS_FLAIR_KEY"
// notifications // notifications
const val SETTINGS_NOTIFICATIONS_KEY = "SETTINGS_NOTIFICATIONS_KEY"
const val SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY = "SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY" const val SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY = "SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
const val SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY = "SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY" const val SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY = "SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
// public static final String SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY = "SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY"; // public static final String SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY = "SETTINGS_TURN_SCREEN_ON_PREFERENCE_KEY";
@ -115,12 +112,6 @@ class VectorPreferences @Inject constructor(private val context: Context) {
const val SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY = "SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY" const val SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY = "SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY"
const val SETTINGS_NOTIFICATION_RINGTONE_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_RINGTONE_PREFERENCE_KEY" const val SETTINGS_NOTIFICATION_RINGTONE_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_RINGTONE_PREFERENCE_KEY"
const val SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY" const val SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY"
const val SETTINGS_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY = "SETTINGS_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY_2"
const val SETTINGS_CONTAINING_MY_USER_NAME_PREFERENCE_KEY = "SETTINGS_CONTAINING_MY_USER_NAME_PREFERENCE_KEY_2"
const val SETTINGS_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY = "SETTINGS_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY_2"
const val SETTINGS_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY = "SETTINGS_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY_2"
const val SETTINGS_INVITED_TO_ROOM_PREFERENCE_KEY = "SETTINGS_INVITED_TO_ROOM_PREFERENCE_KEY_2"
const val SETTINGS_CALL_INVITATIONS_PREFERENCE_KEY = "SETTINGS_CALL_INVITATIONS_PREFERENCE_KEY_2"
// media // media
private const val SETTINGS_DEFAULT_MEDIA_COMPRESSION_KEY = "SETTINGS_DEFAULT_MEDIA_COMPRESSION_KEY" private const val SETTINGS_DEFAULT_MEDIA_COMPRESSION_KEY = "SETTINGS_DEFAULT_MEDIA_COMPRESSION_KEY"

View File

@ -77,21 +77,14 @@ class VectorSettingsActivity : VectorBaseActivity(),
} }
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean { override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
val oFragment = when { val oFragment = try {
VectorPreferences.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref.key -> pref.fragment?.let {
supportFragmentManager.fragmentFactory.instantiate(classLoader, VectorSettingsNotificationsTroubleshootFragment::class.java.name) supportFragmentManager.fragmentFactory.instantiate(classLoader, it)
VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY == pref.key -> }
supportFragmentManager.fragmentFactory.instantiate(classLoader, VectorSettingsAdvancedNotificationPreferenceFragment::class.java.name) } catch (e: Throwable) {
else -> showSnackbar(getString(R.string.not_implemented))
try { Timber.e(e)
pref.fragment?.let { null
supportFragmentManager.fragmentFactory.instantiate(classLoader, it)
}
} catch (e: Throwable) {
showSnackbar(getString(R.string.not_implemented))
Timber.e(e)
null
}
} }
if (oFragment != null) { if (oFragment != null) {

View File

@ -15,125 +15,64 @@
*/ */
package im.vector.riotx.features.settings package im.vector.riotx.features.settings
import android.app.Activity
import android.content.Intent
import android.media.RingtoneManager
import android.net.Uri
import android.os.Parcelable
import androidx.core.content.edit
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceManager import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.pushrules.rest.PushRuleAndKind
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.core.preference.BingRule import im.vector.riotx.core.preference.PushRulePreference
import im.vector.riotx.core.preference.BingRulePreference
import im.vector.riotx.core.preference.VectorPreference import im.vector.riotx.core.preference.VectorPreference
import im.vector.riotx.features.notifications.NotificationUtils import im.vector.riotx.core.utils.toast
import javax.inject.Inject import javax.inject.Inject
class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor( class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor()
private val vectorPreferences: VectorPreferences : VectorSettingsBaseFragment() {
) : VectorSettingsBaseFragment() {
// events listener
/* TODO
private val mEventsListener = object : MXEventListener() {
override fun onBingRulesUpdate() {
refreshPreferences()
refreshDisplay()
}
} */
override var titleRes: Int = R.string.settings_notification_advanced override var titleRes: Int = R.string.settings_notification_advanced
override val preferenceXmlRes = R.xml.vector_settings_notification_advanced_preferences override val preferenceXmlRes = R.xml.vector_settings_notification_advanced_preferences
override fun bindPref() { override fun bindPref() {
val callNotificationsSystemOptions = findPreference<VectorPreference>(VectorPreferences.SETTINGS_SYSTEM_CALL_NOTIFICATION_PREFERENCE_KEY)!! for (preferenceKey in prefKeyToPushRuleId.keys) {
if (NotificationUtils.supportNotificationChannels()) {
callNotificationsSystemOptions.onPreferenceClickListener = Preference.OnPreferenceClickListener {
NotificationUtils.openSystemSettingsForCallCategory(this)
false
}
} else {
callNotificationsSystemOptions.isVisible = false
}
val noisyNotificationsSystemOptions = findPreference<VectorPreference>(VectorPreferences.SETTINGS_SYSTEM_NOISY_NOTIFICATION_PREFERENCE_KEY)!!
if (NotificationUtils.supportNotificationChannels()) {
noisyNotificationsSystemOptions.onPreferenceClickListener = Preference.OnPreferenceClickListener {
NotificationUtils.openSystemSettingsForNoisyCategory(this)
false
}
} else {
noisyNotificationsSystemOptions.isVisible = false
}
val silentNotificationsSystemOptions = findPreference<VectorPreference>(VectorPreferences.SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY)!!
if (NotificationUtils.supportNotificationChannels()) {
silentNotificationsSystemOptions.onPreferenceClickListener = Preference.OnPreferenceClickListener {
NotificationUtils.openSystemSettingsForSilentCategory(this)
false
}
} else {
silentNotificationsSystemOptions.isVisible = false
}
// Ringtone
val ringtonePreference = findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY)!!
if (NotificationUtils.supportNotificationChannels()) {
ringtonePreference.isVisible = false
} else {
ringtonePreference.summary = vectorPreferences.getNotificationRingToneName()
ringtonePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION)
if (null != vectorPreferences.getNotificationRingTone()) {
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, vectorPreferences.getNotificationRingTone())
}
startActivityForResult(intent, REQUEST_NOTIFICATION_RINGTONE)
false
}
}
for (preferenceKey in mPrefKeyToBingRuleId.keys) {
val preference = findPreference<VectorPreference>(preferenceKey) val preference = findPreference<VectorPreference>(preferenceKey)
if (preference is BingRulePreference) { if (preference is PushRulePreference) {
// preference.isEnabled = null != rules && isConnected && pushManager.areDeviceNotificationsAllowed() // preference.isEnabled = null != rules && isConnected && pushManager.areDeviceNotificationsAllowed()
val rule: BingRule? = null // TODO session.dataHandler.pushRules()?.findDefaultRule(mPrefKeyToBingRuleId[preferenceKey]) val ruleAndKind: PushRuleAndKind? = session.getPushRules().findDefaultRule(prefKeyToPushRuleId[preferenceKey])
if (rule == null) { if (ruleAndKind == null) {
// The rule is not defined, hide the preference // The rule is not defined, hide the preference
preference.isVisible = false preference.isVisible = false
} else { } else {
preference.isVisible = true preference.isVisible = true
preference.setBingRule(rule) preference.setPushRule(ruleAndKind)
preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
val rule2 = preference.createRule(newValue as Int) val newRule = preference.createNewRule(newValue as Int)
if (null != rule2) { if (newRule != null) {
/* displayLoadingView()
TODO
displayLoadingView() session.updatePushRuleActions(
session.dataHandler.bingRulesManager.updateRule(preference.rule, ruleAndKind.kind,
rule, preference.ruleAndKind?.pushRule ?: ruleAndKind.pushRule,
object : BingRulesManager.onBingRuleUpdateListener { newRule,
private fun onDone() { object : MatrixCallback<Unit> {
refreshDisplay() override fun onSuccess(data: Unit) {
if (!isAdded) {
return
}
preference.setPushRule(ruleAndKind.copy(pushRule = newRule))
hideLoadingView() hideLoadingView()
} }
override fun onBingRuleUpdateSuccess() { override fun onFailure(failure: Throwable) {
onDone() if (!isAdded) {
} return
}
override fun onBingRuleUpdateFailure(errorMessage: String) { hideLoadingView()
activity?.toast(errorMessage) // Restore the previous value
onDone() refreshDisplay()
activity?.toast(errorFormatter.toHumanReadable(failure))
} }
}) })
*/
} }
false false
} }
@ -146,83 +85,24 @@ class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor(
listView?.adapter?.notifyDataSetChanged() listView?.adapter?.notifyDataSetChanged()
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_NOTIFICATION_RINGTONE -> {
vectorPreferences.setNotificationRingTone(data?.getParcelableExtra<Parcelable>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI) as Uri?)
// test if the selected ring tone can be played
val notificationRingToneName = vectorPreferences.getNotificationRingToneName()
if (null != notificationRingToneName) {
vectorPreferences.setNotificationRingTone(vectorPreferences.getNotificationRingTone())
findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY)!!
.summary = notificationRingToneName
}
}
}
}
}
/**
* Refresh the known information about the account
*/
private fun refreshPreferences() {
PreferenceManager.getDefaultSharedPreferences(activity).edit {
/* TODO
session.dataHandler.pushRules()?.let {
for (prefKey in mPrefKeyToBingRuleId.keys) {
val preference = findPreference(prefKey)
if (null != preference && preference is SwitchPreference) {
val ruleId = mPrefKeyToBingRuleId[prefKey]
val rule = it.findDefaultRule(ruleId)
var isEnabled = null != rule && rule.isEnabled
if (TextUtils.equals(ruleId, BingRule.RULE_ID_DISABLE_ALL) || TextUtils.equals(ruleId, BingRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS)) {
isEnabled = !isEnabled
} else if (isEnabled) {
val domainActions = rule!!.domainActions
// no action -> noting will be done
if (null == domainActions || domainActions.isEmpty()) {
isEnabled = false
} else if (1 == domainActions.size) {
try {
isEnabled = !TextUtils.equals(domainActions[0] as String, BingRule.ACTION_DONT_NOTIFY)
} catch (e: Exception) {
Timber.e(e, "## refreshPreferences failed")
}
}
}// check if the rule is only defined by don't notify
putBoolean(prefKey, isEnabled)
}
}
}
*/
}
}
/* ========================================================================================== /* ==========================================================================================
* Companion * Companion
* ========================================================================================== */ * ========================================================================================== */
companion object { companion object {
private const val REQUEST_NOTIFICATION_RINGTONE = 888
// preference name <-> rule Id // preference name <-> rule Id
private var mPrefKeyToBingRuleId = mapOf( private val prefKeyToPushRuleId = mapOf(
VectorPreferences.SETTINGS_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY to BingRule.RULE_ID_CONTAIN_DISPLAY_NAME, "SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to PushRule.RULE_ID_CONTAIN_DISPLAY_NAME,
VectorPreferences.SETTINGS_CONTAINING_MY_USER_NAME_PREFERENCE_KEY to BingRule.RULE_ID_CONTAIN_USER_NAME, "SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to PushRule.RULE_ID_CONTAIN_USER_NAME,
VectorPreferences.SETTINGS_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY to BingRule.RULE_ID_ONE_TO_ONE_ROOM, "SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to PushRule.RULE_ID_ONE_TO_ONE_ROOM,
VectorPreferences.SETTINGS_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY to BingRule.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, "SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to PushRule.RULE_ID_ALL_OTHER_MESSAGES_ROOMS,
VectorPreferences.SETTINGS_INVITED_TO_ROOM_PREFERENCE_KEY to BingRule.RULE_ID_INVITE_ME, "SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to PushRule.RULE_ID_INVITE_ME,
VectorPreferences.SETTINGS_CALL_INVITATIONS_PREFERENCE_KEY to BingRule.RULE_ID_CALL, "SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to PushRule.RULE_ID_CALL,
VectorPreferences.SETTINGS_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY to BingRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS "SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" to PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS,
"SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" to PushRule.RULE_ID_AT_ROOMS,
"SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" to PushRule.RULE_ID_E2E_ONE_TO_ONE_ROOM,
"SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" to PushRule.RULE_ID_E2E_GROUP,
"SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" to PushRule.RULE_ID_TOMBSTONE
) )
} }
} }

View File

@ -26,6 +26,7 @@ import im.vector.riotx.R
import im.vector.riotx.core.di.DaggerScreenComponent import im.vector.riotx.core.di.DaggerScreenComponent
import im.vector.riotx.core.di.HasScreenInjector import im.vector.riotx.core.di.HasScreenInjector
import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.di.ScreenComponent
import im.vector.riotx.core.error.ErrorFormatter
import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseActivity
import im.vector.riotx.core.utils.toast import im.vector.riotx.core.utils.toast
import timber.log.Timber import timber.log.Timber
@ -40,6 +41,7 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScree
// members // members
protected lateinit var session: Session protected lateinit var session: Session
protected lateinit var errorFormatter: ErrorFormatter
private lateinit var screenComponent: ScreenComponent private lateinit var screenComponent: ScreenComponent
abstract val preferenceXmlRes: Int abstract val preferenceXmlRes: Int
@ -54,6 +56,7 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScree
screenComponent = DaggerScreenComponent.factory().create(vectorActivity.getVectorComponent(), vectorActivity) screenComponent = DaggerScreenComponent.factory().create(vectorActivity.getVectorComponent(), vectorActivity)
super.onAttach(context) super.onAttach(context)
session = screenComponent.activeSessionHolder().getActiveSession() session = screenComponent.activeSessionHolder().getActiveSession()
errorFormatter = screenComponent.errorFormatter()
injectWith(injector()) injectWith(injector())
} }

View File

@ -16,6 +16,11 @@
package im.vector.riotx.features.settings package im.vector.riotx.features.settings
import android.app.Activity
import android.content.Intent
import android.media.RingtoneManager
import android.net.Uri
import android.os.Parcelable
import android.widget.Toast import android.widget.Toast
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.SwitchPreference import androidx.preference.SwitchPreference
@ -24,8 +29,10 @@ import im.vector.matrix.android.api.pushrules.RuleIds
import im.vector.matrix.android.api.pushrules.RuleKind import im.vector.matrix.android.api.pushrules.RuleKind
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.preference.VectorPreference
import im.vector.riotx.core.preference.VectorSwitchPreference import im.vector.riotx.core.preference.VectorSwitchPreference
import im.vector.riotx.core.pushers.PushersManager import im.vector.riotx.core.pushers.PushersManager
import im.vector.riotx.features.notifications.NotificationUtils
import im.vector.riotx.push.fcm.FcmHelper import im.vector.riotx.push.fcm.FcmHelper
import javax.inject.Inject import javax.inject.Inject
@ -42,7 +49,7 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
override fun bindPref() { override fun bindPref() {
findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY)!!.let { pref -> findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY)!!.let { pref ->
val pushRuleService = session val pushRuleService = session
val mRuleMaster = pushRuleService.getPushRules() val mRuleMaster = pushRuleService.getPushRules().getAllRules()
.find { it.ruleId == RuleIds.RULE_ID_DISABLE_ALL } .find { it.ruleId == RuleIds.RULE_ID_DISABLE_ALL }
if (mRuleMaster == null) { if (mRuleMaster == null) {
@ -54,6 +61,79 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
val areNotifEnabledAtAccountLevel = !mRuleMaster.enabled val areNotifEnabledAtAccountLevel = !mRuleMaster.enabled
(pref as SwitchPreference).isChecked = areNotifEnabledAtAccountLevel (pref as SwitchPreference).isChecked = areNotifEnabledAtAccountLevel
} }
handleSystemPreference()
}
private fun handleSystemPreference() {
val callNotificationsSystemOptions = findPreference<VectorPreference>(VectorPreferences.SETTINGS_SYSTEM_CALL_NOTIFICATION_PREFERENCE_KEY)!!
if (NotificationUtils.supportNotificationChannels()) {
callNotificationsSystemOptions.onPreferenceClickListener = Preference.OnPreferenceClickListener {
NotificationUtils.openSystemSettingsForCallCategory(this)
false
}
} else {
callNotificationsSystemOptions.isVisible = false
}
val noisyNotificationsSystemOptions = findPreference<VectorPreference>(VectorPreferences.SETTINGS_SYSTEM_NOISY_NOTIFICATION_PREFERENCE_KEY)!!
if (NotificationUtils.supportNotificationChannels()) {
noisyNotificationsSystemOptions.onPreferenceClickListener = Preference.OnPreferenceClickListener {
NotificationUtils.openSystemSettingsForNoisyCategory(this)
false
}
} else {
noisyNotificationsSystemOptions.isVisible = false
}
val silentNotificationsSystemOptions = findPreference<VectorPreference>(VectorPreferences.SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY)!!
if (NotificationUtils.supportNotificationChannels()) {
silentNotificationsSystemOptions.onPreferenceClickListener = Preference.OnPreferenceClickListener {
NotificationUtils.openSystemSettingsForSilentCategory(this)
false
}
} else {
silentNotificationsSystemOptions.isVisible = false
}
// Ringtone
val ringtonePreference = findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY)!!
if (NotificationUtils.supportNotificationChannels()) {
ringtonePreference.isVisible = false
} else {
ringtonePreference.summary = vectorPreferences.getNotificationRingToneName()
ringtonePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION)
if (null != vectorPreferences.getNotificationRingTone()) {
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, vectorPreferences.getNotificationRingTone())
}
startActivityForResult(intent, REQUEST_NOTIFICATION_RINGTONE)
false
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_NOTIFICATION_RINGTONE -> {
vectorPreferences.setNotificationRingTone(data?.getParcelableExtra<Parcelable>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI) as Uri?)
// test if the selected ring tone can be played
val notificationRingToneName = vectorPreferences.getNotificationRingToneName()
if (null != notificationRingToneName) {
vectorPreferences.setNotificationRingTone(vectorPreferences.getNotificationRingTone())
findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY)!!
.summary = notificationRingToneName
}
}
}
}
} }
override fun onResume() { override fun onResume() {
@ -105,7 +185,7 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
private fun updateEnabledForAccount(preference: Preference?) { private fun updateEnabledForAccount(preference: Preference?) {
val pushRuleService = session val pushRuleService = session
val switchPref = preference as SwitchPreference val switchPref = preference as SwitchPreference
pushRuleService.getPushRules() pushRuleService.getPushRules().getAllRules()
.find { it.ruleId == RuleIds.RULE_ID_DISABLE_ALL } .find { it.ruleId == RuleIds.RULE_ID_DISABLE_ALL }
?.let { ?.let {
// Trick, we must enable this room to disable notifications // Trick, we must enable this room to disable notifications
@ -114,7 +194,7 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
!switchPref.isChecked, !switchPref.isChecked,
object : MatrixCallback<Unit> { object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) { override fun onSuccess(data: Unit) {
// Push rules will be updated form the sync // Push rules will be updated from the sync
} }
override fun onFailure(failure: Throwable) { override fun onFailure(failure: Throwable) {
@ -129,4 +209,8 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
}) })
} }
} }
companion object {
private const val REQUEST_NOTIFICATION_RINGTONE = 888
}
} }

View File

@ -35,7 +35,7 @@ class PushRulesViewModel(initialState: PushRulesViewState)
override fun initialState(viewModelContext: ViewModelContext): PushRulesViewState? { override fun initialState(viewModelContext: ViewModelContext): PushRulesViewState? {
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession() val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
val rules = session.getPushRules() val rules = session.getPushRules().getAllRules()
return PushRulesViewState(rules) return PushRulesViewState(rules)
} }
} }

View File

@ -32,7 +32,7 @@ class TestAccountSettings @Inject constructor(private val stringProvider: String
override fun perform() { override fun perform() {
val session = activeSessionHolder.getSafeActiveSession() ?: return val session = activeSessionHolder.getSafeActiveSession() ?: return
val defaultRule = session.getPushRules() val defaultRule = session.getPushRules().getAllRules()
.find { it.ruleId == RuleIds.RULE_ID_DISABLE_ALL } .find { it.ruleId == RuleIds.RULE_ID_DISABLE_ALL }
if (defaultRule != null) { if (defaultRule != null) {

View File

@ -23,7 +23,7 @@ import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.features.notifications.toNotificationAction import im.vector.riotx.features.notifications.toNotificationAction
import javax.inject.Inject import javax.inject.Inject
class TestBingRulesSettings @Inject constructor(private val activeSessionHolder: ActiveSessionHolder, class TestPushRulesSettings @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
private val stringProvider: StringProvider) private val stringProvider: StringProvider)
: TroubleshootTest(R.string.settings_troubleshoot_test_bing_settings_title) { : TroubleshootTest(R.string.settings_troubleshoot_test_bing_settings_title) {
@ -40,7 +40,7 @@ class TestBingRulesSettings @Inject constructor(private val activeSessionHolder:
override fun perform() { override fun perform() {
val session = activeSessionHolder.getSafeActiveSession() ?: return val session = activeSessionHolder.getSafeActiveSession() ?: return
val pushRules = session.getPushRules() val pushRules = session.getPushRules().getAllRules()
var oneOrMoreRuleIsOff = false var oneOrMoreRuleIsOff = false
var oneOrMoreRuleAreSilent = false var oneOrMoreRuleAreSilent = false
testedRules.forEach { ruleId -> testedRules.forEach { ruleId ->

View File

@ -11,6 +11,13 @@
<!-- BEGIN Strings added by Benoit --> <!-- BEGIN Strings added by Benoit -->
<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_riotx">Set notification importance by event</string>
<!-- END Strings added by Benoit --> <!-- END Strings added by Benoit -->

View File

@ -3,62 +3,65 @@
<im.vector.riotx.core.preference.VectorPreferenceCategory <im.vector.riotx.core.preference.VectorPreferenceCategory
android:key="SETTINGS_NOTIFICATION_LEVEL" android:key="SETTINGS_NOTIFICATION_LEVEL"
android:persistent="false"
android:title="@string/settings_notification_by_event"> android:title="@string/settings_notification_by_event">
<im.vector.riotx.core.preference.BingRulePreference <im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY_2" 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_containing_my_display_name" />
<im.vector.riotx.core.preference.BingRulePreference <im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_CONTAINING_MY_USER_NAME_PREFERENCE_KEY_2" 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_containing_my_user_name" />
<im.vector.riotx.core.preference.BingRulePreference <im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY_2" 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.riotx.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" /> android:title="@string/settings_messages_in_one_to_one" />
<im.vector.riotx.core.preference.BingRulePreference <im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY_2" 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.riotx.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" /> android:title="@string/settings_messages_in_group_chat" />
<im.vector.riotx.core.preference.BingRulePreference <im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_INVITED_TO_ROOM_PREFERENCE_KEY_2" 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.riotx.core.preference.PushRulePreference
android:key="SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY"
android:persistent="false"
android:title="@string/settings_invited_to_room" /> android:title="@string/settings_invited_to_room" />
<im.vector.riotx.core.preference.BingRulePreference <im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_CALL_INVITATIONS_PREFERENCE_KEY_2" android:key="SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY"
android:persistent="false"
android:title="@string/settings_call_invitations" /> android:title="@string/settings_call_invitations" />
<im.vector.riotx.core.preference.BingRulePreference <im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY_2" 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_sent_by_bot" />
<im.vector.riotx.core.preference.PushRulePreference
android:key="SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY"
android:persistent="false"
android:title="@string/settings_when_rooms_are_upgraded" />
</im.vector.riotx.core.preference.VectorPreferenceCategory> </im.vector.riotx.core.preference.VectorPreferenceCategory>
<!-- For API < 26 -->
<im.vector.riotx.core.preference.VectorPreference
android:dialogTitle="@string/settings_notification_ringtone"
android:key="SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY"
android:title="@string/settings_notification_ringtone" />
<!-- For API >= 26 -->
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_SYSTEM_NOISY_NOTIFICATION_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/settings_system_preferences_summary"
android:title="@string/settings_noisy_notifications_preferences" />
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/settings_system_preferences_summary"
android:title="@string/settings_silent_notifications_preferences" />
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_SYSTEM_CALL_NOTIFICATION_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/settings_system_preferences_summary"
android:title="@string/settings_call_notifications_preferences" />
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>

View File

@ -2,9 +2,7 @@
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<im.vector.riotx.core.preference.VectorPreferenceCategory <im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_notifications">
android:key="SETTINGS_NOTIFICATIONS_KEY"
android:title="@string/settings_notifications">
<im.vector.riotx.core.preference.VectorSwitchPreference <im.vector.riotx.core.preference.VectorSwitchPreference
android:defaultValue="true" android:defaultValue="true"
@ -24,13 +22,47 @@
<im.vector.riotx.core.preference.VectorPreference <im.vector.riotx.core.preference.VectorPreference
android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY" android:dependency="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
android:enabled="false"
android:key="SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY" android:key="SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY"
android:persistent="false" android:persistent="false"
android:summary="@string/settings_notification_advanced_summary" android:summary="@string/settings_notification_advanced_summary_riotx"
android:title="@string/settings_notification_advanced" android:title="@string/settings_notification_advanced"
android:visibility="gone" app:fragment="im.vector.riotx.features.settings.VectorSettingsAdvancedNotificationPreferenceFragment" />
app:fragment="im.vector.fragments.VectorSettingsNotificationsAdvancedFragment" />
</im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceCategory
android:persistent="false"
android:title="@string/settings_notification_configuration">
<!-- For API < 26 -->
<im.vector.riotx.core.preference.VectorPreference
android:dialogTitle="@string/settings_notification_ringtone"
android:key="SETTINGS_NOTIFICATION_RINGTONE_SELECTION_PREFERENCE_KEY"
android:persistent="false"
android:title="@string/settings_notification_ringtone" />
<!-- For API >= 26 -->
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_SYSTEM_NOISY_NOTIFICATION_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/settings_system_preferences_summary"
android:title="@string/settings_noisy_notifications_preferences" />
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_SYSTEM_SILENT_NOTIFICATION_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/settings_system_preferences_summary"
android:title="@string/settings_silent_notifications_preferences" />
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_SYSTEM_CALL_NOTIFICATION_PREFERENCE_KEY"
android:persistent="false"
android:summary="@string/settings_system_preferences_summary"
android:title="@string/settings_call_notifications_preferences" />
</im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_troubleshoot_title">
<im.vector.riotx.core.preference.VectorPreference <im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY" android:key="SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY"
@ -39,7 +71,6 @@
</im.vector.riotx.core.preference.VectorPreferenceCategory> </im.vector.riotx.core.preference.VectorPreferenceCategory>
<!--im.vector.riotx.core.preference.VectorPreferenceCategory <!--im.vector.riotx.core.preference.VectorPreferenceCategory
android:key="SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY" android:key="SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY"
android:title="@string/settings_background_sync"> android:title="@string/settings_background_sync">

View File

@ -15,7 +15,6 @@
<im.vector.riotx.core.preference.VectorPreference <im.vector.riotx.core.preference.VectorPreference
android:icon="@drawable/ic_settings_root_notification" android:icon="@drawable/ic_settings_root_notification"
android:key="SETTINGS_NOTIFICATIONS_KEY"
android:title="@string/settings_notifications" android:title="@string/settings_notifications"
app:fragment="im.vector.riotx.features.settings.VectorSettingsNotificationPreferenceFragment" /> app:fragment="im.vector.riotx.features.settings.VectorSettingsNotificationPreferenceFragment" />