mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 21:52:30 -04:00
Merge pull request #2396 from matrix-org/nicolas/notification_settings_user_defined_room_rules
sdk+ffi: Get the user-defined notification mode for a room and all rooms for which a user-defined rule exists.
This commit is contained in:
@@ -176,6 +176,24 @@ impl NotificationSettings {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the user defined room notification mode
|
||||
pub async fn get_user_defined_room_notification_mode(
|
||||
&self,
|
||||
room_id: String,
|
||||
) -> Result<Option<RoomNotificationMode>, NotificationSettingsError> {
|
||||
let notification_settings = self.sdk_notification_settings.read().await;
|
||||
let parsed_room_id = RoomId::parse(&room_id)
|
||||
.map_err(|_e| NotificationSettingsError::InvalidRoomId(room_id))?;
|
||||
// Get the current user defined mode for this room
|
||||
if let Some(mode) =
|
||||
notification_settings.get_user_defined_room_notification_mode(&parsed_room_id).await
|
||||
{
|
||||
Ok(Some(mode.into()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the default room notification mode
|
||||
///
|
||||
/// The mode will depend on the associated `PushRule` based on whether the
|
||||
@@ -235,6 +253,12 @@ impl NotificationSettings {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get all room IDs for which a user-defined rule exists.
|
||||
pub async fn get_rooms_with_user_defined_rules(&self, enabled: Option<bool>) -> Vec<String> {
|
||||
let notification_settings = self.sdk_notification_settings.read().await;
|
||||
notification_settings.get_rooms_with_user_defined_rules(enabled).await
|
||||
}
|
||||
|
||||
/// Get whether some enabled keyword rules exist.
|
||||
pub async fn contains_keywords_rules(&self) -> bool {
|
||||
let notification_settings = self.sdk_notification_settings.read().await;
|
||||
|
||||
@@ -130,6 +130,11 @@ impl NotificationSettings {
|
||||
self.rules.read().await.get_default_room_notification_mode(is_encrypted, members_count)
|
||||
}
|
||||
|
||||
/// Get all room IDs for which a user-defined rule exists.
|
||||
pub async fn get_rooms_with_user_defined_rules(&self, enabled: Option<bool>) -> Vec<String> {
|
||||
self.rules.read().await.get_rooms_with_user_defined_rules(enabled)
|
||||
}
|
||||
|
||||
/// Get whether the given ruleset contains some enabled keywords rules.
|
||||
pub async fn contains_keyword_rules(&self) -> bool {
|
||||
self.rules.read().await.contains_keyword_rules()
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
//! Ruleset utility struct
|
||||
|
||||
use imbl::HashSet;
|
||||
use ruma::{
|
||||
push::{
|
||||
PredefinedContentRuleId, PredefinedOverrideRuleId, PredefinedUnderrideRuleId,
|
||||
PushCondition, RuleKind, Ruleset,
|
||||
AnyPushRuleRef, PredefinedContentRuleId, PredefinedOverrideRuleId,
|
||||
PredefinedUnderrideRuleId, PushCondition, RuleKind, Ruleset,
|
||||
},
|
||||
RoomId,
|
||||
};
|
||||
@@ -123,6 +124,39 @@ impl Rules {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all room IDs for which a user-defined rule exists.
|
||||
pub(crate) fn get_rooms_with_user_defined_rules(&self, enabled: Option<bool>) -> Vec<String> {
|
||||
let test_if_enabled = enabled.is_some();
|
||||
let must_be_enabled = enabled.unwrap_or(false);
|
||||
|
||||
let mut room_ids = HashSet::new();
|
||||
for rule in &self.ruleset {
|
||||
if rule.is_server_default() {
|
||||
continue;
|
||||
}
|
||||
if test_if_enabled && rule.enabled() != must_be_enabled {
|
||||
continue;
|
||||
}
|
||||
match rule {
|
||||
AnyPushRuleRef::Override(r) | AnyPushRuleRef::Underride(r) => {
|
||||
for condition in &r.conditions {
|
||||
if let PushCondition::EventMatch { key, pattern } = condition {
|
||||
if key == "room_id" {
|
||||
room_ids.insert(pattern.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AnyPushRuleRef::Room(r) => {
|
||||
room_ids.insert(r.rule_id.to_string());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Vec::from_iter(room_ids)
|
||||
}
|
||||
|
||||
/// Get whether the `IsUserMention` rule is enabled.
|
||||
fn is_user_mention_enabled(&self) -> bool {
|
||||
// Search for an `Override` rule `IsUserMention` (MSC3952).
|
||||
@@ -245,6 +279,7 @@ pub(crate) fn get_predefined_underride_room_rule_id(
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use imbl::HashSet;
|
||||
use matrix_sdk_test::{
|
||||
async_test,
|
||||
notification_settings::{build_ruleset, get_server_default_ruleset},
|
||||
@@ -567,4 +602,79 @@ pub(crate) mod tests {
|
||||
.is_enabled(RuleKind::Override, PredefinedOverrideRuleId::Reaction.as_str())
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_get_rooms_with_user_defined_rules() {
|
||||
// Without user-defined rules
|
||||
let rules = Rules::new(get_server_default_ruleset());
|
||||
let room_ids = rules.get_rooms_with_user_defined_rules(None);
|
||||
assert!(room_ids.is_empty());
|
||||
|
||||
// With one rule.
|
||||
let room_id = RoomId::parse("!room_a:matrix.org").unwrap();
|
||||
let ruleset = build_ruleset(vec![(RuleKind::Override, &room_id, false)]);
|
||||
let rules = Rules::new(ruleset);
|
||||
|
||||
let room_ids = rules.get_rooms_with_user_defined_rules(None);
|
||||
assert_eq!(room_ids.len(), 1);
|
||||
|
||||
// With duplicates
|
||||
let ruleset = build_ruleset(vec![
|
||||
(RuleKind::Override, &room_id, false),
|
||||
(RuleKind::Underride, &room_id, false),
|
||||
(RuleKind::Room, &room_id, false),
|
||||
]);
|
||||
let rules = Rules::new(ruleset);
|
||||
|
||||
let room_ids = rules.get_rooms_with_user_defined_rules(None);
|
||||
assert_eq!(room_ids.len(), 1);
|
||||
assert_eq!(room_ids[0], room_id.to_string());
|
||||
|
||||
// With multiple rules
|
||||
let ruleset = build_ruleset(vec![
|
||||
(RuleKind::Room, &RoomId::parse("!room_a:matrix.org").unwrap(), false),
|
||||
(RuleKind::Room, &RoomId::parse("!room_b:matrix.org").unwrap(), false),
|
||||
(RuleKind::Room, &RoomId::parse("!room_c:matrix.org").unwrap(), false),
|
||||
(RuleKind::Override, &RoomId::parse("!room_d:matrix.org").unwrap(), false),
|
||||
(RuleKind::Underride, &RoomId::parse("!room_e:matrix.org").unwrap(), false),
|
||||
]);
|
||||
let rules = Rules::new(ruleset);
|
||||
|
||||
let room_ids = rules.get_rooms_with_user_defined_rules(None);
|
||||
assert_eq!(room_ids.len(), 5);
|
||||
let expected_set: HashSet<String> = vec![
|
||||
"!room_a:matrix.org",
|
||||
"!room_b:matrix.org",
|
||||
"!room_c:matrix.org",
|
||||
"!room_d:matrix.org",
|
||||
"!room_e:matrix.org",
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
assert!(expected_set.difference(HashSet::from(room_ids)).is_empty());
|
||||
|
||||
// Only disabled rules
|
||||
let room_ids = rules.get_rooms_with_user_defined_rules(Some(false));
|
||||
assert_eq!(room_ids.len(), 0);
|
||||
|
||||
// Only enabled rules
|
||||
let room_ids = rules.get_rooms_with_user_defined_rules(Some(true));
|
||||
assert_eq!(room_ids.len(), 5);
|
||||
|
||||
let mut ruleset = build_ruleset(vec![
|
||||
(RuleKind::Room, &RoomId::parse("!room_a:matrix.org").unwrap(), false),
|
||||
(RuleKind::Room, &RoomId::parse("!room_b:matrix.org").unwrap(), false),
|
||||
(RuleKind::Override, &RoomId::parse("!room_c:matrix.org").unwrap(), false),
|
||||
(RuleKind::Underride, &RoomId::parse("!room_d:matrix.org").unwrap(), false),
|
||||
]);
|
||||
ruleset.set_enabled(RuleKind::Room, "!room_b:matrix.org", false).unwrap();
|
||||
ruleset.set_enabled(RuleKind::Override, "!room_c:matrix.org", false).unwrap();
|
||||
let rules = Rules::new(ruleset);
|
||||
// Only room_a and room_d rules are enabled
|
||||
let room_ids = rules.get_rooms_with_user_defined_rules(Some(true));
|
||||
assert_eq!(room_ids.len(), 2);
|
||||
let expected_set: HashSet<String> =
|
||||
vec!["!room_a:matrix.org", "!room_d:matrix.org"].into_iter().collect();
|
||||
assert!(expected_set.difference(HashSet::from(room_ids)).is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user