Browse Source

app: Get rid of SessionIntentType

fractal-12
Kévin Commaille 8 months ago
parent
commit
b632397022
No known key found for this signature in database
GPG Key ID: F26F4BE20A08255B
  1. 66
      src/application.rs
  2. 122
      src/intent.rs
  3. 2
      src/session/model/notifications/mod.rs

66
src/application.rs

@ -7,7 +7,7 @@ use tracing::{debug, error, info, warn};
use crate::{
GETTEXT_PACKAGE, Window, config,
intent::{SessionIntent, SessionIntentType},
intent::SessionIntent,
prelude::*,
session::model::{Session, SessionState},
session_list::{FailedSession, SessionInfo, SessionList},
@ -182,23 +182,20 @@ mod imp {
.build(),
// Show a room. This is the action triggered when clicking a notification about a
// message.
gio::ActionEntry::builder(SessionIntentType::ShowMatrixId.action_name())
.parameter_type(Some(&SessionIntentType::static_variant_type()))
gio::ActionEntry::builder(SessionIntent::SHOW_MATRIX_ID_ACTION_NAME)
.parameter_type(Some(&SessionIntent::static_variant_type()))
.activate(|obj: &super::Application, _, variant| {
debug!(
"`app.{}` action activated",
SessionIntentType::ShowMatrixId.action_name()
"`{}` action activated",
SessionIntent::SHOW_MATRIX_ID_APP_ACTION_NAME
);
let Some((session_id, intent)) = variant.and_then(|variant| {
SessionIntent::from_variant_with_session_id(
SessionIntentType::ShowMatrixId,
variant,
)
}) else {
let Some((session_id, intent)) =
variant.and_then(SessionIntent::show_matrix_id_from_variant)
else {
error!(
"Activated `app.{}` action without the proper payload",
SessionIntentType::ShowMatrixId.action_name()
"Activated `{}` action without the proper payload",
SessionIntent::SHOW_MATRIX_ID_APP_ACTION_NAME
);
return;
};
@ -208,32 +205,27 @@ mod imp {
.build(),
// Show an identity verification. This is the action triggered when clicking a
// notification about a new verification.
gio::ActionEntry::builder(
SessionIntentType::ShowIdentityVerification.action_name(),
)
.parameter_type(Some(&SessionIntentType::static_variant_type()))
.activate(|obj: &super::Application, _, variant| {
debug!(
"`app.{}` action activated",
SessionIntentType::ShowIdentityVerification.action_name()
);
let Some((session_id, intent)) = variant.and_then(|variant| {
SessionIntent::from_variant_with_session_id(
SessionIntentType::ShowIdentityVerification,
variant,
)
}) else {
error!(
"Activated `app.{}` action without the proper payload",
SessionIntentType::ShowIdentityVerification.action_name()
gio::ActionEntry::builder(SessionIntent::SHOW_IDENTITY_VERIFICATION_ACTION_NAME)
.parameter_type(Some(&SessionIntent::static_variant_type()))
.activate(|obj: &super::Application, _, variant| {
debug!(
"`{}` action activated",
SessionIntent::SHOW_IDENTITY_VERIFICATION_APP_ACTION_NAME
);
return;
};
obj.imp().process_session_intent(session_id, intent);
})
.build(),
let Some((session_id, intent)) = variant
.and_then(SessionIntent::show_identity_verification_from_variant)
else {
error!(
"Activated `{}` action without the proper payload",
SessionIntent::SHOW_IDENTITY_VERIFICATION_APP_ACTION_NAME
);
return;
};
obj.imp().process_session_intent(session_id, intent);
})
.build(),
]);
}

122
src/intent.rs

@ -1,7 +1,6 @@
use std::borrow::Cow;
use gtk::{glib, prelude::*};
use ruma::OwnedUserId;
use crate::{session::model::VerificationKey, utils::matrix::MatrixIdUri};
@ -17,44 +16,86 @@ pub(crate) enum SessionIntent {
}
impl SessionIntent {
/// The application action name for the [`SessionIntent::ShowMatrixId`]
/// variant.
pub(crate) const SHOW_MATRIX_ID_APP_ACTION_NAME: &str = "app.show-matrix-id";
/// The action name without the `app.` prefix for the
/// [`SessionIntent::ShowMatrixId`] variant.
pub(crate) const SHOW_MATRIX_ID_ACTION_NAME: &str =
Self::SHOW_MATRIX_ID_APP_ACTION_NAME.split_at(4).1;
/// The application action name for the
/// [`SessionIntent::ShowIdentityVerification`] variant.
pub(crate) const SHOW_IDENTITY_VERIFICATION_APP_ACTION_NAME: &str =
"app.show-identity-verification";
/// The action name without the `app.` prefix for the
/// [`SessionIntent::ShowIdentityVerification`] variant.
pub(crate) const SHOW_IDENTITY_VERIFICATION_ACTION_NAME: &str =
Self::SHOW_IDENTITY_VERIFICATION_APP_ACTION_NAME
.split_at(4)
.1;
/// Get the application action name for this session intent type.
pub(crate) fn app_action_name(&self) -> &'static str {
match self {
SessionIntent::ShowMatrixId(_) => "app.show-matrix-id",
SessionIntent::ShowIdentityVerification(_) => "app.show-identity-verification",
SessionIntent::ShowMatrixId(_) => Self::SHOW_MATRIX_ID_APP_ACTION_NAME,
SessionIntent::ShowIdentityVerification(_) => {
Self::SHOW_IDENTITY_VERIFICATION_APP_ACTION_NAME
}
}
}
/// Convert this intent to a `GVariant` with the given session ID.
pub(crate) fn to_variant_with_session_id(&self, session_id: &str) -> glib::Variant {
let payload = match self {
Self::ShowMatrixId(uri) => uri.to_variant(),
Self::ShowIdentityVerification(key) => key.to_variant(),
};
(session_id, payload).to_variant()
/// Convert the given `GVariant` to a [`SessionIntent::ShowMatrixId`] and
/// session ID, given the intent type.
///
/// Returns a `(session_id, intent)` tuple on success. Returns `None` if
/// the `GVariant` could not be parsed successfully.
pub(crate) fn show_matrix_id_from_variant(variant: &glib::Variant) -> Option<(String, Self)> {
let SessionIntentActionParameter {
session_id,
payload,
} = variant.get()?;
Some((session_id, Self::ShowMatrixId(payload.get()?)))
}
/// Convert a `GVariant` to a `SessionIntent` and session ID, given the
/// Convert the given `GVariant` to a
/// [`SessionIntent::ShowIdentityVerification`] and session ID, given the
/// intent type.
///
/// Returns an `(session_id, intent)` tuple on success. Returns `None` if
/// the payload could not be parsed successfully.
pub(crate) fn from_variant_with_session_id(
intent_type: SessionIntentType,
/// Returns a `(session_id, intent)` tuple on success. Returns `None` if
/// the `GVariant` could not be parsed successfully.
pub(crate) fn show_identity_verification_from_variant(
variant: &glib::Variant,
) -> Option<(String, Self)> {
let (session_id, payload) = variant.get::<(String, glib::Variant)>()?;
let intent = match intent_type {
SessionIntentType::ShowMatrixId => Self::ShowMatrixId(payload.get::<MatrixIdUri>()?),
SessionIntentType::ShowIdentityVerification => {
let (user_id_str, flow_id) = payload.get::<(String, String)>()?;
let user_id = OwnedUserId::try_from(user_id_str).ok()?;
Self::ShowIdentityVerification(VerificationKey { user_id, flow_id })
}
let SessionIntentActionParameter {
session_id,
payload,
} = variant.get()?;
Some((session_id, Self::ShowIdentityVerification(payload.get()?)))
}
/// Convert this intent to a `GVariant` with the given session ID.
pub(crate) fn to_variant_with_session_id(&self, session_id: String) -> glib::Variant {
let payload = match self {
Self::ShowMatrixId(uri) => uri.to_variant(),
Self::ShowIdentityVerification(key) => key.to_variant(),
};
Some((session_id, intent))
SessionIntentActionParameter {
session_id,
payload,
}
.to_variant()
}
}
impl StaticVariantType for SessionIntent {
fn static_variant_type() -> Cow<'static, glib::VariantTy> {
SessionIntentActionParameter::static_variant_type()
}
}
@ -70,27 +111,12 @@ impl From<VerificationKey> for SessionIntent {
}
}
/// The type of an intent that can be handled by a session.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum SessionIntentType {
/// Show the target of a Matrix ID URI.
ShowMatrixId,
/// Show an ongoing identity verification.
ShowIdentityVerification,
}
impl SessionIntentType {
/// Get the action name for this session intent type.
pub(crate) fn action_name(self) -> &'static str {
match self {
SessionIntentType::ShowMatrixId => "show-matrix-id",
SessionIntentType::ShowIdentityVerification => "show-identity-verification",
}
}
}
impl StaticVariantType for SessionIntentType {
fn static_variant_type() -> Cow<'static, glib::VariantTy> {
<(String, glib::Variant)>::static_variant_type()
}
/// The payload of a [`SessionIntent`], when converted to a `GVariant` for an
/// app action.
#[derive(Debug, Clone, glib::Variant)]
struct SessionIntentActionParameter {
/// The ID of the session that should handle the intent.
session_id: String,
/// The payload of the intent.
payload: glib::Variant,
}

2
src/session/model/notifications/mod.rs

@ -135,7 +135,7 @@ impl Notifications {
notification.set_body(Some(&body));
let action = intent.app_action_name();
let target_value = intent.to_variant_with_session_id(session_id);
let target_value = intent.to_variant_with_session_id(session_id.to_owned());
notification.set_default_action_and_target_value(action, Some(&target_value));
if let Some(notification_icon) = icon {

Loading…
Cancel
Save