Browse Source

misc: Intercept activation of Matrix URIs in room descriptions

fractal-8
Kévin Commaille 2 years ago
parent
commit
e96a8532d4
No known key found for this signature in database
GPG Key ID: C971D9DBC9D678D
  1. 32
      src/components/dialogs/join_room.rs
  2. 20
      src/session/view/content/explore/public_room_row.rs
  3. 17
      src/session/view/content/invite.rs
  4. 38
      src/session/view/content/room_details/general_page.rs
  5. 28
      src/session/view/session_view.rs
  6. 15
      src/utils/matrix.rs

32
src/components/dialogs/join_room.rs

@ -9,7 +9,10 @@ use crate::{
prelude::*,
session::model::{RemoteRoom, Session},
toast,
utils::{matrix::MatrixRoomIdUri, LoadingState},
utils::{
matrix::{MatrixIdUri, MatrixRoomIdUri},
LoadingState,
},
Window,
};
@ -78,7 +81,32 @@ mod imp {
}
#[glib::derived_properties]
impl ObjectImpl for JoinRoomDialog {}
impl ObjectImpl for JoinRoomDialog {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
self.room_topic.connect_activate_link(clone!(
#[weak]
obj,
#[upgrade_or]
glib::Propagation::Proceed,
move |_, uri| {
let Ok(uri) = MatrixIdUri::parse(uri) else {
return glib::Propagation::Proceed;
};
let Some(parent_window) =
obj.ancestor(Window::static_type()).and_downcast::<Window>()
else {
return glib::Propagation::Proceed;
};
parent_window.session_view().show_matrix_uri(uri);
glib::Propagation::Stop
}
));
}
}
impl WidgetImpl for JoinRoomDialog {}
impl AdwDialogImpl for JoinRoomDialog {}

20
src/session/view/content/explore/public_room_row.rs

@ -9,7 +9,7 @@ use crate::{
gettext_f, ngettext_f,
prelude::*,
spawn, toast,
utils::{string::linkify, BoundObject},
utils::{matrix::MatrixIdUri, string::linkify, BoundObject},
Window,
};
@ -63,6 +63,8 @@ mod imp {
impl ObjectImpl for PublicRoomRow {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
self.button.connect_clicked(clone!(
#[weak(rename_to = imp)]
self,
@ -70,6 +72,22 @@ mod imp {
imp.obj().join_or_view();
}
));
self.description.connect_activate_link(clone!(
#[weak]
obj,
#[upgrade_or]
glib::Propagation::Proceed,
move |_, uri| {
if MatrixIdUri::parse(uri).is_ok() {
let _ =
obj.activate_action("session.show-matrix-uri", Some(&uri.to_variant()));
glib::Propagation::Stop
} else {
glib::Propagation::Proceed
}
}
));
}
}

17
src/session/view/content/invite.rs

@ -8,6 +8,7 @@ use crate::{
prelude::*,
session::model::{MemberList, Room, RoomType, User},
toast,
utils::matrix::MatrixIdUri,
};
mod imp {
@ -73,6 +74,7 @@ mod imp {
impl ObjectImpl for Invite {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
self.room_alias.connect_label_notify(|room_alias| {
room_alias.set_visible(!room_alias.label().is_empty());
@ -85,6 +87,21 @@ mod imp {
});
self.room_topic
.set_visible(!self.room_topic.label().is_empty());
self.room_topic.connect_activate_link(clone!(
#[weak]
obj,
#[upgrade_or]
glib::Propagation::Proceed,
move |_, uri| {
if MatrixIdUri::parse(uri).is_ok() {
let _ =
obj.activate_action("session.show-matrix-uri", Some(&uri.to_variant()));
glib::Propagation::Stop
} else {
glib::Propagation::Proceed
}
}
));
}
fn dispose(&self) {

38
src/session/view/content/room_details/general_page.rs

@ -21,7 +21,7 @@ use ruma::{
};
use tracing::error;
use super::room_upgrade_dialog::confirm_room_upgrade;
use super::{room_upgrade_dialog::confirm_room_upgrade, RoomDetails};
use crate::{
components::{
ButtonCountRow, ButtonRow, CheckLoadingRow, ComboLoadingRow, CopyableRow, LoadingButton,
@ -34,8 +34,10 @@ use crate::{
},
spawn, spawn_tokio, toast,
utils::{
expression, template_callbacks::TemplateCallbacks, BoundObjectWeakRef, OngoingAsyncAction,
expression, matrix::MatrixIdUri, template_callbacks::TemplateCallbacks, BoundObjectWeakRef,
OngoingAsyncAction,
},
Window,
};
mod imp {
@ -143,6 +145,38 @@ mod imp {
#[glib::derived_properties]
impl ObjectImpl for GeneralPage {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
self.room_topic.connect_activate_link(clone!(
#[weak]
obj,
#[upgrade_or]
glib::Propagation::Proceed,
move |_, uri| {
let Ok(uri) = MatrixIdUri::parse(uri) else {
return glib::Propagation::Proceed;
};
let Some(room_details) = obj
.ancestor(RoomDetails::static_type())
.and_downcast::<RoomDetails>()
else {
return glib::Propagation::Proceed;
};
let Some(parent_window) = room_details.transient_for().and_downcast::<Window>()
else {
return glib::Propagation::Proceed;
};
parent_window.session_view().show_matrix_uri(uri);
room_details.close();
glib::Propagation::Stop
}
));
}
fn dispose(&self) {
self.disconnect_all();
}

28
src/session/view/session_view.rs

@ -14,7 +14,7 @@ use crate::{
Event, IdentityVerification, Room, Selection, Session, SidebarListModel, VerificationKey,
},
toast,
utils::matrix::MatrixRoomIdUri,
utils::matrix::{MatrixEventIdUri, MatrixIdUri, MatrixRoomIdUri},
Window,
};
@ -113,6 +113,18 @@ mod imp {
gdk::ModifierType::CONTROL_MASK,
"session.toggle-room-search",
);
klass.install_action(
"session.show-matrix-uri",
Some(&MatrixIdUri::static_variant_type()),
|obj, _, parameter| {
if let Some(uri) = parameter.unwrap().get::<MatrixIdUri>() {
obj.show_matrix_uri(uri);
} else {
error!("Cannot show invalid Matrix URI");
}
},
);
}
fn instance_init(obj: &InitializingObject<Self>) {
@ -397,4 +409,18 @@ impl SessionView {
notifications.withdraw_identity_verification(&verification.key());
}
}
/// Show the given `MatrixIdUri`.
pub fn show_matrix_uri(&self, uri: MatrixIdUri) {
match uri {
MatrixIdUri::Room(room_uri) | MatrixIdUri::Event(MatrixEventIdUri { room_uri, .. }) => {
if !self.select_room_if_exists(&room_uri.id) {
self.show_join_room_dialog(Some(room_uri));
}
}
MatrixIdUri::User(user_id) => {
self.show_user_profile_dialog(user_id);
}
}
}
}

15
src/utils/matrix.rs

@ -1,7 +1,8 @@
//! Collection of methods related to the Matrix specification.
use std::str::FromStr;
use std::{borrow::Cow, str::FromStr};
use gtk::{glib, prelude::*};
use matrix_sdk::{
config::RequestConfig,
deserialized_responses::RawAnySyncOrStrippedTimelineEvent,
@ -623,6 +624,18 @@ impl TryFrom<AnchorUri> for MatrixIdUri {
}
}
impl StaticVariantType for MatrixIdUri {
fn static_variant_type() -> Cow<'static, glib::VariantTy> {
String::static_variant_type()
}
}
impl FromVariant for MatrixIdUri {
fn from_variant(variant: &glib::Variant) -> Option<Self> {
Self::parse(&variant.get::<String>()?).ok()
}
}
/// A URI for a Matrix room ID.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MatrixRoomIdUri {

Loading…
Cancel
Save