[fractal/ui-refactor: 4/15] Deprecate get_op()




commit e7f55935a89ff575372bc0e38d9738a7f791c750
Author: Alejandro Domínguez <adomu net-c com>
Date:   Mon Oct 12 08:13:38 2020 +0200

    Deprecate get_op()

 fractal-gtk/src/actions/global.rs              |  54 +++----
 fractal-gtk/src/actions/message.rs             | 189 ++++++++++++++-----------
 fractal-gtk/src/app/connect/account.rs         |  20 ++-
 fractal-gtk/src/app/connect/direct.rs          |  14 +-
 fractal-gtk/src/app/connect/directory.rs       |   9 +-
 fractal-gtk/src/app/connect/invite.rs          |  20 +--
 fractal-gtk/src/app/connect/join_room.rs       |   4 +-
 fractal-gtk/src/app/connect/leave_room.rs      |   2 +-
 fractal-gtk/src/app/connect/markdown.rs        |   9 +-
 fractal-gtk/src/app/connect/new_room.rs        |   4 +-
 fractal-gtk/src/app/connect/roomlist_search.rs |   6 +-
 fractal-gtk/src/app/connect/send.rs            |   4 +-
 fractal-gtk/src/app/mod.rs                     |  11 +-
 fractal-gtk/src/appop/account.rs               |   2 +
 fractal-gtk/src/appop/media_viewer.rs          |  15 +-
 fractal-gtk/src/appop/mod.rs                   |   5 +-
 fractal-gtk/src/appop/room.rs                  |   6 +-
 fractal-gtk/src/backend/user.rs                |   5 -
 18 files changed, 203 insertions(+), 176 deletions(-)
---
diff --git a/fractal-gtk/src/actions/global.rs b/fractal-gtk/src/actions/global.rs
index d1c4ed62..9f3f1a9a 100644
--- a/fractal-gtk/src/actions/global.rs
+++ b/fractal-gtk/src/actions/global.rs
@@ -4,7 +4,7 @@ use std::convert::TryInto;
 use std::rc::Rc;
 use std::sync::{Arc, Mutex};
 
-use crate::app;
+use crate::app::UpdateApp;
 use crate::appop::AppOp;
 use crate::model::message::Message;
 use crate::util::i18n::i18n;
@@ -65,7 +65,7 @@ impl From<AppState> for glib::Variant {
 
 /* This creates globale actions which are connected to the application */
 /* TODO: Remove op */
-pub fn new(app: &gtk::Application, op: &Arc<Mutex<AppOp>>) {
+pub fn new(app: &gtk::Application, app_tx: glib::Sender<UpdateApp>, op: &Arc<Mutex<AppOp>>) {
     let settings = SimpleAction::new("settings", None);
     let chat = SimpleAction::new("start_chat", None);
     let newr = SimpleAction::new("new_room", None);
@@ -267,7 +267,7 @@ pub fn new(app: &gtk::Application, op: &Arc<Mutex<AppOp>>) {
     media_viewer.connect_activate(clone!(
     @weak back_history as back
     => move |_, data| {
-        open_viewer(data);
+        open_viewer(&app_tx, data.cloned());
         back.borrow_mut().push(AppState::MediaViewer);
     }));
 
@@ -280,7 +280,7 @@ pub fn new(app: &gtk::Application, op: &Arc<Mutex<AppOp>>) {
 
     let mv = op.lock().unwrap().media_viewer.clone();
     let back_weak = Rc::downgrade(&back_history);
-    back.connect_activate(clone!(@weak mv => move |_, _| {
+    back.connect_activate(clone!(@weak mv, @strong op => move |_, _| {
         if let Some(mut mv) = mv.borrow_mut().take() {
             mv.disconnect_signal_id();
         }
@@ -288,14 +288,13 @@ pub fn new(app: &gtk::Application, op: &Arc<Mutex<AppOp>>) {
         // Remove the current state from the store
         if let Some(back) = back_weak.upgrade() {
             back.borrow_mut().pop();
+            let mut op = op.lock().unwrap();
             if let Some(state) = back.borrow().last() {
                 debug!("Go back to state {:?}", state);
-                let mut op = app::get_op().lock().unwrap();
                 op.set_state(*state);
             } else {
                 // Fallback when there is no back history
                 debug!("There is no state to go back to. Go back to state NoRoom");
-                let mut op = app::get_op().lock().unwrap();
                 if op.login_data.is_some() {
                     op.set_state(AppState::NoRoom);
                 }
@@ -378,28 +377,35 @@ pub fn get_event_id(data: Option<&glib::Variant>) -> Option<EventId> {
 }
 
 /* TODO: get message from storage once implemented */
-pub fn get_message_by_id(id: &EventId) -> Option<Message> {
-    let op = app::get_op().lock().unwrap();
+pub(super) fn get_message_by_id(op: &AppOp, id: &EventId) -> Option<Message> {
     let room_id = op.active_room.as_ref()?;
     op.get_message_by_id(room_id, id)
 }
 
-fn open_viewer(data: Option<&glib::Variant>) -> Option<()> {
-    let msg = get_event_id(data).as_ref().and_then(get_message_by_id)?;
-    let mut op = app::get_op().lock().unwrap();
-    op.create_media_viewer(msg);
-    None
+fn open_viewer(app_tx: &glib::Sender<UpdateApp>, data: Option<glib::Variant>) {
+    let _ = app_tx.send(Box::new(move |op| {
+        if let Some(msg) = get_event_id(data.as_ref())
+            .as_ref()
+            .and_then(|evid| get_message_by_id(op, evid))
+        {
+            op.create_media_viewer(msg);
+        }
+    }));
 }
 
-pub fn activate_action(action_group_name: &str, action_name: &str) {
-    let main_window = app::get_op()
-        .lock()
-        .unwrap()
-        .ui
-        .builder
-        .get_object::<gtk::Window>("main_window")
-        .expect("Can't find main_window in ui file.");
-    if let Some(action_group) = main_window.get_action_group(action_group_name) {
-        action_group.activate_action(action_name, None);
-    }
+pub fn activate_action(
+    app_tx: &glib::Sender<UpdateApp>,
+    action_group_name: &'static str,
+    action_name: &'static str,
+) {
+    let _ = app_tx.send(Box::new(move |op| {
+        let main_window = op
+            .ui
+            .builder
+            .get_object::<gtk::Window>("main_window")
+            .expect("Can't find main_window in ui file.");
+        if let Some(action_group) = main_window.get_action_group(action_group_name) {
+            action_group.activate_action(action_name, None);
+        }
+    }));
 }
diff --git a/fractal-gtk/src/actions/message.rs b/fractal-gtk/src/actions/message.rs
index f608f8ba..319f4d22 100644
--- a/fractal-gtk/src/actions/message.rs
+++ b/fractal-gtk/src/actions/message.rs
@@ -2,14 +2,14 @@ use crate::backend::{dw_media, media, room, ContentType};
 use glib::clone;
 use log::error;
 use matrix_sdk::identifiers::RoomId;
-use matrix_sdk::Client as MatrixClient;
 use std::cell::RefCell;
 use std::fs;
 use std::process::Command;
 use std::rc::Rc;
 
 use crate::actions::AppState;
-use crate::app::{self, RUNTIME};
+use crate::app::{UpdateApp, RUNTIME};
+use crate::appop::AppOp;
 use crate::backend::HandleError;
 use crate::model::message::Message;
 use crate::uibuilder::UI;
@@ -28,7 +28,7 @@ use crate::widgets::SourceDialog;
 
 /* This creates all actions the room history can perform */
 pub fn new(
-    session_client: MatrixClient,
+    app_tx: glib::Sender<UpdateApp>,
     ui: UI,
     back_history: Rc<RefCell<Vec<AppState>>>,
 ) -> gio::SimpleActionGroup {
@@ -59,15 +59,18 @@ pub fn new(
         .builder
         .get_object("main_window")
         .expect("Can't find main_window in ui file.");
-    show_source.connect_activate(clone!(@weak parent => move |_, data| {
+    show_source.connect_activate(clone!(@weak parent, @strong app_tx => move |_, data| {
         let viewer = SourceDialog::new();
         viewer.set_parent_window(&parent);
-        if let Some(m) = get_message(data) {
-            let error = i18n("This message has no source.");
-            let source = m.source.as_ref().unwrap_or(&error);
+        let data = data.cloned();
+        let _ = app_tx.send(Box::new(move |op| {
+            if let Some(m) = get_message(op, data.as_ref()) {
+                let error = i18n("This message has no source.");
+                let source = m.source.as_ref().unwrap_or(&error);
 
-            viewer.show(source);
-        }
+                viewer.show(source);
+            }
+        }));
     }));
 
     let window = ui
@@ -77,7 +80,8 @@ pub fn new(
     reply.connect_activate(clone!(
     @weak back_history,
     @weak window,
-    @weak ui.sventry.view as msg_entry
+    @weak ui.sventry.view as msg_entry,
+    @strong app_tx
     => move |_, data| {
         let state = back_history.borrow().last().cloned();
         if let Some(AppState::MediaViewer) = state {
@@ -89,24 +93,30 @@ pub fn new(
         }
         if let Some(buffer) = msg_entry.get_buffer() {
             let mut start = buffer.get_start_iter();
-            if let Some(m) = get_message(data) {
-                let quote = m
-                    .body
-                    .lines()
-                    .map(|l| "> ".to_owned() + l)
-                    .collect::<Vec<String>>()
-                    .join("\n")
-                    + "\n"
-                    + "\n";
-                buffer.insert(&mut start, &quote);
-                msg_entry.grab_focus();
-            }
+            let data = data.cloned();
+            let _ = app_tx.send(Box::new(move |op| {
+                if let Some(m) = get_message(op, data.as_ref()) {
+                    let quote = m
+                        .body
+                        .lines()
+                        .map(|l| "> ".to_owned() + l)
+                        .collect::<Vec<String>>()
+                        .join("\n")
+                        + "\n"
+                        + "\n";
+                    buffer.insert(&mut start, &quote);
+                    msg_entry.grab_focus();
+                }
+            }));
         }
     }));
 
-    open_with.connect_activate(clone!(@strong session_client => move |_, data| {
-        if let Some(url) = get_message(data).and_then(|m| m.url) {
-            let session_client = session_client.clone();
+    open_with.connect_activate(clone!(@strong app_tx => move |_, data| {
+        let data = data.cloned();
+        let _ = app_tx.send(Box::new(move |op| {
+            let url = unwrap_or_unit_return!(get_message(op, data.as_ref()).and_then(|m| m.url));
+            let session_client =
+                unwrap_or_unit_return!(op.login_data.as_ref().map(|ld| ld.session_client.clone()));
             RUNTIME.spawn(async move {
                 match dw_media(session_client, &url, ContentType::Download, None).await {
                     Ok(fname) => {
@@ -115,52 +125,57 @@ pub fn new(
                             .spawn()
                             .expect("failed to execute process");
                     }
-                    Err(err) => {
-                        err.handle_error()
-                    }
+                    Err(err) => err.handle_error(),
                 }
             });
-        }
+        }));
     }));
 
-    save_as.connect_activate(clone!(
-    @strong session_client,
-    @weak parent as window
-    => move |_, data| {
-        if let Some((Some(url), name)) = get_message(data).map(|m| (m.url, m.body)) {
-            let session_client = session_client.clone();
-            let response = RUNTIME.spawn(async move {
-                media::get_media(session_client, &url).await
-            });
+    save_as.connect_activate(
+        clone!(@weak parent as window, @strong app_tx => move |_, data| {
+            let data = data.cloned();
+            let _ = app_tx.send(Box::new(move |op| {
+                let (url, name) = unwrap_or_unit_return!(
+                    get_message(op, data.as_ref()).and_then(|m| Some((m.url?, m.body)))
+                );
+                let session_client = unwrap_or_unit_return!(
+                    op.login_data.as_ref().map(|ld| ld.session_client.clone())
+                );
+                let response = RUNTIME.spawn(async move {
+                    media::get_media(session_client, &url).await
+                });
 
-            glib::MainContext::default().spawn_local(async move {
-                match response.await {
-                    Err(_) => {
-                        let msg = i18n("Could not download the file");
-                        ErrorDialog::new(false, &msg);
-                    },
-                    Ok(Ok(fname)) => {
-                        if let Some(path) = save(&window.upcast_ref(), &name, &[]) {
-                            // TODO use glib to copy file
-                            if fs::copy(fname, path).is_err() {
-                                ErrorDialog::new(false, &i18n("Couldn’t save file"));
+                glib::MainContext::default().spawn_local(async move {
+                    match response.await {
+                        Err(_) => {
+                            let msg = i18n("Could not download the file");
+                            ErrorDialog::new(false, &msg);
+                        },
+                        Ok(Ok(fname)) => {
+                            if let Some(path) = save(&window.upcast_ref(), &name, &[]) {
+                                // TODO use glib to copy file
+                                if fs::copy(fname, path).is_err() {
+                                    ErrorDialog::new(false, &i18n("Couldn’t save file"));
+                                }
                             }
                         }
+                        Ok(Err(err)) => {
+                            error!("Media path could not be found due to error: {:?}", err);
+                        }
                     }
-                    Ok(Err(err)) => {
-                        error!("Media path could not be found due to error: {:?}", err);
-                    }
-                }
-            });
-        }
-    }));
+                });
+            }));
+        }),
+    );
 
-    copy_image.connect_activate(clone!(@strong session_client => move |_, data| {
-        if let Some(url) = get_message(data).and_then(|m| m.url) {
-            let session_client = session_client.clone();
-            let response = RUNTIME.spawn(async move {
-                media::get_media(session_client, &url).await
-            });
+    copy_image.connect_activate(clone!(@strong app_tx => move |_, data| {
+        let data = data.cloned();
+        let _ = app_tx.send(Box::new(move |op| {
+            let url = unwrap_or_unit_return!(get_message(op, data.as_ref()).and_then(|m| m.url));
+            let session_client =
+                unwrap_or_unit_return!(op.login_data.as_ref().map(|ld| ld.session_client.clone()));
+            let response =
+                RUNTIME.spawn(async move { media::get_media(session_client, &url).await });
 
             glib::MainContext::default().spawn_local(async move {
                 match response.await {
@@ -180,22 +195,25 @@ pub fn new(
                     }
                 }
             });
-        }
+        }));
     }));
 
-    copy_text.connect_activate(move |_, data| {
-        if let Some(m) = get_message(data) {
-            let atom = gdk::Atom::intern("CLIPBOARD");
-            let clipboard = gtk::Clipboard::get(&atom);
+    copy_text.connect_activate(clone!(@strong app_tx => move |_, data| {
+        let data = data.cloned();
+        let _ = app_tx.send(Box::new(move |op| {
+            if let Some(m) = get_message(op, data.as_ref()) {
+                let atom = gdk::Atom::intern("CLIPBOARD");
+                let clipboard = gtk::Clipboard::get(&atom);
 
-            clipboard.set_text(&m.body);
-        }
-    });
+                clipboard.set_text(&m.body);
+            }
+        }));
+    }));
 
     delete.connect_activate(clone!(
-    @strong session_client,
     @weak back_history,
-    @weak window
+    @weak window,
+    @strong app_tx
     => move |_, data| {
         let state = back_history.borrow().last().cloned();
         if let Some(AppState::MediaViewer) = state {
@@ -205,32 +223,41 @@ pub fn new(
                 error!("The action group app is not attached to the main window.");
             }
         }
-        if let Some(msg) = get_message(data) {
-            let session_client = session_client.clone();
+        let data = data.cloned();
+        let _ = app_tx.send(Box::new(move |op| {
+            let msg = unwrap_or_unit_return!(get_message(op, data.as_ref()));
+            let session_client = unwrap_or_unit_return!(
+                op.login_data.as_ref().map(|ld| ld.session_client.clone())
+            );
             RUNTIME.spawn(async move {
                 let query = room::redact_msg(session_client, msg).await;
                 if let Err(err) = query {
                     err.handle_error();
                 }
             });
-        }
+        }));
     }));
 
     load_more_messages.connect_activate(move |_, data| {
-        let id = get_room_id(data);
-        request_more_messages(session_client.clone(), id);
+        let data = data.cloned();
+        let _ = app_tx.send(Box::new(move |op| {
+            let id = get_room_id(data.as_ref());
+            request_more_messages(op, id);
+        }));
     });
 
     actions
 }
 
-fn get_message(id: Option<&glib::Variant>) -> Option<Message> {
-    get_event_id(id).as_ref().and_then(get_message_by_id)
+fn get_message(op: &AppOp, id: Option<&glib::Variant>) -> Option<Message> {
+    get_event_id(id)
+        .as_ref()
+        .and_then(|evid| get_message_by_id(op, evid))
 }
 
-fn request_more_messages(session_client: MatrixClient, id: Option<RoomId>) -> Option<()> {
-    let op = app::get_op().lock().unwrap();
+fn request_more_messages(op: &AppOp, id: Option<RoomId>) -> Option<()> {
     let id = id?;
+    let session_client = op.login_data.as_ref()?.session_client.clone();
     let r = op.rooms.get(&id)?;
     if let Some(prev_batch) = r.prev_batch.clone() {
         RUNTIME.spawn(async move {
diff --git a/fractal-gtk/src/app/connect/account.rs b/fractal-gtk/src/app/connect/account.rs
index f5d3d51d..b5d1abe1 100644
--- a/fractal-gtk/src/app/connect/account.rs
+++ b/fractal-gtk/src/app/connect/account.rs
@@ -125,10 +125,7 @@ impl App {
         });
 
         name_btn.connect_clicked(move |_w| {
-            app::get_op()
-                .lock()
-                .unwrap()
-                .update_username_account_settings();
+            let _ = app::get_app_tx().send(Box::new(|op| op.update_username_account_settings()));
         });
 
         /*
@@ -186,23 +183,24 @@ impl App {
 
         /* Passsword dialog */
         password_btn.connect_clicked(move |_| {
-            app::get_op().lock().unwrap().show_password_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| op.show_password_dialog()));
         });
 
         password_dialog.connect_delete_event(move |_, _| {
-            app::get_op().lock().unwrap().close_password_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| op.close_password_dialog()));
             glib::signal::Inhibit(true)
         });
 
         /* Headerbar */
         cancel_password.connect_clicked(move |_| {
-            app::get_op().lock().unwrap().close_password_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| op.close_password_dialog()));
         });
 
         confirm_password.connect_clicked(move |_| {
-            let mut op = app::get_op().lock().unwrap();
-            op.set_new_password();
-            op.close_password_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| {
+                op.set_new_password();
+                op.close_password_dialog();
+            }));
         });
 
         /* Body */
@@ -227,7 +225,7 @@ impl App {
         );
 
         destruction_btn.connect_clicked(move |_| {
-            app::get_op().lock().unwrap().account_destruction();
+            let _ = app::get_app_tx().send(Box::new(|op| op.account_destruction()));
         });
     }
 }
diff --git a/fractal-gtk/src/app/connect/direct.rs b/fractal-gtk/src/app/connect/direct.rs
index 5d3b34a5..a2ea4594 100644
--- a/fractal-gtk/src/app/connect/direct.rs
+++ b/fractal-gtk/src/app/connect/direct.rs
@@ -73,7 +73,7 @@ impl App {
                         if let Some(text) =
                             buffer.get_text(&start, &end, false).map(|gstr| gstr.to_string())
                         {
-                            app::get_op().lock().unwrap().search_invite_user(text);
+                            let _ = app::get_app_tx().send(Box::new(|op| op.search_invite_user(text)));
                         }
                     }
 
@@ -89,7 +89,7 @@ impl App {
         to_chat_entry.connect_focus_in_event(clone!(@strong to_chat_entry_box => move |_, _| {
             to_chat_entry_box.get_style_context().add_class("message-input-focused");
 
-            app::get_op().lock().unwrap().remove_invite_user_dialog_placeholder();
+            let _ = app::get_app_tx().send(Box::new(|op| op.remove_invite_user_dialog_placeholder()));
 
             Inhibit(false)
         }));
@@ -97,7 +97,7 @@ impl App {
         to_chat_entry.connect_focus_out_event(clone!(@strong to_chat_entry_box => move |_, _| {
             to_chat_entry_box.get_style_context().remove_class("message-input-focused");
 
-            app::get_op().lock().unwrap().set_invite_user_dialog_placeholder();
+            let _ = app::get_app_tx().send(Box::new(|op| op.set_invite_user_dialog_placeholder()));
 
             Inhibit(false)
         }));
@@ -105,22 +105,22 @@ impl App {
         if let Some(buffer) = to_chat_entry.get_buffer() {
             buffer.connect_delete_range(move |_, _, _| {
                 glib::idle_add_local(move || {
-                    app::get_op().lock().unwrap().detect_removed_invite();
+                    let _ = app::get_app_tx().send(Box::new(|op| op.detect_removed_invite()));
                     Continue(false)
                 });
             });
         }
 
         dialog.connect_delete_event(move |_, _| {
-            app::get_op().lock().unwrap().close_direct_chat_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| op.close_direct_chat_dialog()));
             glib::signal::Inhibit(true)
         });
         cancel.connect_clicked(move |_| {
-            app::get_op().lock().unwrap().close_direct_chat_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| op.close_direct_chat_dialog()));
         });
         invite.set_sensitive(false);
         invite.connect_clicked(move |_| {
-            app::get_op().lock().unwrap().start_chat();
+            let _ = app::get_app_tx().send(Box::new(|op| op.start_chat()));
         });
     }
 }
diff --git a/fractal-gtk/src/app/connect/directory.rs b/fractal-gtk/src/app/connect/directory.rs
index 48bf7798..d9036ee7 100644
--- a/fractal-gtk/src/app/connect/directory.rs
+++ b/fractal-gtk/src/app/connect/directory.rs
@@ -105,14 +105,15 @@ impl App {
 
         scroll.connect_edge_reached(move |_, dir| {
             if dir == gtk::PositionType::Bottom {
-                app::get_op().lock().unwrap().load_more_rooms();
+                let _ = app::get_app_tx().send(Box::new(|op| op.load_more_rooms()));
             }
         });
 
         q.connect_activate(move |_| {
-            let mut op = app::get_op().lock().unwrap();
-            op.directory_pagination = RoomSearchPagination::Initial;
-            op.search_rooms();
+            let _ = app::get_app_tx().send(Box::new(|op| {
+                op.directory_pagination = RoomSearchPagination::Initial;
+                op.search_rooms();
+            }));
         });
 
         default_matrix_server_radio.connect_toggled(clone!(
diff --git a/fractal-gtk/src/app/connect/invite.rs b/fractal-gtk/src/app/connect/invite.rs
index 0db031ce..1b8f295d 100644
--- a/fractal-gtk/src/app/connect/invite.rs
+++ b/fractal-gtk/src/app/connect/invite.rs
@@ -25,17 +25,17 @@ impl App {
             .expect("Can't find invite_reject in ui file.");
 
         reject.connect_clicked(clone!(@strong dialog => move |_| {
-            app::get_op().lock().unwrap().accept_inv(false);
+            let _ = app::get_app_tx().send(Box::new(|op| op.accept_inv(false)));
             dialog.hide();
         }));
         dialog.connect_delete_event(clone!(@strong dialog => move |_, _| {
-            app::get_op().lock().unwrap().accept_inv(false);
+            let _ = app::get_app_tx().send(Box::new(|op| op.accept_inv(false)));
             dialog.hide();
             glib::signal::Inhibit(true)
         }));
 
         accept.connect_clicked(clone!(@strong dialog => move |_| {
-            app::get_op().lock().unwrap().accept_inv(true);
+            let _ = app::get_app_tx().send(Box::new(|op| op.accept_inv(true)));
             dialog.hide();
         }));
     }
@@ -99,7 +99,7 @@ impl App {
                     let end = buffer.get_end_iter();
 
                     if let Some(text) = buffer.get_text(&start, &end, false).map(|gstr| gstr.to_string()) {
-                        app::get_op().lock().unwrap().search_invite_user(text);
+                        let _ = app::get_app_tx().send(Box::new(|op| op.search_invite_user(text)));
                     }
                 }
 
@@ -114,7 +114,7 @@ impl App {
         invite_entry.connect_focus_in_event(clone!(@strong invite_entry_box => move |_, _| {
             invite_entry_box.get_style_context().add_class("message-input-focused");
 
-            app::get_op().lock().unwrap().remove_invite_user_dialog_placeholder();
+            let _ = app::get_app_tx().send(Box::new(|op| op.remove_invite_user_dialog_placeholder()));
 
             Inhibit(false)
         }));
@@ -122,7 +122,7 @@ impl App {
         invite_entry.connect_focus_out_event(clone!(@strong invite_entry_box => move |_, _| {
             invite_entry_box.get_style_context().remove_class("message-input-focused");
 
-            app::get_op().lock().unwrap().set_invite_user_dialog_placeholder();
+            let _ = app::get_app_tx().send(Box::new(|op| op.set_invite_user_dialog_placeholder()));
 
             Inhibit(false)
         }));
@@ -130,22 +130,22 @@ impl App {
         if let Some(buffer) = invite_entry.get_buffer() {
             buffer.connect_delete_range(move |_, _, _| {
                 glib::idle_add_local(move || {
-                    app::get_op().lock().unwrap().detect_removed_invite();
+                    let _ = app::get_app_tx().send(Box::new(|op| op.detect_removed_invite()));
                     Continue(false)
                 });
             });
         }
 
         dialog.connect_delete_event(move |_, _| {
-            app::get_op().lock().unwrap().close_invite_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| op.close_invite_dialog()));
             glib::signal::Inhibit(true)
         });
         cancel.connect_clicked(move |_| {
-            app::get_op().lock().unwrap().close_invite_dialog();
+            let _ = app::get_app_tx().send(Box::new(|op| op.close_invite_dialog()));
         });
         invite.set_sensitive(false);
         invite.connect_clicked(move |_| {
-            app::get_op().lock().unwrap().invite();
+            let _ = app::get_app_tx().send(Box::new(|op| op.invite()));
         });
     }
 }
diff --git a/fractal-gtk/src/app/connect/join_room.rs b/fractal-gtk/src/app/connect/join_room.rs
index 3d97e04f..af41e121 100644
--- a/fractal-gtk/src/app/connect/join_room.rs
+++ b/fractal-gtk/src/app/connect/join_room.rs
@@ -38,13 +38,13 @@ impl App {
 
         confirm.connect_clicked(clone!(@strong entry, @strong dialog => move |_| {
             dialog.hide();
-            app::get_op().lock().unwrap().join_to_room();
+            let _ = app::get_app_tx().send(Box::new(|op| op.join_to_room()));
             entry.set_text("");
         }));
 
         entry.connect_activate(clone!(@strong dialog => move |entry| {
             dialog.hide();
-            app::get_op().lock().unwrap().join_to_room();
+            let _ = app::get_app_tx().send(Box::new(|op| op.join_to_room()));
             entry.set_text("");
         }));
         entry.connect_changed(clone!(@strong confirm => move |entry| {
diff --git a/fractal-gtk/src/app/connect/leave_room.rs b/fractal-gtk/src/app/connect/leave_room.rs
index 9bead08e..1f2cbf2e 100644
--- a/fractal-gtk/src/app/connect/leave_room.rs
+++ b/fractal-gtk/src/app/connect/leave_room.rs
@@ -31,7 +31,7 @@ impl App {
 
         confirm.connect_clicked(clone!(@strong dialog => move |_| {
             dialog.hide();
-            app::get_op().lock().unwrap().really_leave_active_room();
+            let _ = app::get_app_tx().send(Box::new(|op| op.really_leave_active_room()));
         }));
     }
 }
diff --git a/fractal-gtk/src/app/connect/markdown.rs b/fractal-gtk/src/app/connect/markdown.rs
index cc74571b..1d1ac9f5 100644
--- a/fractal-gtk/src/app/connect/markdown.rs
+++ b/fractal-gtk/src/app/connect/markdown.rs
@@ -37,7 +37,9 @@ impl App {
 
         let md_active = util::get_markdown_schema();
         if md_active {
-            app::get_op().lock().unwrap().md_enabled = true;
+            let _ = app::get_app_tx().send(Box::new(|op| {
+                op.md_enabled = true;
+            }));
             markdown_switch.set_active(true);
             md_img.set_from_icon_name(Some("format-indent-more-symbolic"), gtk::IconSize::Menu);
             txt.get_style_context().remove_class("dim-label");
@@ -51,7 +53,10 @@ impl App {
 
         markdown_switch.connect_property_active_notify(
             clone!(@strong markdown_switch => move |_| {
-                app::get_op().lock().unwrap().md_enabled = markdown_switch.get_active();
+                let md_active = markdown_switch.get_active();
+                let _ = app::get_app_tx().send(Box::new(move |op| {
+                    op.md_enabled = md_active;
+                }));
 
                 if markdown_switch.get_active() {
                     md_img.set_from_icon_name(
diff --git a/fractal-gtk/src/app/connect/new_room.rs b/fractal-gtk/src/app/connect/new_room.rs
index e20e004a..f4fe763c 100644
--- a/fractal-gtk/src/app/connect/new_room.rs
+++ b/fractal-gtk/src/app/connect/new_room.rs
@@ -51,7 +51,7 @@ impl App {
         confirm.connect_clicked(
             clone!(@strong entry, @strong dialog, @strong private => move |_| {
                 dialog.hide();
-                app::get_op().lock().unwrap().create_new_room();
+                let _ = app::get_app_tx().send(Box::new(|op| op.create_new_room()));
                 entry.set_text("");
                 private.set_active(true);
             }),
@@ -59,7 +59,7 @@ impl App {
 
         entry.connect_activate(clone!(@strong dialog => move |entry| {
             dialog.hide();
-            app::get_op().lock().unwrap().create_new_room();
+            let _ = app::get_app_tx().send(Box::new(|op| op.create_new_room()));
             entry.set_text("");
             private.set_active(true);
         }));
diff --git a/fractal-gtk/src/app/connect/roomlist_search.rs b/fractal-gtk/src/app/connect/roomlist_search.rs
index 608d08b0..9f329393 100644
--- a/fractal-gtk/src/app/connect/roomlist_search.rs
+++ b/fractal-gtk/src/app/connect/roomlist_search.rs
@@ -32,10 +32,8 @@ impl App {
         );
 
         search_entry.connect_search_changed(move |entry| {
-            app::get_op()
-                .lock()
-                .unwrap()
-                .filter_rooms(Some(entry.get_text().to_string()));
+            let search_text = Some(entry.get_text().to_string());
+            let _ = app::get_app_tx().send(Box::new(|op| op.filter_rooms(search_text)));
         });
 
         // hidding left and right boxes to align with top buttons
diff --git a/fractal-gtk/src/app/connect/send.rs b/fractal-gtk/src/app/connect/send.rs
index 1926d1a8..35a9dbed 100644
--- a/fractal-gtk/src/app/connect/send.rs
+++ b/fractal-gtk/src/app/connect/send.rs
@@ -37,7 +37,7 @@ impl App {
                 if !key.get_state().contains(gdk::ModifierType::SHIFT_MASK)
                     && !autocomplete_popover.is_visible() =>
             {
-                activate_action("app", "send-message");
+                activate_action(app::get_app_tx(), "app", "send-message");
                 Inhibit(true)
             }
             _ => Inhibit(false),
@@ -45,7 +45,7 @@ impl App {
 
         msg_entry.connect_key_release_event(move |_, ev| {
             if ev.get_keyval().to_unicode().is_some() {
-                app::get_op().lock().unwrap().send_typing();
+                let _ = app::get_app_tx().send(Box::new(|op| op.send_typing()));
             }
             Inhibit(false)
         });
diff --git a/fractal-gtk/src/app/mod.rs b/fractal-gtk/src/app/mod.rs
index f1e7a1e2..b4fcc605 100644
--- a/fractal-gtk/src/app/mod.rs
+++ b/fractal-gtk/src/app/mod.rs
@@ -24,9 +24,10 @@ mod windowstate;
 use windowstate::WindowState;
 
 type GlobalAppOp = Arc<Mutex<AppOp>>;
-type UpdateApp = Box<dyn FnOnce(&mut AppOp)>;
+pub type UpdateApp = Box<dyn FnOnce(&mut AppOp)>;
 
 static mut APP_TX: Option<glib::Sender<UpdateApp>> = None;
+// TODO: Deprecated. It should be removed
 static mut OP: Option<GlobalAppOp> = None;
 
 lazy_static! {
@@ -77,9 +78,10 @@ impl App {
 
         let (app_tx, app_rx) = glib::MainContext::channel(Default::default());
         let ui = uibuilder::UI::new();
+        let op = AppOp::new(ui.clone(), app_tx.clone());
 
         unsafe {
-            OP = Some(Arc::new(Mutex::new(AppOp::new(ui.clone()))));
+            OP = Some(Arc::new(Mutex::new(op)));
             APP_TX = Some(app_tx);
         }
 
@@ -166,7 +168,7 @@ impl App {
 
         gtk_app.set_accels_for_action("login.back", &["Escape"]);
 
-        actions::Global::new(gtk_app, get_op());
+        actions::Global::new(gtk_app, get_app_tx().clone(), get_op());
 
         let app = AppRef::new(Self {
             main_window: window,
@@ -227,7 +229,8 @@ impl App {
     }
 }
 
-pub fn get_op() -> &'static GlobalAppOp {
+// TODO: Deprecated. It should be removed
+pub(self) fn get_op() -> &'static GlobalAppOp {
     unsafe { OP.as_ref().expect("Fatal: AppOp has not been initialized") }
 }
 
diff --git a/fractal-gtk/src/appop/account.rs b/fractal-gtk/src/appop/account.rs
index 00e80641..6e3c07e6 100644
--- a/fractal-gtk/src/appop/account.rs
+++ b/fractal-gtk/src/appop/account.rs
@@ -3,6 +3,7 @@ use gtk::prelude::*;
 use log::info;
 use std::path::PathBuf;
 
+use crate::actions::global::activate_action;
 use crate::app::RUNTIME;
 use crate::appop::AppOp;
 use crate::appop::AppState;
@@ -200,6 +201,7 @@ impl AppOp {
         let dialog = self.create_error_dialog(error);
         dialog.connect_response(move |w, _| w.close());
         dialog.show_all();
+        activate_action(&self.app_tx, "app", "back");
     }
 
     pub fn create_error_dialog(&self, error: String) -> gtk::MessageDialog {
diff --git a/fractal-gtk/src/appop/media_viewer.rs b/fractal-gtk/src/appop/media_viewer.rs
index f44b4a02..5e7ad473 100644
--- a/fractal-gtk/src/appop/media_viewer.rs
+++ b/fractal-gtk/src/appop/media_viewer.rs
@@ -1,7 +1,5 @@
 use gtk::prelude::*;
 
-use log::error;
-
 use crate::actions;
 
 use crate::appop::AppOp;
@@ -35,15 +33,10 @@ impl AppOp {
             let (body, header) = panel.create(login_data.session_client.clone())?;
             *self.media_viewer.borrow_mut() = Some(panel);
 
-            if let Some(login_data) = self.login_data.clone() {
-                let back_history = self.room_back_history.clone();
-                let actions =
-                    actions::Message::new(login_data.session_client, self.ui.clone(), back_history);
-                header.insert_action_group("message", Some(&actions));
-                body.insert_action_group("message", Some(&actions));
-            } else {
-                error!("No login data!");
-            }
+            let back_history = self.room_back_history.clone();
+            let actions = actions::Message::new(self.app_tx.clone(), self.ui.clone(), back_history);
+            header.insert_action_group("message", Some(&actions));
+            body.insert_action_group("message", Some(&actions));
 
             /* remove old panel */
             if let Some(widget) = stack.get_child_by_name("media-viewer") {
diff --git a/fractal-gtk/src/appop/mod.rs b/fractal-gtk/src/appop/mod.rs
index 59b77d5f..8d00827a 100644
--- a/fractal-gtk/src/appop/mod.rs
+++ b/fractal-gtk/src/appop/mod.rs
@@ -22,6 +22,7 @@ use crate::model::{
 use crate::passwd::PasswordStorage;
 
 use crate::actions::AppState;
+use crate::app::UpdateApp;
 use crate::cache;
 use crate::uibuilder;
 use crate::widgets;
@@ -83,6 +84,7 @@ pub struct LoginData {
 }
 
 pub struct AppOp {
+    pub app_tx: glib::Sender<UpdateApp>,
     pub ui: uibuilder::UI,
 
     pub syncing: bool, // TODO: Replace with a Mutex
@@ -123,7 +125,7 @@ pub struct AppOp {
 impl PasswordStorage for AppOp {}
 
 impl AppOp {
-    pub fn new(ui: uibuilder::UI) -> AppOp {
+    pub fn new(ui: uibuilder::UI, app_tx: glib::Sender<UpdateApp>) -> AppOp {
         let leaflet = ui
             .builder
             .get_object::<libhandy::Leaflet>("chat_page")
@@ -134,6 +136,7 @@ impl AppOp {
             .expect("Couldn't find main_deck in ui file");
 
         AppOp {
+            app_tx,
             ui,
             active_room: None,
             join_to_room: None,
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index 9bb446f2..020e9b12 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -298,11 +298,7 @@ impl AppOp {
         }
 
         let back_history = self.room_back_history.clone();
-        let actions = actions::Message::new(
-            login_data.session_client.clone(),
-            self.ui.clone(),
-            back_history,
-        );
+        let actions = actions::Message::new(self.app_tx.clone(), self.ui.clone(), back_history);
         let history = widgets::RoomHistory::new(actions, active_room.clone(), &self.ui);
         self.history = if let Some(mut history) = history {
             history.create(
diff --git a/fractal-gtk/src/backend/user.rs b/fractal-gtk/src/backend/user.rs
index d262e512..11935974 100644
--- a/fractal-gtk/src/backend/user.rs
+++ b/fractal-gtk/src/backend/user.rs
@@ -7,7 +7,6 @@ use std::io::Error as IoError;
 use url::{ParseError as UrlError, Url};
 
 use super::MediaError;
-use crate::actions::global::activate_action;
 use crate::appop::UserInfoCache;
 use crate::backend::HTTP_CLIENT;
 use crate::util::cache_dir_path;
@@ -113,10 +112,6 @@ impl HandleError for GetThreePIDError {
     fn handle_error(&self) {
         let error = i18n("Sorry, account settings can’t be loaded.");
         APPOP!(show_load_settings_error_dialog, (error));
-        let ctx = glib::MainContext::default();
-        ctx.invoke(move || {
-            activate_action("app", "back");
-        })
     }
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]