Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sdk: Allow to update notification settings #2135

Merged
merged 21 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions crates/matrix-sdk/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ use ruma::{
error::FromHttpResponseError,
MatrixVersion, OutgoingRequest,
},
assign, DeviceId, OwnedDeviceId, OwnedRoomId, OwnedServerName, RoomAliasId, RoomId,
RoomOrAliasId, ServerName, UInt, UserId,
assign,
push::Ruleset,
DeviceId, OwnedDeviceId, OwnedRoomId, OwnedServerName, RoomAliasId, RoomId, RoomOrAliasId,
ServerName, UInt, UserId,
};
use serde::de::DeserializeOwned;
use tokio::sync::{broadcast, Mutex, OnceCell, RwLock, RwLockReadGuard};
Expand All @@ -81,6 +83,7 @@ use crate::{
},
http_client::HttpClient,
matrix_auth::MatrixAuth,
notification_settings::NotificationSettings,
room,
sync::{RoomUpdate, SyncResponse},
Account, AuthApi, AuthSession, Error, Media, RefreshTokenError, Result, TransmissionProgress,
Expand Down Expand Up @@ -1926,6 +1929,12 @@ impl Client {
let request = get_profile::v3::Request::new(user_id.to_owned());
Ok(self.send(request, Some(RequestConfig::short_retry())).await?)
}

/// Get the notification settings of the current owner of the client.
pub async fn notification_settings(&self) -> NotificationSettings {
let ruleset = self.account().push_rules().await.unwrap_or_else(|_| Ruleset::new());
NotificationSettings::new(self.clone(), ruleset)
}
}

// The http mocking library is not supported for wasm32
Expand Down
23 changes: 19 additions & 4 deletions crates/matrix-sdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use ruma::{
error::{FromHttpResponseError, IntoHttpError},
},
events::tag::InvalidUserTagName,
push::{InsertPushRuleError, RuleNotFoundError},
push::{InsertPushRuleError, RemovePushRuleError, RuleNotFoundError},
IdParseError,
};
use serde_json::Error as JsonError;
Expand Down Expand Up @@ -430,12 +430,21 @@ pub enum NotificationSettingsError {
/// Invalid parameter.
#[error("Invalid parameter `{0}`")]
InvalidParameter(String),
/// Rule not found
#[error("Rule not found")]
RuleNotFound,
/// Unable to add push rule.
#[error("Unable to add push rule")]
UnableToAddPushRule,
/// Unable to remove push rule.
#[error("Unable to remove push rule")]
UnableToRemovePushRule,
/// Unable to update push rule.
#[error("Unable to update push rule")]
UnableToUpdatePushRule,
/// Rule not found
#[error("Rule not found")]
RuleNotFound,
/// Unable to save the push rules
#[error("Unable to save push rules")]
UnableToSavePushRules,
}

impl From<InsertPushRuleError> for NotificationSettingsError {
Expand All @@ -444,6 +453,12 @@ impl From<InsertPushRuleError> for NotificationSettingsError {
}
}

impl From<RemovePushRuleError> for NotificationSettingsError {
fn from(_: RemovePushRuleError) -> Self {
Self::UnableToRemovePushRule
}
}

impl From<RuleNotFoundError> for NotificationSettingsError {
fn from(_: RuleNotFoundError) -> Self {
Self::RuleNotFound
Expand Down
5 changes: 4 additions & 1 deletion crates/matrix-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ pub use authentication::{AuthApi, AuthSession};
pub use client::{Client, ClientBuildError, ClientBuilder, LoopCtrl, SendRequest, UnknownToken};
#[cfg(feature = "image-proc")]
pub use error::ImageError;
pub use error::{Error, HttpError, HttpResult, RefreshTokenError, Result, RumaApiError};
pub use error::{
Error, HttpError, HttpResult, NotificationSettingsError, RefreshTokenError, Result,
RumaApiError,
};
pub use http_client::TransmissionProgress;
pub use media::Media;
pub use ruma::{IdParseError, OwnedServerName, ServerName};
Expand Down
65 changes: 65 additions & 0 deletions crates/matrix-sdk/src/notification_settings/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::fmt::Debug;

use ruma::{
api::client::push::RuleScope,
push::{
Action, NewConditionalPushRule, NewPushRule, NewSimplePushRule, PushCondition, RuleKind,
Tweak,
},
OwnedRoomId,
};

use crate::NotificationSettingsError;

/// Enum describing the commands required to modify the owner's account data.
#[derive(Clone, Debug)]
pub(crate) enum Command {
/// Set a new `Room` push rule
SetRoomPushRule { scope: RuleScope, room_id: OwnedRoomId, notify: bool },
/// Set a new `Override` push rule matching a `RoomId`
SetOverridePushRule { scope: RuleScope, rule_id: String, room_id: OwnedRoomId, notify: bool },
/// Set whether a push rule is enabled
SetPushRuleEnabled { scope: RuleScope, kind: RuleKind, rule_id: String, enabled: bool },
/// Delete a push rule
DeletePushRule { scope: RuleScope, kind: RuleKind, rule_id: String },
}

fn get_notify_actions(notify: bool) -> Vec<Action> {
if notify {
vec![Action::Notify, Action::SetTweak(Tweak::Sound("default".into()))]
} else {
vec![]
}
}

impl Command {
/// Tries to create a push rule corresponding to this command
pub(crate) fn to_push_rule(&self) -> Result<NewPushRule, NotificationSettingsError> {
match self {
Self::SetRoomPushRule { scope: _, room_id, notify } => {
// `Room` push rule for this `room_id`
let new_rule = NewSimplePushRule::new(room_id.clone(), get_notify_actions(*notify));
Ok(NewPushRule::Room(new_rule))
}

Self::SetOverridePushRule { scope: _, rule_id, room_id, notify } => {
// `Override` push rule matching this `room_id`
let new_rule = NewConditionalPushRule::new(
rule_id.clone(),
vec![PushCondition::EventMatch {
key: "room_id".to_owned(),
pattern: room_id.to_string(),
}],
get_notify_actions(*notify),
);
Ok(NewPushRule::Override(new_rule))
}

Self::SetPushRuleEnabled { .. } | Self::DeletePushRule { .. } => {
Err(NotificationSettingsError::InvalidParameter(
"cannot create a push rule from this command.".to_owned(),
))
}
}
}
}
Loading