session: Create JoinRoomDialog instead of building it in Session
This commit is contained in:
parent
686de7b5b6
commit
3541be94eb
4 changed files with 196 additions and 64 deletions
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="AdwMessageDialog" id="dialog">
|
||||
<template class="JoinRoomDialog" parent="AdwMessageDialog">
|
||||
<property name="heading" translatable="yes">Join a Room</property>
|
||||
<property name="body" translatable="yes">Enter a room ID, room alias, or permalink.</property>
|
||||
<property name="default-response">join</property>
|
||||
|
@ -12,7 +12,8 @@
|
|||
<property name="extra-child">
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="activates-default">True</property>
|
||||
<signal name="changed" handler="entry_changed" swapped="yes"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</template>
|
||||
</interface>
|
||||
|
|
|
@ -85,6 +85,7 @@ src/session/content/room_history/typing_row.rs
|
|||
src/session/content/room_history/verification_info_bar.rs
|
||||
src/session/content/verification/identity_verification_widget.rs
|
||||
src/session/content/verification/session_verification.rs
|
||||
src/session/join_room_dialog.rs
|
||||
src/session/mod.rs
|
||||
src/session/room/event/event_actions.rs
|
||||
src/session/room/member.rs
|
||||
|
|
187
src/session/join_room_dialog.rs
Normal file
187
src/session/join_room_dialog.rs
Normal file
|
@ -0,0 +1,187 @@
|
|||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gettextrs::gettext;
|
||||
use gtk::{gdk, glib, CompositeTemplate};
|
||||
use ruma::{
|
||||
matrix_uri::MatrixId, MatrixToUri, MatrixUri, OwnedRoomOrAliasId, OwnedServerName,
|
||||
RoomOrAliasId,
|
||||
};
|
||||
|
||||
use crate::session::Session;
|
||||
|
||||
mod imp {
|
||||
use glib::{object::WeakRef, subclass::InitializingObject};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, CompositeTemplate)]
|
||||
#[template(resource = "/org/gnome/Fractal/join-room-dialog.ui")]
|
||||
pub struct JoinRoomDialog {
|
||||
pub session: WeakRef<Session>,
|
||||
#[template_child]
|
||||
pub entry: TemplateChild<gtk::Entry>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for JoinRoomDialog {
|
||||
const NAME: &'static str = "JoinRoomDialog";
|
||||
type Type = super::JoinRoomDialog;
|
||||
type ParentType = adw::MessageDialog;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
Self::bind_template(klass);
|
||||
Self::Type::bind_template_callbacks(klass);
|
||||
|
||||
klass.add_binding(
|
||||
gdk::Key::Escape,
|
||||
gdk::ModifierType::empty(),
|
||||
|obj, _| {
|
||||
obj.close();
|
||||
true
|
||||
},
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for JoinRoomDialog {
|
||||
fn properties() -> &'static [glib::ParamSpec] {
|
||||
use once_cell::sync::Lazy;
|
||||
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
|
||||
vec![glib::ParamSpecObject::builder::<Session>("session")
|
||||
.explicit_notify()
|
||||
.build()]
|
||||
});
|
||||
|
||||
PROPERTIES.as_ref()
|
||||
}
|
||||
|
||||
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||
match pspec.name() {
|
||||
"session" => self.obj().set_session(value.get().unwrap()),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||
match pspec.name() {
|
||||
"session" => self.obj().session().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for JoinRoomDialog {}
|
||||
impl WindowImpl for JoinRoomDialog {}
|
||||
|
||||
impl MessageDialogImpl for JoinRoomDialog {
|
||||
fn response(&self, response: &str) {
|
||||
self.obj().join_room();
|
||||
|
||||
self.parent_response(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
/// Dialog to join a room.
|
||||
pub struct JoinRoomDialog(ObjectSubclass<imp::JoinRoomDialog>)
|
||||
@extends gtk::Widget, gtk::Window, adw::MessageDialog, @implements gtk::Accessible;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl JoinRoomDialog {
|
||||
pub fn new(parent_window: Option<&impl IsA<gtk::Window>>, session: &Session) -> Self {
|
||||
glib::Object::builder()
|
||||
.property("transient-for", parent_window)
|
||||
.property("session", session)
|
||||
.build()
|
||||
}
|
||||
|
||||
/// The current session.
|
||||
pub fn session(&self) -> Option<Session> {
|
||||
self.imp().session.upgrade()
|
||||
}
|
||||
|
||||
/// Set the current session.
|
||||
pub fn set_session(&self, session: Option<&Session>) {
|
||||
let imp = self.imp();
|
||||
|
||||
if self.session().as_ref() == session {
|
||||
return;
|
||||
}
|
||||
|
||||
imp.session.set(session);
|
||||
self.notify("session");
|
||||
}
|
||||
|
||||
/// Handle when the entry text changed.
|
||||
#[template_callback]
|
||||
fn entry_changed(&self, entry: >k::Entry) {
|
||||
let Some(session) = self.session() else {
|
||||
self.set_response_enabled("join", false);
|
||||
return;
|
||||
};
|
||||
|
||||
let Some((room_id, _)) = parse_room(&entry.text()) else {
|
||||
self.set_response_enabled("join", false);
|
||||
return;
|
||||
};
|
||||
|
||||
self.set_response_enabled("join", true);
|
||||
|
||||
if session.room_list().find_joined_room(&room_id).is_some() {
|
||||
self.set_response_label("join", &gettext("_View"));
|
||||
} else {
|
||||
self.set_response_label("join", &gettext("_Join"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Join the room that was entered, if it is valid.
|
||||
fn join_room(&self) {
|
||||
let Some(session) = self.session() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some((room_id, via)) = parse_room(&self.imp().entry.text()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(room) = session.room_list().find_joined_room(&room_id) {
|
||||
session.select_room(Some(room));
|
||||
} else {
|
||||
session.room_list().join_by_id_or_alias(room_id, via)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_room(room: &str) -> Option<(OwnedRoomOrAliasId, Vec<OwnedServerName>)> {
|
||||
MatrixUri::parse(room)
|
||||
.ok()
|
||||
.and_then(|uri| match uri.id() {
|
||||
MatrixId::Room(room_id) => Some((room_id.clone().into(), uri.via().to_owned())),
|
||||
MatrixId::RoomAlias(room_alias) => {
|
||||
Some((room_alias.clone().into(), uri.via().to_owned()))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.or_else(|| {
|
||||
MatrixToUri::parse(room)
|
||||
.ok()
|
||||
.and_then(|uri| match uri.id() {
|
||||
MatrixId::Room(room_id) => Some((room_id.clone().into(), uri.via().to_owned())),
|
||||
MatrixId::RoomAlias(room_alias) => {
|
||||
Some((room_alias.clone().into(), uri.via().to_owned()))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
.or_else(|| {
|
||||
RoomOrAliasId::parse(room)
|
||||
.ok()
|
||||
.map(|room_id| (room_id, vec![]))
|
||||
})
|
||||
}
|
|
@ -2,6 +2,7 @@ mod account_settings;
|
|||
mod avatar;
|
||||
mod content;
|
||||
mod event_source_dialog;
|
||||
mod join_room_dialog;
|
||||
mod media_viewer;
|
||||
pub mod room;
|
||||
mod room_creation;
|
||||
|
@ -36,9 +37,7 @@ use matrix_sdk::{
|
|||
direct::DirectEventContent, room::encryption::SyncRoomEncryptionEvent,
|
||||
GlobalAccountDataEvent,
|
||||
},
|
||||
matrix_uri::MatrixId,
|
||||
MatrixToUri, MatrixUri, OwnedEventId, OwnedRoomId, OwnedRoomOrAliasId, OwnedServerName,
|
||||
RoomId, RoomOrAliasId,
|
||||
OwnedEventId, OwnedRoomId, RoomId,
|
||||
},
|
||||
sync::SyncResponse,
|
||||
Client,
|
||||
|
@ -49,6 +48,7 @@ use tokio::task::JoinHandle;
|
|||
use self::{
|
||||
account_settings::AccountSettings,
|
||||
content::{verification::SessionVerification, Content},
|
||||
join_room_dialog::JoinRoomDialog,
|
||||
media_viewer::MediaViewer,
|
||||
room_list::RoomList,
|
||||
sidebar::Sidebar,
|
||||
|
@ -684,37 +684,8 @@ impl Session {
|
|||
}
|
||||
|
||||
async fn show_join_room_dialog(&self) {
|
||||
let builder = gtk::Builder::from_resource("/org/gnome/Fractal/join-room-dialog.ui");
|
||||
let dialog = builder.object::<adw::MessageDialog>("dialog").unwrap();
|
||||
let entry = builder.object::<gtk::Entry>("entry").unwrap();
|
||||
|
||||
entry.connect_changed(clone!(@weak self as obj, @weak dialog => move |entry| {
|
||||
let room = parse_room(&entry.text());
|
||||
dialog.set_response_enabled("join", room.is_some());
|
||||
|
||||
if room
|
||||
.and_then(|(room_id, _)| obj.room_list().find_joined_room(&room_id))
|
||||
.is_some()
|
||||
{
|
||||
dialog.set_response_label("join", &gettext("_View"));
|
||||
} else {
|
||||
dialog.set_response_label("join", &gettext("_Join"));
|
||||
}
|
||||
}));
|
||||
|
||||
dialog.set_transient_for(self.parent_window().as_ref());
|
||||
if dialog.choose_future().await == "join" {
|
||||
let (room_id, via) = match parse_room(&entry.text()) {
|
||||
Some(room) => room,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if let Some(room) = self.room_list().find_joined_room(&room_id) {
|
||||
self.select_room(Some(room));
|
||||
} else {
|
||||
self.room_list().join_by_id_or_alias(room_id, via)
|
||||
}
|
||||
}
|
||||
let dialog = JoinRoomDialog::new(self.parent_window().as_ref(), self);
|
||||
dialog.present();
|
||||
}
|
||||
|
||||
pub async fn logout(&self) {
|
||||
|
@ -1004,34 +975,6 @@ impl Session {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_room(room: &str) -> Option<(OwnedRoomOrAliasId, Vec<OwnedServerName>)> {
|
||||
MatrixUri::parse(room)
|
||||
.ok()
|
||||
.and_then(|uri| match uri.id() {
|
||||
MatrixId::Room(room_id) => Some((room_id.clone().into(), uri.via().to_owned())),
|
||||
MatrixId::RoomAlias(room_alias) => {
|
||||
Some((room_alias.clone().into(), uri.via().to_owned()))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.or_else(|| {
|
||||
MatrixToUri::parse(room)
|
||||
.ok()
|
||||
.and_then(|uri| match uri.id() {
|
||||
MatrixId::Room(room_id) => Some((room_id.clone().into(), uri.via().to_owned())),
|
||||
MatrixId::RoomAlias(room_alias) => {
|
||||
Some((room_alias.clone().into(), uri.via().to_owned()))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
.or_else(|| {
|
||||
RoomOrAliasId::parse(room)
|
||||
.ok()
|
||||
.map(|room_id| (room_id, vec![]))
|
||||
})
|
||||
}
|
||||
|
||||
fn notification_id(session_id: &str, room_id: &RoomId, event_id: &EventId) -> String {
|
||||
format!("{session_id}:{room_id}:{event_id}")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue