[fractal] API, BackendData: remove server_url field



commit 09eca65e1190146daeb8cec479fdfcfa1e482d7d
Author: Alejandro Domínguez <adomu net-c com>
Date:   Wed Sep 25 17:11:01 2019 +0200

    API, BackendData: remove server_url field

 fractal-gtk/src/actions/account_settings.rs |  12 +-
 fractal-gtk/src/actions/room_history.rs     |  45 ++++---
 fractal-gtk/src/actions/room_settings.rs    |  13 +-
 fractal-gtk/src/app/backend_loop.rs         |   5 +-
 fractal-gtk/src/app/connect/account.rs      |   3 +-
 fractal-gtk/src/appop/account.rs            |  41 ++++--
 fractal-gtk/src/appop/directory.rs          |   5 +-
 fractal-gtk/src/appop/invite.rs             |  10 +-
 fractal-gtk/src/appop/login.rs              |   7 +-
 fractal-gtk/src/appop/media_viewer.rs       |   9 +-
 fractal-gtk/src/appop/member.rs             |   4 +-
 fractal-gtk/src/appop/message.rs            |  15 ++-
 fractal-gtk/src/appop/notify.rs             |   8 +-
 fractal-gtk/src/appop/room.rs               |  54 ++++++--
 fractal-gtk/src/appop/room_settings.rs      |   1 +
 fractal-gtk/src/appop/start_chat.rs         |   6 +-
 fractal-gtk/src/appop/sync.rs               |   4 +-
 fractal-gtk/src/appop/user.rs               |  22 +++-
 fractal-gtk/src/cache/mod.rs                |  20 ++-
 fractal-gtk/src/widgets/address.rs          |  17 ++-
 fractal-gtk/src/widgets/image.rs            |   9 +-
 fractal-gtk/src/widgets/media_viewer.rs     |  26 ++--
 fractal-gtk/src/widgets/member.rs           |  14 ++-
 fractal-gtk/src/widgets/message.rs          |  28 +++--
 fractal-gtk/src/widgets/room.rs             |   5 +-
 fractal-gtk/src/widgets/room_history.rs     |  21 +++-
 fractal-gtk/src/widgets/room_settings.rs    |  27 ++--
 fractal-matrix-api/src/backend/directory.rs |   5 +-
 fractal-matrix-api/src/backend/media.rs     |  18 +--
 fractal-matrix-api/src/backend/mod.rs       | 189 ++++++++++++++--------------
 fractal-matrix-api/src/backend/register.rs  |  17 +--
 fractal-matrix-api/src/backend/room.rs      | 122 +++++++++++-------
 fractal-matrix-api/src/backend/stickers.rs  |  32 ++---
 fractal-matrix-api/src/backend/sync.rs      |   8 +-
 fractal-matrix-api/src/backend/types.rs     | 102 +++++++--------
 fractal-matrix-api/src/backend/user.rs      |  68 +++++-----
 36 files changed, 601 insertions(+), 391 deletions(-)
---
diff --git a/fractal-gtk/src/actions/account_settings.rs b/fractal-gtk/src/actions/account_settings.rs
index 68184e60..de8928fc 100644
--- a/fractal-gtk/src/actions/account_settings.rs
+++ b/fractal-gtk/src/actions/account_settings.rs
@@ -5,6 +5,7 @@ use gio::SimpleActionGroup;
 use gtk;
 use gtk::prelude::*;
 use std::sync::mpsc::Sender;
+use url::Url;
 
 use crate::backend::BKCommand;
 
@@ -14,7 +15,11 @@ use crate::widgets::FileDialog::open;
 use crate::actions::ButtonState;
 
 // This creates all actions a user can perform in the account settings
-pub fn new(window: &gtk::Window, backend: &Sender<BKCommand>) -> gio::SimpleActionGroup {
+pub fn new(
+    window: &gtk::Window,
+    backend: &Sender<BKCommand>,
+    server_url: Url,
+) -> gio::SimpleActionGroup {
     let actions = SimpleActionGroup::new();
     // TODO create two stats loading interaction and connect it to the avatar box
     let change_avatar =
@@ -32,7 +37,10 @@ pub fn new(window: &gtk::Window, backend: &Sender<BKCommand>) -> gio::SimpleActi
         if let Some(path) = open(&window, i18n("Select a new avatar").as_str(), &[filter]) {
             if let Some(file) = path.to_str() {
                 a.change_state(&ButtonState::Insensitive.into());
-                let _ = backend.send(BKCommand::SetUserAvatar(file.to_string()));
+                let _ = backend.send(BKCommand::SetUserAvatar(
+                    server_url.clone(),
+                    file.to_string(),
+                ));
             } else {
                 ErrorDialog::new(false, &i18n("Couldn’t open file"));
             }
diff --git a/fractal-gtk/src/actions/room_history.rs b/fractal-gtk/src/actions/room_history.rs
index 0a1ca80e..b56efc64 100644
--- a/fractal-gtk/src/actions/room_history.rs
+++ b/fractal-gtk/src/actions/room_history.rs
@@ -14,13 +14,14 @@ use gio::SimpleAction;
 use gio::SimpleActionGroup;
 use gtk;
 use gtk::prelude::*;
+use url::Url;
 
 use crate::widgets::ErrorDialog;
 use crate::widgets::FileDialog::save;
 use crate::widgets::SourceDialog;
 
 /* This creates all actions the room history can perform */
-pub fn new(backend: Sender<BKCommand>, ui: UI) -> gio::SimpleActionGroup {
+pub fn new(backend: Sender<BKCommand>, server_url: Url, ui: UI) -> gio::SimpleActionGroup {
     let actions = SimpleActionGroup::new();
     /* Action for each message */
     let reply = SimpleAction::new("reply", glib::VariantTy::new("s").ok());
@@ -83,22 +84,22 @@ pub fn new(backend: Sender<BKCommand>, ui: UI) -> gio::SimpleActionGroup {
     });
 
     let b = backend.clone();
-    open_with.connect_activate(move |_, data| {
+    open_with.connect_activate(clone!(server_url => move |_, data| {
         if let Some(m) = get_message(data) {
             let url = m.url.unwrap_or_default();
-            let _ = b.send(BKCommand::GetMedia(url));
+            let _ = b.send(BKCommand::GetMedia(server_url.clone(), url));
         }
-    });
+    }));
 
     let b = backend.clone();
     let parent_weak = parent.downgrade();
-    save_as.connect_activate(move |_, data| {
+    save_as.connect_activate(clone!(server_url => move |_, data| {
         if let Some(m) = get_message(data) {
             let name = m.body;
             let url = m.url.unwrap_or_default();
 
             let (tx, rx): (Sender<String>, Receiver<String>) = channel();
-            let _ = b.send(BKCommand::GetMediaAsync(url, tx));
+            let _ = b.send(BKCommand::GetMediaAsync(server_url.clone(), url, tx));
 
             let parent_weak = parent_weak.clone();
             gtk::timeout_add(
@@ -124,16 +125,16 @@ pub fn new(backend: Sender<BKCommand>, ui: UI) -> gio::SimpleActionGroup {
                 }),
             );
         }
-    });
+    }));
 
     let b = backend.clone();
-    copy_image.connect_activate(move |_, data| {
+    copy_image.connect_activate(clone!(server_url => move |_, data| {
         if let Some(m) = get_message(data) {
             let url = m.url.unwrap_or_default();
 
             let (tx, rx): (Sender<String>, Receiver<String>) = channel();
 
-            let _ = b.send(BKCommand::GetMediaAsync(url.clone(), tx));
+            let _ = b.send(BKCommand::GetMediaAsync(server_url.clone(), url.clone(), tx));
 
             gtk::timeout_add(50, move || match rx.try_recv() {
                 Err(TryRecvError::Empty) => gtk::Continue(true),
@@ -155,7 +156,7 @@ pub fn new(backend: Sender<BKCommand>, ui: UI) -> gio::SimpleActionGroup {
                 }
             });
         }
-    });
+    }));
 
     copy_text.connect_activate(move |_, data| {
         if let Some(m) = get_message(data) {
@@ -166,10 +167,10 @@ pub fn new(backend: Sender<BKCommand>, ui: UI) -> gio::SimpleActionGroup {
         }
     });
 
-    load_more_messages.connect_activate(move |_, data| {
+    load_more_messages.connect_activate(clone!(server_url => move |_, data| {
         let id = get_room_id(data);
-        request_more_messages(&backend, id);
-    });
+        request_more_messages(&backend, server_url.clone(), id);
+    }));
 
     actions
 }
@@ -190,23 +191,33 @@ fn get_room_id(data: Option<&glib::Variant>) -> Option<String> {
     data.as_ref()?.get_str().map(|s| s.to_string())
 }
 
-fn request_more_messages(backend: &Sender<BKCommand>, id: Option<String>) -> Option<()> {
+fn request_more_messages(
+    backend: &Sender<BKCommand>,
+    server_url: Url,
+    id: Option<String>,
+) -> Option<()> {
     let op = App::get_op()?;
     let op = op.lock().unwrap();
     let id = id?;
     let r = op.rooms.get(&id)?;
     if let Some(prev_batch) = r.prev_batch.clone() {
         backend
-            .send(BKCommand::GetRoomMessages(id, prev_batch))
+            .send(BKCommand::GetRoomMessages(server_url, id, prev_batch))
             .unwrap();
     } else if let Some(msg) = r.messages.iter().next() {
         // no prev_batch so we use the last message to calculate that in the backend
         backend
-            .send(BKCommand::GetRoomMessagesFromMsg(id, msg.clone()))
+            .send(BKCommand::GetRoomMessagesFromMsg(
+                server_url,
+                id,
+                msg.clone(),
+            ))
             .unwrap();
     } else if let Some(from) = op.since.clone() {
         // no messages and no prev_batch so we use the last since
-        backend.send(BKCommand::GetRoomMessages(id, from)).unwrap();
+        backend
+            .send(BKCommand::GetRoomMessages(server_url, id, from))
+            .unwrap();
     }
     None
 }
diff --git a/fractal-gtk/src/actions/room_settings.rs b/fractal-gtk/src/actions/room_settings.rs
index f0fbbbf8..a3ae076e 100644
--- a/fractal-gtk/src/actions/room_settings.rs
+++ b/fractal-gtk/src/actions/room_settings.rs
@@ -5,6 +5,7 @@ use glib;
 use gtk;
 use gtk::prelude::*;
 use std::sync::mpsc::Sender;
+use url::Url;
 
 use crate::backend::BKCommand;
 use crate::i18n::i18n;
@@ -15,7 +16,11 @@ use crate::widgets::FileDialog::open;
 use crate::actions::ButtonState;
 
 // This creates all actions a user can perform in the room settings
-pub fn new(window: &gtk::Window, backend: &Sender<BKCommand>) -> gio::SimpleActionGroup {
+pub fn new(
+    window: &gtk::Window,
+    backend: &Sender<BKCommand>,
+    server_url: Url,
+) -> gio::SimpleActionGroup {
     let actions = SimpleActionGroup::new();
     // TODO create two stats loading interaction and conect it to the avatar box
     let change_avatar = SimpleAction::new_stateful(
@@ -37,7 +42,11 @@ pub fn new(window: &gtk::Window, backend: &Sender<BKCommand>) -> gio::SimpleActi
             if let Some(path) = open(&window, i18n("Select a new avatar").as_str(), &[filter]) {
                 if let Some(file) = path.to_str() {
                     a.change_state(&ButtonState::Insensitive.into());
-                    let _ = backend.send(BKCommand::SetRoomAvatar(id, file.to_string()));
+                    let _ = backend.send(BKCommand::SetRoomAvatar(
+                        server_url.clone(),
+                        id,
+                        file.to_string(),
+                    ));
                 } 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 1f3d1892..9ef327dc 100644
--- a/fractal-gtk/src/app/backend_loop.rs
+++ b/fractal-gtk/src/app/backend_loop.rs
@@ -72,9 +72,8 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                     let secret = Some(secret);
                     APPOP!(valid_phone_token, (sid, secret));
                 }
-                Ok(BKResponse::AddThreePID(Ok(list))) => {
-                    let l = Some(list);
-                    APPOP!(added_three_pid, (l));
+                Ok(BKResponse::AddThreePID(Ok(_))) => {
+                    APPOP!(added_three_pid);
                 }
                 Ok(BKResponse::DeleteThreePID(Ok(_))) => {
                     APPOP!(get_three_pid);
diff --git a/fractal-gtk/src/app/connect/account.rs b/fractal-gtk/src/app/connect/account.rs
index 598abc96..b82e4446 100644
--- a/fractal-gtk/src/app/connect/account.rs
+++ b/fractal-gtk/src/app/connect/account.rs
@@ -76,7 +76,8 @@ impl App {
         // FIXME: don't clone the backend
         let backend = self.op.lock().unwrap().backend.clone();
         let window = self.main_window.upcast_ref::<gtk::Window>();
-        let actions = AccountSettings::new(&window, &backend);
+        let server_url = self.op.lock().unwrap().server_url.clone();
+        let actions = AccountSettings::new(&window, &backend, server_url);
         let container = self
             .ui
             .builder
diff --git a/fractal-gtk/src/appop/account.rs b/fractal-gtk/src/appop/account.rs
index 442ce3be..16b2cb2a 100644
--- a/fractal-gtk/src/appop/account.rs
+++ b/fractal-gtk/src/appop/account.rs
@@ -1,4 +1,3 @@
-use fractal_api::clone;
 use gtk;
 use gtk::prelude::*;
 use log::info;
@@ -21,10 +20,12 @@ impl AppOp {
     }
 
     pub fn get_three_pid(&self) {
-        self.backend.send(BKCommand::GetThreePID).unwrap();
+        self.backend
+            .send(BKCommand::GetThreePID(self.server_url.clone()))
+            .unwrap();
     }
 
-    pub fn added_three_pid(&self, _l: Option<String>) {
+    pub fn added_three_pid(&self) {
         self.get_three_pid();
     }
 
@@ -32,6 +33,7 @@ impl AppOp {
         if let Some(sid) = sid {
             if let Some(secret) = secret {
                 let _ = self.backend.send(BKCommand::AddThreePID(
+                    self.server_url.clone(),
                     self.identity_url.to_string(), // TODO: Change type to Url
                     secret.clone(),
                     sid.clone(),
@@ -86,13 +88,13 @@ impl AppOp {
         });
 
         let value = entry.clone();
-        let id_server = self.identity_url.to_string();
+        let server_url = self.server_url.clone();
         dialog.connect_response(move |w, r| {
             match gtk::ResponseType::from(r) {
                 gtk::ResponseType::Ok => {
                     if let Some(token) = value.get_text() {
                         let _ = backend.send(BKCommand::SubmitPhoneToken(
-                            id_server.clone(), // TODO: Change type to Url
+                            server_url.clone(),
                             secret.clone(),
                             sid.clone(),
                             token.to_string(),
@@ -125,12 +127,14 @@ impl AppOp {
         );
         let backend = self.backend.clone();
         let id_server = self.identity_url.to_string();
+        let server_url = self.server_url.clone();
         dialog.add_button(&i18n("Cancel"), gtk::ResponseType::Cancel.into());
         dialog.add_button(&i18n("Continue"), gtk::ResponseType::Ok.into());
         dialog.connect_response(move |w, r| {
             match gtk::ResponseType::from(r) {
                 gtk::ResponseType::Ok => {
                     let _ = backend.send(BKCommand::AddThreePID(
+                        server_url.clone(),
                         id_server.clone(), // TODO: Change type to Url
                         secret.clone(),
                         sid.clone(),
@@ -486,7 +490,12 @@ impl AppOp {
 
         let uid = self.uid.clone().unwrap_or_default();
         let data = w.circle(uid.clone(), self.username.clone(), 100, None, None);
-        download_to_cache(self.backend.clone(), uid.clone(), data.clone());
+        download_to_cache(
+            self.backend.clone(),
+            self.server_url.clone(),
+            uid.clone(),
+            data.clone(),
+        );
 
         /* FIXME: hack to make the avatar drawing area clickable*/
         let current = stack.get_visible_child_name();
@@ -542,7 +551,9 @@ impl AppOp {
             button.set_image(Some(&spinner));
             button.set_sensitive(false);
             name.set_editable(false);
-            self.backend.send(BKCommand::SetUserName(username)).unwrap();
+            self.backend
+                .send(BKCommand::SetUserName(self.server_url.clone(), username))
+                .unwrap();
         } else {
             button.hide();
         }
@@ -599,6 +610,7 @@ impl AppOp {
                         password_btn.set_sensitive(false);
                         password_btn_stack.set_visible_child_name("spinner");
                         let _ = self.backend.send(BKCommand::ChangePassword(
+                            self.server_url.clone(),
                             mxid,
                             old.to_string(),
                             new.to_string(),
@@ -698,20 +710,25 @@ impl AppOp {
         dialog.add_button("Confirm", gtk::ResponseType::Ok.into());
         dialog.add_button("Cancel", gtk::ResponseType::Cancel.into());
 
-        let flag = mark.get_active();
+        let _flag = mark.get_active(); // TODO: This is not used, remove from UI?
+        let server_url = self.server_url.clone();
         if let Some(password) = entry.get_text() {
             if let Some(mxid) = self.uid.clone() {
                 let backend = self.backend.clone();
                 let password = password.to_string();
-                dialog.connect_response(clone!(mxid, password, flag => move |w, r| {
+                dialog.connect_response(move |w, r| {
                     match gtk::ResponseType::from(r) {
                         gtk::ResponseType::Ok => {
-                            let _ = backend.send(BKCommand::AccountDestruction(mxid.clone(), 
password.clone(), flag));
-                        },
+                            let _ = backend.send(BKCommand::AccountDestruction(
+                                server_url.clone(),
+                                mxid.clone(),
+                                password.clone(),
+                            ));
+                        }
                         _ => {}
                     }
                     w.destroy();
-                }));
+                });
                 dialog.show_all();
             }
         }
diff --git a/fractal-gtk/src/appop/directory.rs b/fractal-gtk/src/appop/directory.rs
index 48fd9a4f..513b1910 100644
--- a/fractal-gtk/src/appop/directory.rs
+++ b/fractal-gtk/src/appop/directory.rs
@@ -12,7 +12,9 @@ use fractal_api::r0::thirdparty::get_supported_protocols::ProtocolInstance;
 
 impl AppOp {
     pub fn init_protocols(&self) {
-        self.backend.send(BKCommand::DirectoryProtocols).unwrap();
+        self.backend
+            .send(BKCommand::DirectoryProtocols(self.server_url.clone()))
+            .unwrap();
     }
 
     pub fn set_protocols(&self, protocols: Vec<ProtocolInstance>) {
@@ -116,6 +118,7 @@ impl AppOp {
 
         self.backend
             .send(BKCommand::DirectorySearch(
+                self.server_url.clone(),
                 homeserver,
                 q.get_text().unwrap().to_string(),
                 protocol,
diff --git a/fractal-gtk/src/appop/invite.rs b/fractal-gtk/src/appop/invite.rs
index 5dedce58..74661c1a 100644
--- a/fractal-gtk/src/appop/invite.rs
+++ b/fractal-gtk/src/appop/invite.rs
@@ -159,7 +159,11 @@ impl AppOp {
         if let &Some(ref r) = &self.active_room {
             for user in &self.invite_list {
                 self.backend
-                    .send(BKCommand::Invite(r.clone(), user.0.uid.clone()))
+                    .send(BKCommand::Invite(
+                        self.server_url.clone(),
+                        r.clone(),
+                        user.0.uid.clone(),
+                    ))
                     .unwrap();
             }
         }
@@ -213,11 +217,11 @@ impl AppOp {
         if let Some(rid) = rid {
             if accept {
                 self.backend
-                    .send(BKCommand::AcceptInv(rid.clone()))
+                    .send(BKCommand::AcceptInv(self.server_url.clone(), rid.clone()))
                     .unwrap();
             } else {
                 self.backend
-                    .send(BKCommand::RejectInv(rid.clone()))
+                    .send(BKCommand::RejectInv(self.server_url.clone(), rid.clone()))
                     .unwrap();
             }
             self.remove_inv(rid);
diff --git a/fractal-gtk/src/appop/login.rs b/fractal-gtk/src/appop/login.rs
index 09f80016..74efbe8a 100644
--- a/fractal-gtk/src/appop/login.rs
+++ b/fractal-gtk/src/appop/login.rs
@@ -185,9 +185,8 @@ impl AppOp {
     ) -> Option<()> {
         self.server_url = server;
 
-        let ser = self.server_url.to_string();
         self.backend
-            .send(BKCommand::SetToken(token?, uid?, ser))  // TODO: Change command type to url
+            .send(BKCommand::SetToken(token?, uid?))
             .unwrap();
         Some(())
     }
@@ -207,7 +206,9 @@ impl AppOp {
 
     pub fn logout(&mut self) {
         let _ = self.delete_pass("fractal");
-        self.backend.send(BKCommand::Logout).unwrap();
+        self.backend
+            .send(BKCommand::Logout(self.server_url.clone()))
+            .unwrap();
         self.bk_logout();
     }
 }
diff --git a/fractal-gtk/src/appop/media_viewer.rs b/fractal-gtk/src/appop/media_viewer.rs
index 5e63a609..814e4458 100644
--- a/fractal-gtk/src/appop/media_viewer.rs
+++ b/fractal-gtk/src/appop/media_viewer.rs
@@ -31,8 +31,13 @@ impl AppOp {
         {
             let room_id = self.active_room.as_ref()?;
             let room = self.rooms.get(room_id)?;
-            let mut panel =
-                widgets::MediaViewer::new(self.backend.clone(), main_window.clone(), room, &msg);
+            let mut panel = widgets::MediaViewer::new(
+                self.backend.clone(),
+                main_window.clone(),
+                room,
+                &msg,
+                self.server_url.clone(),
+            );
             panel.display_media_viewer(msg);
             let (body, header) = panel.create()?;
 
diff --git a/fractal-gtk/src/appop/member.rs b/fractal-gtk/src/appop/member.rs
index 0649f2f2..0307d945 100644
--- a/fractal-gtk/src/appop/member.rs
+++ b/fractal-gtk/src/appop/member.rs
@@ -191,7 +191,9 @@ impl AppOp {
 
     pub fn search_invite_user(&self, term: Option<String>) {
         if let Some(t) = term {
-            self.backend.send(BKCommand::UserSearch(t)).unwrap();
+            self.backend
+                .send(BKCommand::UserSearch(self.server_url.clone(), t))
+                .unwrap();
         }
     }
 }
diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs
index 1e8f872e..92804cb0 100644
--- a/fractal-gtk/src/appop/message.rs
+++ b/fractal-gtk/src/appop/message.rs
@@ -58,7 +58,8 @@ impl AppOp {
         let messages = self.history.as_ref()?.get_listbox();
         if let Some(ui_msg) = self.create_new_room_message(&msg) {
             let backend = self.backend.clone();
-            let mb = widgets::MessageBox::new(backend).tmpwidget(&ui_msg)?;
+            let mb =
+                widgets::MessageBox::new(backend, self.server_url.clone()).tmpwidget(&ui_msg)?;
             let m = mb.get_listbox_row()?;
             messages.add(m);
 
@@ -92,7 +93,8 @@ impl AppOp {
         for t in self.msg_queue.iter().rev().filter(|m| m.msg.room == r.id) {
             if let Some(ui_msg) = self.create_new_room_message(&t.msg) {
                 let backend = self.backend.clone();
-                let mb = widgets::MessageBox::new(backend).tmpwidget(&ui_msg)?;
+                let mb = widgets::MessageBox::new(backend, self.server_url.clone())
+                    .tmpwidget(&ui_msg)?;
                 let m = mb.get_listbox_row()?;
                 messages.add(m);
 
@@ -129,6 +131,7 @@ impl AppOp {
 
             self.backend
                 .send(BKCommand::MarkAsRead(
+                    self.server_url.clone(),
                     last_message.room.clone(),
                     last_message.id.clone(),
                 ))
@@ -172,10 +175,14 @@ impl AppOp {
             let msg = next.msg.clone();
             match &next.msg.mtype[..] {
                 "m.image" | "m.file" | "m.audio" => {
-                    self.backend.send(BKCommand::AttachFile(msg)).unwrap();
+                    self.backend
+                        .send(BKCommand::AttachFile(self.server_url.clone(), msg))
+                        .unwrap();
                 }
                 _ => {
-                    self.backend.send(BKCommand::SendMsg(msg)).unwrap();
+                    self.backend
+                        .send(BKCommand::SendMsg(self.server_url.clone(), msg))
+                        .unwrap();
                 }
             }
         } else {
diff --git a/fractal-gtk/src/appop/notify.rs b/fractal-gtk/src/appop/notify.rs
index 5162412d..a570eea7 100644
--- a/fractal-gtk/src/appop/notify.rs
+++ b/fractal-gtk/src/appop/notify.rs
@@ -57,9 +57,11 @@ impl AppOp {
         };
 
         let (tx, rx): (Sender<(String, String)>, Receiver<(String, String)>) = channel();
-        let _ = self
-            .backend
-            .send(BKCommand::GetUserInfoAsync(msg.sender.clone(), Some(tx)));
+        let _ = self.backend.send(BKCommand::GetUserInfoAsync(
+            self.server_url.clone(),
+            msg.sender.clone(),
+            Some(tx),
+        ));
 
         let room_id = room_id.to_string();
         let id = id.to_string();
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index 5c2d8e34..18a71618 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -72,12 +72,18 @@ impl AppOp {
             } else {
                 // Request all joined members for each new room
                 self.backend
-                    .send(BKCommand::GetRoomMembers(room.id.clone()))
+                    .send(BKCommand::GetRoomMembers(
+                        self.server_url.clone(),
+                        room.id.clone(),
+                    ))
                     .unwrap();
                 // Download the room avatar
                 // TODO: Use the avatar url returned by sync
                 self.backend
-                    .send(BKCommand::GetRoomAvatar(room.id.clone()))
+                    .send(BKCommand::GetRoomAvatar(
+                        self.server_url.clone(),
+                        room.id.clone(),
+                    ))
                     .unwrap();
                 if clear_room_list {
                     roomlist.push(room.clone());
@@ -117,9 +123,14 @@ impl AppOp {
             container.add(self.roomlist.widget());
 
             let bk = self.backend.clone();
+            let server_url = self.server_url.clone();
             self.roomlist.connect_fav(move |room, tofav| {
-                bk.send(BKCommand::AddToFav(room.id.clone(), tofav))
-                    .unwrap();
+                bk.send(BKCommand::AddToFav(
+                    server_url.clone(),
+                    room.id.clone(),
+                    tofav,
+                ))
+                .unwrap();
             });
             // Select active room in the sidebar
             if let Some(ref active_room) = self.active_room {
@@ -200,7 +211,10 @@ impl AppOp {
 
         // getting room details
         self.backend
-            .send(BKCommand::SetRoom(active_room.clone()))
+            .send(BKCommand::SetRoom(
+                self.server_url.clone(),
+                active_room.clone(),
+            ))
             .unwrap();
 
         /* create the intitial list of messages to fill the new room history */
@@ -228,7 +242,11 @@ impl AppOp {
             history.destroy();
         }
 
-        let actions = actions::RoomHistory::new(self.backend.clone(), self.ui.clone());
+        let actions = actions::RoomHistory::new(
+            self.backend.clone(),
+            self.server_url.clone(),
+            self.ui.clone(),
+        );
         let mut history = widgets::RoomHistory::new(actions, active_room.clone(), self);
         history.create(messages);
         self.history = Some(history);
@@ -242,7 +260,9 @@ impl AppOp {
 
     pub fn really_leave_active_room(&mut self) {
         let r = self.active_room.clone().unwrap_or_default();
-        self.backend.send(BKCommand::LeaveRoom(r.clone())).unwrap();
+        self.backend
+            .send(BKCommand::LeaveRoom(self.server_url.clone(), r.clone()))
+            .unwrap();
         self.rooms.remove(&r);
         self.active_room = None;
         self.clear_tmp_msgs();
@@ -308,7 +328,12 @@ impl AppOp {
 
         let internal_id: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
         self.backend
-            .send(BKCommand::NewRoom(n.clone(), p, internal_id.clone()))
+            .send(BKCommand::NewRoom(
+                self.server_url.clone(),
+                n.clone(),
+                p,
+                internal_id.clone(),
+            ))
             .unwrap();
 
         let mut fakeroom = Room::new(internal_id.clone(), RoomMembership::Joined(RoomTag::None));
@@ -443,7 +468,9 @@ impl AppOp {
             .trim()
             .to_string();
 
-        self.backend.send(BKCommand::JoinRoom(n.clone())).unwrap();
+        self.backend
+            .send(BKCommand::JoinRoom(self.server_url.clone(), n.clone()))
+            .unwrap();
     }
 
     pub fn new_room(&mut self, r: Room, internal_id: Option<String>) {
@@ -590,7 +617,9 @@ impl AppOp {
             return;
         }
 
-        self.backend.send(BKCommand::GetRoomAvatar(roomid)).unwrap();
+        self.backend
+            .send(BKCommand::GetRoomAvatar(self.server_url.clone(), roomid))
+            .unwrap();
     }
 
     pub fn update_typing_notification(&mut self) {
@@ -635,7 +664,10 @@ impl AppOp {
             }
             self.typing.insert(active_room.clone(), now);
             self.backend
-                .send(BKCommand::SendTyping(active_room.clone()))
+                .send(BKCommand::SendTyping(
+                    self.server_url.clone(),
+                    active_room.clone(),
+                ))
                 .unwrap();
         }
     }
diff --git a/fractal-gtk/src/appop/room_settings.rs b/fractal-gtk/src/appop/room_settings.rs
index 6bb3fb9d..7c22d9f4 100644
--- a/fractal-gtk/src/appop/room_settings.rs
+++ b/fractal-gtk/src/appop/room_settings.rs
@@ -31,6 +31,7 @@ impl AppOp {
                 self.backend.clone(),
                 self.uid.clone(),
                 room.clone(),
+                self.server_url.clone(),
             );
             let (body, header) = panel.create()?;
 
diff --git a/fractal-gtk/src/appop/start_chat.rs b/fractal-gtk/src/appop/start_chat.rs
index 72dbd2e8..1bdfca39 100644
--- a/fractal-gtk/src/appop/start_chat.rs
+++ b/fractal-gtk/src/appop/start_chat.rs
@@ -21,7 +21,11 @@ impl AppOp {
 
         let internal_id: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
         self.backend
-            .send(BKCommand::DirectChat(user.0.clone(), internal_id.clone()))
+            .send(BKCommand::DirectChat(
+                self.server_url.clone(),
+                user.0.clone(),
+                internal_id.clone(),
+            ))
             .unwrap();
         self.close_direct_chat_dialog();
 
diff --git a/fractal-gtk/src/appop/sync.rs b/fractal-gtk/src/appop/sync.rs
index 5cc85862..ab36f39a 100644
--- a/fractal-gtk/src/appop/sync.rs
+++ b/fractal-gtk/src/appop/sync.rs
@@ -21,7 +21,9 @@ impl AppOp {
             // do the initial sync without a since:
             // https://matrix.org/docs/spec/client_server/latest.html#syncing
             let since = if initial { None } else { self.since.clone() };
-            self.backend.send(BKCommand::Sync(since, initial)).unwrap();
+            self.backend
+                .send(BKCommand::Sync(self.server_url.clone(), since, initial))
+                .unwrap();
         }
     }
 
diff --git a/fractal-gtk/src/appop/user.rs b/fractal-gtk/src/appop/user.rs
index 8a000fc8..8e92dd0d 100644
--- a/fractal-gtk/src/appop/user.rs
+++ b/fractal-gtk/src/appop/user.rs
@@ -11,8 +11,12 @@ use crate::widgets::AvatarExt;
 
 impl AppOp {
     pub fn get_username(&self) {
-        self.backend.send(BKCommand::GetUsername).unwrap();
-        self.backend.send(BKCommand::GetAvatar).unwrap();
+        self.backend
+            .send(BKCommand::GetUsername(self.server_url.clone()))
+            .unwrap();
+        self.backend
+            .send(BKCommand::GetAvatar(self.server_url.clone()))
+            .unwrap();
     }
 
     pub fn show_user_info(&self) {
@@ -53,7 +57,12 @@ impl AppOp {
             let w = widgets::Avatar::avatar_new(Some(40));
             let uid = self.uid.clone().unwrap_or_default();
             let data = w.circle(uid.clone(), self.username.clone(), 40, None, None);
-            download_to_cache(self.backend.clone(), uid.clone(), data.clone());
+            download_to_cache(
+                self.backend.clone(),
+                self.server_url.clone(),
+                uid.clone(),
+                data.clone(),
+            );
 
             avatar.add(&w);
             stack.set_visible_child_name("info");
@@ -67,7 +76,12 @@ impl AppOp {
                 let w = widgets::Avatar::avatar_new(Some(24));
                 let uid = self.uid.clone().unwrap_or_default();
                 let data = w.circle(uid.clone(), self.username.clone(), 24, None, None);
-                download_to_cache(self.backend.clone(), uid.clone(), data.clone());
+                download_to_cache(
+                    self.backend.clone(),
+                    self.server_url.clone(),
+                    uid.clone(),
+                    data.clone(),
+                );
 
                 eb.add(&w);
             }
diff --git a/fractal-gtk/src/cache/mod.rs b/fractal-gtk/src/cache/mod.rs
index 1213d6ea..bd7e8a4f 100644
--- a/fractal-gtk/src/cache/mod.rs
+++ b/fractal-gtk/src/cache/mod.rs
@@ -1,6 +1,7 @@
 use gtk;
 use gtk::LabelExt;
 use serde::{Deserialize, Serialize};
+use url::Url;
 
 use crate::types::Room;
 use crate::types::RoomList;
@@ -96,9 +97,18 @@ pub fn load() -> Result<CacheData, Error> {
 }
 
 /// this downloads a avatar and stores it in the cache folder
-pub fn download_to_cache(backend: Sender<BKCommand>, name: String, data: Rc<RefCell<AvatarData>>) {
+pub fn download_to_cache(
+    backend: Sender<BKCommand>,
+    server_url: Url,
+    name: String,
+    data: Rc<RefCell<AvatarData>>,
+) {
     let (tx, rx) = channel::<(String, String)>();
-    let _ = backend.send(BKCommand::GetUserInfoAsync(name.clone(), Some(tx)));
+    let _ = backend.send(BKCommand::GetUserInfoAsync(
+        server_url,
+        name.clone(),
+        Some(tx),
+    ));
 
     gtk::timeout_add(50, move || match rx.try_recv() {
         Err(TryRecvError::Empty) => gtk::Continue(true),
@@ -113,13 +123,14 @@ pub fn download_to_cache(backend: Sender<BKCommand>, name: String, data: Rc<RefC
 /* Get username based on the MXID, we should cache the username */
 pub fn download_to_cache_username(
     backend: Sender<BKCommand>,
+    server_url: Url,
     uid: &str,
     label: gtk::Label,
     avatar: Option<Rc<RefCell<AvatarData>>>,
 ) {
     let (tx, rx): (Sender<String>, Receiver<String>) = channel();
     backend
-        .send(BKCommand::GetUserNameAsync(uid.to_string(), tx))
+        .send(BKCommand::GetUserNameAsync(server_url, uid.to_string(), tx))
         .unwrap();
     gtk::timeout_add(50, move || match rx.try_recv() {
         Err(TryRecvError::Empty) => gtk::Continue(true),
@@ -140,6 +151,7 @@ pub fn download_to_cache_username(
  * FIXME: We should cache this request and do it before we need to display the username in an emote*/
 pub fn download_to_cache_username_emote(
     backend: Sender<BKCommand>,
+    server_url: Url,
     uid: &str,
     text: &str,
     label: gtk::Label,
@@ -147,7 +159,7 @@ pub fn download_to_cache_username_emote(
 ) {
     let (tx, rx): (Sender<String>, Receiver<String>) = channel();
     backend
-        .send(BKCommand::GetUserNameAsync(uid.to_string(), tx))
+        .send(BKCommand::GetUserNameAsync(server_url, uid.to_string(), tx))
         .unwrap();
     let text = text.to_string();
     gtk::timeout_add(50, move || match rx.try_recv() {
diff --git a/fractal-gtk/src/widgets/address.rs b/fractal-gtk/src/widgets/address.rs
index 08c53506..697d29d5 100644
--- a/fractal-gtk/src/widgets/address.rs
+++ b/fractal-gtk/src/widgets/address.rs
@@ -5,6 +5,7 @@ use gtk::prelude::*;
 use rand::distributions::Alphanumeric;
 use rand::{thread_rng, Rng};
 use std::sync::mpsc::Sender;
+use url::Url;
 
 use crate::appop::AppOp;
 use crate::backend::BKCommand;
@@ -159,6 +160,7 @@ impl<'a> Address<'a> {
         let action = self.action.clone();
         let entry = self.entry.clone();
         let address = self.address.clone();
+        let server_url = self.op.server_url.clone();
         let id_server = self.op.identity_url.to_string();
         let backend = self.op.backend.clone();
         self.signal_id = Some(self.button.clone().connect_clicked(move |w| {
@@ -179,7 +181,7 @@ impl<'a> Address<'a> {
 
             match action {
                 Some(AddressAction::Delete) => {
-                    delete_address(&backend, medium, address.clone());
+                    delete_address(&backend, medium, address.clone(), server_url.clone());
                 }
                 Some(AddressAction::Add) => {
                     add_address(
@@ -187,6 +189,7 @@ impl<'a> Address<'a> {
                         medium,
                         id_server.clone(), // TODO: Change type to Url
                         entry.get_text().map_or(None, |gstr| Some(gstr.to_string())),
+                        server_url.clone(),
                     );
                 }
                 _ => {}
@@ -199,9 +202,10 @@ fn delete_address(
     backend: &Sender<BKCommand>,
     medium: Medium,
     address: Option<String>,
+    server_url: Url,
 ) -> Option<String> {
     backend
-        .send(BKCommand::DeleteThreePID(medium, address?))
+        .send(BKCommand::DeleteThreePID(server_url, medium, address?))
         .unwrap();
     None
 }
@@ -211,17 +215,22 @@ fn add_address(
     medium: Medium,
     id_server: String,
     address: Option<String>,
+    server_url: Url,
 ) -> Option<String> {
     let secret: String = thread_rng().sample_iter(&Alphanumeric).take(36).collect();
     match medium {
         Medium::MsIsdn => {
             backend
-                .send(BKCommand::GetTokenPhone(id_server, address?, secret))
+                .send(BKCommand::GetTokenPhone(
+                    server_url, id_server, address?, secret,
+                ))
                 .unwrap();
         }
         Medium::Email => {
             backend
-                .send(BKCommand::GetTokenEmail(id_server, address?, secret))
+                .send(BKCommand::GetTokenEmail(
+                    server_url, id_server, address?, secret,
+                ))
                 .unwrap();
         }
     }
diff --git a/fractal-gtk/src/widgets/image.rs b/fractal-gtk/src/widgets/image.rs
index 14d63ec6..cb59e33b 100644
--- a/fractal-gtk/src/widgets/image.rs
+++ b/fractal-gtk/src/widgets/image.rs
@@ -12,6 +12,7 @@ use std::path::Path;
 use std::sync::mpsc::channel;
 use std::sync::mpsc::{Receiver, Sender};
 use std::sync::{Arc, Mutex};
+use url::Url;
 
 use crate::backend::BKCommand;
 use std::sync::mpsc::TryRecvError;
@@ -20,6 +21,7 @@ use std::sync::mpsc::TryRecvError;
 pub struct Image {
     pub path: String,
     pub local_path: Arc<Mutex<Option<String>>>,
+    pub server_url: Url,
     pub max_size: Option<(i32, i32)>,
     pub widget: DrawingArea,
     pub backend: Sender<BKCommand>,
@@ -47,7 +49,7 @@ impl Image {
     ///           .size(Some((50, 50)))
     ///           .build();
     /// ```
-    pub fn new(backend: &Sender<BKCommand>, path: &str) -> Image {
+    pub fn new(backend: &Sender<BKCommand>, server_url: Url, path: &str) -> Image {
         let da = DrawingArea::new();
         da.add_events(gdk::EventMask::ENTER_NOTIFY_MASK);
         da.add_events(gdk::EventMask::LEAVE_NOTIFY_MASK);
@@ -66,6 +68,7 @@ impl Image {
         Image {
             path: path.to_string(),
             local_path: Arc::new(Mutex::new(None)),
+            server_url,
             max_size: None,
             widget: da,
             pixbuf: Arc::new(Mutex::new(None)),
@@ -262,9 +265,9 @@ impl Image {
             // asyn load
             let (tx, rx): (Sender<String>, Receiver<String>) = channel();
             let command = if self.thumb {
-                BKCommand::GetThumbAsync(self.path.to_string(), tx)
+                BKCommand::GetThumbAsync(self.server_url.clone(), self.path.to_string(), tx)
             } else {
-                BKCommand::GetMediaAsync(self.path.to_string(), tx)
+                BKCommand::GetMediaAsync(self.server_url.clone(), self.path.to_string(), tx)
             };
             self.backend.send(command).unwrap();
             let local_path = self.local_path.clone();
diff --git a/fractal-gtk/src/widgets/media_viewer.rs b/fractal-gtk/src/widgets/media_viewer.rs
index 87c3588b..5c55214b 100644
--- a/fractal-gtk/src/widgets/media_viewer.rs
+++ b/fractal-gtk/src/widgets/media_viewer.rs
@@ -12,6 +12,7 @@ use glib::signal;
 use gtk;
 use gtk::prelude::*;
 use gtk::ResponseType;
+use url::Url;
 
 use crate::types::Message;
 use crate::types::Room;
@@ -40,6 +41,7 @@ struct Data {
     builder: gtk::Builder,
     main_window: gtk::Window,
     backend: Sender<BKCommand>,
+    server_url: Url,
 
     pub image: Option<image::Image>,
     media_list: Vec<Message>,
@@ -55,14 +57,15 @@ struct Data {
 impl Data {
     pub fn new(
         backend: Sender<BKCommand>,
+        server_url: Url,
         media_list: Vec<Message>,
         current_media_index: usize,
         main_window: gtk::Window,
         builder: gtk::Builder,
     ) -> Data {
         Data {
-            media_list: media_list,
-            current_media_index: current_media_index,
+            media_list,
+            current_media_index,
             prev_batch: None,
             loading_more_media: false,
             loading_error: false,
@@ -70,6 +73,7 @@ impl Data {
             image: None,
             builder,
             backend,
+            server_url,
             main_window,
             signal_id: None,
         }
@@ -235,7 +239,7 @@ impl Data {
             .clone()
             .unwrap_or_default();
 
-        let image = image::Image::new(&self.backend, &url)
+        let image = image::Image::new(&self.backend, self.server_url.clone(), &url)
             .fit_to_width(true)
             .center(true)
             .build();
@@ -255,6 +259,7 @@ impl MediaViewer {
         main_window: gtk::Window,
         room: &Room,
         current_media_msg: &Message,
+        server_url: Url,
     ) -> MediaViewer {
         let builder = gtk::Builder::new();
         builder
@@ -279,6 +284,7 @@ impl MediaViewer {
         MediaViewer {
             data: Rc::new(RefCell::new(Data::new(
                 backend.clone(),
+                server_url,
                 media_list,
                 current_media_index,
                 main_window,
@@ -324,10 +330,14 @@ impl MediaViewer {
             .get_object::<gtk::Viewport>("media_viewport")
             .expect("Cant find media_viewport in ui file.");
 
-        let image = image::Image::new(&self.backend, &media_msg.url.clone().unwrap_or_default())
-            .fit_to_width(true)
-            .center(true)
-            .build();
+        let image = image::Image::new(
+            &self.backend,
+            self.data.borrow().server_url.clone(),
+            &media_msg.url.clone().unwrap_or_default(),
+        )
+        .fit_to_width(true)
+        .center(true)
+        .build();
 
         media_viewport.add(&image.widget);
         media_viewport.show_all();
@@ -583,6 +593,7 @@ fn load_more_media(data: Rc<RefCell<Data>>, builder: gtk::Builder, backend: Send
     let roomid = msg.room.clone();
     let first_media_id = Some(msg.id.clone());
     let prev_batch = data.borrow().prev_batch.clone();
+    let server_url = data.borrow().server_url.clone();
 
     let (tx, rx): (
         Sender<(Vec<Message>, String)>,
@@ -590,6 +601,7 @@ fn load_more_media(data: Rc<RefCell<Data>>, builder: gtk::Builder, backend: Send
     ) = channel();
     backend
         .send(BKCommand::GetMediaListAsync(
+            server_url,
             roomid,
             first_media_id,
             prev_batch,
diff --git a/fractal-gtk/src/widgets/member.rs b/fractal-gtk/src/widgets/member.rs
index 334de806..3174badd 100644
--- a/fractal-gtk/src/widgets/member.rs
+++ b/fractal-gtk/src/widgets/member.rs
@@ -63,7 +63,12 @@ impl<'a> MemberBox<'a> {
             None,
         );
         let member_id = self.member.uid.clone();
-        download_to_cache(backend.clone(), member_id.clone(), data.clone());
+        download_to_cache(
+            backend.clone(),
+            self.op.server_url.clone(),
+            member_id.clone(),
+            data.clone(),
+        );
 
         avatar.set_margin_start(3);
         avatar.set_valign(gtk::Align::Center);
@@ -101,7 +106,12 @@ impl<'a> MemberBox<'a> {
             None,
         );
         let member_id = self.member.uid.clone();
-        download_to_cache(backend.clone(), member_id.clone(), data.clone());
+        download_to_cache(
+            backend.clone(),
+            self.op.server_url.clone(),
+            member_id.clone(),
+            data.clone(),
+        );
 
         avatar.set_margin_start(3);
 
diff --git a/fractal-gtk/src/widgets/message.rs b/fractal-gtk/src/widgets/message.rs
index bee93301..b1428316 100644
--- a/fractal-gtk/src/widgets/message.rs
+++ b/fractal-gtk/src/widgets/message.rs
@@ -9,6 +9,7 @@ use glib;
 use gtk;
 use gtk::prelude::*;
 use pango;
+use url::Url;
 
 use crate::backend::BKCommand;
 
@@ -33,6 +34,7 @@ use crate::widgets::AvatarExt;
 #[derive(Clone, Debug)]
 pub struct MessageBox {
     backend: Sender<BKCommand>,
+    server_url: Url,
     username: gtk::Label,
     pub username_event_box: gtk::EventBox,
     eventbox: gtk::EventBox,
@@ -43,7 +45,7 @@ pub struct MessageBox {
 }
 
 impl MessageBox {
-    pub fn new(backend: Sender<BKCommand>) -> MessageBox {
+    pub fn new(backend: Sender<BKCommand>, server_url: Url) -> MessageBox {
         let username = gtk::Label::new(None);
         let eb = gtk::EventBox::new();
         let eventbox = gtk::EventBox::new();
@@ -55,8 +57,9 @@ impl MessageBox {
         gesture.set_touch_only(true);
 
         MessageBox {
-            backend: backend,
-            username: username,
+            backend,
+            server_url,
+            username,
             username_event_box: eb,
             eventbox,
             gesture,
@@ -180,9 +183,15 @@ impl MessageBox {
             self.username.set_text(&uid);
         }
 
-        download_to_cache(self.backend.clone(), uid.clone(), data.clone());
+        download_to_cache(
+            self.backend.clone(),
+            self.server_url.clone(),
+            uid.clone(),
+            data.clone(),
+        );
         download_to_cache_username(
             self.backend.clone(),
+            self.server_url.clone(),
             &uid,
             self.username.clone(),
             Some(data.clone()),
@@ -311,7 +320,7 @@ impl MessageBox {
             Some(ref m) => m.clone(),
             None => msg.url.clone().unwrap_or_default(),
         };
-        let image = widgets::image::Image::new(&self.backend, &img_path)
+        let image = widgets::image::Image::new(&self.backend, self.server_url.clone(), &img_path)
             .size(Some(globals::MAX_IMAGE_SIZE))
             .build();
 
@@ -329,7 +338,7 @@ impl MessageBox {
         let bx = gtk::Box::new(gtk::Orientation::Horizontal, 0);
         let backend = self.backend.clone();
         if let Some(url) = msg.url.as_ref() {
-            let image = widgets::image::Image::new(&backend, url)
+            let image = widgets::image::Image::new(&backend, self.server_url.clone(), url)
                 .size(Some(globals::MAX_STICKER_SIZE))
                 .build();
             image.widget.set_tooltip_text(Some(&msg.body[..]));
@@ -349,7 +358,11 @@ impl MessageBox {
 
         let (tx, rx): (Sender<String>, Receiver<String>) = channel();
         backend
-            .send(BKCommand::GetMediaUrl(url.clone(), tx))
+            .send(BKCommand::GetMediaUrl(
+                self.server_url.clone(),
+                url.clone(),
+                tx,
+            ))
             .unwrap();
 
         gtk::timeout_add(
@@ -482,6 +495,7 @@ impl MessageBox {
 
         download_to_cache_username_emote(
             self.backend.clone(),
+            self.server_url.clone(),
             &sname,
             &markup,
             msg_label.clone(),
diff --git a/fractal-gtk/src/widgets/room.rs b/fractal-gtk/src/widgets/room.rs
index 8d56a946..244cf6c4 100644
--- a/fractal-gtk/src/widgets/room.rs
+++ b/fractal-gtk/src/widgets/room.rs
@@ -119,8 +119,11 @@ impl<'a> RoomBox<'a> {
         let join_button = gtk::Button::new_with_label(i18n("Join").as_str());
         let room_id = room.id.clone();
         let backend = self.op.backend.clone();
+        let server_url = self.op.server_url.clone();
         join_button.connect_clicked(move |_| {
-            backend.send(BKCommand::JoinRoom(room_id.clone())).unwrap();
+            backend
+                .send(BKCommand::JoinRoom(server_url.clone(), room_id.clone()))
+                .unwrap();
         });
         join_button.set_property_width_request(JOIN_BUTTON_WIDTH);
 
diff --git a/fractal-gtk/src/widgets/room_history.rs b/fractal-gtk/src/widgets/room_history.rs
index c6d7177a..36bc4382 100644
--- a/fractal-gtk/src/widgets/room_history.rs
+++ b/fractal-gtk/src/widgets/room_history.rs
@@ -20,6 +20,7 @@ use gio::SimpleActionGroup;
 use glib::source;
 use gtk;
 use gtk::prelude::*;
+use url::Url;
 
 struct List {
     list: VecDeque<Element>,
@@ -89,6 +90,7 @@ pub struct RoomHistory {
     /* Contains a list of msg ids to keep track of the displayed messages */
     rows: Rc<RefCell<List>>,
     backend: Sender<BKCommand>,
+    server_url: Url,
     source_id: Rc<RefCell<Option<source::SourceId>>>,
     queue: Rc<RefCell<VecDeque<MessageContent>>>,
 }
@@ -116,6 +118,7 @@ impl RoomHistory {
         RoomHistory {
             rows: Rc::new(RefCell::new(List::new(scroll, listbox))),
             backend: op.backend.clone(),
+            server_url: op.server_url.clone(),
             source_id: Rc::new(RefCell::new(None)),
             queue: Rc::new(RefCell::new(VecDeque::new())),
         }
@@ -152,6 +155,7 @@ impl RoomHistory {
         } else {
             /* Lacy load initial messages */
             let source_id = self.source_id.clone();
+            let server_url = self.server_url.clone();
             *self.source_id.borrow_mut() = Some(gtk::idle_add(move || {
                 let mut data = queue.borrow_mut();
                 if let Some(mut item) = data.pop_front() {
@@ -189,7 +193,12 @@ impl RoomHistory {
                         let divider = Element::NewDivider(create_new_message_divider());
                         rows.borrow_mut().add_top(divider);
                     }
-                    item.widget = create_row(item.clone(), has_header, backend.clone());
+                    item.widget = create_row(
+                        item.clone(),
+                        has_header,
+                        backend.clone(),
+                        server_url.clone(),
+                    );
                     rows.borrow_mut().add_top(Element::Message(item));
                     if let Some(day_divider) = day_divider {
                         rows.borrow_mut().add_top(day_divider);
@@ -247,7 +256,12 @@ impl RoomHistory {
             rows.add_bottom(day_divider);
         }
 
-        let b = create_row(item.clone(), has_header, self.backend.clone());
+        let b = create_row(
+            item.clone(),
+            has_header,
+            self.backend.clone(),
+            self.server_url.clone(),
+        );
         item.widget = b;
         rows.add_bottom(Element::Message(item));
         None
@@ -291,10 +305,11 @@ fn create_row(
     row: MessageContent,
     has_header: bool,
     backend: Sender<BKCommand>,
+    server_url: Url,
 ) -> Option<widgets::MessageBox> {
     /* we need to create a message with the username, so that we don't have to pass
      * all information to the widget creating each row */
-    let mut mb = widgets::MessageBox::new(backend);
+    let mut mb = widgets::MessageBox::new(backend, server_url);
     mb.create(&row, has_header && row.mtype != RowType::Emote);
 
     Some(mb)
diff --git a/fractal-gtk/src/widgets/room_settings.rs b/fractal-gtk/src/widgets/room_settings.rs
index d6474172..24ed4cc5 100644
--- a/fractal-gtk/src/widgets/room_settings.rs
+++ b/fractal-gtk/src/widgets/room_settings.rs
@@ -7,6 +7,7 @@ use crate::i18n::ni18n_f;
 use gio::prelude::*;
 use gtk;
 use gtk::prelude::*;
+use url::Url;
 
 use crate::actions;
 use crate::actions::{ButtonState, StateExt};
@@ -27,6 +28,7 @@ pub struct RoomSettings {
     builder: gtk::Builder,
     members_list: Option<MembersList>,
     backend: Sender<BKCommand>,
+    server_url: Url,
 }
 
 impl RoomSettings {
@@ -35,6 +37,7 @@ impl RoomSettings {
         backend: Sender<BKCommand>,
         uid: Option<String>,
         room: Room,
+        server_url: Url,
     ) -> RoomSettings {
         let builder = gtk::Builder::new();
 
@@ -46,16 +49,17 @@ impl RoomSettings {
             .get_object::<gtk::Stack>("room_settings_stack")
             .expect("Can't find room_settings_stack in ui file.");
 
-        let actions = actions::RoomSettings::new(&window, &backend);
+        let actions = actions::RoomSettings::new(&window, &backend, server_url.clone());
         stack.insert_action_group("room-settings", Some(&actions));
 
         RoomSettings {
             actions,
-            room: room,
-            uid: uid,
-            builder: builder,
+            room,
+            uid,
+            builder,
             members_list: None,
-            backend: backend,
+            backend,
+            server_url,
         }
     }
 
@@ -430,7 +434,12 @@ impl RoomSettings {
             None,
             None,
         );
-        download_to_cache(self.backend.clone(), self.room.id.clone(), data);
+        download_to_cache(
+            self.backend.clone(),
+            self.server_url.clone(),
+            self.room.id.clone(),
+            data,
+        );
 
         if edit {
             let overlay = self
@@ -483,7 +492,8 @@ impl RoomSettings {
         button.set_sensitive(false);
         entry.set_editable(false);
 
-        let command = BKCommand::SetRoomName(room.id.clone(), new_name.clone());
+        let command =
+            BKCommand::SetRoomName(self.server_url.clone(), room.id.clone(), new_name.clone());
         self.backend.send(command).unwrap();
 
         None
@@ -530,7 +540,8 @@ impl RoomSettings {
         button.set_sensitive(false);
         name.set_editable(false);
 
-        let command = BKCommand::SetRoomTopic(room.id.clone(), topic.clone());
+        let command =
+            BKCommand::SetRoomTopic(self.server_url.clone(), room.id.clone(), topic.clone());
         self.backend.send(command).unwrap();
 
         None
diff --git a/fractal-matrix-api/src/backend/directory.rs b/fractal-matrix-api/src/backend/directory.rs
index 487026a6..3136ac67 100644
--- a/fractal-matrix-api/src/backend/directory.rs
+++ b/fractal-matrix-api/src/backend/directory.rs
@@ -24,11 +24,10 @@ use crate::r0::thirdparty::get_supported_protocols::Parameters as SupportedProto
 use crate::r0::thirdparty::get_supported_protocols::Response as SupportedProtocolsResponse;
 use crate::types::Room;
 
-pub fn protocols(bk: &Backend) {
+pub fn protocols(bk: &Backend, base: Url) {
     let tx = bk.tx.clone();
     let access_token = bk.data.lock().unwrap().access_token.clone();
 
-    let base = bk.get_base_url();
     let params = SupportedProtocolsParameters { access_token };
 
     thread::spawn(move || {
@@ -55,6 +54,7 @@ pub fn protocols(bk: &Backend) {
 
 pub fn room_search(
     bk: &Backend,
+    base: Url,
     homeserver: Option<String>,
     generic_search_term: Option<String>,
     third_party: Option<String>,
@@ -78,7 +78,6 @@ pub fn room_search(
         })
         .unwrap_or(Ok(None))?;
 
-    let base = bk.get_base_url();
     let access_token = data.lock().unwrap().access_token.clone();
 
     let since = if more {
diff --git a/fractal-matrix-api/src/backend/media.rs b/fractal-matrix-api/src/backend/media.rs
index 58168626..1821c8f2 100644
--- a/fractal-matrix-api/src/backend/media.rs
+++ b/fractal-matrix-api/src/backend/media.rs
@@ -21,9 +21,7 @@ use crate::util::ResultExpectLog;
 use crate::r0::filter::RoomEventFilter;
 use crate::types::Message;
 
-pub fn get_thumb_async(bk: &Backend, media: String, tx: Sender<String>) {
-    let baseu = bk.get_base_url();
-
+pub fn get_thumb_async(bk: &Backend, baseu: Url, media: String, tx: Sender<String>) {
     semaphore(bk.limit_threads.clone(), move || {
         let fname =
             dw_media(&baseu, &media, ContentType::default_thumbnail(), None).unwrap_or_default();
@@ -31,9 +29,7 @@ pub fn get_thumb_async(bk: &Backend, media: String, tx: Sender<String>) {
     });
 }
 
-pub fn get_media_async(bk: &Backend, media: String, tx: Sender<String>) {
-    let baseu = bk.get_base_url();
-
+pub fn get_media_async(bk: &Backend, baseu: Url, media: String, tx: Sender<String>) {
     semaphore(bk.limit_threads.clone(), move || {
         let fname = dw_media(&baseu, &media, ContentType::Download, None).unwrap_or_default();
         tx.send(fname).expect_log("Connection closed");
@@ -42,12 +38,12 @@ pub fn get_media_async(bk: &Backend, media: String, tx: Sender<String>) {
 
 pub fn get_media_list_async(
     bk: &Backend,
+    baseu: Url,
     roomid: &str,
     first_media_id: Option<String>,
     prev_batch: Option<String>,
     tx: Sender<(Vec<Message>, String)>,
 ) {
-    let baseu = bk.get_base_url();
     let tk = bk.data.lock().unwrap().access_token.clone();
     let room = String::from(roomid);
 
@@ -65,9 +61,7 @@ pub fn get_media_list_async(
     });
 }
 
-pub fn get_media(bk: &Backend, media: String) {
-    let baseu = bk.get_base_url();
-
+pub fn get_media(bk: &Backend, baseu: Url, media: String) {
     let tx = bk.tx.clone();
     thread::spawn(move || {
         let fname = dw_media(&baseu, &media, ContentType::Download, None);
@@ -76,9 +70,7 @@ pub fn get_media(bk: &Backend, media: String) {
     });
 }
 
-pub fn get_media_url(bk: &Backend, media: String, tx: Sender<String>) {
-    let baseu = bk.get_base_url();
-
+pub fn get_media_url(bk: &Backend, baseu: Url, media: String, tx: Sender<String>) {
     semaphore(bk.limit_threads.clone(), move || {
         let uri = resolve_media_url(&baseu, &media, ContentType::Download)
             .map(Url::into_string)
diff --git a/fractal-matrix-api/src/backend/mod.rs b/fractal-matrix-api/src/backend/mod.rs
index 6c863dd2..82284ab6 100644
--- a/fractal-matrix-api/src/backend/mod.rs
+++ b/fractal-matrix-api/src/backend/mod.rs
@@ -35,8 +35,6 @@ impl Backend {
         let data = BackendData {
             user_id: String::from("Guest"),
             access_token: String::new(),
-            server_url: Url::parse("https://matrix.org";)
-                .expect("Wrong server_url value in BackendData"),
             scalar_token: None,
             scalar_url: Url::parse("https://scalar.vector.im";)
                 .expect("Wrong scalar_url value in BackendData"),
@@ -55,12 +53,7 @@ impl Backend {
         }
     }
 
-    fn get_base_url(&self) -> Url {
-        self.data.lock().unwrap().server_url.clone()
-    }
-
-    fn url(&self, path: &str, mut params: Vec<(&str, String)>) -> Result<Url, Error> {
-        let base = self.get_base_url();
+    fn url(&self, base: Url, path: &str, mut params: Vec<(&str, String)>) -> Result<Url, Error> {
         let tk = self.data.lock().unwrap().access_token.clone();
 
         params.push(("access_token", tk));
@@ -91,7 +84,7 @@ impl Backend {
                 let r = register::login(self, user, passwd, &server);
                 bkerror!(r, tx, BKResponse::LoginError);
             }
-            Ok(BKCommand::Logout) => register::logout(self),
+            Ok(BKCommand::Logout(server)) => register::logout(self, server),
             Ok(BKCommand::Register(user, passwd, server)) => {
                 let r = register::register(self, user, passwd, &server);
                 bkerror!(r, tx, BKResponse::LoginError);
@@ -100,159 +93,161 @@ impl Backend {
                 let r = register::guest(self, &server);
                 bkerror!(r, tx, BKResponse::GuestLoginError);
             }
-            Ok(BKCommand::SetToken(token, uid, server)) => {
-                let r = register::set_token(self, token, uid, &server);
-                bkerror!(r, tx, BKResponse::LoginError);
-            }
+            Ok(BKCommand::SetToken(token, uid)) => register::set_token(self, token, uid),
 
             // User module
-            Ok(BKCommand::GetUsername) => user::get_username(self),
-            Ok(BKCommand::SetUserName(name)) => user::set_username(self, name),
-            Ok(BKCommand::GetThreePID) => user::get_threepid(self),
-            Ok(BKCommand::GetTokenEmail(identity, email, client_secret)) => {
-                let r = user::get_email_token(self, identity, email, client_secret);
+            Ok(BKCommand::GetUsername(server)) => user::get_username(self, server),
+            Ok(BKCommand::SetUserName(server, name)) => user::set_username(self, server, name),
+            Ok(BKCommand::GetThreePID(server)) => user::get_threepid(self, server),
+            Ok(BKCommand::GetTokenEmail(server, identity, email, client_secret)) => {
+                let r = user::get_email_token(self, server, identity, email, client_secret);
                 bkerror2!(r, tx, BKResponse::GetTokenEmail);
             }
-            Ok(BKCommand::GetTokenPhone(identity, phone, client_secret)) => {
-                let r = user::get_phone_token(self, identity, phone, client_secret);
+            Ok(BKCommand::GetTokenPhone(server, identity, phone, client_secret)) => {
+                let r = user::get_phone_token(self, server, identity, phone, client_secret);
                 bkerror2!(r, tx, BKResponse::GetTokenPhone);
             }
-            Ok(BKCommand::SubmitPhoneToken(_, client_secret, sid, token)) => {
-                user::submit_phone_token(self, client_secret, sid, token)
+            Ok(BKCommand::SubmitPhoneToken(server, client_secret, sid, token)) => {
+                user::submit_phone_token(self, server, client_secret, sid, token)
             }
-            Ok(BKCommand::AddThreePID(identity, client_secret, sid)) => {
-                let r = user::add_threepid(self, identity, client_secret, sid);
+            Ok(BKCommand::AddThreePID(server, identity, client_secret, sid)) => {
+                let r = user::add_threepid(self, server, identity, client_secret, sid);
                 bkerror2!(r, tx, BKResponse::AddThreePID);
             }
-            Ok(BKCommand::DeleteThreePID(medium, address)) => {
-                user::delete_three_pid(self, medium, address)
+            Ok(BKCommand::DeleteThreePID(server, medium, address)) => {
+                user::delete_three_pid(self, server, medium, address)
             }
-            Ok(BKCommand::ChangePassword(username, old_password, new_password)) => {
-                user::change_password(self, username, old_password, new_password)
+            Ok(BKCommand::ChangePassword(server, username, old_password, new_password)) => {
+                user::change_password(self, server, username, old_password, new_password)
             }
-            Ok(BKCommand::AccountDestruction(username, password, _)) => {
-                user::account_destruction(self, username, password)
+            Ok(BKCommand::AccountDestruction(server, username, password)) => {
+                user::account_destruction(self, server, username, password)
             }
-            Ok(BKCommand::GetAvatar) => user::get_avatar(self),
-            Ok(BKCommand::SetUserAvatar(file)) => user::set_user_avatar(self, file),
-            Ok(BKCommand::GetAvatarAsync(member, ctx)) => user::get_avatar_async(self, member, ctx),
-            Ok(BKCommand::GetUserInfoAsync(sender, ctx)) => {
-                user::get_user_info_async(self, sender, ctx)
+            Ok(BKCommand::GetAvatar(server)) => user::get_avatar(self, server),
+            Ok(BKCommand::SetUserAvatar(server, file)) => user::set_user_avatar(self, server, file),
+            Ok(BKCommand::GetAvatarAsync(server, member, ctx)) => {
+                user::get_avatar_async(self, server, member, ctx)
             }
-            Ok(BKCommand::GetUserNameAsync(sender, ctx)) => {
-                user::get_username_async(self, sender, ctx)
+            Ok(BKCommand::GetUserInfoAsync(server, sender, ctx)) => {
+                user::get_user_info_async(self, server, sender, ctx)
             }
-            Ok(BKCommand::UserSearch(term)) => user::search(self, term),
+            Ok(BKCommand::GetUserNameAsync(server, sender, ctx)) => {
+                user::get_username_async(server, sender, ctx)
+            }
+            Ok(BKCommand::UserSearch(server, term)) => user::search(self, server, term),
 
             // Sync module
-            Ok(BKCommand::Sync(since, initial)) => sync::sync(self, since, initial),
-            Ok(BKCommand::SyncForced) => sync::force_sync(self),
+            Ok(BKCommand::Sync(server, since, initial)) => sync::sync(self, server, since, initial),
+            Ok(BKCommand::SyncForced(server)) => sync::force_sync(self, server),
 
             // Room module
-            Ok(BKCommand::GetRoomMembers(room)) => {
-                let r = room::get_room_members(self, room);
+            Ok(BKCommand::GetRoomMembers(server, room)) => {
+                let r = room::get_room_members(self, server, room);
                 bkerror2!(r, tx, BKResponse::RoomMembers);
             }
-            Ok(BKCommand::GetRoomMessages(room, from)) => {
-                let r = room::get_room_messages(self, room, from);
+            Ok(BKCommand::GetRoomMessages(server, room, from)) => {
+                let r = room::get_room_messages(self, server, room, from);
                 bkerror2!(r, tx, BKResponse::RoomMessagesTo);
             }
-            Ok(BKCommand::GetRoomMessagesFromMsg(room, from)) => {
-                let r = room::get_room_messages_from_msg(self, room, from);
-                bkerror2!(r, tx, BKResponse::RoomMessagesTo);
+            Ok(BKCommand::GetRoomMessagesFromMsg(server, room, from)) => {
+                room::get_room_messages_from_msg(self, server, room, from)
             }
-            Ok(BKCommand::GetMessageContext(message)) => {
-                let r = room::get_message_context(self, message);
+            Ok(BKCommand::GetMessageContext(server, message)) => {
+                let r = room::get_message_context(self, server, message);
                 bkerror2!(r, tx, BKResponse::RoomMessagesTo);
             }
-            Ok(BKCommand::SendMsg(msg)) => {
-                let r = room::send_msg(self, msg);
+            Ok(BKCommand::SendMsg(server, msg)) => {
+                let r = room::send_msg(self, server, msg);
                 bkerror2!(r, tx, BKResponse::SentMsg);
             }
-            Ok(BKCommand::SendMsgRedaction(msg)) => {
-                let r = room::redact_msg(self, &msg);
+            Ok(BKCommand::SendMsgRedaction(server, msg)) => {
+                let r = room::redact_msg(self, server, &msg);
                 bkerror2!(r, tx, BKResponse::SentMsgRedaction);
             }
-            Ok(BKCommand::SendTyping(room)) => {
-                let r = room::send_typing(self, room);
+            Ok(BKCommand::SendTyping(server, room)) => {
+                let r = room::send_typing(self, server, room);
                 bkerror!(r, tx, BKResponse::SendTypingError);
             }
-            Ok(BKCommand::SetRoom(id)) => {
-                let r = room::set_room(self, id);
+            Ok(BKCommand::SetRoom(server, id)) => {
+                let r = room::set_room(self, server, id);
                 bkerror!(r, tx, BKResponse::SetRoomError);
             }
-            Ok(BKCommand::GetRoomAvatar(room)) => {
-                let r = room::get_room_avatar(self, room);
+            Ok(BKCommand::GetRoomAvatar(server, room)) => {
+                let r = room::get_room_avatar(self, server, room);
                 bkerror2!(r, tx, BKResponse::RoomAvatar);
             }
-            Ok(BKCommand::JoinRoom(roomid)) => {
-                let r = room::join_room(self, roomid);
+            Ok(BKCommand::JoinRoom(server, roomid)) => {
+                let r = room::join_room(self, server, roomid);
                 bkerror2!(r, tx, BKResponse::JoinRoom);
             }
-            Ok(BKCommand::LeaveRoom(roomid)) => {
-                let r = room::leave_room(self, &roomid);
+            Ok(BKCommand::LeaveRoom(server, roomid)) => {
+                let r = room::leave_room(self, server, &roomid);
                 bkerror2!(r, tx, BKResponse::LeaveRoom);
             }
-            Ok(BKCommand::MarkAsRead(roomid, evid)) => {
-                let r = room::mark_as_read(self, &roomid, &evid);
+            Ok(BKCommand::MarkAsRead(server, roomid, evid)) => {
+                let r = room::mark_as_read(self, server, &roomid, &evid);
                 bkerror2!(r, tx, BKResponse::MarkedAsRead);
             }
-            Ok(BKCommand::SetRoomName(roomid, name)) => {
-                let r = room::set_room_name(self, &roomid, &name);
+            Ok(BKCommand::SetRoomName(server, roomid, name)) => {
+                let r = room::set_room_name(self, server, &roomid, &name);
                 bkerror2!(r, tx, BKResponse::SetRoomName);
             }
-            Ok(BKCommand::SetRoomTopic(roomid, topic)) => {
-                let r = room::set_room_topic(self, &roomid, &topic);
+            Ok(BKCommand::SetRoomTopic(server, roomid, topic)) => {
+                let r = room::set_room_topic(self, server, &roomid, &topic);
                 bkerror2!(r, tx, BKResponse::SetRoomTopic);
             }
-            Ok(BKCommand::SetRoomAvatar(roomid, fname)) => {
-                let r = room::set_room_avatar(self, &roomid, &fname);
+            Ok(BKCommand::SetRoomAvatar(server, roomid, fname)) => {
+                let r = room::set_room_avatar(self, server, &roomid, &fname);
                 bkerror2!(r, tx, BKResponse::SetRoomAvatar);
             }
-            Ok(BKCommand::AttachFile(msg)) => {
-                let r = room::attach_file(self, msg);
+            Ok(BKCommand::AttachFile(server, msg)) => {
+                let r = room::attach_file(self, server, msg);
                 bkerror2!(r, tx, BKResponse::AttachedFile);
             }
-            Ok(BKCommand::NewRoom(name, privacy, internalid)) => {
-                let r = room::new_room(self, &name, privacy, internalid.clone());
+            Ok(BKCommand::NewRoom(server, name, privacy, internalid)) => {
+                let r = room::new_room(self, server, &name, privacy, internalid.clone());
                 if let Err(e) = r {
                     tx.send(BKResponse::NewRoom(Err(e), internalid))
                         .expect_log("Connection closed");
                 }
             }
-            Ok(BKCommand::DirectChat(user, internalid)) => {
-                let r = room::direct_chat(self, &user, internalid.clone());
+            Ok(BKCommand::DirectChat(server, user, internalid)) => {
+                let r = room::direct_chat(self, server, &user, internalid.clone());
                 if let Err(e) = r {
                     tx.send(BKResponse::NewRoom(Err(e), internalid))
                         .expect_log("Connection closed");
                 }
             }
-            Ok(BKCommand::AddToFav(roomid, tofav)) => {
-                let r = room::add_to_fav(self, roomid, tofav);
+            Ok(BKCommand::AddToFav(server, roomid, tofav)) => {
+                let r = room::add_to_fav(self, server, roomid, tofav);
                 bkerror2!(r, tx, BKResponse::AddedToFav);
             }
-            Ok(BKCommand::AcceptInv(roomid)) => {
-                let r = room::join_room(self, roomid);
+            Ok(BKCommand::AcceptInv(server, roomid)) => {
+                let r = room::join_room(self, server, roomid);
                 bkerror2!(r, tx, BKResponse::JoinRoom);
             }
-            Ok(BKCommand::RejectInv(roomid)) => {
-                let r = room::leave_room(self, &roomid);
+            Ok(BKCommand::RejectInv(server, roomid)) => {
+                let r = room::leave_room(self, server, &roomid);
                 bkerror2!(r, tx, BKResponse::LeaveRoom);
             }
-            Ok(BKCommand::Invite(room, userid)) => {
-                let r = room::invite(self, &room, &userid);
+            Ok(BKCommand::Invite(server, room, userid)) => {
+                let r = room::invite(self, server, &room, &userid);
                 bkerror!(r, tx, BKResponse::InviteError);
             }
 
             // Media module
-            Ok(BKCommand::GetThumbAsync(media, ctx)) => media::get_thumb_async(self, media, ctx),
-            Ok(BKCommand::GetMediaAsync(media, ctx)) => media::get_media_async(self, media, ctx),
-            Ok(BKCommand::GetMediaListAsync(roomid, first_media_id, prev_batch, ctx)) => {
-                media::get_media_list_async(self, &roomid, first_media_id, prev_batch, ctx)
+            Ok(BKCommand::GetThumbAsync(server, media, ctx)) => {
+                media::get_thumb_async(self, server, media, ctx)
+            }
+            Ok(BKCommand::GetMediaAsync(server, media, ctx)) => {
+                media::get_media_async(self, server, media, ctx)
+            }
+            Ok(BKCommand::GetMediaListAsync(server, roomid, first_media_id, prev_batch, ctx)) => {
+                media::get_media_list_async(self, server, &roomid, first_media_id, prev_batch, ctx)
             }
-            Ok(BKCommand::GetMedia(media)) => media::get_media(self, media),
-            Ok(BKCommand::GetMediaUrl(media, ctx)) => {
-                media::get_media_url(self, media.to_string(), ctx)
+            Ok(BKCommand::GetMedia(server, media)) => media::get_media(self, server, media),
+            Ok(BKCommand::GetMediaUrl(server, media, ctx)) => {
+                media::get_media_url(self, server, media, ctx)
             }
             Ok(BKCommand::GetFileAsync(url, ctx)) => {
                 let r = media::get_file_async(url, ctx);
@@ -260,8 +255,8 @@ impl Backend {
             }
 
             // Directory module
-            Ok(BKCommand::DirectoryProtocols) => directory::protocols(self),
-            Ok(BKCommand::DirectorySearch(dhs, dq, dtp, more)) => {
+            Ok(BKCommand::DirectoryProtocols(server)) => directory::protocols(self, server),
+            Ok(BKCommand::DirectorySearch(server, dhs, dq, dtp, more)) => {
                 let hs = match dhs {
                     ref a if a.is_empty() => None,
                     b => Some(b),
@@ -277,7 +272,7 @@ impl Backend {
                     b => Some(b),
                 };
 
-                let r = directory::room_search(self, hs, q, tp, more);
+                let r = directory::room_search(self, server, hs, q, tp, more);
                 bkerror2!(r, tx, BKResponse::DirectorySearch);
             }
 
@@ -286,8 +281,8 @@ impl Backend {
                 let r = stickers::list(self);
                 bkerror2!(r, tx, BKResponse::Stickers);
             }
-            Ok(BKCommand::SendSticker(room, sticker)) => {
-                let r = stickers::send(self, &room, &sticker);
+            Ok(BKCommand::SendSticker(server, room, sticker)) => {
+                let r = stickers::send(self, server, &room, &sticker);
                 bkerror2!(r, tx, BKResponse::Stickers);
             }
             Ok(BKCommand::PurchaseSticker(group)) => {
diff --git a/fractal-matrix-api/src/backend/register.rs b/fractal-matrix-api/src/backend/register.rs
index 5428f8a1..73cd6e9d 100644
--- a/fractal-matrix-api/src/backend/register.rs
+++ b/fractal-matrix-api/src/backend/register.rs
@@ -27,11 +27,10 @@ use crate::backend::types::BKResponse;
 use crate::backend::types::Backend;
 
 pub fn guest(bk: &Backend, server: &str) -> Result<(), Error> {
-    let data = bk.data.clone();
     let tx = bk.tx.clone();
+    let data = bk.data.clone();
 
     let base = Url::parse(server)?;
-    data.lock().unwrap().server_url = base.clone();
 
     let params = RegisterParameters {
         kind: RegistrationKind::Guest,
@@ -74,11 +73,10 @@ pub fn guest(bk: &Backend, server: &str) -> Result<(), Error> {
 }
 
 pub fn login(bk: &Backend, user: String, password: String, server: &str) -> Result<(), Error> {
-    let data = bk.data.clone();
     let tx = bk.tx.clone();
+    let data = bk.data.clone();
 
     let base = Url::parse(server)?;
-    data.lock().unwrap().server_url = base.clone();
 
     let body = if globals::EMAIL_RE.is_match(&user) {
         LoginBody {
@@ -137,29 +135,25 @@ pub fn login(bk: &Backend, user: String, password: String, server: &str) -> Resu
     Ok(())
 }
 
-pub fn set_token(bk: &Backend, token: String, uid: String, server: &str) -> Result<(), Error> {
-    bk.data.lock().unwrap().server_url = Url::parse(server)?;
+pub fn set_token(bk: &Backend, token: String, uid: String) {
     bk.data.lock().unwrap().access_token = token.clone();
     bk.data.lock().unwrap().user_id = uid.clone();
     bk.data.lock().unwrap().since = None;
     bk.tx
         .send(BKResponse::Token(uid, token, None))
         .expect_log("Connection closed");
-
-    Ok(())
 }
 
-pub fn logout(bk: &Backend) {
+pub fn logout(bk: &Backend, server: Url) {
     let data = bk.data.clone();
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let params = LogoutParameters {
         access_token: data.lock().unwrap().access_token.clone(),
     };
 
     thread::spawn(move || {
-        let query = logout_req(base, &params)
+        let query = logout_req(server, &params)
             .map_err(Into::into)
             .and_then(|request| {
                 HTTP_CLIENT
@@ -185,7 +179,6 @@ pub fn register(bk: &Backend, user: String, password: String, server: &str) -> R
     let tx = bk.tx.clone();
 
     let base = Url::parse(server)?;
-    data.lock().unwrap().server_url = base.clone();
     let params = Default::default();
     let body = RegisterBody {
         username: Some(user),
diff --git a/fractal-matrix-api/src/backend/room.rs b/fractal-matrix-api/src/backend/room.rs
index 80a082fe..a785bfc7 100644
--- a/fractal-matrix-api/src/backend/room.rs
+++ b/fractal-matrix-api/src/backend/room.rs
@@ -39,16 +39,16 @@ use serde_json::Value as JsonValue;
 
 // FIXME: Remove this function, this is used only to request information we should already have
 // when opening a room
-pub fn set_room(bk: &Backend, id: String) -> Result<(), Error> {
+pub fn set_room(bk: &Backend, base: Url, id: String) -> Result<(), Error> {
     /* FIXME: remove clone and pass id by reference */
-    get_room_avatar(bk, id.clone())?;
-    get_room_detail(bk, id.clone(), String::from("m.room.topic"))?;
+    get_room_avatar(bk, base.clone(), id.clone())?;
+    get_room_detail(bk, base, id.clone(), String::from("m.room.topic"))?;
 
     Ok(())
 }
 
-pub fn get_room_detail(bk: &Backend, roomid: String, key: String) -> Result<(), Error> {
-    let url = bk.url(&format!("rooms/{}/state/{}", roomid, key), vec![])?;
+pub fn get_room_detail(bk: &Backend, base: Url, roomid: String, key: String) -> Result<(), Error> {
+    let url = bk.url(base, &format!("rooms/{}/state/{}", roomid, key), vec![])?;
 
     let tx = bk.tx.clone();
     let keys = key.clone();
@@ -70,9 +70,12 @@ pub fn get_room_detail(bk: &Backend, roomid: String, key: String) -> Result<(),
     Ok(())
 }
 
-pub fn get_room_avatar(bk: &Backend, roomid: String) -> Result<(), Error> {
-    let url = bk.url(&format!("rooms/{}/state/m.room.avatar", roomid), vec![])?;
-    let baseu = bk.get_base_url();
+pub fn get_room_avatar(bk: &Backend, baseu: Url, roomid: String) -> Result<(), Error> {
+    let url = bk.url(
+        baseu.clone(),
+        &format!("rooms/{}/state/m.room.avatar", roomid),
+        vec![],
+    )?;
     let tx = bk.tx.clone();
     get!(
         &url,
@@ -107,8 +110,8 @@ pub fn get_room_avatar(bk: &Backend, roomid: String) -> Result<(), Error> {
     Ok(())
 }
 
-pub fn get_room_members(bk: &Backend, roomid: String) -> Result<(), Error> {
-    let url = bk.url(&format!("rooms/{}/joined_members", roomid), vec![])?;
+pub fn get_room_members(bk: &Backend, base: Url, roomid: String) -> Result<(), Error> {
+    let url = bk.url(base, &format!("rooms/{}/joined_members", roomid), vec![])?;
 
     let tx = bk.tx.clone();
     get!(
@@ -138,7 +141,12 @@ pub fn get_room_members(bk: &Backend, roomid: String) -> Result<(), Error> {
 /* Load older messages starting by prev_batch
  * https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-rooms-roomid-messages
  */
-pub fn get_room_messages(bk: &Backend, roomid: String, from: String) -> Result<(), Error> {
+pub fn get_room_messages(
+    bk: &Backend,
+    base: Url,
+    roomid: String,
+    from: String,
+) -> Result<(), Error> {
     let params = vec![
         ("from", from),
         ("dir", String::from("b")),
@@ -152,7 +160,7 @@ pub fn get_room_messages(bk: &Backend, roomid: String, from: String) -> Result<(
             .expect("Failed to serialize room messages request filter"),
         ),
     ];
-    let url = bk.url(&format!("rooms/{}/messages", roomid), params)?;
+    let url = bk.url(base, &format!("rooms/{}/messages", roomid), params)?;
     let tx = bk.tx.clone();
     get!(
         &url,
@@ -173,23 +181,20 @@ pub fn get_room_messages(bk: &Backend, roomid: String, from: String) -> Result<(
     Ok(())
 }
 
-pub fn get_room_messages_from_msg(bk: &Backend, roomid: String, msg: Message) -> Result<(), Error> {
+pub fn get_room_messages_from_msg(bk: &Backend, baseu: Url, roomid: String, msg: Message) {
     // first of all, we calculate the from param using the context api, then we call the
     // normal get_room_messages
-    let baseu = bk.get_base_url();
     let tk = bk.data.lock().unwrap().access_token.clone();
     let itx = bk.internal_tx.clone();
 
     thread::spawn(move || {
         if let Ok(from) = get_prev_batch_from(&baseu, &tk, &roomid, &msg.id) {
             if let Some(t) = itx {
-                t.send(BKCommand::GetRoomMessages(roomid, from))
+                t.send(BKCommand::GetRoomMessages(baseu, roomid, from))
                     .expect_log("Connection closed");
             }
         }
     });
-
-    Ok(())
 }
 
 fn parse_context(
@@ -251,9 +256,8 @@ fn parse_context(
     Ok(())
 }
 
-pub fn get_message_context(bk: &Backend, msg: Message) -> Result<(), Error> {
+pub fn get_message_context(bk: &Backend, baseu: Url, msg: Message) -> Result<(), Error> {
     let tx = bk.tx.clone();
-    let baseu = bk.get_base_url();
     let roomid = msg.room.clone();
     let tk = bk.data.lock().unwrap().access_token.clone();
 
@@ -262,10 +266,11 @@ pub fn get_message_context(bk: &Backend, msg: Message) -> Result<(), Error> {
     Ok(())
 }
 
-pub fn send_msg(bk: &Backend, msg: Message) -> Result<(), Error> {
+pub fn send_msg(bk: &Backend, base: Url, msg: Message) -> Result<(), Error> {
     let roomid = msg.room.clone();
 
     let url = bk.url(
+        base,
         &format!("rooms/{}/send/m.room.message/{}", roomid, msg.id),
         vec![],
     )?;
@@ -311,9 +316,9 @@ pub fn send_msg(bk: &Backend, msg: Message) -> Result<(), Error> {
     Ok(())
 }
 
-pub fn send_typing(bk: &Backend, roomid: String) -> Result<(), Error> {
+pub fn send_typing(bk: &Backend, base: Url, roomid: String) -> Result<(), Error> {
     let userid = bk.data.lock().unwrap().user_id.clone();
-    let url = bk.url(&format!("rooms/{}/typing/{}", roomid, userid), vec![])?;
+    let url = bk.url(base, &format!("rooms/{}/typing/{}", roomid, userid), vec![])?;
 
     let attrs = json!({
         "timeout": 4000,
@@ -329,11 +334,12 @@ pub fn send_typing(bk: &Backend, roomid: String) -> Result<(), Error> {
     Ok(())
 }
 
-pub fn redact_msg(bk: &Backend, msg: &Message) -> Result<(), Error> {
+pub fn redact_msg(bk: &Backend, base: Url, msg: &Message) -> Result<(), Error> {
     let roomid = msg.room.clone();
     let txnid = msg.id.clone();
 
     let url = bk.url(
+        base,
         &format!("rooms/{}/redact/{}/{}", roomid, msg.id, txnid),
         vec![],
     )?;
@@ -364,8 +370,12 @@ pub fn redact_msg(bk: &Backend, msg: &Message) -> Result<(), Error> {
     Ok(())
 }
 
-pub fn join_room(bk: &Backend, roomid: String) -> Result<(), Error> {
-    let url = bk.url(&format!("join/{}", urlencoding::encode(&roomid)), vec![])?;
+pub fn join_room(bk: &Backend, base: Url, roomid: String) -> Result<(), Error> {
+    let url = bk.url(
+        base,
+        &format!("join/{}", urlencoding::encode(&roomid)),
+        vec![],
+    )?;
 
     let tx = bk.tx.clone();
     let data = bk.data.clone();
@@ -385,8 +395,8 @@ pub fn join_room(bk: &Backend, roomid: String) -> Result<(), Error> {
     Ok(())
 }
 
-pub fn leave_room(bk: &Backend, roomid: &str) -> Result<(), Error> {
-    let url = bk.url(&format!("rooms/{}/leave", roomid), vec![])?;
+pub fn leave_room(bk: &Backend, base: Url, roomid: &str) -> Result<(), Error> {
+    let url = bk.url(base, &format!("rooms/{}/leave", roomid), vec![])?;
 
     let tx = bk.tx.clone();
     post!(
@@ -404,8 +414,9 @@ pub fn leave_room(bk: &Backend, roomid: &str) -> Result<(), Error> {
     Ok(())
 }
 
-pub fn mark_as_read(bk: &Backend, roomid: &str, eventid: &str) -> Result<(), Error> {
+pub fn mark_as_read(bk: &Backend, base: Url, roomid: &str, eventid: &str) -> Result<(), Error> {
     let url = bk.url(
+        base.clone(),
         &format!("rooms/{}/receipt/m.read/{}", roomid, eventid),
         vec![],
     )?;
@@ -429,7 +440,7 @@ pub fn mark_as_read(bk: &Backend, roomid: &str, eventid: &str) -> Result<(), Err
     // This event API call isn't in the current doc but I found this in the
     // matrix-js-sdk
     // https://github.com/matrix-org/matrix-js-sdk/blob/master/src/base-apis.js#L851
-    let url = bk.url(&format!("rooms/{}/read_markers", roomid), vec![])?;
+    let url = bk.url(base, &format!("rooms/{}/read_markers", roomid), vec![])?;
     let attrs = json!({
         "m.fully_read": eventid,
         "m.read": json!(null),
@@ -439,8 +450,8 @@ pub fn mark_as_read(bk: &Backend, roomid: &str, eventid: &str) -> Result<(), Err
     Ok(())
 }
 
-pub fn set_room_name(bk: &Backend, roomid: &str, name: &str) -> Result<(), Error> {
-    let url = bk.url(&format!("rooms/{}/state/m.room.name", roomid), vec![])?;
+pub fn set_room_name(bk: &Backend, base: Url, roomid: &str, name: &str) -> Result<(), Error> {
+    let url = bk.url(base, &format!("rooms/{}/state/m.room.name", roomid), vec![])?;
 
     let attrs = json!({
         "name": name,
@@ -464,8 +475,12 @@ pub fn set_room_name(bk: &Backend, roomid: &str, name: &str) -> Result<(), Error
     Ok(())
 }
 
-pub fn set_room_topic(bk: &Backend, roomid: &str, topic: &str) -> Result<(), Error> {
-    let url = bk.url(&format!("rooms/{}/state/m.room.topic", roomid), vec![])?;
+pub fn set_room_topic(bk: &Backend, base: Url, roomid: &str, topic: &str) -> Result<(), Error> {
+    let url = bk.url(
+        base,
+        &format!("rooms/{}/state/m.room.topic", roomid),
+        vec![],
+    )?;
 
     let attrs = json!({
         "topic": topic,
@@ -489,12 +504,15 @@ pub fn set_room_topic(bk: &Backend, roomid: &str, topic: &str) -> Result<(), Err
     Ok(())
 }
 
-pub fn set_room_avatar(bk: &Backend, roomid: &str, avatar: &str) -> Result<(), Error> {
-    let baseu = bk.get_base_url();
+pub fn set_room_avatar(bk: &Backend, baseu: Url, roomid: &str, avatar: &str) -> Result<(), Error> {
     let tk = bk.data.lock().unwrap().access_token.clone();
     let params = &[("access_token", tk.clone())];
     let mediaurl = media_url(&baseu, "upload", params)?;
-    let roomurl = bk.url(&format!("rooms/{}/state/m.room.avatar", roomid), vec![])?;
+    let roomurl = bk.url(
+        baseu,
+        &format!("rooms/{}/state/m.room.avatar", roomid),
+        vec![],
+    )?;
 
     let mut file = File::open(&avatar)?;
     let mut contents: Vec<u8> = vec![];
@@ -529,7 +547,7 @@ pub fn set_room_avatar(bk: &Backend, roomid: &str, avatar: &str) -> Result<(), E
     Ok(())
 }
 
-pub fn attach_file(bk: &Backend, mut msg: Message) -> Result<(), Error> {
+pub fn attach_file(bk: &Backend, baseu: Url, mut msg: Message) -> Result<(), Error> {
     let fname = msg.url.clone().unwrap_or_default();
     let mut extra_content: ExtraContent =
         serde_json::from_value(msg.clone().extra_content.unwrap()).unwrap();
@@ -537,11 +555,10 @@ pub fn attach_file(bk: &Backend, mut msg: Message) -> Result<(), Error> {
 
     let tx = bk.tx.clone();
     let itx = bk.internal_tx.clone();
-    let baseu = bk.get_base_url().clone();
     let tk = bk.data.lock().unwrap().access_token.clone();
 
     if fname.starts_with("mxc://") && thumb.starts_with("mxc://") {
-        return send_msg(bk, msg);
+        return send_msg(bk, baseu, msg);
     }
 
     thread::spawn(move || {
@@ -570,7 +587,7 @@ pub fn attach_file(bk: &Backend, mut msg: Message) -> Result<(), Error> {
             Ok(uri) => {
                 msg.url = Some(uri.to_string());
                 if let Some(t) = itx {
-                    t.send(BKCommand::SendMsg(msg.clone()))
+                    t.send(BKCommand::SendMsg(baseu, msg.clone()))
                         .expect_log("Connection closed");
                 }
                 tx.send(BKResponse::AttachedFile(Ok(msg)))
@@ -598,11 +615,12 @@ fn upload_file(tk: &str, baseu: &Url, fname: &str) -> Result<String, Error> {
 
 pub fn new_room(
     bk: &Backend,
+    base: Url,
     name: &str,
     privacy: RoomType,
     internal_id: String,
 ) -> Result<(), Error> {
-    let url = bk.url("createRoom", vec![])?;
+    let url = bk.url(base, "createRoom", vec![])?;
     let attrs = json!({
         "invite": [],
         "invite_3pid": [],
@@ -673,8 +691,13 @@ pub fn update_direct_chats(url: Url, data: Arc<Mutex<BackendData>>, user: String
     );
 }
 
-pub fn direct_chat(bk: &Backend, user: &Member, internal_id: String) -> Result<(), Error> {
-    let url = bk.url("createRoom", vec![])?;
+pub fn direct_chat(
+    bk: &Backend,
+    base: Url,
+    user: &Member,
+    internal_id: String,
+) -> Result<(), Error> {
+    let url = bk.url(base.clone(), "createRoom", vec![])?;
     let attrs = json!({
         "invite": [user.uid.clone()],
         "invite_3pid": [],
@@ -690,7 +713,11 @@ pub fn direct_chat(bk: &Backend, user: &Member, internal_id: String) -> Result<(
     });
 
     let userid = bk.data.lock().unwrap().user_id.clone();
-    let direct_url = bk.url(&format!("user/{}/account_data/m.direct", userid), vec![])?;
+    let direct_url = bk.url(
+        base,
+        &format!("user/{}/account_data/m.direct", userid),
+        vec![],
+    )?;
 
     let m = user.clone();
     let tx = bk.tx.clone();
@@ -717,9 +744,10 @@ pub fn direct_chat(bk: &Backend, user: &Member, internal_id: String) -> Result<(
     Ok(())
 }
 
-pub fn add_to_fav(bk: &Backend, roomid: String, tofav: bool) -> Result<(), Error> {
+pub fn add_to_fav(bk: &Backend, base: Url, roomid: String, tofav: bool) -> Result<(), Error> {
     let userid = bk.data.lock().unwrap().user_id.clone();
     let url = bk.url(
+        base,
         &format!("user/{}/rooms/{}/tags/m.favourite", userid, roomid),
         vec![],
     )?;
@@ -747,8 +775,8 @@ pub fn add_to_fav(bk: &Backend, roomid: String, tofav: bool) -> Result<(), Error
     Ok(())
 }
 
-pub fn invite(bk: &Backend, roomid: &str, userid: &str) -> Result<(), Error> {
-    let url = bk.url(&format!("rooms/{}/invite", roomid), vec![])?;
+pub fn invite(bk: &Backend, base: Url, roomid: &str, userid: &str) -> Result<(), Error> {
+    let url = bk.url(base, &format!("rooms/{}/invite", roomid), vec![])?;
 
     let attrs = json!({
         "user_id": userid,
diff --git a/fractal-matrix-api/src/backend/stickers.rs b/fractal-matrix-api/src/backend/stickers.rs
index 1d79e63d..d9f99fbc 100644
--- a/fractal-matrix-api/src/backend/stickers.rs
+++ b/fractal-matrix-api/src/backend/stickers.rs
@@ -103,14 +103,18 @@ pub fn get_sticker_widget_id(bk: &Backend, then: BKCommand) -> Result<(), Error>
     Ok(())
 }
 
-pub fn send(bk: &Backend, roomid: &str, sticker: &Sticker) -> Result<(), Error> {
+pub fn send(bk: &Backend, base: Url, roomid: &str, sticker: &Sticker) -> Result<(), Error> {
     let now = Local::now();
     let msg = format!("{}{}{}", roomid, sticker.name, now.to_string());
     let digest = md5::compute(msg.as_bytes());
     // TODO: we need to generate the msg.id in the frontend
     let id = format!("{:x}", digest);
 
-    let url = bk.url(&format!("rooms/{}/send/m.sticker/{}", roomid, id), vec![])?;
+    let url = bk.url(
+        base,
+        &format!("rooms/{}/send/m.sticker/{}", roomid, id),
+        vec![],
+    )?;
 
     let attrs = json!({
         "body": sticker.body.clone(),
@@ -173,28 +177,14 @@ pub fn purchase(bk: &Backend, group: &StickerGroup) -> Result<(), Error> {
     Ok(())
 }
 
-fn get_base_url(data: &Arc<Mutex<BackendData>>) -> Url {
-    data.lock().unwrap().server_url.clone()
-}
-
-fn url(
-    data: &Arc<Mutex<BackendData>>,
-    path: &str,
-    mut params: Vec<(&str, String)>,
-) -> Result<Url, Error> {
-    let base = get_base_url(data);
-    let tk = data.lock().unwrap().access_token.clone();
-
-    params.push(("access_token", tk.clone()));
-
-    client_url(&base, path, &params)
-}
-
 fn get_scalar_token(data: &Arc<Mutex<BackendData>>) -> Result<String, Error> {
     let base = data.lock().unwrap().scalar_url.clone();
     let uid = data.lock().unwrap().user_id.clone();
+    let tk = data.lock().unwrap().access_token.clone();
 
-    let url = url(data, &format!("user/{}/openid/request_token", uid), vec![])?;
+    let params = &[("access_token", tk)];
+    let path = &format!("user/{}/openid/request_token", uid);
+    let url = client_url(&base, path, params)?;
     let js = json_q("post", &url, &json!({}))?;
 
     let vurl = base
@@ -219,7 +209,7 @@ fn vurl(
     let base = data.lock().unwrap().scalar_url.clone();
     let token = data.lock().unwrap().scalar_token.clone();
     let tk = match token {
-        None => get_scalar_token(&data)?,
+        None => get_scalar_token(data)?,
         Some(t) => t.clone(),
     };
 
diff --git a/fractal-matrix-api/src/backend/sync.rs b/fractal-matrix-api/src/backend/sync.rs
index 27a6811e..8ddda518 100644
--- a/fractal-matrix-api/src/backend/sync.rs
+++ b/fractal-matrix-api/src/backend/sync.rs
@@ -27,8 +27,9 @@ use std::{
     thread,
     time::{self, Duration},
 };
+use url::Url;
 
-pub fn sync(bk: &Backend, new_since: Option<String>, initial: bool) {
+pub fn sync(bk: &Backend, base: Url, new_since: Option<String>, initial: bool) {
     let tx = bk.tx.clone();
     let data = bk.data.clone();
     let userid = bk.data.lock().unwrap().user_id.clone();
@@ -81,7 +82,6 @@ pub fn sync(bk: &Backend, new_since: Option<String>, initial: bool) {
         (Default::default(), filter)
     };
 
-    let base = bk.get_base_url();
     let params = SyncParameters {
         access_token: data.lock().unwrap().access_token.clone(),
         filter,
@@ -254,7 +254,7 @@ pub fn sync(bk: &Backend, new_since: Option<String>, initial: bool) {
     });
 }
 
-pub fn force_sync(bk: &Backend) {
+pub fn force_sync(bk: &Backend, base: Url) {
     bk.data.lock().unwrap().since = None;
-    sync(bk, None, true)
+    sync(bk, base, None, true)
 }
diff --git a/fractal-matrix-api/src/backend/types.rs b/fractal-matrix-api/src/backend/types.rs
index ca2bf248..bc63d0bd 100644
--- a/fractal-matrix-api/src/backend/types.rs
+++ b/fractal-matrix-api/src/backend/types.rs
@@ -20,68 +20,69 @@ use url::Url;
 #[derive(Debug)]
 pub enum BKCommand {
     Login(String, String, String),
-    SetToken(String, String, String),
-    Logout,
+    SetToken(String, String),
+    Logout(Url),
     #[allow(dead_code)]
     Register(String, String, String),
     #[allow(dead_code)]
     Guest(String),
-    GetUsername,
-    SetUserName(String),
-    GetThreePID,
-    GetTokenEmail(String, String, String),
-    GetTokenPhone(String, String, String),
-    SubmitPhoneToken(String, String, String, String),
-    AddThreePID(String, String, String),
-    DeleteThreePID(Medium, String),
-    ChangePassword(String, String, String),
-    AccountDestruction(String, String, bool),
-    GetAvatar,
-    SetUserAvatar(String),
-    Sync(Option<String>, bool),
-    SyncForced,
-    GetRoomMembers(String),
-    GetRoomMessages(String, String),
-    GetRoomMessagesFromMsg(String, Message),
-    GetMessageContext(Message),
-    GetRoomAvatar(String),
-    GetThumbAsync(String, Sender<String>),
-    GetMediaAsync(String, Sender<String>),
+    GetUsername(Url),
+    SetUserName(Url, String),
+    GetThreePID(Url),
+    GetTokenEmail(Url, String, String, String),
+    GetTokenPhone(Url, String, String, String),
+    SubmitPhoneToken(Url, String, String, String),
+    AddThreePID(Url, String, String, String),
+    DeleteThreePID(Url, Medium, String),
+    ChangePassword(Url, String, String, String),
+    AccountDestruction(Url, String, String),
+    GetAvatar(Url),
+    SetUserAvatar(Url, String),
+    Sync(Url, Option<String>, bool),
+    SyncForced(Url),
+    GetRoomMembers(Url, String),
+    GetRoomMessages(Url, String, String),
+    GetRoomMessagesFromMsg(Url, String, Message),
+    GetMessageContext(Url, Message),
+    GetRoomAvatar(Url, String),
+    GetThumbAsync(Url, String, Sender<String>),
+    GetMediaAsync(Url, String, Sender<String>),
     GetMediaListAsync(
+        Url,
         String,
         Option<String>,
         Option<String>,
         Sender<(Vec<Message>, String)>,
     ),
     GetFileAsync(String, Sender<String>),
-    GetAvatarAsync(Option<Member>, Sender<String>),
-    GetMedia(String),
-    GetMediaUrl(String, Sender<String>),
-    GetUserInfoAsync(String, Option<Sender<(String, String)>>),
-    GetUserNameAsync(String, Sender<String>),
-    SendMsg(Message),
-    SendMsgRedaction(Message),
-    SendTyping(String),
-    SetRoom(String),
+    GetAvatarAsync(Url, Option<Member>, Sender<String>),
+    GetMedia(Url, String),
+    GetMediaUrl(Url, String, Sender<String>),
+    GetUserInfoAsync(Url, String, Option<Sender<(String, String)>>),
+    GetUserNameAsync(Url, String, Sender<String>),
+    SendMsg(Url, Message),
+    SendMsgRedaction(Url, Message),
+    SendTyping(Url, String),
+    SetRoom(Url, String),
     ShutDown,
-    DirectoryProtocols,
-    DirectorySearch(String, String, String, bool),
-    JoinRoom(String),
-    MarkAsRead(String, String),
-    LeaveRoom(String),
-    SetRoomName(String, String),
-    SetRoomTopic(String, String),
-    SetRoomAvatar(String, String),
-    AttachFile(Message),
-    NewRoom(String, RoomType, String),
-    DirectChat(Member, String),
-    AddToFav(String, bool),
-    AcceptInv(String),
-    RejectInv(String),
-    UserSearch(String),
-    Invite(String, String),
+    DirectoryProtocols(Url),
+    DirectorySearch(Url, String, String, String, bool),
+    JoinRoom(Url, String),
+    MarkAsRead(Url, String, String),
+    LeaveRoom(Url, String),
+    SetRoomName(Url, String, String),
+    SetRoomTopic(Url, String, String),
+    SetRoomAvatar(Url, String, String),
+    AttachFile(Url, Message),
+    NewRoom(Url, String, RoomType, String),
+    DirectChat(Url, Member, String),
+    AddToFav(Url, String, bool),
+    AcceptInv(Url, String),
+    RejectInv(Url, String),
+    UserSearch(Url, String),
+    Invite(Url, String, String),
     ListStickers,
-    SendSticker(String, Sticker),
+    SendSticker(Url, String, Sticker),
     PurchaseSticker(StickerGroup),
 }
 
@@ -96,7 +97,7 @@ pub enum BKResponse {
     GetTokenEmail(Result<(String, String), Error>),
     GetTokenPhone(Result<(String, String), Error>),
     SubmitPhoneToken(Result<(Option<String>, String), Error>),
-    AddThreePID(Result<String, Error>),
+    AddThreePID(Result<(), Error>),
     DeleteThreePID(Result<(), Error>),
     ChangePassword(Result<(), Error>),
     AccountDestruction(Result<(), Error>),
@@ -152,7 +153,6 @@ pub enum RoomType {
 pub struct BackendData {
     pub user_id: String,
     pub access_token: String,
-    pub server_url: Url,
     pub scalar_token: Option<String>,
     pub scalar_url: Url,
     pub sticker_widget: Option<String>,
diff --git a/fractal-matrix-api/src/backend/user.rs b/fractal-matrix-api/src/backend/user.rs
index f8e50d9d..6cca1db1 100644
--- a/fractal-matrix-api/src/backend/user.rs
+++ b/fractal-matrix-api/src/backend/user.rs
@@ -1,4 +1,5 @@
 use std::fs;
+use url::Url;
 
 use crate::backend::types::BKResponse;
 use crate::backend::types::Backend;
@@ -16,7 +17,6 @@ use std::convert::TryInto;
 use std::sync::mpsc::Sender;
 use std::sync::{Arc, Mutex};
 use std::thread;
-use url::Url;
 
 use crate::identity::r0::association::msisdn::submit_token::request as submit_phone_token_req;
 use crate::identity::r0::association::msisdn::submit_token::Body as SubmitPhoneTokenBody;
@@ -66,10 +66,9 @@ use crate::r0::Medium;
 use crate::r0::ThreePIDCredentials;
 use crate::types::Member;
 
-pub fn get_username(bk: &Backend) {
+pub fn get_username(bk: &Backend, base: Url) {
     let tx = bk.tx.clone();
     let uid = bk.data.lock().unwrap().user_id.clone();
-    let base = bk.get_base_url();
 
     thread::spawn(move || {
         let query = get_display_name(base, &encode_uid(&uid))
@@ -90,9 +89,7 @@ pub fn get_username(bk: &Backend) {
 
 // FIXME: This function manages errors *really* wrong and isn't more async
 // than the normal function. It should be removed.
-pub fn get_username_async(bk: &Backend, uid: String, tx: Sender<String>) {
-    let base = bk.get_base_url();
-
+pub fn get_username_async(base: Url, uid: String, tx: Sender<String>) {
     thread::spawn(move || {
         let query = get_display_name(base, &encode_uid(&uid))
             .map_err::<Error, _>(Into::into)
@@ -111,10 +108,9 @@ pub fn get_username_async(bk: &Backend, uid: String, tx: Sender<String>) {
     });
 }
 
-pub fn set_username(bk: &Backend, name: String) {
+pub fn set_username(bk: &Backend, base: Url, name: String) {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let uid = bk.data.lock().unwrap().user_id.clone();
     let params = SetDisplayNameParameters { access_token };
@@ -138,10 +134,9 @@ pub fn set_username(bk: &Backend, name: String) {
     });
 }
 
-pub fn get_threepid(bk: &Backend) {
+pub fn get_threepid(bk: &Backend, base: Url) {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params = ThirdPartyIDParameters { access_token };
 
@@ -164,13 +159,13 @@ pub fn get_threepid(bk: &Backend) {
 
 pub fn get_email_token(
     bk: &Backend,
+    base: Url,
     identity: String,
     email: String,
     client_secret: String,
 ) -> Result<(), Error> {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params = EmailTokenParameters { access_token };
     let body = EmailTokenBody {
@@ -212,13 +207,13 @@ pub fn get_email_token(
 
 pub fn get_phone_token(
     bk: &Backend,
+    base: Url,
     identity: String,
     phone: String,
     client_secret: String,
 ) -> Result<(), Error> {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params = PhoneTokenParameters { access_token };
     let body = PhoneTokenBody {
@@ -261,13 +256,13 @@ pub fn get_phone_token(
 
 pub fn add_threepid(
     bk: &Backend,
+    base: Url,
     identity: String,
     client_secret: String,
     sid: String,
 ) -> Result<(), Error> {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params = AddThreePIDParameters { access_token };
     let body = AddThreePIDBody {
@@ -288,7 +283,7 @@ pub fn add_threepid(
                     .execute(request)
                     .map_err(Into::into)
             })
-            .and(Ok(sid));
+            .and(Ok(()));
 
         tx.send(BKResponse::AddThreePID(query))
             .expect_log("Connection closed");
@@ -297,10 +292,15 @@ pub fn add_threepid(
     Ok(())
 }
 
-pub fn submit_phone_token(bk: &Backend, client_secret: String, sid: String, token: String) {
+pub fn submit_phone_token(
+    bk: &Backend,
+    base: Url,
+    client_secret: String,
+    sid: String,
+    token: String,
+) {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let body = SubmitPhoneTokenBody {
         sid: sid.clone(),
         client_secret: client_secret.clone(),
@@ -324,10 +324,9 @@ pub fn submit_phone_token(bk: &Backend, client_secret: String, sid: String, toke
     });
 }
 
-pub fn delete_three_pid(bk: &Backend, medium: Medium, address: String) {
+pub fn delete_three_pid(bk: &Backend, base: Url, medium: Medium, address: String) {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params = DeleteThreePIDParameters { access_token };
     let body = DeleteThreePIDBody { address, medium };
@@ -348,11 +347,16 @@ pub fn delete_three_pid(bk: &Backend, medium: Medium, address: String) {
     });
 }
 
-pub fn change_password(bk: &Backend, user: String, old_password: String, new_password: String) {
+pub fn change_password(
+    bk: &Backend,
+    base: Url,
+    user: String,
+    old_password: String,
+    new_password: String,
+) {
     let tx = bk.tx.clone();
 
     let access_token = bk.data.lock().unwrap().access_token.clone();
-    let base = bk.get_base_url();
     let params = ChangePasswordParameters { access_token };
     let body = ChangePasswordBody {
         new_password,
@@ -379,10 +383,9 @@ pub fn change_password(bk: &Backend, user: String, old_password: String, new_pas
     });
 }
 
-pub fn account_destruction(bk: &Backend, user: String, password: String) {
+pub fn account_destruction(bk: &Backend, base: Url, user: String, password: String) {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params = DeactivateParameters { access_token };
     let body = DeactivateBody {
@@ -409,8 +412,7 @@ pub fn account_destruction(bk: &Backend, user: String, password: String) {
     });
 }
 
-pub fn get_avatar(bk: &Backend) {
-    let base = bk.get_base_url();
+pub fn get_avatar(bk: &Backend, base: Url) {
     let userid = bk.data.lock().unwrap().user_id.clone();
 
     let tx = bk.tx.clone();
@@ -421,9 +423,8 @@ pub fn get_avatar(bk: &Backend) {
     });
 }
 
-pub fn get_avatar_async(bk: &Backend, member: Option<Member>, tx: Sender<String>) {
+pub fn get_avatar_async(bk: &Backend, base: Url, member: Option<Member>, tx: Sender<String>) {
     if let Some(member) = member {
-        let base = bk.get_base_url();
         let uid = member.uid.clone();
         let avatar = member.avatar.clone().unwrap_or_default();
 
@@ -436,10 +437,9 @@ pub fn get_avatar_async(bk: &Backend, member: Option<Member>, tx: Sender<String>
     }
 }
 
-pub fn set_user_avatar(bk: &Backend, avatar: String) {
+pub fn set_user_avatar(bk: &Backend, base: Url, avatar: String) {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let id = bk.data.lock().unwrap().user_id.clone();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params_upload = CreateContentParameters {
@@ -485,9 +485,12 @@ pub fn set_user_avatar(bk: &Backend, avatar: String) {
     });
 }
 
-pub fn get_user_info_async(bk: &mut Backend, uid: String, tx: Option<Sender<(String, String)>>) {
-    let baseu = bk.get_base_url();
-
+pub fn get_user_info_async(
+    bk: &mut Backend,
+    baseu: Url,
+    uid: String,
+    tx: Option<Sender<(String, String)>>,
+) {
     if let Some(info) = bk.user_info_cache.get(&uid) {
         if let Some(tx) = tx.clone() {
             let info = info.clone();
@@ -516,10 +519,9 @@ pub fn get_user_info_async(bk: &mut Backend, uid: String, tx: Option<Sender<(Str
     });
 }
 
-pub fn search(bk: &Backend, search_term: String) {
+pub fn search(bk: &Backend, base: Url, search_term: String) {
     let tx = bk.tx.clone();
 
-    let base = bk.get_base_url();
     let access_token = bk.data.lock().unwrap().access_token.clone();
     let params = UserDirectoryParameters { access_token };
     let body = UserDirectoryBody {


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