diff --git a/data/resources/ui/window.ui b/data/resources/ui/window.ui index 7cdee88ef8c29b125388ae48d638dc28227337a8..c1696d38b769e83692d8644cf1e9c82812ac7575 100644 --- a/data/resources/ui/window.ui +++ b/data/resources/ui/window.ui @@ -26,34 +26,6 @@ crossfade - - - - - vertical - - - True - - - - - - True - center - center - True - - - - - - - diff --git a/src/components/auth_dialog.rs b/src/components/auth_dialog.rs index 4206786282ab3fda73d688f428ab0360ebae029c..00dbd0c6bfc2e5c7f027238a1e11b809e4ea9a02 100644 --- a/src/components/auth_dialog.rs +++ b/src/components/auth_dialog.rs @@ -73,15 +73,16 @@ impl AuthData { mod imp { use super::*; + use glib::object::WeakRef; use glib::subclass::{InitializingObject, Signal}; use glib::SignalHandlerId; - use once_cell::sync::Lazy; + use once_cell::sync::{Lazy, OnceCell}; use std::cell::RefCell; #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/org/gnome/FractalNext/components-auth-dialog.ui")] pub struct AuthDialog { - pub session: RefCell>, + pub session: OnceCell>, #[template_child] pub stack: TemplateChild, #[template_child] @@ -129,7 +130,7 @@ mod imp { "Session", "The session", Session::static_type(), - glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY, + glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY, )] }); @@ -138,13 +139,16 @@ mod imp { fn set_property( &self, - obj: &Self::Type, + _obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec, ) { match pspec.name() { - "session" => obj.set_session(value.get().unwrap()), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), _ => unimplemented!(), } } @@ -207,21 +211,9 @@ impl AuthDialog { .expect("Failed to create AuthDialog") } - pub fn session(&self) -> Option { + pub fn session(&self) -> Session { let priv_ = imp::AuthDialog::from_instance(self); - priv_.session.borrow().clone() - } - - pub fn set_session(&self, session: Option) { - let priv_ = imp::AuthDialog::from_instance(self); - - if self.session() == session { - return; - }; - - priv_.session.replace(session); - - self.notify("session"); + priv_.session.get().unwrap().upgrade().unwrap() } pub async fn authenticate< @@ -266,13 +258,7 @@ impl AuthDialog { "m.login.password" => { priv_.stack.set_visible_child_name("m.login.password"); if self.show_and_wait_for_response().await { - let user_id = self - .session() - .unwrap() - .user() - .unwrap() - .user_id() - .to_string(); + let user_id = self.session().user().unwrap().user_id().to_string(); let password = priv_.password.text().to_string(); let session = uiaa_info.session; @@ -291,7 +277,7 @@ impl AuthDialog { if let Some(session) = uiaa_info.session { priv_.stack.set_visible_child_name("fallback"); - let client = self.session()?.client().clone(); + let client = self.session().client().clone(); let (sender, receiver) = futures::channel::oneshot::channel(); RUNTIME.spawn(async move { sender.send(client.homeserver().await) }); let homeserver = receiver.await.unwrap(); diff --git a/src/login.rs b/src/login.rs index fa2accd7f1d3556c3a9713875ac4d57ea0093d19..f5a63c3bed6829070e6749b951a4b77f8843b7df 100644 --- a/src/login.rs +++ b/src/login.rs @@ -14,10 +14,12 @@ mod imp { use super::*; use glib::subclass::{InitializingObject, Signal}; use once_cell::sync::Lazy; + use std::cell::RefCell; #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/org/gnome/FractalNext/login.ui")] pub struct Login { + pub current_session: RefCell>, #[template_child] pub next_button: TemplateChild, #[template_child] @@ -135,6 +137,8 @@ impl Login { username, password, ); + + priv_.current_session.replace(Some(session)); } fn clean(&self) { @@ -163,7 +167,7 @@ impl Login { priv_.main_stack.set_sensitive(true); } - pub fn connect_new_session( + pub fn connect_new_session( &self, f: F, ) -> glib::SignalHandlerId { @@ -171,13 +175,19 @@ impl Login { let obj = values[0].get::().unwrap(); let session = values[1].get::().unwrap(); - f(&obj, &session); + f(&obj, session); None }) .unwrap() } + fn drop_session_reference(&self) { + let priv_ = imp::Login::from_instance(self); + + priv_.current_session.take(); + } + pub fn default_widget(&self) -> gtk::Widget { imp::Login::from_instance(self).next_button.get().upcast() } @@ -188,7 +198,7 @@ impl Login { priv_.back_to_session_button.set_visible(show); } - pub fn set_handler_for_prepared_session(&self, session: &Session) { + fn set_handler_for_prepared_session(&self, session: &Session) { session.connect_prepared(clone!(@weak self as login => move |session| { if let Some(error) = session.get_error() { let error_message = &imp::Login::from_instance(&login).error_message; @@ -202,6 +212,7 @@ impl Login { login.emit_by_name("new-session", &[&session]).unwrap(); login.clean(); } + login.drop_session_reference(); })); } } diff --git a/src/session/account_settings/devices_page/device.rs b/src/session/account_settings/devices_page/device.rs index 70862b3143191f3901edfc7302f0d12651c10f89..9c470b0f3efadd2f535a813fd5963e6f4b81fd40 100644 --- a/src/session/account_settings/devices_page/device.rs +++ b/src/session/account_settings/devices_page/device.rs @@ -15,14 +15,14 @@ use log::error; mod imp { use super::*; + use glib::object::WeakRef; use once_cell::sync::{Lazy, OnceCell}; - use std::cell::RefCell; #[derive(Debug, Default)] pub struct Device { pub device: OnceCell, pub crypto_device: OnceCell, - pub session: RefCell>, + pub session: OnceCell>, } #[glib::object_subclass] @@ -41,7 +41,7 @@ mod imp { "Session", "The session", Session::static_type(), - glib::ParamFlags::READWRITE, + glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY, ), glib::ParamSpec::new_string( "device-id", @@ -84,13 +84,16 @@ mod imp { fn set_property( &self, - obj: &Self::Type, + _obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec, ) { match pspec.name() { - "session" => obj.set_session(value.get().unwrap()), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), _ => unimplemented!(), } } @@ -116,33 +119,21 @@ glib::wrapper! { impl Device { pub fn new( - session: Option<&Session>, + session: &Session, device: MatrixDevice, crypto_device: Option, ) -> Self { let obj: Self = - glib::Object::new(&[("session", &session)]).expect("Failed to create Device"); + glib::Object::new(&[("session", session)]).expect("Failed to create Device"); obj.set_matrix_device(device, crypto_device); obj } - pub fn session(&self) -> Option { - let priv_ = imp::Device::from_instance(self); - priv_.session.borrow().clone() - } - - fn set_session(&self, session: Option) { + pub fn session(&self) -> Session { let priv_ = imp::Device::from_instance(self); - - if self.session() == session { - return; - }; - - priv_.session.replace(session); - - self.notify("session"); + priv_.session.get().unwrap().upgrade().unwrap() } fn set_matrix_device(&self, device: MatrixDevice, crypto_device: Option) { @@ -197,9 +188,7 @@ impl Device { /// /// Returns `true` for success pub async fn delete(&self, transient_for: Option<&impl IsA>) -> bool { - let session = self - .session() - .expect("Session needs to be set when removing a device"); + let session = self.session(); let client = session.client().clone(); let device_id = self.device_id().to_owned(); diff --git a/src/session/account_settings/devices_page/device_list.rs b/src/session/account_settings/devices_page/device_list.rs index 5ab1ddb78780525e24f6b497521697a05fc5293d..65396d8704ab9e5f7c02694d1ac94ddb83e24625 100644 --- a/src/session/account_settings/devices_page/device_list.rs +++ b/src/session/account_settings/devices_page/device_list.rs @@ -10,7 +10,8 @@ use crate::{session::Session, utils::do_async}; use super::{Device, DeviceItem}; mod imp { - use once_cell::sync::Lazy; + use glib::object::WeakRef; + use once_cell::sync::{Lazy, OnceCell}; use std::cell::{Cell, RefCell}; use super::*; @@ -18,7 +19,7 @@ mod imp { #[derive(Debug, Default)] pub struct DeviceList { pub list: RefCell>, - pub session: RefCell>, + pub session: OnceCell>, pub current_device: RefCell>, pub loading: Cell, } @@ -40,7 +41,7 @@ mod imp { "Session", "The session", Session::static_type(), - glib::ParamFlags::READWRITE, + glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY, ), glib::ParamSpec::new_object( "current-device", @@ -57,13 +58,16 @@ mod imp { fn set_property( &self, - obj: &Self::Type, + _obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec, ) { match pspec.name() { - "session" => obj.set_session(value.get().unwrap()), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), _ => unimplemented!(), } } @@ -105,23 +109,9 @@ impl DeviceList { glib::Object::new(&[("session", session)]).expect("Failed to create DeviceList") } - pub fn session(&self) -> Option { + pub fn session(&self) -> Session { let priv_ = imp::DeviceList::from_instance(self); - priv_.session.borrow().clone() - } - - fn set_session(&self, session: Option) { - let priv_ = imp::DeviceList::from_instance(self); - - if self.session() == session { - return; - }; - - priv_.session.replace(session); - - self.load_devices(); - - self.notify("session"); + priv_.session.get().unwrap().upgrade().unwrap() } fn set_loading(&self, loading: bool) { @@ -176,7 +166,6 @@ impl DeviceList { response: Result<(Option, Vec, CryptoDevices), Error>, ) { let session = self.session(); - let session = session.as_ref(); match response { Ok((current_device, devices, crypto_devices)) => { @@ -184,7 +173,7 @@ impl DeviceList { .into_iter() .map(|device| { let crypto_device = crypto_devices.get(&device.device_id); - DeviceItem::for_device(Device::new(session, device, crypto_device)) + DeviceItem::for_device(Device::new(&session, device, crypto_device)) }) .collect(); @@ -192,7 +181,7 @@ impl DeviceList { self.set_current_device(current_device.map(|device| { let crypto_device = crypto_devices.get(&device.device_id); - DeviceItem::for_device(Device::new(session, device, crypto_device)) + DeviceItem::for_device(Device::new(&session, device, crypto_device)) })); } Err(error) => { @@ -206,11 +195,7 @@ impl DeviceList { } pub fn load_devices(&self) { - let client = if let Some(session) = self.session() { - session.client().clone() - } else { - return; - }; + let client = self.session().client().clone(); self.set_loading(true); diff --git a/src/session/account_settings/devices_page/mod.rs b/src/session/account_settings/devices_page/mod.rs index cfb98eab08c446cb7f2aac3cea30888597e5ecb9..111774a2371848e5e7b9906625d9acb7c292371f 100644 --- a/src/session/account_settings/devices_page/mod.rs +++ b/src/session/account_settings/devices_page/mod.rs @@ -113,7 +113,7 @@ impl DevicesPage { } if let Some(ref user) = user { - let device_list = DeviceList::new(user.session()); + let device_list = DeviceList::new(&user.session()); priv_.other_sessions.bind_model( Some(&device_list), clone!(@weak device_list => @default-panic, move |item| { diff --git a/src/session/avatar.rs b/src/session/avatar.rs index 90f775b8a972155cb738e5a56d36219befebee1a..d7c62cccfb10b58a3edbe0e4bc5490001c8b3159 100644 --- a/src/session/avatar.rs +++ b/src/session/avatar.rs @@ -18,6 +18,7 @@ use crate::session::Session; mod imp { use super::*; + use glib::object::WeakRef; use once_cell::sync::{Lazy, OnceCell}; use std::cell::{Cell, RefCell}; @@ -27,7 +28,7 @@ mod imp { pub needed: Cell, pub url: RefCell>, pub display_name: RefCell>, - pub session: OnceCell, + pub session: OnceCell>, } #[glib::object_subclass] @@ -92,7 +93,10 @@ mod imp { match pspec.name() { "needed" => obj.set_needed(value.get().unwrap()), "url" => obj.set_url(value.get::>().unwrap().map(Into::into)), - "session" => self.session.set(value.get().unwrap()).unwrap(), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), "display-name" => { let _ = obj.set_display_name(value.get().unwrap()); } @@ -132,9 +136,9 @@ impl Avatar { .expect("Failed to create Avatar") } - fn session(&self) -> &Session { + fn session(&self) -> Session { let priv_ = imp::Avatar::from_instance(self); - priv_.session.get().unwrap() + priv_.session.get().unwrap().upgrade().unwrap() } pub fn image(&self) -> Option { diff --git a/src/session/content/explore/mod.rs b/src/session/content/explore/mod.rs index 01d190bbf2d813122caf0d8b41104856c55d0bde..a7de1fed8c7543a3a65313e46a885b964e51dc9f 100644 --- a/src/session/content/explore/mod.rs +++ b/src/session/content/explore/mod.rs @@ -16,6 +16,7 @@ use crate::utils::do_async; mod imp { use super::*; + use glib::object::WeakRef; use glib::subclass::InitializingObject; use once_cell::sync::Lazy; use std::cell::{Cell, RefCell}; @@ -24,7 +25,7 @@ mod imp { #[template(resource = "/org/gnome/FractalNext/content-explore.ui")] pub struct Explore { pub compact: Cell, - pub session: RefCell>, + pub session: RefCell>>, #[template_child] pub stack: TemplateChild, #[template_child] @@ -148,7 +149,11 @@ impl Explore { pub fn session(&self) -> Option { let priv_ = imp::Explore::from_instance(self); - priv_.session.borrow().to_owned() + priv_ + .session + .borrow() + .as_ref() + .and_then(|session| session.upgrade()) } pub fn init(&self) { @@ -189,7 +194,9 @@ impl Explore { priv_.public_room_list.replace(Some(public_room_list)); } - priv_.session.replace(session); + priv_ + .session + .replace(session.map(|session| session.downgrade())); self.notify("session"); } diff --git a/src/session/content/explore/public_room.rs b/src/session/content/explore/public_room.rs index ecf79425b8e218092d5a61ba1b2c38a669d3ebb0..baf747d1df0bb4790ed3bed90f48fd9289cb5934 100644 --- a/src/session/content/explore/public_room.rs +++ b/src/session/content/explore/public_room.rs @@ -5,13 +5,14 @@ use crate::session::{room::Room, Avatar, Session}; mod imp { use super::*; + use glib::object::WeakRef; use glib::signal::SignalHandlerId; use once_cell::sync::{Lazy, OnceCell}; use std::cell::{Cell, RefCell}; #[derive(Debug, Default)] pub struct PublicRoom { - pub session: OnceCell, + pub session: OnceCell>, pub matrix_public_room: OnceCell, pub avatar: OnceCell, pub room: OnceCell, @@ -72,7 +73,10 @@ mod imp { pspec: &glib::ParamSpec, ) { match pspec.name() { - "session" => self.session.set(value.get().unwrap()).unwrap(), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), _ => unimplemented!(), } } @@ -90,7 +94,7 @@ mod imp { fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - self.avatar.set(Avatar::new(obj.session(), None)).unwrap(); + self.avatar.set(Avatar::new(&obj.session(), None)).unwrap(); obj.session() .room_list() @@ -120,9 +124,9 @@ impl PublicRoom { glib::Object::new(&[("session", session)]).expect("Failed to create Room") } - pub fn session(&self) -> &Session { + pub fn session(&self) -> Session { let priv_ = imp::PublicRoom::from_instance(self); - priv_.session.get().unwrap() + priv_.session.get().unwrap().upgrade().unwrap() } pub fn avatar(&self) -> &Avatar { diff --git a/src/session/content/explore/public_room_list.rs b/src/session/content/explore/public_room_list.rs index e94243def17869eedd7e9df5c1f9d14fe003211a..7d530d1d63e5e69623f4a432cc8eaf03e5de1dd6 100644 --- a/src/session/content/explore/public_room_list.rs +++ b/src/session/content/explore/public_room_list.rs @@ -17,6 +17,7 @@ use matrix_sdk::ruma::{ use std::convert::TryFrom; mod imp { + use glib::object::WeakRef; use once_cell::sync::Lazy; use std::cell::{Cell, RefCell}; @@ -32,7 +33,7 @@ mod imp { pub loading: Cell, pub request_sent: Cell, pub total_room_count_estimate: Cell>, - pub session: RefCell>, + pub session: RefCell>>, } #[glib::object_subclass] @@ -83,15 +84,13 @@ mod imp { fn set_property( &self, - _obj: &Self::Type, + obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec, ) { match pspec.name() { - "session" => { - let _ = self.session.replace(value.get().unwrap()); - } + "session" => obj.set_session(value.get().unwrap()), _ => unimplemented!(), } } @@ -136,7 +135,24 @@ impl PublicRoomList { pub fn session(&self) -> Option { let priv_ = imp::PublicRoomList::from_instance(self); - priv_.session.borrow().to_owned() + priv_ + .session + .borrow() + .as_ref() + .and_then(|session| session.upgrade()) + } + + pub fn set_session(&self, session: Option) { + let priv_ = imp::PublicRoomList::from_instance(self); + + if session == self.session() { + return; + } + + priv_ + .session + .replace(session.map(|session| session.downgrade())); + self.notify("session"); } pub fn loading(&self) -> bool { diff --git a/src/session/content/mod.rs b/src/session/content/mod.rs index c1a0897473bfee76aca0cb4f70bb1a0c06576ac4..d07515ee1943d40fe9f49986ea408d29cc0cd578 100644 --- a/src/session/content/mod.rs +++ b/src/session/content/mod.rs @@ -28,6 +28,7 @@ use crate::session::Session; mod imp { use super::*; + use glib::object::WeakRef; use glib::{signal::SignalHandlerId, subclass::InitializingObject}; use once_cell::sync::Lazy; use std::cell::{Cell, RefCell}; @@ -36,7 +37,7 @@ mod imp { #[template(resource = "/org/gnome/FractalNext/content.ui")] pub struct Content { pub compact: Cell, - pub session: RefCell>, + pub session: RefCell>>, pub room: RefCell>, pub content_type: Cell, pub error_list: RefCell>, @@ -134,9 +135,7 @@ mod imp { let compact = value.get().unwrap(); self.compact.set(compact); } - "session" => { - let _ = self.session.replace(value.get().unwrap()); - } + "session" => obj.set_session(value.get().unwrap()), "room" => { let room = value.get().unwrap(); obj.set_room(room); @@ -177,7 +176,24 @@ impl Content { pub fn session(&self) -> Option { let priv_ = imp::Content::from_instance(self); - priv_.session.borrow().to_owned() + priv_ + .session + .borrow() + .as_ref() + .and_then(|session| session.upgrade()) + } + + pub fn set_session(&self, session: Option) { + let priv_ = imp::Content::from_instance(self); + + if session == self.session() { + return; + } + + priv_ + .session + .replace(session.map(|session| session.downgrade())); + self.notify("session"); } pub fn content_type(&self) -> ContentType { diff --git a/src/session/room/mod.rs b/src/session/room/mod.rs index 175f42ebd722561e3672e9b3d8acefd432c939ac..91f285f6c1ecc83e6f45a263a0ace0ccffb62a85 100644 --- a/src/session/room/mod.rs +++ b/src/session/room/mod.rs @@ -61,6 +61,7 @@ use crate::RUNTIME; mod imp { use super::*; + use glib::object::WeakRef; use glib::subclass::Signal; use once_cell::sync::{Lazy, OnceCell}; use std::cell::Cell; @@ -70,7 +71,7 @@ mod imp { pub struct Room { pub room_id: OnceCell, pub matrix_room: RefCell>, - pub session: OnceCell, + pub session: OnceCell>, pub name: RefCell>, pub avatar: OnceCell, pub category: Cell, @@ -189,7 +190,10 @@ mod imp { pspec: &glib::ParamSpec, ) { match pspec.name() { - "session" => self.session.set(value.get().unwrap()).unwrap(), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), "display-name" => { let room_name = value.get().unwrap(); obj.store_room_name(room_name) @@ -252,7 +256,7 @@ mod imp { obj.set_matrix_room(obj.session().client().get_room(obj.room_id()).unwrap()); self.timeline.set(Timeline::new(obj)).unwrap(); self.avatar - .set(Avatar::new(obj.session(), obj.matrix_room().avatar_url())) + .set(Avatar::new(&obj.session(), obj.matrix_room().avatar_url())) .unwrap(); obj.load_power_levels(); @@ -278,9 +282,9 @@ impl Room { .expect("Failed to create Room") } - pub fn session(&self) -> &Session { + pub fn session(&self) -> Session { let priv_ = imp::Room::from_instance(self); - priv_.session.get().unwrap() + priv_.session.get().unwrap().upgrade().unwrap() } pub fn room_id(&self) -> &RoomId { @@ -854,7 +858,8 @@ impl Room { /// Creates an expression that is true when the user is allowed the given action. pub fn new_allowed_expr(&self, room_action: RoomAction) -> gtk::Expression { - let user_id = self.session().user().unwrap().user_id(); + let session = self.session(); + let user_id = session.user().unwrap().user_id(); let member = self.member_by_id(user_id); self.power_levels().new_allowed_expr(&member, room_action) } diff --git a/src/session/room_creation/mod.rs b/src/session/room_creation/mod.rs index d1115d786c9ed5c19cec9dd53647bb168308c484..7ab1f4628f05f81c287d9e3d5f8c141cc0f8548e 100644 --- a/src/session/room_creation/mod.rs +++ b/src/session/room_creation/mod.rs @@ -30,13 +30,14 @@ const MAX_BYTES: usize = 255; mod imp { use super::*; + use glib::object::WeakRef; use glib::subclass::InitializingObject; use std::cell::RefCell; #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/org/gnome/FractalNext/room-creation.ui")] pub struct RoomCreation { - pub session: RefCell>, + pub session: RefCell>>, #[template_child] pub content: TemplateChild, #[template_child] @@ -171,7 +172,11 @@ impl RoomCreation { pub fn session(&self) -> Option { let priv_ = imp::RoomCreation::from_instance(self); - priv_.session.borrow().clone() + priv_ + .session + .borrow() + .as_ref() + .and_then(|session| session.upgrade()) } fn set_session(&self, session: Option) { @@ -187,7 +192,9 @@ impl RoomCreation { .set_label(&[":", user.user_id().server_name().as_str()].concat()); } - priv_.session.replace(session); + priv_ + .session + .replace(session.map(|session| session.downgrade())); self.notify("session"); } diff --git a/src/session/room_list.rs b/src/session/room_list.rs index ae860808e70067f999ced321b25afc31a7e76a37..eae50a0ac68e5f6d50b819ab303a3dc2cd5a6eb8 100644 --- a/src/session/room_list.rs +++ b/src/session/room_list.rs @@ -16,6 +16,7 @@ use std::cell::Cell; use std::collections::HashSet; mod imp { + use glib::object::WeakRef; use glib::subclass::Signal; use once_cell::sync::{Lazy, OnceCell}; use std::cell::RefCell; @@ -26,7 +27,7 @@ mod imp { pub struct RoomList { pub list: RefCell>, pub pending_rooms: RefCell>, - pub session: OnceCell, + pub session: OnceCell>, } #[glib::object_subclass] @@ -60,7 +61,10 @@ mod imp { pspec: &glib::ParamSpec, ) { match pspec.name() { - "session" => self.session.set(value.get().unwrap()).unwrap(), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), _ => unimplemented!(), } } @@ -119,9 +123,9 @@ impl RoomList { glib::Object::new(&[("session", session)]).expect("Failed to create RoomList") } - pub fn session(&self) -> &Session { + pub fn session(&self) -> Session { let priv_ = imp::RoomList::from_instance(self); - priv_.session.get().unwrap() + priv_.session.get().unwrap().upgrade().unwrap() } pub fn is_pending_room(&self, identifier: &RoomIdOrAliasId) -> bool { @@ -244,7 +248,7 @@ impl RoomList { let mut list = priv_.list.borrow_mut(); for matrix_room in matrix_rooms { let room_id = matrix_room.room_id().to_owned(); - let room = Room::new(session, &room_id); + let room = Room::new(&session, &room_id); list.insert(room_id, room); } } @@ -266,7 +270,7 @@ impl RoomList { .entry(room_id.clone()) .or_insert_with(|| { added += 1; - Room::new(session, &room_id) + Room::new(&session, &room_id) }) .clone(); @@ -281,7 +285,7 @@ impl RoomList { .entry(room_id.clone()) .or_insert_with(|| { added += 1; - Room::new(session, &room_id) + Room::new(&session, &room_id) }) .clone(); @@ -296,7 +300,7 @@ impl RoomList { .entry(room_id.clone()) .or_insert_with(|| { added += 1; - Room::new(session, &room_id) + Room::new(&session, &room_id) }) .clone(); diff --git a/src/session/user.rs b/src/session/user.rs index 21c56b099b6400d1a4f500e95bae3a12fbc02a74..71e83bfab70f45b7a5da574c2759526876fc8a73 100644 --- a/src/session/user.rs +++ b/src/session/user.rs @@ -5,6 +5,7 @@ use crate::session::{Avatar, Session}; mod imp { use super::*; + use glib::object::WeakRef; use once_cell::sync::{Lazy, OnceCell}; use std::{cell::RefCell, convert::TryInto}; @@ -12,7 +13,7 @@ mod imp { pub struct User { pub user_id: OnceCell, pub display_name: RefCell>, - pub session: OnceCell, + pub session: OnceCell>, pub avatar: OnceCell, } @@ -73,7 +74,10 @@ mod imp { let user_id = value.get::<&str>().unwrap().try_into().unwrap(); self.user_id.set(user_id).unwrap(); } - "session" => self.session.set(value.get().unwrap()).unwrap(), + "session" => self + .session + .set(value.get::().unwrap().downgrade()) + .unwrap(), _ => unimplemented!(), } } @@ -91,7 +95,7 @@ mod imp { fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let avatar = Avatar::new(obj.session(), None); + let avatar = Avatar::new(&obj.session(), None); self.avatar.set(avatar).unwrap(); obj.bind_property("display-name", obj.avatar(), "display-name") @@ -115,9 +119,9 @@ impl User { } pub trait UserExt: IsA { - fn session(&self) -> &Session { + fn session(&self) -> Session { let priv_ = imp::User::from_instance(self.upcast_ref()); - priv_.session.get().unwrap() + priv_.session.get().unwrap().upgrade().unwrap() } fn user_id(&self) -> &UserId { diff --git a/src/window.rs b/src/window.rs index 513a8e5c4e9a50ada7f586bcca9aaaac17e76463..538698b276dc0f9e373df55a2c75150c1ec6894e 100644 --- a/src/window.rs +++ b/src/window.rs @@ -26,8 +26,6 @@ mod imp { #[template_child] pub sessions: TemplateChild, #[template_child] - pub loading_page: TemplateChild, - #[template_child] pub error_list: TemplateChild, } @@ -66,7 +64,7 @@ mod imp { self.login .connect_new_session(clone!(@weak obj => move |_login, session| { - obj.add_session(session); + obj.add_session(&session); obj.switch_to_sessions_page(); })); @@ -115,16 +113,11 @@ impl Window { fn restore_sessions(&self) { match secret::restore_sessions() { Ok(sessions) => { - let login = &imp::Window::from_instance(self).login.get(); - let n = sessions.len(); for stored_session in sessions { let session = Session::new(); - login.set_handler_for_prepared_session(&session); session.login_with_previous_session(stored_session); - } - - if n > 0 { - self.switch_to_loading_page(); + self.add_session(&session); + self.switch_to_sessions_page(); } } Err(error) => warn!("Failed to restore previous sessions: {:?}", error), @@ -171,13 +164,6 @@ impl Window { priv_.main_stack.set_visible_child(&priv_.sessions.get()); } - pub fn switch_to_loading_page(&self) { - let priv_ = imp::Window::from_instance(self); - priv_ - .main_stack - .set_visible_child(&priv_.loading_page.get()); - } - pub fn switch_to_login_page(&self) { let priv_ = imp::Window::from_instance(self); priv_