[fractal] AppOp: Call APPOP! directly



commit 7e85cc6612058adcf64bbf2fc01c88a4d8d04ed6
Author: Alejandro Domínguez <adomu net-c com>
Date:   Fri Apr 24 04:07:18 2020 +0200

    AppOp: Call APPOP! directly
    
    Pass messages only for errors

 fractal-gtk/src/actions/account_settings.rs |  15 +++-
 fractal-gtk/src/actions/message.rs          |  72 +++++++++++----
 fractal-gtk/src/actions/room_settings.rs    |  15 +++-
 fractal-gtk/src/app/backend_loop.rs         | 134 ++++++----------------------
 fractal-gtk/src/app/connect/language.rs     |   6 +-
 fractal-gtk/src/appop/account.rs            | 110 ++++++++++++++++-------
 fractal-gtk/src/appop/directory.rs          |  17 ++--
 fractal-gtk/src/appop/invite.rs             |   6 +-
 fractal-gtk/src/appop/login.rs              |  13 ++-
 fractal-gtk/src/appop/member.rs             |  12 ++-
 fractal-gtk/src/appop/message.rs            |  31 +++++--
 fractal-gtk/src/appop/room.rs               |  80 ++++++++++++-----
 fractal-gtk/src/appop/user.rs               |  25 ++++--
 fractal-gtk/src/widgets/address.rs          |  47 ++++++++--
 fractal-gtk/src/widgets/room_settings.rs    |  51 +++++++----
 fractal-matrix-api/src/backend/types.rs     |  55 ++++++------
 16 files changed, 422 insertions(+), 267 deletions(-)
---
diff --git a/fractal-gtk/src/actions/account_settings.rs b/fractal-gtk/src/actions/account_settings.rs
index 0a128cf8..62fb9116 100644
--- a/fractal-gtk/src/actions/account_settings.rs
+++ b/fractal-gtk/src/actions/account_settings.rs
@@ -11,6 +11,7 @@ use gtk;
 use std::sync::mpsc::Sender;
 use std::thread;
 
+use crate::app::App;
 use crate::backend::{BKCommand, BKResponse};
 
 use crate::widgets::FileDialog::open;
@@ -45,9 +46,17 @@ pub fn new(
             let access_token = access_token.clone();
             let uid = uid.clone();
             thread::spawn(move || {
-                let query = user::set_user_avatar(server_url, access_token, uid, path);
-                tx.send(BKCommand::SendBKResponse(BKResponse::SetUserAvatar(query)))
-                    .expect_log("Connection closed");
+                match user::set_user_avatar(server_url, access_token, uid, path) {
+                    Ok(path) => {
+                        APPOP!(show_new_avatar, (path));
+                    }
+                    Err(err) => {
+                        tx.send(BKCommand::SendBKResponse(BKResponse::SetUserAvatarError(
+                            err,
+                        )))
+                        .expect_log("Connection closed");
+                    }
+                }
             });
         }
     });
diff --git a/fractal-gtk/src/actions/message.rs b/fractal-gtk/src/actions/message.rs
index 943e9819..29b5e224 100644
--- a/fractal-gtk/src/actions/message.rs
+++ b/fractal-gtk/src/actions/message.rs
@@ -7,6 +7,7 @@ use log::error;
 use std::cell::RefCell;
 use std::convert::TryFrom;
 use std::fs;
+use std::process::Command;
 use std::rc::Rc;
 use std::sync::mpsc::channel;
 use std::sync::mpsc::TryRecvError;
@@ -127,9 +128,18 @@ pub fn new(
             let server_url = server_url.clone();
             let tx = b.clone();
             thread::spawn(move || {
-                let fname = dw_media(server_url, &url, ContentType::Download, None);
-                tx.send(BKCommand::SendBKResponse(BKResponse::Media(fname)))
-                    .expect_log("Connection closed");
+                match dw_media(server_url, &url, ContentType::Download, None) {
+                    Ok(fname) => {
+                        Command::new("xdg-open")
+                            .arg(&fname)
+                            .spawn()
+                            .expect("failed to execute process");
+                    }
+                    Err(err) => {
+                        tx.send(BKCommand::SendBKResponse(BKResponse::MediaError(err)))
+                            .expect_log("Connection closed");
+                    }
+                }
             });
         }
     }));
@@ -250,10 +260,12 @@ pub fn new(
             let tx = b.clone();
             thread::spawn(move || {
                 let query = room::redact_msg(server, access_token, msg);
-                tx.send(BKCommand::SendBKResponse(BKResponse::SentMsgRedaction(
-                    query,
-                )))
-                .expect_log("Connection closed");
+                if let Err(err) = query {
+                    tx.send(BKCommand::SendBKResponse(
+                        BKResponse::SentMsgRedactionError(err),
+                    ))
+                    .expect_log("Connection closed");
+                }
             });
         }
     });
@@ -296,24 +308,48 @@ fn request_more_messages(
     let r = op.rooms.get(&id)?;
     if let Some(prev_batch) = r.prev_batch.clone() {
         thread::spawn(move || {
-            let query = room::get_room_messages(server_url, access_token, id, prev_batch);
-            tx.send(BKCommand::SendBKResponse(BKResponse::RoomMessagesTo(query)))
-                .expect_log("Connection closed");
+            match room::get_room_messages(server_url, access_token, id, prev_batch) {
+                Ok((msgs, room, prev_batch)) => {
+                    APPOP!(show_room_messages_top, (msgs, room, prev_batch));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::RoomMessagesToError(
+                        err,
+                    )))
+                    .expect_log("Connection closed");
+                }
+            }
         });
     } else if let Some(msg) = r.messages.iter().next().cloned() {
         // no prev_batch so we use the last message to calculate that in the backend
         thread::spawn(move || {
-            let query = room::get_room_messages_from_msg(server_url, access_token, id, msg);
-            tx.send(BKCommand::SendBKResponse(BKResponse::RoomMessagesTo(query)))
-                .expect_log("Connection closed");
+            match room::get_room_messages_from_msg(server_url, access_token, id, msg) {
+                Ok((msgs, room, prev_batch)) => {
+                    APPOP!(show_room_messages_top, (msgs, room, prev_batch));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::RoomMessagesToError(
+                        err,
+                    )))
+                    .expect_log("Connection closed");
+                }
+            }
         });
     } else if let Some(from) = op.since.clone() {
         // no messages and no prev_batch so we use the last since
-        thread::spawn(move || {
-            let query = room::get_room_messages(server_url, access_token, id, from);
-            tx.send(BKCommand::SendBKResponse(BKResponse::RoomMessagesTo(query)))
-                .expect_log("Connection closed");
-        });
+        thread::spawn(
+            move || match room::get_room_messages(server_url, access_token, id, from) {
+                Ok((msgs, room, prev_batch)) => {
+                    APPOP!(show_room_messages_top, (msgs, room, prev_batch));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::RoomMessagesToError(
+                        err,
+                    )))
+                    .expect_log("Connection closed");
+                }
+            },
+        );
     }
     None
 }
diff --git a/fractal-gtk/src/actions/room_settings.rs b/fractal-gtk/src/actions/room_settings.rs
index f539886e..737bb531 100644
--- a/fractal-gtk/src/actions/room_settings.rs
+++ b/fractal-gtk/src/actions/room_settings.rs
@@ -12,6 +12,7 @@ use std::convert::TryFrom;
 use std::sync::mpsc::Sender;
 use std::thread;
 
+use crate::app::App;
 use crate::backend::{BKCommand, BKResponse};
 use crate::i18n::i18n;
 
@@ -55,9 +56,17 @@ pub fn new(
                     let server = server_url.clone();
                     let access_token = access_token.clone();
                     thread::spawn(move || {
-                        let query = room::set_room_avatar(server, access_token, room_id, file);
-                        tx.send(BKCommand::SendBKResponse(BKResponse::SetRoomAvatar(query)))
-                            .expect_log("Connection closed");
+                        match room::set_room_avatar(server, access_token, room_id, file) {
+                            Ok(_) => {
+                                APPOP!(show_new_room_avatar);
+                            }
+                            Err(err) => {
+                                tx.send(BKCommand::SendBKResponse(BKResponse::SetRoomAvatarError(
+                                    err,
+                                )))
+                                .expect_log("Connection closed");
+                            }
+                        }
                     });
                 } else {
                     ErrorDialog::new(false, &i18n("Couldn’t open file"));
diff --git a/fractal-gtk/src/app/backend_loop.rs b/fractal-gtk/src/app/backend_loop.rs
index 326c9e65..3e1c6e85 100644
--- a/fractal-gtk/src/app/backend_loop.rs
+++ b/fractal-gtk/src/app/backend_loop.rs
@@ -7,7 +7,6 @@ use regex::Regex;
 use crate::actions::{activate_action, AppState};
 
 use glib;
-use std::process::Command;
 use std::sync::mpsc::Receiver;
 use std::thread;
 
@@ -24,70 +23,6 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                 BKResponse::Token(uid, tk, dev, server_url, id_url) => {
                     APPOP!(bk_login, (uid, tk, dev, server_url, id_url));
                 }
-                BKResponse::Logout(Ok(_)) => {
-                    APPOP!(bk_logout);
-                }
-                BKResponse::Name(Ok(username)) => {
-                    APPOP!(set_username, (username));
-                }
-                BKResponse::GetThreePID(Ok(list)) => {
-                    let l = Some(list);
-                    APPOP!(set_three_pid, (l));
-                }
-                BKResponse::GetTokenEmail(Ok((sid, secret))) => {
-                    let sid = Some(sid);
-                    let secret = Some(secret);
-                    APPOP!(get_token_email, (sid, secret));
-                }
-                BKResponse::GetTokenPhone(Ok((sid, secret))) => {
-                    let sid = Some(sid);
-                    let secret = Some(secret);
-                    APPOP!(get_token_phone, (sid, secret));
-                }
-                BKResponse::GetTokenEmail(Err(Error::TokenUsed)) => {
-                    let error = i18n("Email is already in use");
-                    APPOP!(show_error_dialog_in_settings, (error));
-                }
-                BKResponse::GetTokenEmail(Err(Error::Denied)) => {
-                    let error = i18n("Please enter a valid email address.");
-                    APPOP!(show_error_dialog_in_settings, (error));
-                }
-                BKResponse::GetTokenPhone(Err(Error::TokenUsed)) => {
-                    let error = i18n("Phone number is already in use");
-                    APPOP!(show_error_dialog_in_settings, (error));
-                }
-                BKResponse::GetTokenPhone(Err(Error::Denied)) => {
-                    let error = i18n(
-                        "Please enter your phone number in the format: \n + your country code and your phone 
number.",
-                    );
-                    APPOP!(show_error_dialog_in_settings, (error));
-                }
-                BKResponse::SubmitPhoneToken(Ok((sid, secret))) => {
-                    let secret = Some(secret);
-                    APPOP!(valid_phone_token, (sid, secret));
-                }
-                BKResponse::AddThreePID(Ok(_)) => {
-                    APPOP!(added_three_pid);
-                }
-                BKResponse::DeleteThreePID(Ok(_)) => {
-                    APPOP!(get_three_pid);
-                }
-                BKResponse::ChangePassword(Ok(_)) => {
-                    APPOP!(password_changed);
-                }
-                BKResponse::SetUserName(Ok(username)) => {
-                    let u = Some(username);
-                    APPOP!(show_new_username, (u));
-                }
-                BKResponse::AccountDestruction(Ok(_)) => {
-                    APPOP!(account_destruction_logoff);
-                }
-                BKResponse::Avatar(Ok(path)) => {
-                    APPOP!(set_avatar, (path));
-                }
-                BKResponse::SetUserAvatar(Ok(path)) => {
-                    APPOP!(show_new_avatar, (path));
-                }
                 BKResponse::Sync(Ok(since)) => {
                     info!("SYNC");
                     let s = Some(since);
@@ -113,23 +48,14 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                 BKResponse::RoomAvatar(Ok((room, avatar))) => {
                     APPOP!(set_room_avatar, (room, avatar));
                 }
-                BKResponse::RoomMembers(Ok((room, members))) => {
-                    APPOP!(set_room_members, (room, members));
-                }
                 BKResponse::RoomMessages(Ok(msgs)) => {
                     APPOP!(show_room_messages, (msgs));
                 }
-                BKResponse::RoomMessagesTo(Ok((msgs, room, prev_batch))) => {
-                    APPOP!(show_room_messages_top, (msgs, room, prev_batch));
-                }
                 BKResponse::SentMsg(Ok((txid, evid))) => {
                     APPOP!(msg_sent, (txid, evid));
                     let initial = false;
                     APPOP!(sync, (initial));
                 }
-                BKResponse::DirectoryProtocols(Ok(protocols)) => {
-                    APPOP!(set_protocols, (protocols));
-                }
                 BKResponse::DirectorySearch(Ok(rooms)) => {
                     APPOP!(append_directory_rooms, (rooms));
                 }
@@ -137,26 +63,12 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                 BKResponse::JoinRoom(Ok(_)) => {
                     APPOP!(reload_rooms);
                 }
-                BKResponse::LeaveRoom(Ok(_)) => {}
-                BKResponse::SetRoomName(Ok(_)) => {
-                    APPOP!(show_new_room_name);
-                }
-                BKResponse::SetRoomTopic(Ok(_)) => {
-                    APPOP!(show_new_room_topic);
-                }
-                BKResponse::SetRoomAvatar(Ok(_)) => {
-                    APPOP!(show_new_room_avatar);
-                }
                 BKResponse::RemoveMessage(Ok((room, msg))) => {
                     APPOP!(remove_message, (room, msg));
                 }
-                BKResponse::MarkedAsRead(Ok((r, _))) => {
-                    APPOP!(clear_room_notifications, (r));
-                }
                 BKResponse::RoomNotifications(r, n, h) => {
                     APPOP!(set_room_notifications, (r, n, h));
                 }
-
                 BKResponse::RoomName(roomid, name) => {
                     let n = Some(name);
                     APPOP!(room_name_change, (roomid, n));
@@ -171,12 +83,6 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                 BKResponse::RoomMemberEvent(ev) => {
                     APPOP!(room_member_event, (ev));
                 }
-                BKResponse::Media(Ok(fname)) => {
-                    Command::new("xdg-open")
-                        .arg(&fname)
-                        .spawn()
-                        .expect("failed to execute process");
-                }
                 BKResponse::AttachedFile(Ok(msg)) => {
                     APPOP!(attached_file, (msg));
                 }
@@ -184,15 +90,9 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                     let id = Some(internal_id);
                     APPOP!(new_room, (r, id));
                 }
-                BKResponse::AddedToFav(Ok((r, tofav))) => {
-                    APPOP!(added_to_fav, (r, tofav));
-                }
-                BKResponse::UserSearch(Ok(users)) => {
-                    APPOP!(user_search_finished, (users));
-                }
 
                 // errors
-                BKResponse::AccountDestruction(Err(err)) => {
+                BKResponse::AccountDestructionError(err) => {
                     let error = i18n("Couldn’t delete the account");
                     let err_str = format!("{:?}", err);
                     error!(
@@ -201,7 +101,7 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                     );
                     APPOP!(show_error_dialog_in_settings, (error));
                 }
-                BKResponse::ChangePassword(Err(err)) => {
+                BKResponse::ChangePasswordError(err) => {
                     let error = i18n("Couldn’t change the password");
                     let err_str = format!("{:?}", err);
                     error!(
@@ -210,7 +110,7 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                     );
                     APPOP!(show_password_error_dialog, (error));
                 }
-                BKResponse::GetThreePID(Err(_)) => {
+                BKResponse::GetThreePIDError(_) => {
                     let error = i18n("Sorry, account settings can’t be loaded.");
                     APPOP!(show_load_settings_error_dialog, (error));
                     let ctx = glib::MainContext::default();
@@ -218,7 +118,15 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                         activate_action("app", "back");
                     })
                 }
-                BKResponse::GetTokenEmail(Err(err)) => {
+                BKResponse::GetTokenEmailError(Error::TokenUsed) => {
+                    let error = i18n("Email is already in use");
+                    APPOP!(show_error_dialog_in_settings, (error));
+                }
+                BKResponse::GetTokenEmailError(Error::Denied) => {
+                    let error = i18n("Please enter a valid email address.");
+                    APPOP!(show_error_dialog_in_settings, (error));
+                }
+                BKResponse::GetTokenEmailError(err) => {
                     let error = i18n("Couldn’t add the email address.");
                     let err_str = format!("{:?}", err);
                     error!(
@@ -227,7 +135,17 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                     );
                     APPOP!(show_error_dialog_in_settings, (error));
                 }
-                BKResponse::GetTokenPhone(Err(err)) => {
+                BKResponse::GetTokenPhoneError(Error::TokenUsed) => {
+                    let error = i18n("Phone number is already in use");
+                    APPOP!(show_error_dialog_in_settings, (error));
+                }
+                BKResponse::GetTokenPhoneError(Error::Denied) => {
+                    let error = i18n(
+                        "Please enter your phone number in the format: \n + your country code and your phone 
number.",
+                    );
+                    APPOP!(show_error_dialog_in_settings, (error));
+                }
+                BKResponse::GetTokenPhoneError(err) => {
                     let error = i18n("Couldn’t add the phone number.");
                     let err_str = format!("{:?}", err);
                     error!(
@@ -261,7 +179,7 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                     APPOP!(show_error, (error));
                     APPOP!(set_state, (state));
                 }
-                BKResponse::ChangeLanguage(Err(err)) => {
+                BKResponse::ChangeLanguageError(err) => {
                     let err_str = format!("{:?}", err);
                     error!(
                         "Error forming url to set room language: {}",
@@ -293,11 +211,11 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                         APPOP!(show_error, (error));
                     }
                 },
-                BKResponse::SentMsgRedaction(Err(_)) => {
+                BKResponse::SentMsgRedactionError(_) => {
                     let error = i18n("Error deleting message");
                     APPOP!(show_error, (error));
                 }
-                BKResponse::DirectoryProtocols(Err(_)) | BKResponse::DirectorySearch(Err(_)) => {
+                BKResponse::DirectoryProtocolsError(_) | BKResponse::DirectorySearch(Err(_)) => {
                     let error = i18n("Error searching for rooms");
                     APPOP!(reset_directory_state);
                     APPOP!(show_error, (error));
diff --git a/fractal-gtk/src/app/connect/language.rs b/fractal-gtk/src/app/connect/language.rs
index 877bc080..3e4d6675 100644
--- a/fractal-gtk/src/app/connect/language.rs
+++ b/fractal-gtk/src/app/connect/language.rs
@@ -37,8 +37,10 @@ impl App {
                             let tx = op.backend.clone();
                             thread::spawn(move || {
                                 let query = room::set_language(access_token, server, uid, room_id, 
lang_code);
-                                tx.send(BKCommand::SendBKResponse(BKResponse::ChangeLanguage(query)))
-                                    .expect_log("Connection closed");
+                                if let Err(err) = query {
+                                    tx.send(BKCommand::SendBKResponse(BKResponse::ChangeLanguageError(err)))
+                                        .expect_log("Connection closed");
+                                }
                             });
                         }
                     }
diff --git a/fractal-gtk/src/appop/account.rs b/fractal-gtk/src/appop/account.rs
index 778b856b..e5cc58a8 100644
--- a/fractal-gtk/src/appop/account.rs
+++ b/fractal-gtk/src/appop/account.rs
@@ -6,6 +6,7 @@ use log::info;
 use std::path::PathBuf;
 use std::thread;
 
+use crate::app::App;
 use crate::appop::AppOp;
 use crate::appop::AppState;
 
@@ -29,9 +30,16 @@ impl AppOp {
         let login_data = unwrap_or_unit_return!(self.login_data.clone());
         let tx = self.backend.clone();
         thread::spawn(move || {
-            let query = user::get_threepid(login_data.server_url, login_data.access_token);
-            tx.send(BKCommand::SendBKResponse(BKResponse::GetThreePID(query)))
-                .expect_log("Connection closed");
+            match user::get_threepid(login_data.server_url, login_data.access_token) {
+                Ok(list) => {
+                    let l = Some(list);
+                    APPOP!(set_three_pid, (l));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::GetThreePIDError(err)))
+                        .expect_log("Connection closed");
+                }
+            }
         });
     }
 
@@ -45,15 +53,21 @@ impl AppOp {
             if let Some(secret) = secret {
                 let tx = self.backend.clone();
                 thread::spawn(move || {
-                    let query = user::add_threepid(
+                    match user::add_threepid(
                         login_data.server_url,
                         login_data.access_token,
                         login_data.identity_url,
                         secret,
                         sid,
-                    );
-                    tx.send(BKCommand::SendBKResponse(BKResponse::AddThreePID(query)))
-                        .expect_log("Connection closed");
+                    ) {
+                        Ok(_) => {
+                            APPOP!(added_three_pid);
+                        }
+                        Err(err) => {
+                            tx.send(BKCommand::SendBKResponse(BKResponse::AddThreePIDError(err)))
+                                .expect_log("Connection closed");
+                        }
+                    }
                 });
             }
         } else {
@@ -115,11 +129,18 @@ impl AppOp {
                         let sid = sid.clone();
                         let tx = backend.clone();
                         thread::spawn(move || {
-                            let query = user::submit_phone_token(server_url, secret, sid, token);
-                            tx.send(BKCommand::SendBKResponse(BKResponse::SubmitPhoneToken(
-                                query,
-                            )))
-                            .expect_log("Connection closed");
+                            match user::submit_phone_token(server_url, secret, sid, token) {
+                                Ok((sid, secret)) => {
+                                    let secret = Some(secret);
+                                    APPOP!(valid_phone_token, (sid, secret));
+                                }
+                                Err(err) => {
+                                    tx.send(BKCommand::SendBKResponse(
+                                        BKResponse::SubmitPhoneTokenError(err),
+                                    ))
+                                    .expect_log("Connection closed");
+                                }
+                            }
                         });
                     }
                 }
@@ -159,15 +180,23 @@ impl AppOp {
                     let sid = sid.clone();
                     let tx = backend.clone();
                     thread::spawn(move || {
-                        let query = user::add_threepid(
+                        match user::add_threepid(
                             login_data.server_url,
                             login_data.access_token,
                             login_data.identity_url,
                             secret,
                             sid,
-                        );
-                        tx.send(BKCommand::SendBKResponse(BKResponse::AddThreePID(query)))
-                            .expect_log("Connection closed");
+                        ) {
+                            Ok(_) => {
+                                APPOP!(added_three_pid);
+                            }
+                            Err(err) => {
+                                tx.send(BKCommand::SendBKResponse(BKResponse::AddThreePIDError(
+                                    err,
+                                )))
+                                .expect_log("Connection closed");
+                            }
+                        }
                     });
                 }
                 _ => {}
@@ -599,14 +628,21 @@ impl AppOp {
             button.set_sensitive(false);
             name.set_editable(false);
             thread::spawn(move || {
-                let query = user::set_username(
+                match user::set_username(
                     login_data.server_url,
                     login_data.access_token,
                     login_data.uid,
                     username,
-                );
-                tx.send(BKCommand::SendBKResponse(BKResponse::SetUserName(query)))
-                    .expect_log("Connection closed");
+                ) {
+                    Ok(username) => {
+                        let u = Some(username);
+                        APPOP!(show_new_username, (u));
+                    }
+                    Err(err) => {
+                        tx.send(BKCommand::SendBKResponse(BKResponse::SetUserNameError(err)))
+                            .expect_log("Connection closed");
+                    }
+                }
             });
         } else {
             button.hide();
@@ -665,15 +701,23 @@ impl AppOp {
                     password_btn_stack.set_visible_child_name("spinner");
                     let tx = self.backend.clone();
                     thread::spawn(move || {
-                        let query = user::change_password(
+                        match user::change_password(
                             login_data.server_url,
                             login_data.access_token,
                             login_data.uid.localpart().into(),
                             old.to_string(),
                             new.to_string(),
-                        );
-                        tx.send(BKCommand::SendBKResponse(BKResponse::ChangePassword(query)))
-                            .expect_log("Connection closed");
+                        ) {
+                            Ok(_) => {
+                                APPOP!(password_changed);
+                            }
+                            Err(err) => {
+                                tx.send(BKCommand::SendBKResponse(
+                                    BKResponse::ChangePasswordError(err),
+                                ))
+                                .expect_log("Connection closed");
+                            }
+                        }
                     });
                 }
             }
@@ -780,16 +824,22 @@ impl AppOp {
                         let password = password.clone();
                         let login_data = login_data.clone();
                         thread::spawn(move || {
-                            let query = user::account_destruction(
+                            match user::account_destruction(
                                 login_data.server_url.clone(),
                                 login_data.access_token.clone(),
                                 login_data.uid.localpart().into(),
                                 password,
-                            );
-                            tx.send(BKCommand::SendBKResponse(BKResponse::AccountDestruction(
-                                query,
-                            )))
-                            .expect_log("Connection closed");
+                            ) {
+                                Ok(_) => {
+                                    APPOP!(account_destruction_logoff);
+                                }
+                                Err(err) => {
+                                    tx.send(BKCommand::SendBKResponse(
+                                        BKResponse::AccountDestructionError(err),
+                                    ))
+                                    .expect_log("Connection closed");
+                                }
+                            }
                         });
                     }
                     _ => {}
diff --git a/fractal-gtk/src/appop/directory.rs b/fractal-gtk/src/appop/directory.rs
index 05661378..0eb9bae9 100644
--- a/fractal-gtk/src/appop/directory.rs
+++ b/fractal-gtk/src/appop/directory.rs
@@ -6,6 +6,7 @@ use std::thread;
 use fractal_api::backend::directory;
 use fractal_api::util::ResultExpectLog;
 
+use crate::app::App;
 use crate::appop::AppOp;
 
 use crate::backend::{BKCommand, BKResponse};
@@ -19,11 +20,17 @@ impl AppOp {
         let login_data = unwrap_or_unit_return!(self.login_data.clone());
         let tx = self.backend.clone();
         thread::spawn(move || {
-            let query = directory::protocols(login_data.server_url, login_data.access_token);
-            tx.send(BKCommand::SendBKResponse(BKResponse::DirectoryProtocols(
-                query,
-            )))
-            .expect_log("Connection closed");
+            match directory::protocols(login_data.server_url, login_data.access_token) {
+                Ok(protocols) => {
+                    APPOP!(set_protocols, (protocols));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(
+                        BKResponse::DirectoryProtocolsError(err),
+                    ))
+                    .expect_log("Connection closed");
+                }
+            }
         });
     }
 
diff --git a/fractal-gtk/src/appop/invite.rs b/fractal-gtk/src/appop/invite.rs
index 92090edc..550184db 100644
--- a/fractal-gtk/src/appop/invite.rs
+++ b/fractal-gtk/src/appop/invite.rs
@@ -239,8 +239,10 @@ impl AppOp {
                 thread::spawn(move || {
                     let query =
                         room::leave_room(login_data.server_url, login_data.access_token, room_id);
-                    tx.send(BKCommand::SendBKResponse(BKResponse::LeaveRoom(query)))
-                        .expect_log("Connection closed");
+                    if let Err(err) = query {
+                        tx.send(BKCommand::SendBKResponse(BKResponse::LeaveRoomError(err)))
+                            .expect_log("Connection closed");
+                    }
                 });
             }
             self.remove_inv(rid);
diff --git a/fractal-gtk/src/appop/login.rs b/fractal-gtk/src/appop/login.rs
index 8ba4521c..9e91c928 100644
--- a/fractal-gtk/src/appop/login.rs
+++ b/fractal-gtk/src/appop/login.rs
@@ -7,6 +7,7 @@ use fractal_api::util::ResultExpectLog;
 
 use fractal_api::url::Url;
 
+use crate::app::App;
 use crate::appop::AppOp;
 
 use crate::backend::BKCommand;
@@ -183,9 +184,15 @@ impl AppOp {
         let _ = self.delete_pass("fractal");
         let tx = self.backend.clone();
         thread::spawn(move || {
-            let query = register::logout(login_data.server_url, login_data.access_token);
-            tx.send(BKCommand::SendBKResponse(BKResponse::Logout(query)))
-                .expect_log("Connection closed");
+            match register::logout(login_data.server_url, login_data.access_token) {
+                Ok(_) => {
+                    APPOP!(bk_logout);
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::LogoutError(err)))
+                        .expect_log("Connection closed");
+                }
+            }
         });
         self.bk_logout();
         *self.room_back_history.borrow_mut() = vec![];
diff --git a/fractal-gtk/src/appop/member.rs b/fractal-gtk/src/appop/member.rs
index 3528b69b..d8593060 100644
--- a/fractal-gtk/src/appop/member.rs
+++ b/fractal-gtk/src/appop/member.rs
@@ -195,9 +195,15 @@ impl AppOp {
         let login_data = unwrap_or_unit_return!(self.login_data.clone());
         let tx = self.backend.clone();
         thread::spawn(move || {
-            let query = user::search(login_data.server_url, login_data.access_token, term);
-            tx.send(BKCommand::SendBKResponse(BKResponse::UserSearch(query)))
-                .expect_log("Connection closed");
+            match user::search(login_data.server_url, login_data.access_token, term) {
+                Ok(users) => {
+                    APPOP!(user_search_finished, (users));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::UserSearchError(err)))
+                        .expect_log("Connection closed");
+                }
+            }
         });
     }
 }
diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs
index b599d88e..8c290d3f 100644
--- a/fractal-gtk/src/appop/message.rs
+++ b/fractal-gtk/src/appop/message.rs
@@ -146,14 +146,22 @@ impl AppOp {
             let event_id = last_message.id.clone();
             let tx = self.backend.clone();
             thread::spawn(move || {
-                let query = room::mark_as_read(
+                match room::mark_as_read(
                     login_data.server_url,
                     login_data.access_token,
                     room_id,
                     event_id,
-                );
-                tx.send(BKCommand::SendBKResponse(BKResponse::MarkedAsRead(query)))
-                    .expect_log("Connection closed");
+                ) {
+                    Ok((r, _)) => {
+                        APPOP!(clear_room_notifications, (r));
+                    }
+                    Err(err) => {
+                        tx.send(BKCommand::SendBKResponse(BKResponse::MarkedAsReadError(
+                            err,
+                        )))
+                        .expect_log("Connection closed");
+                    }
+                }
             });
         }
         None
@@ -206,10 +214,17 @@ impl AppOp {
                 _ => {
                     let tx = self.backend.clone();
                     thread::spawn(move || {
-                        let query =
-                            room::send_msg(login_data.server_url, login_data.access_token, msg);
-                        tx.send(BKCommand::SendBKResponse(BKResponse::SentMsg(query)))
-                            .expect_log("Connection closed");
+                        match room::send_msg(login_data.server_url, login_data.access_token, msg) {
+                            Ok((txid, evid)) => {
+                                APPOP!(msg_sent, (txid, evid));
+                                let initial = false;
+                                APPOP!(sync, (initial));
+                            }
+                            Err(err) => {
+                                tx.send(BKCommand::SendBKResponse(BKResponse::SentMsg(Err(err))))
+                                    .expect_log("Connection closed");
+                            }
+                        }
                     });
                 }
             }
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index cf796e96..e58add62 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -12,6 +12,7 @@ use std::thread;
 use gtk;
 use gtk::prelude::*;
 
+use crate::app::App;
 use crate::appop::AppOp;
 
 use crate::backend;
@@ -84,9 +85,15 @@ impl AppOp {
                 let room_id = room.id.clone();
                 let tx = self.backend.clone();
                 thread::spawn(move || {
-                    let query = room::get_room_members(server, access_token, room_id);
-                    tx.send(BKCommand::SendBKResponse(BKResponse::RoomMembers(query)))
-                        .expect_log("Connection closed");
+                    match room::get_room_members(server, access_token, room_id) {
+                        Ok((room, members)) => {
+                            APPOP!(set_room_members, (room, members));
+                        }
+                        Err(err) => {
+                            tx.send(BKCommand::SendBKResponse(BKResponse::RoomMembersError(err)))
+                                .expect_log("Connection closed");
+                        }
+                    }
                 });
                 // Download the room avatar
                 // TODO: Use the avatar url returned by sync
@@ -94,11 +101,17 @@ impl AppOp {
                 let access_token = login_data.access_token.clone();
                 let room_id = room.id.clone();
                 let tx = self.backend.clone();
-                thread::spawn(move || {
-                    let query = room::get_room_avatar(server, access_token, room_id);
-                    tx.send(BKCommand::SendBKResponse(BKResponse::RoomAvatar(query)))
-                        .expect_log("Connection closed");
-                });
+                thread::spawn(
+                    move || match room::get_room_avatar(server, access_token, room_id) {
+                        Ok((room, avatar)) => {
+                            APPOP!(set_room_avatar, (room, avatar));
+                        }
+                        Err(err) => {
+                            tx.send(BKCommand::SendBKResponse(BKResponse::RoomAvatar(Err(err))))
+                                .expect_log("Connection closed");
+                        }
+                    },
+                );
                 if clear_room_list {
                     roomlist.push(room.clone());
                 } else {
@@ -143,9 +156,15 @@ impl AppOp {
                 let access_token = login_data.access_token.clone();
                 let uid = login_data.uid.clone();
                 thread::spawn(move || {
-                    let query = room::add_to_fav(server, access_token, uid, room.id, tofav);
-                    tx.send(BKCommand::SendBKResponse(BKResponse::AddedToFav(query)))
-                        .expect_log("Connection closed");
+                    match room::add_to_fav(server, access_token, uid, room.id, tofav) {
+                        Ok((r, tofav)) => {
+                            APPOP!(added_to_fav, (r, tofav));
+                        }
+                        Err(err) => {
+                            tx.send(BKCommand::SendBKResponse(BKResponse::AddedToFavError(err)))
+                                .expect_log("Connection closed");
+                        }
+                    }
                 });
             });
 
@@ -293,8 +312,10 @@ impl AppOp {
         let tx = self.backend.clone();
         thread::spawn(move || {
             let query = room::leave_room(login_data.server_url, login_data.access_token, room_id);
-            tx.send(BKCommand::SendBKResponse(BKResponse::LeaveRoom(query)))
-                .expect_log("Connection closed");
+            if let Err(err) = query {
+                tx.send(BKCommand::SendBKResponse(BKResponse::LeaveRoomError(err)))
+                    .expect_log("Connection closed");
+            }
         });
         self.rooms.remove(&r);
         self.active_room = None;
@@ -364,16 +385,24 @@ impl AppOp {
         let name = n.clone();
         let tx = self.backend.clone();
         thread::spawn(move || {
-            let room_res = room::new_room(
+            match room::new_room(
                 login_data.server_url,
                 login_data.access_token,
                 name,
                 privacy,
-            );
-            tx.send(BKCommand::SendBKResponse(BKResponse::NewRoom(
-                room_res, int_id,
-            )))
-            .expect_log("Connection closed");
+            ) {
+                Ok(r) => {
+                    let id = Some(int_id);
+                    APPOP!(new_room, (r, id));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::NewRoom(
+                        Err(err),
+                        int_id,
+                    )))
+                    .expect_log("Connection closed");
+                }
+            }
         });
 
         let fakeroom = Room {
@@ -666,10 +695,15 @@ impl AppOp {
 
         let tx = self.backend.clone();
         thread::spawn(move || {
-            let query =
-                room::get_room_avatar(login_data.server_url, login_data.access_token, room_id);
-            tx.send(BKCommand::SendBKResponse(BKResponse::RoomAvatar(query)))
-                .expect_log("Connection closed");
+            match room::get_room_avatar(login_data.server_url, login_data.access_token, room_id) {
+                Ok((room, avatar)) => {
+                    APPOP!(set_room_avatar, (room, avatar));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::RoomAvatar(Err(err))))
+                        .expect_log("Connection closed");
+                }
+            }
         });
     }
 
diff --git a/fractal-gtk/src/appop/user.rs b/fractal-gtk/src/appop/user.rs
index 9a1f2ae6..7fbd1281 100644
--- a/fractal-gtk/src/appop/user.rs
+++ b/fractal-gtk/src/appop/user.rs
@@ -8,6 +8,7 @@ use fractal_api::util::ResultExpectLog;
 use std::path::PathBuf;
 use std::thread;
 
+use crate::app::App;
 use crate::appop::AppOp;
 
 use crate::cache::download_to_cache;
@@ -24,15 +25,27 @@ impl AppOp {
         let tx = self.backend.clone();
 
         thread::spawn(clone!(login_data, tx => move || {
-            let query = user::get_username(login_data.server_url, login_data.uid);
-            tx.send(BKCommand::SendBKResponse(BKResponse::Name(query)))
-                .expect_log("Connection closed");
+            match user::get_username(login_data.server_url, login_data.uid) {
+                Ok(username) => {
+                    APPOP!(set_username, (username));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::NameError(err)))
+                        .expect_log("Connection closed");
+                }
+            }
         }));
 
         thread::spawn(clone!(login_data, tx => move || {
-            let query = user::get_avatar(login_data.server_url, login_data.uid);
-            tx.send(BKCommand::SendBKResponse(BKResponse::Avatar(query)))
-                .expect_log("Connection closed");
+            match user::get_avatar(login_data.server_url, login_data.uid) {
+                Ok(path) => {
+                    APPOP!(set_avatar, (path));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::AvatarError(err)))
+                        .expect_log("Connection closed");
+                }
+            }
         }));
     }
 
diff --git a/fractal-gtk/src/widgets/address.rs b/fractal-gtk/src/widgets/address.rs
index bda3cd5a..4c21bdbe 100644
--- a/fractal-gtk/src/widgets/address.rs
+++ b/fractal-gtk/src/widgets/address.rs
@@ -11,6 +11,7 @@ use rand::{thread_rng, Rng};
 use std::sync::mpsc::Sender;
 use std::thread;
 
+use crate::app::App;
 use crate::appop::AppOp;
 use crate::backend::{BKCommand, BKResponse};
 
@@ -223,9 +224,17 @@ fn delete_address(
     access_token: AccessToken,
 ) {
     thread::spawn(move || {
-        let query = user::delete_three_pid(server_url, access_token, medium, address);
-        tx.send(BKCommand::SendBKResponse(BKResponse::DeleteThreePID(query)))
-            .expect_log("Connection closed");
+        match user::delete_three_pid(server_url, access_token, medium, address) {
+            Ok(_) => {
+                APPOP!(get_three_pid);
+            }
+            Err(err) => {
+                tx.send(BKCommand::SendBKResponse(BKResponse::DeleteThreePIDError(
+                    err,
+                )))
+                .expect_log("Connection closed");
+            }
+        }
     });
 }
 
@@ -240,14 +249,34 @@ fn add_address(
     let secret: String = thread_rng().sample_iter(&Alphanumeric).take(36).collect();
     thread::spawn(move || match medium {
         Medium::MsIsdn => {
-            let query = user::get_phone_token(server_url, access_token, id_server, address, secret);
-            tx.send(BKCommand::SendBKResponse(BKResponse::GetTokenPhone(query)))
-                .expect_log("Connection closed");
+            match user::get_phone_token(server_url, access_token, id_server, address, secret) {
+                Ok((sid, secret)) => {
+                    let sid = Some(sid);
+                    let secret = Some(secret);
+                    APPOP!(get_token_phone, (sid, secret))
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::GetTokenPhoneError(
+                        err,
+                    )))
+                    .expect_log("Connection closed");
+                }
+            }
         }
         Medium::Email => {
-            let query = user::get_email_token(server_url, access_token, id_server, address, secret);
-            tx.send(BKCommand::SendBKResponse(BKResponse::GetTokenEmail(query)))
-                .expect_log("Connection closed");
+            match user::get_email_token(server_url, access_token, id_server, address, secret) {
+                Ok((sid, secret)) => {
+                    let sid = Some(sid);
+                    let secret = Some(secret);
+                    APPOP!(get_token_email, (sid, secret));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::GetTokenEmailError(
+                        err,
+                    )))
+                    .expect_log("Connection closed");
+                }
+            }
         }
     });
 }
diff --git a/fractal-gtk/src/widgets/room_settings.rs b/fractal-gtk/src/widgets/room_settings.rs
index d33e7d35..37f51637 100644
--- a/fractal-gtk/src/widgets/room_settings.rs
+++ b/fractal-gtk/src/widgets/room_settings.rs
@@ -16,6 +16,7 @@ use gtk::prelude::*;
 
 use crate::actions;
 use crate::actions::{ButtonState, StateExt};
+use crate::app::App;
 use crate::backend::{BKCommand, BKResponse};
 use crate::types::Member;
 use crate::util::markup_text;
@@ -435,11 +436,17 @@ impl RoomSettings {
         let access_token = self.access_token.clone();
         let room_id = self.room.id.clone();
         let tx = self.backend.clone();
-        thread::spawn(move || {
-            let query = room::get_room_avatar(server, access_token, room_id);
-            tx.send(BKCommand::SendBKResponse(BKResponse::RoomAvatar(query)))
-                .expect_log("Connection closed");
-        });
+        thread::spawn(
+            move || match room::get_room_avatar(server, access_token, room_id) {
+                Ok((room, avatar)) => {
+                    APPOP!(set_room_avatar, (room, avatar));
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::RoomAvatar(Err(err))))
+                        .expect_log("Connection closed");
+                }
+            },
+        );
         let image = widgets::Avatar::avatar_new(Some(100));
         let _data = image.circle(
             self.room.id.to_string(),
@@ -502,11 +509,17 @@ impl RoomSettings {
         let access_token = self.access_token.clone();
         let room_id = room.id.clone();
         let tx = self.backend.clone();
-        thread::spawn(move || {
-            let query = room::set_room_name(server, access_token, room_id, new_name);
-            tx.send(BKCommand::SendBKResponse(BKResponse::SetRoomName(query)))
-                .expect_log("Connection closed");
-        });
+        thread::spawn(
+            move || match room::set_room_name(server, access_token, room_id, new_name) {
+                Ok(_) => {
+                    APPOP!(show_new_room_name);
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::SetRoomNameError(err)))
+                        .expect_log("Connection closed");
+                }
+            },
+        );
 
         None
     }
@@ -556,11 +569,19 @@ impl RoomSettings {
         let access_token = self.access_token.clone();
         let room_id = room.id.clone();
         let tx = self.backend.clone();
-        thread::spawn(move || {
-            let query = room::set_room_topic(server, access_token, room_id, topic);
-            tx.send(BKCommand::SendBKResponse(BKResponse::SetRoomTopic(query)))
-                .expect_log("Connection closed");
-        });
+        thread::spawn(
+            move || match room::set_room_topic(server, access_token, room_id, topic) {
+                Ok(_) => {
+                    APPOP!(show_new_room_topic);
+                }
+                Err(err) => {
+                    tx.send(BKCommand::SendBKResponse(BKResponse::SetRoomTopicError(
+                        err,
+                    )))
+                    .expect_log("Connection closed");
+                }
+            },
+        );
 
         None
     }
diff --git a/fractal-matrix-api/src/backend/types.rs b/fractal-matrix-api/src/backend/types.rs
index 535b4452..5afd588b 100644
--- a/fractal-matrix-api/src/backend/types.rs
+++ b/fractal-matrix-api/src/backend/types.rs
@@ -1,14 +1,11 @@
 use ruma_identifiers::{RoomId, UserId};
 use std::collections::HashMap;
-use std::path::PathBuf;
 use std::sync::mpsc::Sender;
 use std::sync::{Arc, Condvar, Mutex};
 use std::thread;
 
 use crate::error::Error;
 
-use crate::r0::contact::get_identifiers::ThirdPartyIdentifier;
-use crate::r0::thirdparty::get_supported_protocols::ProtocolInstance;
 use crate::r0::AccessToken;
 use crate::types::Event;
 use crate::types::Member;
@@ -50,19 +47,6 @@ pub enum BKCommand {
 pub enum BKResponse {
     ShutDown,
     Token(UserId, AccessToken, Option<String>, Url, Url),
-    Logout(Result<(), Error>),
-    Name(Result<Option<String>, Error>),
-    SetUserName(Result<String, Error>),
-    GetThreePID(Result<Vec<ThirdPartyIdentifier>, Error>),
-    GetTokenEmail(Result<(String, String), Error>),
-    GetTokenPhone(Result<(String, String), Error>),
-    SubmitPhoneToken(Result<(Option<String>, String), Error>),
-    AddThreePID(Result<(), Error>),
-    DeleteThreePID(Result<(), Error>),
-    ChangePassword(Result<(), Error>),
-    AccountDestruction(Result<(), Error>),
-    Avatar(Result<PathBuf, Error>),
-    SetUserAvatar(Result<PathBuf, Error>),
     Sync(Result<String, Error>),
     Rooms(Result<(Vec<Room>, Option<Room>), Error>),
     UpdateRooms(Result<Vec<Room>, Error>),
@@ -72,28 +56,16 @@ pub enum BKResponse {
     RoomMemberEvent(Event),
     RoomMessages(Result<Vec<Message>, Error>),
     RoomMessagesInit(Vec<Message>),
-    RoomMessagesTo(Result<(Vec<Message>, RoomId, Option<String>), Error>),
-    RoomMembers(Result<(RoomId, Vec<Member>), Error>),
     SentMsg(Result<(String, String), Error>),
-    SentMsgRedaction(Result<(String, String), Error>),
-    DirectoryProtocols(Result<Vec<ProtocolInstance>, Error>),
     DirectorySearch(Result<Vec<Room>, Error>),
     JoinRoom(Result<(), Error>),
-    LeaveRoom(Result<(), Error>),
-    MarkedAsRead(Result<(RoomId, String), Error>),
-    SetRoomName(Result<(), Error>),
-    SetRoomTopic(Result<(), Error>),
-    SetRoomAvatar(Result<(), Error>),
     RemoveMessage(Result<(RoomId, String), Error>),
     RoomName(RoomId, String),
     RoomTopic(RoomId, String),
-    Media(Result<String, Error>),
     MediaUrl(Url),
     AttachedFile(Result<Message, Error>),
     NewRoom(Result<Room, Error>, RoomId),
-    AddedToFav(Result<(RoomId, bool), Error>),
     RoomNotifications(RoomId, i32, i32),
-    UserSearch(Result<Vec<Member>, Error>),
 
     //errors
     LoginError(Error),
@@ -101,7 +73,32 @@ pub enum BKResponse {
     SendTypingError(Error),
     SetRoomError(Error),
     InviteError(Error),
-    ChangeLanguage(Result<(), Error>),
+    ChangeLanguageError(Error),
+    NameError(Error),
+    AvatarError(Error),
+    MarkedAsReadError(Error),
+    UserSearchError(Error),
+    LogoutError(Error),
+    LeaveRoomError(Error),
+    DirectoryProtocolsError(Error),
+    RoomMembersError(Error),
+    AddedToFavError(Error),
+    GetThreePIDError(Error),
+    AddThreePIDError(Error),
+    SubmitPhoneTokenError(Error),
+    SetUserNameError(Error),
+    ChangePasswordError(Error),
+    AccountDestructionError(Error),
+    DeleteThreePIDError(Error),
+    GetTokenPhoneError(Error),
+    GetTokenEmailError(Error),
+    SetRoomNameError(Error),
+    SetRoomTopicError(Error),
+    SetUserAvatarError(Error),
+    SetRoomAvatarError(Error),
+    RoomMessagesToError(Error),
+    MediaError(Error),
+    SentMsgRedactionError(Error),
 }
 
 #[derive(Debug, Clone, Copy)]


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