mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-25 02:45:53 +03:00
Merge pull request #2001 from vector-im/feature/mention_display_name
Fix mention display name
This commit is contained in:
commit
95e80f0263
22 changed files with 266 additions and 267 deletions
|
@ -9,6 +9,7 @@ Improvements 🙌:
|
|||
|
||||
Bugfix 🐛:
|
||||
- Display name not shown under Settings/General (#1926)
|
||||
- Words containing my name should not trigger notifications (#1781)
|
||||
- Fix changing language issue
|
||||
- Fix FontSize issue (#1483, #1787)
|
||||
- Fix bad color for settings icon on Android < 24 (#1786)
|
||||
|
|
|
@ -24,21 +24,24 @@ sealed class Action {
|
|||
object DoNotNotify : Action()
|
||||
data class Sound(val sound: String = ACTION_OBJECT_VALUE_VALUE_DEFAULT) : Action()
|
||||
data class Highlight(val highlight: Boolean) : Action()
|
||||
|
||||
companion object {
|
||||
const val ACTION_NOTIFY = "notify"
|
||||
const val ACTION_DONT_NOTIFY = "dont_notify"
|
||||
const val ACTION_COALESCE = "coalesce"
|
||||
|
||||
// Ref: https://matrix.org/docs/spec/client_server/latest#tweaks
|
||||
const val ACTION_OBJECT_SET_TWEAK_KEY = "set_tweak"
|
||||
|
||||
const val ACTION_OBJECT_SET_TWEAK_VALUE_SOUND = "sound"
|
||||
const val ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT = "highlight"
|
||||
|
||||
const val ACTION_OBJECT_VALUE_KEY = "value"
|
||||
const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default"
|
||||
const val ACTION_OBJECT_VALUE_VALUE_RING = "ring"
|
||||
}
|
||||
}
|
||||
|
||||
private const val ACTION_NOTIFY = "notify"
|
||||
private const val ACTION_DONT_NOTIFY = "dont_notify"
|
||||
private const val ACTION_COALESCE = "coalesce"
|
||||
|
||||
// Ref: https://matrix.org/docs/spec/client_server/latest#tweaks
|
||||
private const val ACTION_OBJECT_SET_TWEAK_KEY = "set_tweak"
|
||||
|
||||
private const val ACTION_OBJECT_SET_TWEAK_VALUE_SOUND = "sound"
|
||||
private const val ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT = "highlight"
|
||||
|
||||
private const val ACTION_OBJECT_VALUE_KEY = "value"
|
||||
private const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default"
|
||||
|
||||
/**
|
||||
* Ref: https://matrix.org/docs/spec/client_server/latest#actions
|
||||
*
|
||||
|
@ -69,18 +72,18 @@ private const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default"
|
|||
fun List<Action>.toJson(): List<Any> {
|
||||
return map { action ->
|
||||
when (action) {
|
||||
is Action.Notify -> ACTION_NOTIFY
|
||||
is Action.DoNotNotify -> ACTION_DONT_NOTIFY
|
||||
is Action.Sound -> {
|
||||
is Action.Notify -> Action.ACTION_NOTIFY
|
||||
is Action.DoNotNotify -> Action.ACTION_DONT_NOTIFY
|
||||
is Action.Sound -> {
|
||||
mapOf(
|
||||
ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_SOUND,
|
||||
ACTION_OBJECT_VALUE_KEY to action.sound
|
||||
Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND,
|
||||
Action.ACTION_OBJECT_VALUE_KEY to action.sound
|
||||
)
|
||||
}
|
||||
is Action.Highlight -> {
|
||||
is Action.Highlight -> {
|
||||
mapOf(
|
||||
ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT,
|
||||
ACTION_OBJECT_VALUE_KEY to action.highlight
|
||||
Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT,
|
||||
Action.ACTION_OBJECT_VALUE_KEY to action.highlight
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -92,26 +95,26 @@ fun PushRule.getActions(): List<Action> {
|
|||
|
||||
actions.forEach { actionStrOrObj ->
|
||||
when (actionStrOrObj) {
|
||||
ACTION_NOTIFY -> Action.Notify
|
||||
ACTION_DONT_NOTIFY -> Action.DoNotNotify
|
||||
is Map<*, *> -> {
|
||||
when (actionStrOrObj[ACTION_OBJECT_SET_TWEAK_KEY]) {
|
||||
ACTION_OBJECT_SET_TWEAK_VALUE_SOUND -> {
|
||||
(actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? String)?.let { stringValue ->
|
||||
Action.ACTION_NOTIFY -> Action.Notify
|
||||
Action.ACTION_DONT_NOTIFY -> Action.DoNotNotify
|
||||
is Map<*, *> -> {
|
||||
when (actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]) {
|
||||
Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND -> {
|
||||
(actionStrOrObj[Action.ACTION_OBJECT_VALUE_KEY] as? String)?.let { stringValue ->
|
||||
Action.Sound(stringValue)
|
||||
}
|
||||
// When the value is not there, default sound (not specified by the spec)
|
||||
?: Action.Sound(ACTION_OBJECT_VALUE_VALUE_DEFAULT)
|
||||
?: Action.Sound(Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT)
|
||||
}
|
||||
ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT -> {
|
||||
(actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? Boolean)?.let { boolValue ->
|
||||
Action.ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT -> {
|
||||
(actionStrOrObj[Action.ACTION_OBJECT_VALUE_KEY] as? Boolean)?.let { boolValue ->
|
||||
Action.Highlight(boolValue)
|
||||
}
|
||||
// When the value is not there, default is true, says the spec
|
||||
?: Action.Highlight(true)
|
||||
}
|
||||
else -> {
|
||||
Timber.w("Unsupported set_tweak value ${actionStrOrObj[ACTION_OBJECT_SET_TWEAK_KEY]}")
|
||||
Timber.w("Unsupported set_tweak value ${actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]}")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,32 +18,8 @@ package org.matrix.android.sdk.api.pushrules
|
|||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
||||
abstract class Condition(val kind: Kind) {
|
||||
interface Condition {
|
||||
fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean
|
||||
|
||||
enum class Kind(val value: String) {
|
||||
EventMatch("event_match"),
|
||||
ContainsDisplayName("contains_display_name"),
|
||||
RoomMemberCount("room_member_count"),
|
||||
SenderNotificationPermission("sender_notification_permission"),
|
||||
Unrecognised("");
|
||||
|
||||
companion object {
|
||||
|
||||
fun fromString(value: String): Kind {
|
||||
return when (value) {
|
||||
"event_match" -> EventMatch
|
||||
"contains_display_name" -> ContainsDisplayName
|
||||
"room_member_count" -> RoomMemberCount
|
||||
"sender_notification_permission" -> SenderNotificationPermission
|
||||
else -> Unrecognised
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean
|
||||
|
||||
open fun technicalDescription(): String {
|
||||
return "Kind: $kind"
|
||||
}
|
||||
fun technicalDescription(): String
|
||||
}
|
||||
|
|
|
@ -20,17 +20,15 @@ import org.matrix.android.sdk.api.session.events.model.Event
|
|||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||
import timber.log.Timber
|
||||
import org.matrix.android.sdk.internal.util.caseInsensitiveFind
|
||||
|
||||
class ContainsDisplayNameCondition : Condition(Kind.ContainsDisplayName) {
|
||||
class ContainsDisplayNameCondition : Condition {
|
||||
|
||||
override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean {
|
||||
return conditionResolver.resolveContainsDisplayNameCondition(event, this)
|
||||
}
|
||||
|
||||
override fun technicalDescription(): String {
|
||||
return "User is mentioned"
|
||||
}
|
||||
override fun technicalDescription() = "User is mentioned"
|
||||
|
||||
fun isSatisfied(event: Event, displayName: String): Boolean {
|
||||
val message = when (event.type) {
|
||||
|
@ -45,31 +43,6 @@ class ContainsDisplayNameCondition : Condition(Kind.ContainsDisplayName) {
|
|||
else -> null
|
||||
} ?: return false
|
||||
|
||||
return caseInsensitiveFind(displayName, message.body)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Returns whether a string contains an occurrence of another, as a standalone word, regardless of case.
|
||||
*
|
||||
* @param subString the string to search for
|
||||
* @param longString the string to search in
|
||||
* @return whether a match was found
|
||||
*/
|
||||
fun caseInsensitiveFind(subString: String, longString: String): Boolean {
|
||||
// add sanity checks
|
||||
if (subString.isEmpty() || longString.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
val regex = Regex("(\\W|^)" + Regex.escape(subString) + "(\\W|$)", RegexOption.IGNORE_CASE)
|
||||
return regex.containsMatchIn(longString)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "## caseInsensitiveFind() : failed")
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
return message.body.caseInsensitiveFind(displayName)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ package org.matrix.android.sdk.api.pushrules
|
|||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import org.matrix.android.sdk.internal.util.caseInsensitiveFind
|
||||
import org.matrix.android.sdk.internal.util.hasSpecialGlobChar
|
||||
import org.matrix.android.sdk.internal.util.simpleGlobToRegExp
|
||||
import timber.log.Timber
|
||||
|
||||
class EventMatchCondition(
|
||||
|
@ -29,16 +32,18 @@ class EventMatchCondition(
|
|||
* The glob-style pattern to match against. Patterns with no special glob characters should
|
||||
* be treated as having asterisks prepended and appended when testing the condition.
|
||||
*/
|
||||
val pattern: String
|
||||
) : Condition(Kind.EventMatch) {
|
||||
val pattern: String,
|
||||
/**
|
||||
* true to match only words. In this case pattern will not be considered as a glob
|
||||
*/
|
||||
val wordsOnly: Boolean
|
||||
) : Condition {
|
||||
|
||||
override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean {
|
||||
return conditionResolver.resolveEventMatchCondition(event, this)
|
||||
}
|
||||
|
||||
override fun technicalDescription(): String {
|
||||
return "'$key' Matches '$pattern'"
|
||||
}
|
||||
override fun technicalDescription() = "'$key' matches '$pattern', words only '$wordsOnly'"
|
||||
|
||||
fun isSatisfied(event: Event): Boolean {
|
||||
// TODO encrypted events?
|
||||
|
@ -48,14 +53,18 @@ class EventMatchCondition(
|
|||
|
||||
// Patterns with no special glob characters should be treated as having asterisks prepended
|
||||
// and appended when testing the condition.
|
||||
try {
|
||||
val modPattern = if (hasSpecialGlobChar(pattern)) simpleGlobToRegExp(pattern) else simpleGlobToRegExp("*$pattern*")
|
||||
val regex = Regex(modPattern, RegexOption.DOT_MATCHES_ALL)
|
||||
return regex.containsMatchIn(value)
|
||||
return try {
|
||||
if (wordsOnly) {
|
||||
value.caseInsensitiveFind(pattern)
|
||||
} else {
|
||||
val modPattern = if (pattern.hasSpecialGlobChar()) pattern.simpleGlobToRegExp() else "*$pattern*".simpleGlobToRegExp()
|
||||
val regex = Regex(modPattern, RegexOption.DOT_MATCHES_ALL)
|
||||
regex.containsMatchIn(value)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
// e.g PatternSyntaxException
|
||||
Timber.e(e, "Failed to evaluate push condition")
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,27 +87,4 @@ class EventMatchCondition(
|
|||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private fun hasSpecialGlobChar(glob: String): Boolean {
|
||||
return glob.contains("*") || glob.contains("?")
|
||||
}
|
||||
|
||||
// Very simple glob to regexp converter
|
||||
private fun simpleGlobToRegExp(glob: String): String {
|
||||
var out = "" // "^"
|
||||
for (element in glob) {
|
||||
when (element) {
|
||||
'*' -> out += ".*"
|
||||
'?' -> out += '.'.toString()
|
||||
'.' -> out += "\\."
|
||||
'\\' -> out += "\\\\"
|
||||
else -> out += element
|
||||
}
|
||||
}
|
||||
out += "" // '$'.toString()
|
||||
return out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.api.pushrules
|
||||
|
||||
enum class Kind(val value: String) {
|
||||
EventMatch("event_match"),
|
||||
ContainsDisplayName("contains_display_name"),
|
||||
RoomMemberCount("room_member_count"),
|
||||
SenderNotificationPermission("sender_notification_permission"),
|
||||
Unrecognised("");
|
||||
|
||||
companion object {
|
||||
|
||||
fun fromString(value: String): Kind {
|
||||
return when (value) {
|
||||
"event_match" -> EventMatch
|
||||
"contains_display_name" -> ContainsDisplayName
|
||||
"room_member_count" -> RoomMemberCount
|
||||
"sender_notification_permission" -> SenderNotificationPermission
|
||||
else -> Unrecognised
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,15 +29,13 @@ class RoomMemberCountCondition(
|
|||
* If no prefix is present, this parameter defaults to ==.
|
||||
*/
|
||||
val iz: String
|
||||
) : Condition(Kind.RoomMemberCount) {
|
||||
) : Condition {
|
||||
|
||||
override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean {
|
||||
return conditionResolver.resolveRoomMemberCountCondition(event, this)
|
||||
}
|
||||
|
||||
override fun technicalDescription(): String {
|
||||
return "Room member count is $iz"
|
||||
}
|
||||
override fun technicalDescription() = "Room member count is $iz"
|
||||
|
||||
internal fun isSatisfied(event: Event, roomGetter: RoomGetter): Boolean {
|
||||
// sanity checks
|
||||
|
|
|
@ -45,4 +45,6 @@ object RuleIds {
|
|||
|
||||
// Not documented
|
||||
const val RULE_ID_FALLBACK = ".m.rule.fallback"
|
||||
|
||||
const val RULE_ID_REACTION = ".m.rule.reaction"
|
||||
}
|
||||
|
|
|
@ -28,15 +28,13 @@ class SenderNotificationPermissionCondition(
|
|||
* type from the notifications object in the power level event content.
|
||||
*/
|
||||
val key: String
|
||||
) : Condition(Kind.SenderNotificationPermission) {
|
||||
) : Condition {
|
||||
|
||||
override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean {
|
||||
return conditionResolver.resolveSenderNotificationPermissionCondition(event, this)
|
||||
}
|
||||
|
||||
override fun technicalDescription(): String {
|
||||
return "User power level <$key>"
|
||||
}
|
||||
override fun technicalDescription() = "User power level <$key>"
|
||||
|
||||
fun isSatisfied(event: Event, powerLevels: PowerLevelsContent): Boolean {
|
||||
val powerLevelsHelper = PowerLevelsHelper(powerLevels)
|
||||
|
|
|
@ -21,7 +21,9 @@ import com.squareup.moshi.JsonClass
|
|||
import org.matrix.android.sdk.api.pushrules.Condition
|
||||
import org.matrix.android.sdk.api.pushrules.ContainsDisplayNameCondition
|
||||
import org.matrix.android.sdk.api.pushrules.EventMatchCondition
|
||||
import org.matrix.android.sdk.api.pushrules.Kind
|
||||
import org.matrix.android.sdk.api.pushrules.RoomMemberCountCondition
|
||||
import org.matrix.android.sdk.api.pushrules.RuleIds
|
||||
import org.matrix.android.sdk.api.pushrules.SenderNotificationPermissionCondition
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -58,20 +60,20 @@ data class PushCondition(
|
|||
val iz: String? = null
|
||||
) {
|
||||
|
||||
fun asExecutableCondition(): Condition? {
|
||||
return when (Condition.Kind.fromString(kind)) {
|
||||
Condition.Kind.EventMatch -> {
|
||||
fun asExecutableCondition(rule: PushRule): Condition? {
|
||||
return when (Kind.fromString(kind)) {
|
||||
Kind.EventMatch -> {
|
||||
if (key != null && pattern != null) {
|
||||
EventMatchCondition(key, pattern)
|
||||
EventMatchCondition(key, pattern, rule.ruleId == RuleIds.RULE_ID_CONTAIN_USER_NAME)
|
||||
} else {
|
||||
Timber.e("Malformed Event match condition")
|
||||
null
|
||||
}
|
||||
}
|
||||
Condition.Kind.ContainsDisplayName -> {
|
||||
Kind.ContainsDisplayName -> {
|
||||
ContainsDisplayNameCondition()
|
||||
}
|
||||
Condition.Kind.RoomMemberCount -> {
|
||||
Kind.RoomMemberCount -> {
|
||||
if (iz.isNullOrEmpty()) {
|
||||
Timber.e("Malformed ROOM_MEMBER_COUNT condition")
|
||||
null
|
||||
|
@ -79,7 +81,7 @@ data class PushCondition(
|
|||
RoomMemberCountCondition(iz)
|
||||
}
|
||||
}
|
||||
Condition.Kind.SenderNotificationPermission -> {
|
||||
Kind.SenderNotificationPermission -> {
|
||||
if (key == null) {
|
||||
Timber.e("Malformed Sender Notification Permission condition")
|
||||
null
|
||||
|
@ -87,7 +89,7 @@ data class PushCondition(
|
|||
SenderNotificationPermissionCondition(key)
|
||||
}
|
||||
}
|
||||
Condition.Kind.Unrecognised -> {
|
||||
Kind.Unrecognised -> {
|
||||
Timber.e("Unknown kind $kind")
|
||||
null
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ data class PushRule(
|
|||
* Add the default notification sound.
|
||||
*/
|
||||
fun setNotificationSound(): PushRule {
|
||||
return setNotificationSound(ACTION_VALUE_DEFAULT)
|
||||
return setNotificationSound(Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT)
|
||||
}
|
||||
|
||||
fun getNotificationSound(): String? {
|
||||
|
@ -109,13 +109,13 @@ data class PushRule(
|
|||
fun setNotify(notify: Boolean): PushRule {
|
||||
val mutableActions = actions.toMutableList()
|
||||
|
||||
mutableActions.remove(ACTION_DONT_NOTIFY)
|
||||
mutableActions.remove(ACTION_NOTIFY)
|
||||
mutableActions.remove(Action.ACTION_DONT_NOTIFY)
|
||||
mutableActions.remove(Action.ACTION_NOTIFY)
|
||||
|
||||
if (notify) {
|
||||
mutableActions.add(ACTION_NOTIFY)
|
||||
mutableActions.add(Action.ACTION_NOTIFY)
|
||||
} else {
|
||||
mutableActions.add(ACTION_DONT_NOTIFY)
|
||||
mutableActions.add(Action.ACTION_DONT_NOTIFY)
|
||||
}
|
||||
|
||||
return copy(actions = mutableActions)
|
||||
|
@ -126,51 +126,12 @@ data class PushRule(
|
|||
*
|
||||
* @return true if the rule should play sound
|
||||
*/
|
||||
fun shouldNotify() = actions.contains(ACTION_NOTIFY)
|
||||
fun shouldNotify() = actions.contains(Action.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"
|
||||
}
|
||||
fun shouldNotNotify() = actions.contains(Action.ACTION_DONT_NOTIFY)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.pushrules.rest
|
|||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import org.matrix.android.sdk.api.pushrules.RuleIds
|
||||
import org.matrix.android.sdk.api.pushrules.RuleSetKey
|
||||
|
||||
/**
|
||||
|
@ -51,7 +52,7 @@ data class RuleSet(
|
|||
var result: PushRuleAndKind? = null
|
||||
// sanity check
|
||||
if (null != ruleId) {
|
||||
if (PushRule.RULE_ID_CONTAIN_USER_NAME == ruleId) {
|
||||
if (RuleIds.RULE_ID_CONTAIN_USER_NAME == ruleId) {
|
||||
result = findRule(content, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.CONTENT) }
|
||||
} else {
|
||||
// assume that the ruleId is unique.
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
package org.matrix.android.sdk.internal.database.mapper
|
||||
|
||||
import com.squareup.moshi.Types
|
||||
import org.matrix.android.sdk.api.pushrules.Condition
|
||||
import io.realm.RealmList
|
||||
import org.matrix.android.sdk.api.pushrules.Kind
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushCondition
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushRule
|
||||
import org.matrix.android.sdk.internal.database.model.PushRuleEntity
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import io.realm.RealmList
|
||||
import timber.log.Timber
|
||||
|
||||
internal object PushRulesMapper {
|
||||
|
@ -39,7 +39,7 @@ internal object PushRulesMapper {
|
|||
enabled = pushrule.enabled,
|
||||
ruleId = pushrule.ruleId,
|
||||
conditions = listOf(
|
||||
PushCondition(Condition.Kind.EventMatch.value, "content.body", pushrule.pattern)
|
||||
PushCondition(Kind.EventMatch.value, "content.body", pushrule.pattern)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ internal object PushRulesMapper {
|
|||
enabled = pushrule.enabled,
|
||||
ruleId = pushrule.ruleId,
|
||||
conditions = listOf(
|
||||
PushCondition(Condition.Kind.EventMatch.value, "room_id", pushrule.ruleId)
|
||||
PushCondition(Kind.EventMatch.value, "room_id", pushrule.ruleId)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ internal object PushRulesMapper {
|
|||
enabled = pushrule.enabled,
|
||||
ruleId = pushrule.ruleId,
|
||||
conditions = listOf(
|
||||
PushCondition(Condition.Kind.EventMatch.value, "user_id", pushrule.ruleId)
|
||||
PushCondition(Kind.EventMatch.value, "user_id", pushrule.ruleId)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
|
|||
return rules.firstOrNull { rule ->
|
||||
// All conditions must hold true for an event in order to apply the action for the event.
|
||||
rule.enabled && rule.conditions?.all {
|
||||
it.asExecutableCondition()?.isSatisfied(event, conditionResolver) ?: false
|
||||
it.asExecutableCondition(rule)?.isSatisfied(event, conditionResolver) ?: false
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package org.matrix.android.sdk.internal.session.room.notification
|
||||
|
||||
import org.matrix.android.sdk.api.pushrules.Action
|
||||
import org.matrix.android.sdk.api.pushrules.Condition
|
||||
import org.matrix.android.sdk.api.pushrules.Kind
|
||||
import org.matrix.android.sdk.api.pushrules.RuleSetKey
|
||||
import org.matrix.android.sdk.api.pushrules.getActions
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushCondition
|
||||
|
@ -59,7 +59,7 @@ internal fun RoomNotificationState.toRoomPushRule(roomId: String): RoomPushRule?
|
|||
}
|
||||
else -> {
|
||||
val condition = PushCondition(
|
||||
kind = Condition.Kind.EventMatch.value,
|
||||
kind = Kind.EventMatch.value,
|
||||
key = "room_id",
|
||||
pattern = roomId
|
||||
)
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.util
|
||||
|
||||
internal fun String.hasSpecialGlobChar(): Boolean {
|
||||
return contains("*") || contains("?")
|
||||
}
|
||||
|
||||
// Very simple glob to regexp converter
|
||||
internal fun String.simpleGlobToRegExp(): String {
|
||||
val string = this
|
||||
return buildString {
|
||||
// append("^")
|
||||
string.forEach { char ->
|
||||
when (char) {
|
||||
'*' -> append(".*")
|
||||
'?' -> append(".")
|
||||
'.' -> append("\\.")
|
||||
'\\' -> append("\\\\")
|
||||
else -> append(char)
|
||||
}
|
||||
}
|
||||
// append("$")
|
||||
}
|
||||
}
|
|
@ -52,3 +52,25 @@ fun convertFromUTF8(s: String): String {
|
|||
}
|
||||
|
||||
fun String.withoutPrefix(prefix: String) = if (startsWith(prefix)) substringAfter(prefix) else this
|
||||
|
||||
/**
|
||||
* Returns whether a string contains an occurrence of another, as a standalone word, regardless of case.
|
||||
*
|
||||
* @param subString the string to search for
|
||||
* @return whether a match was found
|
||||
*/
|
||||
fun String.caseInsensitiveFind(subString: String): Boolean {
|
||||
// add sanity checks
|
||||
if (subString.isEmpty() || isEmpty()) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
val regex = Regex("(\\W|^)" + Regex.escape(subString) + "(\\W|$)", RegexOption.IGNORE_CASE)
|
||||
return regex.containsMatchIn(this)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "## caseInsensitiveFind() : failed")
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
|
||||
package org.matrix.android.sdk.api.pushrules
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.matrix.android.sdk.MatrixTest
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||
|
@ -24,28 +30,26 @@ import org.matrix.android.sdk.api.session.room.model.Membership
|
|||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
|
||||
import org.matrix.android.sdk.internal.session.room.RoomGetter
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class PushrulesConditionTest: MatrixTest {
|
||||
class PushRulesConditionTest : MatrixTest {
|
||||
|
||||
/* ==========================================================================================
|
||||
* Test EventMatchCondition
|
||||
* ========================================================================================== */
|
||||
|
||||
@Test
|
||||
fun test_eventmatch_type_condition() {
|
||||
val condition = EventMatchCondition("type", "m.room.message")
|
||||
|
||||
val simpleTextEvent = Event(
|
||||
private fun createSimpleTextEvent(text: String): Event {
|
||||
return Event(
|
||||
type = "m.room.message",
|
||||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "Yo wtf?").toContent(),
|
||||
content = MessageTextContent("m.text", text).toContent(),
|
||||
originServerTs = 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_eventmatch_type_condition() {
|
||||
val condition = EventMatchCondition("type", "m.room.message", false)
|
||||
|
||||
val simpleTextEvent = createSimpleTextEvent("Yo wtf?")
|
||||
|
||||
val rm = RoomMemberContent(
|
||||
Membership.INVITE,
|
||||
|
@ -65,13 +69,9 @@ class PushrulesConditionTest: MatrixTest {
|
|||
|
||||
@Test
|
||||
fun test_eventmatch_path_condition() {
|
||||
val condition = EventMatchCondition("content.msgtype", "m.text")
|
||||
val condition = EventMatchCondition("content.msgtype", "m.text", false)
|
||||
|
||||
val simpleTextEvent = Event(
|
||||
type = "m.room.message",
|
||||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "Yo wtf?").toContent(),
|
||||
originServerTs = 0)
|
||||
val simpleTextEvent = createSimpleTextEvent("Yo wtf?")
|
||||
|
||||
assert(condition.isSatisfied(simpleTextEvent))
|
||||
|
||||
|
@ -86,49 +86,44 @@ class PushrulesConditionTest: MatrixTest {
|
|||
).toContent(),
|
||||
originServerTs = 0
|
||||
).apply {
|
||||
assert(EventMatchCondition("content.membership", "invite").isSatisfied(this))
|
||||
assert(EventMatchCondition("content.membership", "invite", false).isSatisfied(this))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_eventmatch_cake_condition() {
|
||||
val condition = EventMatchCondition("content.body", "cake")
|
||||
val condition = EventMatchCondition("content.body", "cake", false)
|
||||
|
||||
Event(
|
||||
type = "m.room.message",
|
||||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "How was the cake?").toContent(),
|
||||
originServerTs = 0
|
||||
).apply {
|
||||
assert(condition.isSatisfied(this))
|
||||
}
|
||||
|
||||
Event(
|
||||
type = "m.room.message",
|
||||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "Howwasthecake?").toContent(),
|
||||
originServerTs = 0
|
||||
).apply {
|
||||
assert(condition.isSatisfied(this))
|
||||
}
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("How was the cake?")))
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("Howwasthecake?")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_eventmatch_cakelie_condition() {
|
||||
val condition = EventMatchCondition("content.body", "cake*lie")
|
||||
val condition = EventMatchCondition("content.body", "cake*lie", false)
|
||||
|
||||
val simpleTextEvent = Event(
|
||||
type = "m.room.message",
|
||||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "How was the cakeisalie?").toContent(),
|
||||
originServerTs = 0)
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("How was the cakeisalie?")))
|
||||
}
|
||||
|
||||
assert(condition.isSatisfied(simpleTextEvent))
|
||||
@Test
|
||||
fun test_eventmatch_words_only_condition() {
|
||||
val condition = EventMatchCondition("content.body", "ben", true)
|
||||
|
||||
assertFalse(condition.isSatisfied(createSimpleTextEvent("benoit")))
|
||||
assertFalse(condition.isSatisfied(createSimpleTextEvent("Hello benoit")))
|
||||
assertFalse(condition.isSatisfied(createSimpleTextEvent("superben")))
|
||||
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("ben")))
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("hello ben")))
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("ben is there")))
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("hello ben!")))
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("hello Ben!")))
|
||||
assert(condition.isSatisfied(createSimpleTextEvent("BEN")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_notice_condition() {
|
||||
val conditionEqual = EventMatchCondition("content.msgtype", "m.notice")
|
||||
val conditionEqual = EventMatchCondition("content.msgtype", "m.notice", false)
|
||||
|
||||
Event(
|
||||
type = "m.room.message",
|
|
@ -25,9 +25,6 @@ import androidx.lifecycle.Lifecycle
|
|||
import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import com.google.firebase.messaging.FirebaseMessagingService
|
||||
import com.google.firebase.messaging.RemoteMessage
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushRule
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import im.vector.app.BuildConfig
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
|
@ -40,6 +37,9 @@ import im.vector.app.features.notifications.NotificationDrawerManager
|
|||
import im.vector.app.features.notifications.SimpleNotifiableEvent
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.push.fcm.FcmHelper
|
||||
import org.matrix.android.sdk.api.pushrules.Action
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
|
@ -196,7 +196,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
description = "",
|
||||
type = null,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
soundName = PushRule.ACTION_VALUE_DEFAULT,
|
||||
soundName = Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT,
|
||||
isPushGatewayEvent = true
|
||||
)
|
||||
notificationDrawerManager.onNotifiableEventReceived(simpleNotifiableEvent)
|
||||
|
|
|
@ -22,6 +22,8 @@ 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
|
||||
|
@ -51,7 +53,7 @@ class PushRulePreference : VectorPreference {
|
|||
get() {
|
||||
val safeRule = ruleAndKind?.pushRule ?: return NOTIFICATION_OFF_INDEX
|
||||
|
||||
if (safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
|
||||
if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
|
||||
if (safeRule.shouldNotNotify()) {
|
||||
return if (safeRule.enabled) {
|
||||
NOTIFICATION_OFF_INDEX
|
||||
|
@ -108,7 +110,7 @@ class PushRulePreference : VectorPreference {
|
|||
val safeKind = ruleAndKind?.kind ?: return null
|
||||
|
||||
return if (index != ruleStatusIndex) {
|
||||
if (safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
|
||||
if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
|
||||
when (index) {
|
||||
NOTIFICATION_OFF_INDEX -> {
|
||||
safeRule.copy(enabled = true)
|
||||
|
@ -128,7 +130,7 @@ class PushRulePreference : VectorPreference {
|
|||
}
|
||||
} else {
|
||||
if (NOTIFICATION_OFF_INDEX == index) {
|
||||
if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
|
||||
if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) {
|
||||
safeRule.setNotify(false)
|
||||
} else {
|
||||
safeRule.copy(enabled = false)
|
||||
|
@ -137,15 +139,15 @@ class PushRulePreference : VectorPreference {
|
|||
val newRule = safeRule.copy(enabled = true)
|
||||
.setNotify(true)
|
||||
.setHighlight(safeKind != RuleSetKey.UNDERRIDE
|
||||
&& safeRule.ruleId != PushRule.RULE_ID_INVITE_ME
|
||||
&& safeRule.ruleId != RuleIds.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
|
||||
if (safeRule.ruleId == RuleIds.RULE_ID_CALL) {
|
||||
Action.ACTION_OBJECT_VALUE_VALUE_RING
|
||||
} else {
|
||||
PushRule.ACTION_VALUE_DEFAULT
|
||||
Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT
|
||||
}
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
package im.vector.app.features.settings
|
||||
|
||||
import androidx.preference.Preference
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushRule
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind
|
||||
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 org.matrix.android.sdk.api.MatrixCallback
|
||||
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()
|
||||
|
@ -92,17 +92,17 @@ class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor()
|
|||
companion object {
|
||||
// preference name <-> rule Id
|
||||
private val prefKeyToPushRuleId = mapOf(
|
||||
"SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to PushRule.RULE_ID_CONTAIN_DISPLAY_NAME,
|
||||
"SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to PushRule.RULE_ID_CONTAIN_USER_NAME,
|
||||
"SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to PushRule.RULE_ID_ONE_TO_ONE_ROOM,
|
||||
"SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to PushRule.RULE_ID_ALL_OTHER_MESSAGES_ROOMS,
|
||||
"SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to PushRule.RULE_ID_INVITE_ME,
|
||||
"SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to PushRule.RULE_ID_CALL,
|
||||
"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
|
||||
"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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ import androidx.core.view.isVisible
|
|||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import com.airbnb.epoxy.EpoxyModelWithHolder
|
||||
import org.matrix.android.sdk.api.pushrules.getActions
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushRule
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.features.notifications.toNotificationAction
|
||||
import org.matrix.android.sdk.api.pushrules.getActions
|
||||
import org.matrix.android.sdk.api.pushrules.rest.PushRule
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_pushrule_raw)
|
||||
abstract class PushRuleItem : EpoxyModelWithHolder<PushRuleItem.Holder>() {
|
||||
|
@ -68,7 +68,7 @@ abstract class PushRuleItem : EpoxyModelWithHolder<PushRuleItem.Holder>() {
|
|||
val description = StringBuffer()
|
||||
pushRule.conditions?.forEachIndexed { i, condition ->
|
||||
if (i > 0) description.append("\n")
|
||||
description.append(condition.asExecutableCondition()?.technicalDescription()
|
||||
description.append(condition.asExecutableCondition(pushRule)?.technicalDescription()
|
||||
?: "UNSUPPORTED")
|
||||
}
|
||||
if (description.isBlank()) {
|
||||
|
|
Loading…
Reference in a new issue