[fractal/fractal-next] session-verification: Make sure the request is restarted on error
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/fractal-next] session-verification: Make sure the request is restarted on error
- Date: Tue, 28 Dec 2021 19:27:59 +0000 (UTC)
commit acc3888257d690eabbeb12209ec24f64e3e93550
Author: Julian Sparber <julian sparber net>
Date: Tue Dec 28 18:29:36 2021 +0100
session-verification: Make sure the request is restarted on error
This also makes sure that the request is cancelled when the user goes
back to the login page.
.../content/verification/session_verification.rs | 96 +++++++++-------------
src/session/mod.rs | 47 ++++++++---
2 files changed, 74 insertions(+), 69 deletions(-)
---
diff --git a/src/session/content/verification/session_verification.rs
b/src/session/content/verification/session_verification.rs
index 0e3a6571..cd1f8750 100644
--- a/src/session/content/verification/session_verification.rs
+++ b/src/session/content/verification/session_verification.rs
@@ -10,7 +10,6 @@ use crate::contrib::QRCode;
use crate::contrib::QRCodeExt;
use crate::contrib::QrCodeScanner;
use crate::session::verification::{IdentityVerification, SasData, VerificationMode};
-use crate::session::Session;
use crate::spawn;
use crate::Error;
use crate::Window;
@@ -18,17 +17,14 @@ use matrix_sdk::encryption::verification::QrVerificationData;
mod imp {
use super::*;
- use glib::object::WeakRef;
use glib::subclass::InitializingObject;
use glib::SignalHandlerId;
- use once_cell::unsync::OnceCell;
use std::cell::RefCell;
#[derive(Debug, Default, CompositeTemplate)]
#[template(resource = "/org/gnome/FractalNext/session-verification.ui")]
pub struct SessionVerification {
- pub request: OnceCell<IdentityVerification>,
- pub session: OnceCell<WeakRef<Session>>,
+ pub request: RefCell<Option<IdentityVerification>>,
#[template_child]
pub bootstrap_button: TemplateChild<SpinnerButton>,
#[template_child]
@@ -88,22 +84,15 @@ mod imp {
fn properties() -> &'static [glib::ParamSpec] {
use once_cell::sync::Lazy;
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
- vec![
- glib::ParamSpec::new_object(
- "request",
- "Request",
- "The Object holding the data for the verification",
- IdentityVerification::static_type(),
- glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY,
- ),
- glib::ParamSpec::new_object(
- "session",
- "Session",
- "The current Session",
- Session::static_type(),
- glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY,
- ),
- ]
+ vec![glib::ParamSpec::new_object(
+ "request",
+ "Request",
+ "The Object holding the data for the verification",
+ IdentityVerification::static_type(),
+ glib::ParamFlags::READWRITE
+ | glib::ParamFlags::CONSTRUCT
+ | glib::ParamFlags::EXPLICIT_NOTIFY,
+ )]
});
PROPERTIES.as_ref()
@@ -118,7 +107,6 @@ mod imp {
) {
match pspec.name() {
"request" => obj.set_request(value.get().unwrap()),
- "session" => obj.set_session(value.get().unwrap()),
_ => unimplemented!(),
}
}
@@ -126,7 +114,6 @@ mod imp {
fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() {
"request" => obj.request().to_value(),
- "session" => obj.session().to_value(),
_ => unimplemented!(),
}
}
@@ -211,31 +198,40 @@ glib::wrapper! {
}
impl SessionVerification {
- pub fn new(request: &IdentityVerification, session: &Session) -> Self {
- glib::Object::new(&[("request", request), ("session", session)])
- .expect("Failed to create SessionVerification")
+ pub fn new(request: &IdentityVerification) -> Self {
+ glib::Object::new(&[("request", request)]).expect("Failed to create SessionVerification")
}
- pub fn request(&self) -> &IdentityVerification {
+ pub fn request(&self) -> IdentityVerification {
let priv_ = imp::SessionVerification::from_instance(self);
- priv_.request.get().unwrap()
+ priv_.request.borrow().clone().unwrap()
}
- fn set_request(&self, request: IdentityVerification) {
+ pub fn set_request(&self, request: IdentityVerification) {
let priv_ = imp::SessionVerification::from_instance(self);
- priv_.request.set(request).unwrap();
- }
+ if let Some(old_request) = &*priv_.request.borrow() {
+ if old_request == &request {
+ return;
+ }
- pub fn session(&self) -> Session {
- let priv_ = imp::SessionVerification::from_instance(self);
- priv_.session.get().unwrap().upgrade().unwrap()
- }
+ self.reset();
- fn set_session(&self, session: Session) {
- let priv_ = imp::SessionVerification::from_instance(self);
+ if let Some(handler) = priv_.mode_handler.take() {
+ old_request.disconnect(handler);
+ }
+ }
+
+ let handler = request.connect_notify_local(
+ Some("mode"),
+ clone!(@weak self as obj => move |_, _| {
+ obj.update_view();
+ }),
+ );
+
+ priv_.mode_handler.replace(Some(handler));
- priv_.session.set(session.downgrade()).unwrap()
+ priv_.request.replace(Some(request));
}
/// Returns the parent GtkWindow containing this widget.
@@ -245,6 +241,7 @@ impl SessionVerification {
fn reset(&self) {
let priv_ = imp::SessionVerification::from_instance(self);
+
priv_.emoji_not_match_btn.set_loading(false);
priv_.emoji_not_match_btn.set_sensitive(true);
priv_.emoji_match_btn.set_loading(false);
@@ -268,22 +265,6 @@ impl SessionVerification {
}
}
- pub fn start_verification(&self) {
- let priv_ = imp::SessionVerification::from_instance(self);
- let request = self.request();
-
- self.reset();
-
- let handler = request.connect_notify_local(
- Some("mode"),
- clone!(@weak self as obj => move |_, _| {
- obj.update_view();
- }),
- );
-
- priv_.mode_handler.replace(Some(handler));
- }
-
/// Cancel the verification request without telling the user about it
fn silent_cancel(&self) {
let priv_ = imp::SessionVerification::from_instance(self);
@@ -397,7 +378,6 @@ impl SessionVerification {
match priv_.main_stack.visible_child_name().unwrap().as_str() {
"recovery" => {
self.silent_cancel();
- self.start_verification();
}
"recovery-passphrase" | "recovery-key" => {
priv_.main_stack.set_visible_child_name("recovery");
@@ -408,7 +388,6 @@ impl SessionVerification {
}
"emoji" | "qrcode" | "scan-qr-code" | "no-camera" => {
self.silent_cancel();
- self.start_verification();
}
_ => {}
}
@@ -417,7 +396,7 @@ impl SessionVerification {
fn bootstrap_cross_signing(&self) {
spawn!(clone!(@weak self as obj => async move {
let priv_ = imp::SessionVerification::from_instance(&obj);
- let dialog = AuthDialog::new(obj.parent_window().as_ref(), &obj.session());
+ let dialog = AuthDialog::new(obj.parent_window().as_ref(), &obj.request().session());
let result = dialog
.authenticate(move |client, auth_data| async move {
@@ -452,12 +431,11 @@ impl SessionVerification {
Some(error_label.upcast())
});
- if let Some(window) = obj.session().parent_window() {
+ if let Some(window) = obj.parent_window() {
window.append_error(&error);
}
obj.silent_cancel();
- obj.start_verification();
} else {
priv_
.main_stack
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 6662d464..01617097 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -20,7 +20,7 @@ pub use self::room_creation::RoomCreation;
use self::room_list::RoomList;
use self::sidebar::Sidebar;
pub use self::user::{User, UserExt};
-use self::verification::{IdentityVerification, VerificationList};
+use self::verification::{IdentityVerification, VerificationList, VerificationMode};
use crate::session::sidebar::ItemList;
use crate::secret;
@@ -484,6 +484,36 @@ impl Session {
priv_.sync_tokio_handle.replace(Some(handle));
}
+ async fn create_session_verification(&self) {
+ let priv_ = imp::Session::from_instance(self);
+
+ let request = IdentityVerification::create(&self, self.user().unwrap()).await;
+
+ if let Some(widget) = priv_.stack.child_by_name("session-verification") {
+ widget
+ .downcast::<SessionVerification>()
+ .unwrap()
+ .set_request(request.clone());
+ } else {
+ let widget = SessionVerification::new(&request);
+ priv_.stack.add_named(&widget, Some("session-verification"));
+ priv_.stack.set_visible_child(&widget);
+ }
+
+ request.connect_notify_local(
+ Some("mode"),
+ clone!(@weak self as obj => move |request, _| {
+ if request.is_finished() && request.mode() != VerificationMode::Completed {
+ spawn!(async move {
+ obj.create_session_verification().await;
+ });
+ }
+ }),
+ );
+
+ self.verification_list().add(request);
+ }
+
fn mark_ready(&self) {
let priv_ = imp::Session::from_instance(self);
let client = self.client();
@@ -523,15 +553,7 @@ impl Session {
}
priv_.logout_on_dispose.set(true);
-
- let verification = IdentityVerification::create(&obj, obj.user().unwrap()).await;
- let session = SessionVerification::new(&verification, &obj);
- obj.verification_list().add(verification);
- priv_
- .stack
- .add_named(&session, Some("session-verification"));
- priv_.stack.set_visible_child(&session);
- session.start_verification();
+ obj.create_session_verification().await;
return;
}
@@ -694,6 +716,11 @@ impl Session {
// First stop the verification in progress
if let Some(session_verificiation) = priv_.stack.child_by_name("session-verification") {
priv_.stack.remove(&session_verificiation);
+ session_verificiation
+ .downcast_ref::<SessionVerification>()
+ .unwrap()
+ .request()
+ .cancel();
}
let client = self.client();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]