[fractal] Search room directory and download files through matrix-sdk
- From: Alexandre Franke <afranke src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal] Search room directory and download files through matrix-sdk
- Date: Tue, 1 Dec 2020 20:21:59 +0000 (UTC)
commit 0393568ca48194f58fba2fc681255b4d4e6485ef
Author: Alejandro Domínguez <adomu net-c com>
Date: Sat Aug 15 23:46:01 2020 +0200
Search room directory and download files through matrix-sdk
fractal-gtk/src/actions/message.rs | 135 +++++++++------------
fractal-gtk/src/appop/account.rs | 2 +-
fractal-gtk/src/appop/directory.rs | 52 ++++----
fractal-gtk/src/appop/media_viewer.rs | 8 +-
fractal-gtk/src/appop/message.rs | 10 ++
fractal-gtk/src/appop/notify.rs | 4 +-
fractal-gtk/src/appop/room.rs | 20 +--
fractal-gtk/src/appop/room_settings.rs | 2 +-
fractal-gtk/src/appop/sync.rs | 2 +-
fractal-gtk/src/appop/user.rs | 6 +-
fractal-gtk/src/backend/directory.rs | 121 +++++++++---------
fractal-gtk/src/backend/media.rs | 21 ++--
fractal-gtk/src/backend/mod.rs | 76 +++++++-----
fractal-gtk/src/backend/room.rs | 29 ++++-
fractal-gtk/src/backend/sync.rs | 31 +++--
fractal-gtk/src/backend/user.rs | 16 ++-
fractal-gtk/src/cache/mod.rs | 5 +-
fractal-gtk/src/globals.rs | 2 +-
fractal-gtk/src/model/room.rs | 30 ++---
fractal-gtk/src/widgets/image.rs | 45 +++----
fractal-gtk/src/widgets/inline_player.rs | 94 ++++++--------
fractal-gtk/src/widgets/media_viewer.rs | 78 +++++++-----
fractal-gtk/src/widgets/member.rs | 4 +-
fractal-gtk/src/widgets/message.rs | 75 +++++++-----
fractal-gtk/src/widgets/room.rs | 23 ++--
fractal-gtk/src/widgets/room_history.rs | 56 ++++++---
fractal-gtk/src/widgets/room_settings.rs | 14 +--
fractal-matrix-api/src/meson.build | 4 -
fractal-matrix-api/src/r0.rs | 1 -
fractal-matrix-api/src/r0/context/get_context.rs | 2 +-
fractal-matrix-api/src/r0/directory.rs | 1 -
.../src/r0/directory/post_public_rooms.rs | 102 ----------------
fractal-matrix-api/src/r0/media.rs | 2 -
fractal-matrix-api/src/r0/media/get_content.rs | 33 -----
.../src/r0/media/get_content_thumbnail.rs | 37 ------
35 files changed, 507 insertions(+), 636 deletions(-)
---
diff --git a/fractal-gtk/src/actions/message.rs b/fractal-gtk/src/actions/message.rs
index a4de118b..05d80621 100644
--- a/fractal-gtk/src/actions/message.rs
+++ b/fractal-gtk/src/actions/message.rs
@@ -1,18 +1,17 @@
-use crate::backend::{dw_media, media, room, ContentType, ThreadPool};
+use crate::backend::{dw_media, media, room, ContentType};
use fractal_api::identifiers::RoomId;
use fractal_api::r0::AccessToken;
+use fractal_api::Client as MatrixClient;
use glib::clone;
use log::error;
use std::cell::RefCell;
use std::fs;
use std::process::Command;
use std::rc::Rc;
-use std::sync::mpsc::channel;
-use std::sync::mpsc::TryRecvError;
-use std::sync::mpsc::{Receiver, Sender};
use std::thread;
use crate::actions::AppState;
+use crate::app::RUNTIME;
use crate::backend::HandleError;
use crate::model::message::Message;
use crate::uibuilder::UI;
@@ -23,7 +22,6 @@ use gio::ActionGroupExt;
use gio::ActionMapExt;
use gio::SimpleAction;
use gio::SimpleActionGroup;
-use glib::source::Continue;
use gtk::prelude::*;
use super::global::{get_event_id, get_message_by_id, get_room_id};
@@ -34,12 +32,12 @@ use crate::widgets::SourceDialog;
/* This creates all actions the room history can perform */
pub fn new(
- thread_pool: ThreadPool,
- server_url: Url,
+ session_client: MatrixClient,
access_token: AccessToken,
ui: UI,
back_history: Rc<RefCell<Vec<AppState>>>,
) -> gio::SimpleActionGroup {
+ let server_url = session_client.homeserver().clone();
let actions = SimpleActionGroup::new();
/* Action for each message */
let reply = SimpleAction::new("reply", glib::VariantTy::new("s").ok());
@@ -112,92 +110,69 @@ pub fn new(
}
}));
- open_with.connect_activate(clone!(@strong server_url => move |_, data| {
- if let Some(m) = get_message(data) {
- if let Some(url) = m.url {
- thread::spawn(clone!(@strong server_url => move || {
- match dw_media(server_url, &url, ContentType::Download, None) {
- Ok(fname) => {
- Command::new("xdg-open")
- .arg(&fname)
- .spawn()
- .expect("failed to execute process");
- }
- Err(err) => {
- err.handle_error()
- }
+ open_with.connect_activate(clone!(@strong session_client => move |_, data| {
+ if let Some(url) = get_message(data).and_then(|m| m.url) {
+ let session_client = session_client.clone();
+ RUNTIME.spawn(async move {
+ match dw_media(session_client, &url, ContentType::Download, None).await {
+ Ok(fname) => {
+ Command::new("xdg-open")
+ .arg(&fname)
+ .spawn()
+ .expect("failed to execute process");
}
- }));
- }
+ Err(err) => {
+ err.handle_error()
+ }
+ }
+ });
}
}));
save_as.connect_activate(clone!(
- @strong server_url,
- @strong thread_pool,
+ @strong session_client,
@weak parent as window
=> move |_, data| {
- if let Some(m) = get_message(data) {
- if let Some(url) = m.url {
- let name = m.body;
-
- let (tx, rx): (
- Sender<media::MediaResult>,
- Receiver<media::MediaResult>,
- ) = channel();
-
- media::get_media_async(thread_pool.clone(), server_url.clone(), url, tx);
-
- glib::timeout_add_local(
- 50,
- clone!(
- @strong name,
- @weak window
- => @default-return Continue(true), move || match rx.try_recv() {
- Err(TryRecvError::Empty) => Continue(true),
- Err(TryRecvError::Disconnected) => {
- let msg = i18n("Could not download the file");
- ErrorDialog::new(false, &msg);
+ if let Some((Some(url), name)) = get_message(data).map(|m| (m.url, m.body)) {
+ let session_client = session_client.clone();
+ let response = RUNTIME.spawn(async move {
+ media::get_media(session_client, &url).await
+ });
- Continue(true)
- },
- Ok(Ok(fname)) => {
- if let Some(path) = save(&window.upcast_ref(), &name, &[]) {
- // TODO use glib to copy file
- if fs::copy(fname, path).is_err() {
- ErrorDialog::new(false, &i18n("Couldn’t save file"));
- }
- }
- Continue(false)
- }
- Ok(Err(err)) => {
- error!("Media path could not be found due to error: {:?}", err);
- Continue(false)
+ glib::MainContext::default().spawn_local(async move {
+ match response.await {
+ Err(_) => {
+ let msg = i18n("Could not download the file");
+ ErrorDialog::new(false, &msg);
+ },
+ Ok(Ok(fname)) => {
+ if let Some(path) = save(&window.upcast_ref(), &name, &[]) {
+ // TODO use glib to copy file
+ if fs::copy(fname, path).is_err() {
+ ErrorDialog::new(false, &i18n("Couldn’t save file"));
}
}
- ),
- );
- }
+ }
+ Ok(Err(err)) => {
+ error!("Media path could not be found due to error: {:?}", err);
+ }
+ }
+ });
}
}));
- copy_image.connect_activate(clone!(@strong server_url => move |_, data| {
- if let Some(m) = get_message(data) {
- if let Some(url) = m.url {
- let (tx, rx): (
- Sender<media::MediaResult>,
- Receiver<media::MediaResult>,
- ) = channel();
-
- media::get_media_async(thread_pool.clone(), server_url.clone(), url, tx);
+ copy_image.connect_activate(clone!(@strong session_client => move |_, data| {
+ if let Some(url) = get_message(data).and_then(|m| m.url) {
+ let session_client = session_client.clone();
+ let response = RUNTIME.spawn(async move {
+ media::get_media(session_client, &url).await
+ });
- glib::timeout_add_local(50, move || match rx.try_recv() {
- Err(TryRecvError::Empty) => Continue(true),
- Err(TryRecvError::Disconnected) => {
+ glib::MainContext::default().spawn_local(async move {
+ match response.await {
+ Err(_) => {
let msg = i18n("Could not download the file");
ErrorDialog::new(false, &msg);
-
- Continue(true)
}
Ok(Ok(fname)) => {
if let Ok(pixbuf) = gdk_pixbuf::Pixbuf::from_file(fname) {
@@ -205,14 +180,12 @@ pub fn new(
let clipboard = gtk::Clipboard::get(&atom);
clipboard.set_image(&pixbuf);
}
- Continue(false)
}
Ok(Err(err)) => {
error!("Image path could not be found due to error: {:?}", err);
- Continue(false)
}
- });
- }
+ }
+ });
}
}));
diff --git a/fractal-gtk/src/appop/account.rs b/fractal-gtk/src/appop/account.rs
index 5fd378fd..c8ba7411 100644
--- a/fractal-gtk/src/appop/account.rs
+++ b/fractal-gtk/src/appop/account.rs
@@ -543,9 +543,9 @@ impl AppOp {
None,
);
download_to_cache(
+ login_data.session_client.clone(),
self.thread_pool.clone(),
self.user_info_cache.clone(),
- login_data.session_client.homeserver().clone(),
login_data.access_token,
login_data.uid,
data,
diff --git a/fractal-gtk/src/appop/directory.rs b/fractal-gtk/src/appop/directory.rs
index cc9e8a49..a2cf8064 100644
--- a/fractal-gtk/src/appop/directory.rs
+++ b/fractal-gtk/src/appop/directory.rs
@@ -3,13 +3,14 @@ use std::thread;
use crate::backend::{directory, HandleError};
-use crate::app::App;
+use crate::app::{App, RUNTIME};
use crate::appop::AppOp;
use crate::widgets;
use super::RoomSearchPagination;
use crate::model::room::Room;
+use fractal_api::directory::RoomNetwork;
use fractal_api::r0::thirdparty::get_supported_protocols::ProtocolInstance;
impl AppOp {
@@ -44,14 +45,15 @@ impl AppOp {
}
pub fn search_rooms(&mut self) {
- let login_data = unwrap_or_unit_return!(self.login_data.clone());
+ let session_client =
+ unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone()));
let other_protocol_radio = self
.ui
.builder
.get_object::<gtk::RadioButton>("other_protocol_radio")
.expect("Can't find other_protocol_radio in ui file.");
- let mut protocol = if other_protocol_radio.get_active() {
+ let protocol: Option<String> = if other_protocol_radio.get_active() {
let protocol_combo = self
.ui
.builder
@@ -65,15 +67,12 @@ impl AppOp {
.expect("Can't find protocol_model in ui file.");
let active = protocol_combo.get_active().map_or(-1, |uint| uint as i32);
- match protocol_model.iter_nth_child(None, active) {
- Some(it) => {
- let v = protocol_model.get_value(&it, 1);
- v.get().unwrap().unwrap()
- }
- None => String::new(),
- }
+
+ protocol_model
+ .iter_nth_child(None, active)
+ .and_then(|it| protocol_model.get_value(&it, 1).get().ok()?)
} else {
- String::new()
+ None
};
let q = self
@@ -95,12 +94,9 @@ impl AppOp {
.expect("Can't find other_homeserver_url in ui file.");
let homeserver = if other_homeserver_radio.get_active() {
- other_homeserver_url.get_text()
- } else if protocol == "matrix.org" {
- protocol = String::new();
- String::from("matrix.org")
+ Some(other_homeserver_url.get_text())
} else {
- String::new()
+ None
};
if !self.directory_pagination.has_more() {
@@ -130,22 +126,24 @@ impl AppOp {
q.set_sensitive(false);
}
- let search_term = q.get_text().to_string();
+ let search_term = Some(q.get_text().to_string()).filter(|s| !s.is_empty());
if let RoomSearchPagination::NoMorePages = self.directory_pagination {
// there are no more rooms. We don't need to request for more
return;
}
- let rooms_since = self.directory_pagination.clone().into();
- thread::spawn(move || {
+ let rooms_since: Option<String> = self.directory_pagination.clone().into();
+ RUNTIME.spawn(async move {
let query = directory::room_search(
- login_data.session_client.homeserver().clone(),
- login_data.access_token,
- homeserver,
- search_term,
- protocol,
- rooms_since,
- );
+ session_client,
+ homeserver.as_deref(),
+ search_term.as_deref(),
+ protocol
+ .as_deref()
+ .map_or(RoomNetwork::Matrix, RoomNetwork::ThirdParty),
+ rooms_since.as_deref(),
+ )
+ .await;
match query {
Ok((rooms, rooms_since)) => {
@@ -188,7 +186,7 @@ impl AppOp {
directory_stack.set_visible_child(&directory_clamp);
let mut sorted_rooms = rooms;
- sorted_rooms.sort_by_key(|a| -a.n_members);
+ sorted_rooms.sort_by_key(|a| -i128::from(a.n_members));
for r in sorted_rooms.iter() {
self.directory.push(r.clone());
diff --git a/fractal-gtk/src/appop/media_viewer.rs b/fractal-gtk/src/appop/media_viewer.rs
index 1cd9ad8d..98145f04 100644
--- a/fractal-gtk/src/appop/media_viewer.rs
+++ b/fractal-gtk/src/appop/media_viewer.rs
@@ -38,15 +38,15 @@ impl AppOp {
login_data.access_token,
login_data.uid,
);
- panel.display_media_viewer(self.thread_pool.clone(), msg);
- let (body, header) = panel.create(self.thread_pool.clone())?;
+ panel.display_media_viewer(login_data.session_client.clone(), msg);
+ let (body, header) =
+ panel.create(login_data.session_client.clone(), self.thread_pool.clone())?;
*self.media_viewer.borrow_mut() = Some(panel);
if let Some(login_data) = self.login_data.clone() {
let back_history = self.room_back_history.clone();
let actions = actions::Message::new(
- self.thread_pool.clone(),
- login_data.session_client.homeserver().clone(),
+ login_data.session_client,
login_data.access_token,
self.ui.clone(),
back_history,
diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs
index e757dcf6..20868c51 100644
--- a/fractal-gtk/src/appop/message.rs
+++ b/fractal-gtk/src/appop/message.rs
@@ -48,9 +48,11 @@ impl AppOp {
}
pub fn add_room_message(&mut self, msg: &Message) -> Option<()> {
+ let session_client = self.login_data.as_ref()?.session_client.clone();
if let Some(ui_msg) = self.create_new_room_message(msg) {
if let Some(ref mut history) = self.history {
history.add_new_message(
+ session_client,
self.thread_pool.clone(),
self.user_info_cache.clone(),
ui_msg,
@@ -61,9 +63,12 @@ impl AppOp {
}
pub fn remove_room_message(&mut self, msg: &Message) {
+ let session_client =
+ unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone()));
if let Some(ui_msg) = self.create_new_room_message(msg) {
if let Some(ref mut history) = self.history {
history.remove_message(
+ session_client,
self.thread_pool.clone(),
self.user_info_cache.clone(),
ui_msg,
@@ -81,6 +86,7 @@ impl AppOp {
login_data.access_token,
)
.tmpwidget(
+ login_data.session_client.clone(),
self.thread_pool.clone(),
self.user_info_cache.clone(),
&ui_msg,
@@ -125,6 +131,7 @@ impl AppOp {
login_data.access_token.clone(),
)
.tmpwidget(
+ login_data.session_client.clone(),
self.thread_pool.clone(),
self.user_info_cache.clone(),
&ui_msg,
@@ -441,6 +448,8 @@ impl AppOp {
room_id: RoomId,
prev_batch: Option<String>,
) {
+ let session_client =
+ unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone()));
if let Some(r) = self.rooms.get_mut(&room_id) {
r.prev_batch = prev_batch;
}
@@ -462,6 +471,7 @@ impl AppOp {
if let Some(ref mut history) = self.history {
history.add_old_messages_in_batch(
+ session_client,
self.thread_pool.clone(),
self.user_info_cache.clone(),
list,
diff --git a/fractal-gtk/src/appop/notify.rs b/fractal-gtk/src/appop/notify.rs
index e5ce591f..47b26e1b 100644
--- a/fractal-gtk/src/appop/notify.rs
+++ b/fractal-gtk/src/appop/notify.rs
@@ -46,7 +46,7 @@ impl AppOp {
pub fn notify(&self, app: gtk::Application, room_id: &RoomId, id: &EventId) -> Option<()> {
let login_data = self.login_data.as_ref()?;
let access_token = login_data.access_token.clone();
- let server_url = login_data.session_client.homeserver().clone();
+ let session_client = login_data.session_client.clone();
let msg = self.get_message_by_id(room_id, id)?;
let r = self.rooms.get(room_id)?;
let short_body = match &msg.mtype[..] {
@@ -68,8 +68,8 @@ impl AppOp {
let (tx, rx): (Sender<user::UserInfo>, Receiver<user::UserInfo>) = channel();
user::get_user_info_async(
self.thread_pool.clone(),
+ session_client,
self.user_info_cache.clone(),
- server_url,
access_token,
msg.sender,
tx,
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index 534a2758..74d76477 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -94,19 +94,19 @@ impl AppOp {
});
// Download the room avatar
// TODO: Use the avatar url returned by sync
- let server = login_data.session_client.homeserver().clone();
+ let session_client = login_data.session_client.clone();
let access_token = login_data.access_token.clone();
let room_id = room.id.clone();
- thread::spawn(
- move || match room::get_room_avatar(server, access_token, room_id) {
+ thread::spawn(move || {
+ match room::get_room_avatar(session_client, access_token, room_id) {
Ok((room, avatar)) => {
APPOP!(set_room_avatar, (room, avatar));
}
Err(err) => {
err.handle_error();
}
- },
- );
+ }
+ });
if clear_room_list {
roomlist.push(room.clone());
} else {
@@ -246,11 +246,11 @@ impl AppOp {
self.roomlist.select(&active_room);
// getting room details
- let server_url = login_data.session_client.homeserver().clone();
+ let session_client = login_data.session_client.clone();
let access_token = login_data.access_token.clone();
let a_room = active_room.clone();
thread::spawn(
- move || match room::get_room_avatar(server_url, access_token, a_room) {
+ move || match room::get_room_avatar(session_client, access_token, a_room) {
Ok((room, avatar)) => {
APPOP!(set_room_avatar, (room, avatar));
}
@@ -302,8 +302,7 @@ impl AppOp {
let back_history = self.room_back_history.clone();
let actions = actions::Message::new(
- self.thread_pool.clone(),
- login_data.session_client.homeserver().clone(),
+ login_data.session_client.clone(),
login_data.access_token,
self.ui.clone(),
back_history,
@@ -311,6 +310,7 @@ impl AppOp {
let history = widgets::RoomHistory::new(actions, active_room.clone(), self);
self.history = if let Some(mut history) = history {
history.create(
+ login_data.session_client,
self.thread_pool.clone(),
self.user_info_cache.clone(),
messages,
@@ -701,7 +701,7 @@ impl AppOp {
thread::spawn(move || {
match room::get_room_avatar(
- login_data.session_client.homeserver().clone(),
+ login_data.session_client.clone(),
login_data.access_token,
room_id,
) {
diff --git a/fractal-gtk/src/appop/room_settings.rs b/fractal-gtk/src/appop/room_settings.rs
index d644f154..dfcae863 100644
--- a/fractal-gtk/src/appop/room_settings.rs
+++ b/fractal-gtk/src/appop/room_settings.rs
@@ -28,7 +28,7 @@ impl AppOp {
login_data.session_client.homeserver().clone(),
login_data.access_token,
);
- let page = panel.create()?;
+ let page = panel.create(login_data.session_client.clone())?;
/* remove old panel */
if let Some(widget) = stack.get_child_by_name("room-settings") {
diff --git a/fractal-gtk/src/appop/sync.rs b/fractal-gtk/src/appop/sync.rs
index b399bc1a..e9a63e31 100644
--- a/fractal-gtk/src/appop/sync.rs
+++ b/fractal-gtk/src/appop/sync.rs
@@ -30,7 +30,7 @@ impl AppOp {
let since = self.since.clone().filter(|_| !initial);
thread::spawn(move || {
match sync::sync(
- login_data.session_client.homeserver().clone(),
+ login_data.session_client.clone(),
login_data.access_token,
login_data.uid,
join_to_room,
diff --git a/fractal-gtk/src/appop/user.rs b/fractal-gtk/src/appop/user.rs
index e756c1d9..6fd640f0 100644
--- a/fractal-gtk/src/appop/user.rs
+++ b/fractal-gtk/src/appop/user.rs
@@ -33,7 +33,7 @@ impl AppOp {
thread::spawn(clone!(@strong login_data => move || {
match user::get_user_avatar(
- login_data.session_client.homeserver().clone(),
+ login_data.session_client.clone(),
login_data.access_token,
&login_data.uid,
) {
@@ -92,9 +92,9 @@ impl AppOp {
None,
);
download_to_cache(
+ login_data.session_client.clone(),
self.thread_pool.clone(),
self.user_info_cache.clone(),
- login_data.session_client.homeserver().clone(),
login_data.access_token.clone(),
login_data.uid.clone(),
data,
@@ -118,9 +118,9 @@ impl AppOp {
None,
);
download_to_cache(
+ login_data.session_client.clone(),
self.thread_pool.clone(),
self.user_info_cache.clone(),
- login_data.session_client.homeserver().clone(),
login_data.access_token.clone(),
login_data.uid,
data,
diff --git a/fractal-gtk/src/backend/directory.rs b/fractal-gtk/src/backend/directory.rs
index ffe659af..405bacbb 100644
--- a/fractal-gtk/src/backend/directory.rs
+++ b/fractal-gtk/src/backend/directory.rs
@@ -1,19 +1,20 @@
+use fractal_api::identifiers::{Error as IdentifierError, ServerName};
use fractal_api::reqwest::Error as ReqwestError;
-use fractal_api::url::{Host, ParseError as UrlError, Url};
-use std::convert::TryInto;
+use fractal_api::url::{ParseError as UrlError, Url};
+use fractal_api::Client as MatrixClient;
+use fractal_api::Error as MatrixError;
+use std::convert::{TryFrom, TryInto};
use crate::globals;
-use crate::backend::HTTP_CLIENT;
+use crate::backend::{MediaError, HTTP_CLIENT};
use crate::util::cache_dir_path;
use crate::model::room::Room;
-use fractal_api::r0::directory::post_public_rooms::request as post_public_rooms;
-use fractal_api::r0::directory::post_public_rooms::Body as PublicRoomsBody;
-use fractal_api::r0::directory::post_public_rooms::Filter as PublicRoomsFilter;
-use fractal_api::r0::directory::post_public_rooms::Parameters as PublicRoomsParameters;
-use fractal_api::r0::directory::post_public_rooms::Response as PublicRoomsResponse;
-use fractal_api::r0::directory::post_public_rooms::ThirdPartyNetworks;
+use fractal_api::api::r0::directory::get_public_rooms_filtered::Request as PublicRoomsFilteredRequest;
+use fractal_api::assign;
+use fractal_api::directory::Filter as PublicRoomsFilter;
+use fractal_api::directory::RoomNetwork;
use fractal_api::r0::thirdparty::get_supported_protocols::request as get_supported_protocols;
use fractal_api::r0::thirdparty::get_supported_protocols::Parameters as SupportedProtocolsParameters;
use fractal_api::r0::thirdparty::get_supported_protocols::ProtocolInstance;
@@ -58,14 +59,15 @@ pub fn protocols(
#[derive(Debug)]
pub enum DirectorySearchError {
- InvalidHomeserverUrl(UrlError),
- Reqwest(ReqwestError),
+ Matrix(MatrixError),
+ MalformedServerName(IdentifierError),
ParseUrl(UrlError),
+ Download(MediaError),
}
-impl From<ReqwestError> for DirectorySearchError {
- fn from(err: ReqwestError) -> Self {
- Self::Reqwest(err)
+impl From<MatrixError> for DirectorySearchError {
+ fn from(err: MatrixError) -> Self {
+ Self::Matrix(err)
}
}
@@ -75,6 +77,12 @@ impl From<UrlError> for DirectorySearchError {
}
}
+impl From<MediaError> for DirectorySearchError {
+ fn from(err: MediaError) -> Self {
+ Self::Download(err)
+ }
+}
+
impl HandleError for DirectorySearchError {
fn handle_error(&self) {
let error = i18n("Error searching for rooms");
@@ -83,69 +91,50 @@ impl HandleError for DirectorySearchError {
}
}
-pub fn room_search(
- base: Url,
- access_token: AccessToken,
- homeserver: String,
- generic_search_term: String,
- third_party: String,
- rooms_since: Option<String>,
+pub async fn room_search(
+ session_client: MatrixClient,
+ server: Option<&str>,
+ search_term: Option<&str>,
+ room_network: RoomNetwork<'_>,
+ rooms_since: Option<&str>,
) -> Result<(Vec<Room>, Option<String>), DirectorySearchError> {
- let homeserver = Some(homeserver).filter(|hs| !hs.is_empty());
- let generic_search_term = Some(generic_search_term).filter(|q| !q.is_empty());
- let third_party = Some(third_party).filter(|tp| !tp.is_empty());
-
- let server = homeserver
- .map(|hs| {
- Url::parse(&hs)
- .ok()
- .as_ref()
- .and_then(Url::host)
- .as_ref()
- .map(Host::to_owned)
- .map(Ok)
- .unwrap_or_else(|| Host::parse(&hs))
- // Remove the url::Host enum, we only need the domain string
- .map(|host| host.to_string())
- .map(Some)
- })
- .unwrap_or(Ok(None))
- .map_err(DirectorySearchError::InvalidHomeserverUrl)?;
-
- let params = PublicRoomsParameters {
- access_token,
- server,
- };
+ let server = server
+ .map(<&ServerName>::try_from)
+ .transpose()
+ .map_err(DirectorySearchError::MalformedServerName)?;
- let body = PublicRoomsBody {
- limit: Some(globals::ROOM_DIRECTORY_LIMIT),
- filter: Some(PublicRoomsFilter {
- generic_search_term,
- }),
+ let request = assign!(PublicRoomsFilteredRequest::new(), {
+ server,
+ limit: Some(globals::ROOM_DIRECTORY_LIMIT.into()),
since: rooms_since,
- third_party_networks: third_party
- .map(ThirdPartyNetworks::Only)
- .unwrap_or_default(),
- };
+ filter: assign!(PublicRoomsFilter::new(), {
+ generic_search_term: search_term,
+ }),
+ room_network,
+ });
- let request = post_public_rooms(base.clone(), ¶ms, &body)?;
- let response: PublicRoomsResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
+ let response = session_client.public_rooms_filtered(request).await?;
let since = response.next_batch;
let rooms = response
.chunk
.into_iter()
.map(TryInto::try_into)
- .inspect(|r: &Result<Room, _>| {
- if let Ok(room) = r {
- if let Some(avatar) = room.avatar.clone() {
- if let Ok(dest) = cache_dir_path(None, &room.id.to_string()) {
- let _ = dw_media(base.clone(), &avatar, ContentType::Download, Some(dest));
- }
- }
+ .collect::<Result<Vec<Room>, UrlError>>()?;
+
+ for room in &rooms {
+ if let Some(avatar) = room.avatar.as_ref() {
+ if let Ok(dest) = cache_dir_path(None, room.id.as_str()) {
+ let _ = dw_media(
+ session_client.clone(),
+ avatar,
+ ContentType::Download,
+ Some(dest),
+ )
+ .await;
}
- })
- .collect::<Result<_, UrlError>>()?;
+ }
+ }
Ok((rooms, since))
}
diff --git a/fractal-gtk/src/backend/media.rs b/fractal-gtk/src/backend/media.rs
index 717f54ae..b3f464ee 100644
--- a/fractal-gtk/src/backend/media.rs
+++ b/fractal-gtk/src/backend/media.rs
@@ -3,6 +3,7 @@ use crate::globals;
use fractal_api::identifiers::{Error as IdError, EventId, RoomId};
use fractal_api::reqwest::Error as ReqwestError;
use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
use std::path::PathBuf;
use std::sync::mpsc::Sender;
@@ -22,18 +23,18 @@ use super::{dw_media, get_prev_batch_from, ContentType, ThreadPool};
pub type MediaResult = Result<PathBuf, MediaError>;
pub type MediaList = (Vec<Message>, String);
-pub fn get_thumb_async(thread_pool: ThreadPool, baseu: Url, media: Url, tx: Sender<MediaResult>) {
- thread_pool.run(move || {
- let fname = dw_media(baseu, &media, ContentType::default_thumbnail(), None);
- tx.send(fname).expect_log("Connection closed");
- });
+pub async fn get_thumb(session_client: MatrixClient, media: &Url) -> MediaResult {
+ dw_media(
+ session_client,
+ media,
+ ContentType::default_thumbnail(),
+ None,
+ )
+ .await
}
-pub fn get_media_async(thread_pool: ThreadPool, baseu: Url, media: Url, tx: Sender<MediaResult>) {
- thread_pool.run(move || {
- let fname = dw_media(baseu, &media, ContentType::Download, None);
- tx.send(fname).expect_log("Connection closed");
- });
+pub async fn get_media(session_client: MatrixClient, media: &Url) -> MediaResult {
+ dw_media(session_client, media, ContentType::Download, None).await
}
pub fn get_media_list_async(
diff --git a/fractal-gtk/src/backend/mod.rs b/fractal-gtk/src/backend/mod.rs
index d10b68e0..2eeb4bf4 100644
--- a/fractal-gtk/src/backend/mod.rs
+++ b/fractal-gtk/src/backend/mod.rs
@@ -1,11 +1,12 @@
-use fractal_api::identifiers::{EventId, RoomId};
+use fractal_api::identifiers::{EventId, RoomId, ServerName};
use fractal_api::reqwest::Error as ReqwestError;
use fractal_api::url::Url;
+use fractal_api::{Client as MatrixClient, Error as MatrixError};
use lazy_static::lazy_static;
use log::error;
use regex::Regex;
+use std::convert::TryFrom;
use std::fmt::Debug;
-use std::fs::write;
use std::io::Error as IoError;
use std::path::PathBuf;
use std::sync::{Arc, Condvar, Mutex};
@@ -13,14 +14,13 @@ use std::thread;
use crate::client::ClientBlocking;
use crate::util::cache_dir_path;
+use fractal_api::api::r0::media::get_content::Request as GetContentRequest;
+use fractal_api::api::r0::media::get_content_thumbnail::Method;
+use fractal_api::api::r0::media::get_content_thumbnail::Request as GetContentThumbnailRequest;
+use fractal_api::assign;
use fractal_api::r0::context::get_context::request as get_context;
use fractal_api::r0::context::get_context::Parameters as GetContextParameters;
use fractal_api::r0::context::get_context::Response as GetContextResponse;
-use fractal_api::r0::media::get_content::request as get_content;
-use fractal_api::r0::media::get_content::Parameters as GetContentParameters;
-use fractal_api::r0::media::get_content_thumbnail::request as get_content_thumbnail;
-use fractal_api::r0::media::get_content_thumbnail::Method;
-use fractal_api::r0::media::get_content_thumbnail::Parameters as GetContentThumbnailParameters;
use fractal_api::r0::AccessToken;
pub mod directory;
@@ -79,7 +79,7 @@ impl ThreadPool {
pub enum ContentType {
Download,
- Thumbnail(u64, u64),
+ Thumbnail(u32, u32),
}
impl ContentType {
@@ -118,12 +118,12 @@ pub fn get_prev_batch_from(
pub enum MediaError {
MalformedMxcUrl,
Io(IoError),
- Reqwest(ReqwestError),
+ Matrix(MatrixError),
}
-impl From<ReqwestError> for MediaError {
- fn from(err: ReqwestError) -> Self {
- Self::Reqwest(err)
+impl From<MatrixError> for MediaError {
+ fn from(err: MatrixError) -> Self {
+ Self::Matrix(err)
}
}
@@ -135,8 +135,8 @@ impl From<IoError> for MediaError {
impl HandleError for MediaError {}
-pub fn dw_media(
- base: Url,
+pub async fn dw_media(
+ session_client: MatrixClient,
mxc: &Url,
media_type: ContentType,
dest: Option<PathBuf>,
@@ -145,7 +145,16 @@ pub fn dw_media(
return Err(MediaError::MalformedMxcUrl);
}
- let server = mxc.host().ok_or(MediaError::MalformedMxcUrl)?.to_owned();
+ let server_name = mxc
+ .host()
+ .as_ref()
+ .map(ToString::to_string)
+ .and_then(|host| {
+ <&ServerName>::try_from(host.as_str())
+ .map(ToOwned::to_owned)
+ .ok()
+ })
+ .ok_or(MediaError::MalformedMxcUrl)?;
let media_id = mxc
.path_segments()
@@ -153,19 +162,6 @@ pub fn dw_media(
.filter(|s| !s.is_empty())
.ok_or(MediaError::MalformedMxcUrl)?;
- let request = if let ContentType::Thumbnail(width, height) = media_type {
- let params = GetContentThumbnailParameters {
- width,
- height,
- method: Some(Method::Crop),
- allow_remote: true,
- };
- get_content_thumbnail(base, ¶ms, &server, &media_id)
- } else {
- let params = GetContentParameters::default();
- get_content(base, ¶ms, &server, &media_id)
- }?;
-
let default_fname = || {
let dir = if media_type.is_thumbnail() {
"thumbs"
@@ -185,14 +181,28 @@ pub fn dw_media(
.map_or(false, |dur| dur.as_secs() < 60);
if fname.is_file() && (dest.is_none() || is_fname_recent) {
- Ok(fname)
+ return Ok(fname);
+ }
+
+ let media = if let ContentType::Thumbnail(width, height) = media_type {
+ let request = assign!(GetContentThumbnailRequest::new(
+ &media_id,
+ &server_name,
+ width.into(),
+ height.into(),
+ ), {
+ method: Some(Method::Crop),
+ });
+
+ session_client.send(request).await?.file
} else {
- let media = HTTP_CLIENT.get_client().execute(request)?.bytes()?;
+ let request = GetContentRequest::new(&media_id, &server_name);
+ session_client.send(request).await?.file
+ };
- write(&fname, media)?;
+ tokio::fs::write(&fname, media).await?;
- Ok(fname)
- }
+ Ok(fname)
}
pub trait HandleError: Debug {
diff --git a/fractal-gtk/src/backend/room.rs b/fractal-gtk/src/backend/room.rs
index 369333d6..0afc0c1d 100644
--- a/fractal-gtk/src/backend/room.rs
+++ b/fractal-gtk/src/backend/room.rs
@@ -19,7 +19,8 @@ use std::time::Duration;
use crate::globals;
use crate::actions::AppState;
-use crate::backend::HTTP_CLIENT;
+use crate::app::RUNTIME;
+use crate::backend::{MediaError, HTTP_CLIENT};
use crate::util::cache_dir_path;
use crate::model::{
@@ -122,30 +123,46 @@ pub fn get_room_detail(
}
#[derive(Debug)]
-pub struct RoomAvatarError(ReqwestError);
+pub enum RoomAvatarError {
+ Reqwest(ReqwestError),
+ Download(MediaError),
+}
impl From<ReqwestError> for RoomAvatarError {
fn from(err: ReqwestError) -> Self {
- Self(err)
+ Self::Reqwest(err)
+ }
+}
+
+impl From<MediaError> for RoomAvatarError {
+ fn from(err: MediaError) -> Self {
+ Self::Download(err)
}
}
impl HandleError for RoomAvatarError {}
pub fn get_room_avatar(
- base: Url,
+ session_client: MatrixClient,
access_token: AccessToken,
room_id: RoomId,
) -> Result<(RoomId, Option<Url>), RoomAvatarError> {
+ let base = session_client.homeserver().clone();
+
let params = GetStateEventsForKeyParameters { access_token };
- let request = get_state_events_for_key(base.clone(), ¶ms, &room_id, "m.room.avatar")?;
+ let request = get_state_events_for_key(base, ¶ms, &room_id, "m.room.avatar")?;
let response: JsonValue = HTTP_CLIENT.get_client().execute(request)?.json()?;
let avatar = response["url"].as_str().and_then(|s| Url::parse(s).ok());
let dest = cache_dir_path(None, &room_id.to_string()).ok();
if let Some(ref avatar) = avatar {
- let _ = dw_media(base, avatar, ContentType::default_thumbnail(), dest);
+ RUNTIME.handle().block_on(dw_media(
+ session_client,
+ avatar,
+ ContentType::default_thumbnail(),
+ dest,
+ ))?;
}
Ok((room_id, avatar))
diff --git a/fractal-gtk/src/backend/sync.rs b/fractal-gtk/src/backend/sync.rs
index e7b0d444..091d2f39 100644
--- a/fractal-gtk/src/backend/sync.rs
+++ b/fractal-gtk/src/backend/sync.rs
@@ -20,7 +20,7 @@ use fractal_api::r0::AccessToken;
use fractal_api::identifiers::{EventId, RoomId, UserId};
use fractal_api::reqwest::blocking::{Client, Response};
-use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
use log::error;
use serde::de::DeserializeOwned;
use serde_json::value::from_value;
@@ -117,7 +117,7 @@ pub enum SyncRet {
}
pub fn sync(
- base: Url,
+ session_client: MatrixClient,
access_token: AccessToken,
user_id: UserId,
join_to_room: Option<RoomId>,
@@ -125,6 +125,8 @@ pub fn sync(
initial: bool,
number_tries: u64,
) -> Result<SyncRet, SyncError> {
+ let base = session_client.homeserver().clone();
+
let (timeout, filter) = if !initial {
(time::Duration::from_secs(30), Default::default())
} else {
@@ -190,13 +192,14 @@ pub fn sync(
match query {
Ok(response) => {
if since.is_none() {
- let rooms = Room::from_sync_response(&response, user_id, access_token, base)
- .map(|rooms| {
- let def = join_to_room
- .and_then(|jtr| rooms.iter().find(|x| x.id == jtr).cloned());
- (rooms, def)
- })
- .map_err(Into::into);
+ let rooms =
+ Room::from_sync_response(session_client, &response, user_id, access_token)
+ .map(|rooms| {
+ let def = join_to_room
+ .and_then(|jtr| rooms.iter().find(|x| x.id == jtr).cloned());
+ (rooms, def)
+ })
+ .map_err(Into::into);
let next_batch = response.next_batch;
@@ -205,9 +208,13 @@ pub fn sync(
let join = &response.rooms.join;
// New rooms
- let update_rooms =
- Room::from_sync_response(&response, user_id.clone(), access_token, base)
- .map_err(Into::into);
+ let update_rooms = Room::from_sync_response(
+ session_client,
+ &response,
+ user_id.clone(),
+ access_token,
+ )
+ .map_err(Into::into);
// Message events
let room_messages = join
diff --git a/fractal-gtk/src/backend/user.rs b/fractal-gtk/src/backend/user.rs
index f2690f27..ce2979f9 100644
--- a/fractal-gtk/src/backend/user.rs
+++ b/fractal-gtk/src/backend/user.rs
@@ -1,11 +1,13 @@
use fractal_api::identifiers::UserId;
use fractal_api::reqwest::Error as ReqwestError;
use fractal_api::url::{ParseError as UrlError, Url};
+use fractal_api::Client as MatrixClient;
use std::fs;
use std::io::Error as IoError;
use super::MediaError;
use crate::actions::global::activate_action;
+use crate::app::RUNTIME;
use crate::appop::UserInfoCache;
use crate::backend::ThreadPool;
use crate::backend::HTTP_CLIENT;
@@ -564,8 +566,8 @@ pub fn set_user_avatar(
pub fn get_user_info_async(
thread_pool: ThreadPool,
+ session_client: MatrixClient,
user_info_cache: UserInfoCache,
- baseu: Url,
access_token: AccessToken,
uid: UserId,
tx: Sender<UserInfo>,
@@ -578,7 +580,7 @@ pub fn get_user_info_async(
}
thread_pool.run(move || {
- let info = get_user_avatar(baseu, access_token, &uid);
+ let info = get_user_avatar(session_client, access_token, &uid);
if let Ok(ref i0) = info {
user_info_cache.lock().unwrap().insert(uid, i0.clone());
@@ -659,10 +661,11 @@ impl From<UrlError> for GetUserAvatarError {
impl HandleError for GetUserAvatarError {}
pub fn get_user_avatar(
- base: Url,
+ session_client: MatrixClient,
access_token: AccessToken,
user_id: &UserId,
) -> Result<(String, PathBuf), GetUserAvatarError> {
+ let base = session_client.homeserver().clone();
let params = GetProfileParameters { access_token };
let request = get_profile(base.clone(), ¶ms, user_id)?;
let response: GetProfileResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
@@ -678,7 +681,12 @@ pub fn get_user_avatar(
.transpose()?
.map(|url| {
let dest = cache_dir_path(None, &user_id.to_string())?;
- dw_media(base, &url, ContentType::default_thumbnail(), Some(dest))
+ RUNTIME.handle().block_on(dw_media(
+ session_client,
+ &url,
+ ContentType::default_thumbnail(),
+ Some(dest),
+ ))
})
.unwrap_or_else(|| Ok(Default::default()))
.map_err(GetUserAvatarError::Download)?;
diff --git a/fractal-gtk/src/cache/mod.rs b/fractal-gtk/src/cache/mod.rs
index c16500ca..491c3de9 100644
--- a/fractal-gtk/src/cache/mod.rs
+++ b/fractal-gtk/src/cache/mod.rs
@@ -5,6 +5,7 @@ use crate::util::cache_dir_path;
use crate::util::ResultExpectLog;
use fractal_api::r0::AccessToken;
use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
use glib::source::Continue;
use gtk::LabelExt;
use serde::{Deserialize, Serialize};
@@ -156,9 +157,9 @@ pub fn remove_from_cache(user_info_cache: UserInfoCache, user_id: &UserId) {
/// this downloads a avatar and stores it in the cache folder
pub fn download_to_cache(
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
- server_url: Url,
access_token: AccessToken,
uid: UserId,
data: Rc<RefCell<AvatarData>>,
@@ -166,8 +167,8 @@ pub fn download_to_cache(
let (tx, rx) = channel::<(String, PathBuf)>();
user::get_user_info_async(
thread_pool,
+ session_client,
user_info_cache,
- server_url,
access_token,
uid,
tx,
diff --git a/fractal-gtk/src/globals.rs b/fractal-gtk/src/globals.rs
index 6efcc99e..4a26bf50 100644
--- a/fractal-gtk/src/globals.rs
+++ b/fractal-gtk/src/globals.rs
@@ -6,7 +6,7 @@ use std::{path::PathBuf, time::Duration};
pub const TIMEOUT: Duration = Duration::from_secs(80);
pub const PAGE_LIMIT: i32 = 40;
-pub const ROOM_DIRECTORY_LIMIT: i32 = 20;
+pub const ROOM_DIRECTORY_LIMIT: u32 = 20;
pub const DEVICE_NAME: &str = "Fractal";
pub const CACHE_SIZE: usize = 40;
diff --git a/fractal-gtk/src/model/room.rs b/fractal-gtk/src/model/room.rs
index 807fb8ab..3521114c 100644
--- a/fractal-gtk/src/model/room.rs
+++ b/fractal-gtk/src/model/room.rs
@@ -5,11 +5,12 @@ use crate::model::member::Member;
use crate::model::member::MemberList;
use crate::model::message::Message;
use either::Either;
-use fractal_api::identifiers::{Error as IdError, EventId, RoomId, UserId};
-use fractal_api::r0::directory::post_public_rooms::Chunk as PublicRoomsChunk;
+use fractal_api::directory::PublicRoomsChunk;
+use fractal_api::identifiers::{Error as IdError, EventId, RoomAliasId, RoomId, UserId};
use fractal_api::r0::sync::sync_events::Response as SyncResponse;
use fractal_api::r0::AccessToken;
use fractal_api::url::{ParseError as UrlError, Url};
+use fractal_api::Client as MatrixClient;
use log::{debug, info};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
@@ -88,10 +89,10 @@ pub struct Room {
pub avatar: Option<Url>,
pub name: Option<String>,
pub topic: Option<String>,
- pub alias: Option<String>,
+ pub alias: Option<RoomAliasId>,
pub guest_can_join: bool,
pub world_readable: bool,
- pub n_members: i32,
+ pub n_members: u64,
pub members: MemberList,
pub notifications: i32,
pub highlight: i32,
@@ -134,10 +135,10 @@ impl Room {
}
pub fn from_sync_response(
+ session_client: MatrixClient,
response: &SyncResponse,
user_id: UserId,
access_token: AccessToken,
- baseu: Url,
) -> Result<Vec<Self>, IdError> {
// getting the list of direct rooms
let direct: HashSet<RoomId> = parse_m_direct(&response.account_data.events)
@@ -165,9 +166,9 @@ impl Room {
let mut r = Self {
name: calculate_room_name(stevents, &user_id),
- avatar: evc(stevents, "m.room.avatar", "url")
- .and_then(|ref url| Url::parse(url).ok()),
- alias: evc(stevents, "m.room.canonical_alias", "alias"),
+ avatar: evc(stevents, "m.room.avatar", "url").and_then(|url| Url::parse(&url).ok()),
+ alias: evc(stevents, "m.room.canonical_alias", "alias")
+ .and_then(|alias| RoomAliasId::try_from(alias).ok()),
topic: evc(stevents, "m.room.topic", "topic"),
direct: direct.contains(&k),
notifications: room.unread_notifications.notification_count,
@@ -211,7 +212,7 @@ impl Room {
if leave_id != user_id {
let kick_reason = &last_event["content"]["reason"];
if let Ok((kicker_alias, kicker_avatar)) =
- get_user_avatar(baseu.clone(), access_token.clone(), &leave_id)
+ get_user_avatar(session_client.clone(), access_token.clone(), &leave_id)
{
let kicker = Member {
alias: Some(kicker_alias),
@@ -250,7 +251,7 @@ impl Room {
})
.map_or(Ok(None), |ev| {
Ok(get_user_avatar(
- baseu.clone(),
+ session_client.clone(),
access_token.clone(),
&UserId::try_from(ev["sender"].as_str().unwrap_or_default())?,
)
@@ -266,8 +267,9 @@ impl Room {
Ok(Some(Self {
name: calculate_room_name(stevents, &user_id),
avatar: evc(stevents, "m.room.avatar", "url")
- .and_then(|ref url| Url::parse(url).ok()),
- alias: evc(stevents, "m.room.canonical_alias", "alias"),
+ .and_then(|url| Url::parse(&url).ok()),
+ alias: evc(stevents, "m.room.canonical_alias", "alias")
+ .and_then(|alias| RoomAliasId::try_from(alias).ok()),
topic: evc(stevents, "m.room.topic", "topic"),
direct: direct.contains(&k),
..Self::new(k.clone(), RoomMembership::Invited(inv_sender))
@@ -333,7 +335,7 @@ impl TryFrom<PublicRoomsChunk> for Room {
fn try_from(input: PublicRoomsChunk) -> Result<Self, Self::Error> {
Ok(Self {
- alias: input.canonical_alias.as_ref().map(ToString::to_string),
+ alias: input.canonical_alias,
name: input.name,
avatar: input
.avatar_url
@@ -341,7 +343,7 @@ impl TryFrom<PublicRoomsChunk> for Room {
.map(|url| Url::parse(&url))
.transpose()?,
topic: input.topic,
- n_members: input.num_joined_members,
+ n_members: input.num_joined_members.into(),
world_readable: input.world_readable,
guest_can_join: input.guest_can_join,
..Self::new(input.room_id, RoomMembership::None)
diff --git a/fractal-gtk/src/widgets/image.rs b/fractal-gtk/src/widgets/image.rs
index b28289c0..cd87dec7 100644
--- a/fractal-gtk/src/widgets/image.rs
+++ b/fractal-gtk/src/widgets/image.rs
@@ -1,7 +1,9 @@
-use crate::backend::{media, ThreadPool};
+use crate::app::RUNTIME;
+use crate::backend::media;
use crate::util::get_border_radius;
use either::Either;
use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
use gdk::prelude::GdkContextExt;
use gdk_pixbuf::Pixbuf;
use gdk_pixbuf::PixbufAnimation;
@@ -12,9 +14,6 @@ use gtk::prelude::*;
use gtk::DrawingArea;
use log::error;
use std::path::{Path, PathBuf};
-use std::sync::mpsc::channel;
-use std::sync::mpsc::TryRecvError;
-use std::sync::mpsc::{Receiver, Sender};
use std::sync::{Arc, Mutex};
#[derive(Clone, Debug)]
@@ -99,9 +98,9 @@ impl Image {
self
}
- pub fn build(self, thread_pool: ThreadPool) -> Image {
+ pub fn build(self, session_client: MatrixClient) -> Image {
self.draw();
- self.load_async(thread_pool);
+ self.load_async(session_client);
self
}
@@ -267,37 +266,33 @@ impl Image {
/// If `path` starts with mxc this func download the img async, in other case the image is loaded
/// in the `image` widget scaled to size
- pub fn load_async(&self, thread_pool: ThreadPool) {
+ pub fn load_async(&self, session_client: MatrixClient) {
match self.path.as_ref() {
Either::Left(url) if url.scheme() == "mxc" => {
let mxc = url.clone();
// asyn load
- let (tx, rx): (Sender<media::MediaResult>, Receiver<media::MediaResult>) =
- channel();
- let command = if self.thumb {
- media::get_thumb_async
+ let response = if self.thumb {
+ RUNTIME.spawn(async move { media::get_thumb(session_client, &mxc).await })
} else {
- media::get_media_async
+ RUNTIME.spawn(async move { media::get_media(session_client, &mxc).await })
};
- command(thread_pool, self.server_url.clone(), mxc, tx);
let local_path = self.local_path.clone();
let pix = self.pixbuf.clone();
let scaled = self.scaled.clone();
let da = self.widget.clone();
da.get_style_context().add_class("image-spinner");
- glib::timeout_add_local(50, move || match rx.try_recv() {
- Err(TryRecvError::Empty) => Continue(true),
- Err(TryRecvError::Disconnected) => Continue(false),
- Ok(Ok(fname)) => {
- *local_path.lock().unwrap() = Some(fname.clone());
- load_pixbuf(pix.clone(), scaled.clone(), da.clone(), &fname);
- da.get_style_context().remove_class("image-spinner");
- Continue(false)
- }
- Ok(Err(err)) => {
- error!("Image path could not be found due to error: {:?}", err);
- Continue(false)
+ glib::MainContext::default().spawn_local(async move {
+ match response.await {
+ Err(_) => return,
+ Ok(Ok(fname)) => {
+ *local_path.lock().unwrap() = Some(fname.clone());
+ load_pixbuf(pix.clone(), scaled.clone(), da.clone(), &fname);
+ da.get_style_context().remove_class("image-spinner");
+ }
+ Ok(Err(err)) => {
+ error!("Image path could not be found due to error: {:?}", err);
+ }
}
});
}
diff --git a/fractal-gtk/src/widgets/inline_player.rs b/fractal-gtk/src/widgets/inline_player.rs
index b10cead8..2aca3437 100644
--- a/fractal-gtk/src/widgets/inline_player.rs
+++ b/fractal-gtk/src/widgets/inline_player.rs
@@ -17,7 +17,7 @@
//
// SPDX-License-Identifier: GPL-3.0-or-later
-use crate::backend::{media, ThreadPool};
+use crate::backend::media;
use glib::clone;
use gst::prelude::*;
@@ -40,13 +40,10 @@ use std::ops::Deref;
use std::path::PathBuf;
use std::rc::Rc;
-use std::sync::mpsc::channel;
-use std::sync::mpsc::TryRecvError;
-use std::sync::mpsc::{Receiver, Sender};
-
use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
-use crate::app::App;
+use crate::app::{App, RUNTIME};
use crate::util::i18n::i18n;
pub trait PlayerExt {
@@ -54,11 +51,10 @@ pub trait PlayerExt {
fn pause(&self);
fn stop(&self);
fn initialize_stream(
- player: &Rc<Self>,
+ player: Rc<Self>,
+ session_client: MatrixClient,
media_url: Url,
- server_url: Url,
- thread_pool: ThreadPool,
- bx: >k::Box,
+ bx: gtk::Box,
start_playing: bool,
);
fn get_controls_container(player: &Rc<Self>) -> Option<gtk::Box>;
@@ -501,61 +497,51 @@ impl<T: MediaPlayer + 'static> PlayerExt for T {
}
fn initialize_stream(
- player: &Rc<Self>,
+ player: Rc<Self>,
+ session_client: MatrixClient,
media_url: Url,
- server_url: Url,
- thread_pool: ThreadPool,
- bx: >k::Box,
+ bx: gtk::Box,
start_playing: bool,
) {
+ let response =
+ RUNTIME.spawn(async move { media::get_media(session_client, &media_url).await });
bx.set_opacity(0.3);
- let (tx, rx): (Sender<media::MediaResult>, Receiver<media::MediaResult>) = channel();
- media::get_media_async(thread_pool, server_url, media_url, tx);
let local_path = player.get_local_path_access();
- glib::timeout_add_local(
- 50,
- clone!(@strong player, @strong bx => move || {
- match rx.try_recv() {
- Err(TryRecvError::Empty) => Continue(true),
- Err(TryRecvError::Disconnected) => {
- let msg = i18n("Could not retrieve file URI");
- /* FIXME: don't use APPOP! */
- APPOP!(show_error, (msg));
- Continue(true)
- },
- Ok(Ok(path)) => {
- match Url::from_file_path(&path) {
- Ok(uri) => {
- *local_path.borrow_mut() = Some(path);
- if !start_playing {
- if let Some(controls) = player.get_controls() {
- if let Ok(duration) = get_media_duration(&uri) {
- controls.timer.on_duration_changed(Duration(duration))
- }
- }
- }
- player.get_player().set_uri(uri.as_str());
- if player.get_controls().is_some() {
- ControlsConnection::init(&player);
- }
- bx.set_opacity(1.0);
- if start_playing {
- player.play();
+ glib::MainContext::default().spawn_local(async move {
+ match response.await {
+ Err(_) => {
+ let msg = i18n("Could not retrieve file URI");
+ /* FIXME: don't use APPOP! */
+ APPOP!(show_error, (msg));
+ }
+ Ok(Ok(path)) => match Url::from_file_path(&path) {
+ Ok(uri) => {
+ *local_path.borrow_mut() = Some(path);
+ if !start_playing {
+ if let Some(controls) = player.get_controls() {
+ if let Ok(duration) = get_media_duration(&uri) {
+ controls.timer.on_duration_changed(Duration(duration))
}
}
- Err(_) => {
- error!("Media path is not valid: {:?}", path);
- }
}
- Continue(false)
+ player.get_player().set_uri(uri.as_str());
+ if player.get_controls().is_some() {
+ ControlsConnection::init(&player);
+ }
+ bx.set_opacity(1.0);
+ if start_playing {
+ player.play();
+ }
}
- Ok(Err(err)) => {
- error!("Media path could not be found due to error: {:?}", err);
- Continue(false)
+ Err(_) => {
+ error!("Media path is not valid: {:?}", path);
}
+ },
+ Ok(Err(err)) => {
+ error!("Media path could not be found due to error: {:?}", err);
}
- }),
- );
+ }
+ });
}
fn get_controls_container(player: &Rc<Self>) -> Option<gtk::Box> {
diff --git a/fractal-gtk/src/widgets/media_viewer.rs b/fractal-gtk/src/widgets/media_viewer.rs
index 3f848dfc..292a448a 100644
--- a/fractal-gtk/src/widgets/media_viewer.rs
+++ b/fractal-gtk/src/widgets/media_viewer.rs
@@ -12,6 +12,7 @@ use crate::util::i18n::i18n;
use either::Either;
use fractal_api::identifiers::UserId;
use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
use gdk::*;
use glib::signal;
use glib::source::Continue;
@@ -147,7 +148,7 @@ struct Data {
}
impl Data {
- pub fn enter_full_screen(&mut self, thread_pool: ThreadPool) {
+ pub fn enter_full_screen(&mut self, session_client: MatrixClient) {
self.main_window.fullscreen();
self.is_fullscreen = true;
@@ -194,12 +195,12 @@ impl Data {
media_container.show();
}
_ => {
- self.redraw_media_in_viewport(thread_pool);
+ self.redraw_media_in_viewport(session_client);
}
}
}
- pub fn leave_full_screen(&mut self, thread_pool: ThreadPool) {
+ pub fn leave_full_screen(&mut self, session_client: MatrixClient) {
self.main_window.unfullscreen();
self.is_fullscreen = false;
@@ -252,7 +253,7 @@ impl Data {
}
}
_ => {
- self.redraw_media_in_viewport(thread_pool);
+ self.redraw_media_in_viewport(session_client);
}
}
}
@@ -281,7 +282,7 @@ impl Data {
}
}
- pub fn previous_media(&mut self, thread_pool: ThreadPool) -> bool {
+ pub fn previous_media(&mut self, session_client: MatrixClient) -> bool {
if self.no_more_media {
return true;
}
@@ -295,12 +296,12 @@ impl Data {
set_header_title(&self.builder, name);
}
- self.redraw_media_in_viewport(thread_pool);
+ self.redraw_media_in_viewport(session_client);
true
}
}
- pub fn next_media(&mut self, thread_pool: ThreadPool) {
+ pub fn next_media(&mut self, session_client: MatrixClient) {
if self.current_media_index >= self.media_list.len() - 1 {
return;
}
@@ -310,10 +311,10 @@ impl Data {
set_header_title(&self.builder, name);
}
- self.redraw_media_in_viewport(thread_pool);
+ self.redraw_media_in_viewport(session_client);
}
- pub fn redraw_media_in_viewport(&mut self, thread_pool: ThreadPool) {
+ pub fn redraw_media_in_viewport(&mut self, session_client: MatrixClient) {
let msg = &self.media_list[self.current_media_index];
let url = unwrap_or_unit_return!(msg.url.clone());
let media_container = self
@@ -330,13 +331,13 @@ impl Data {
let image = image::Image::new(self.server_url.clone(), Either::Left(url))
.shrink_to_fit(true)
.center(true)
- .build(thread_pool);
+ .build(session_client);
media_container.add(&image.widget);
image.widget.show();
self.widget = Widget::Image(image);
}
"m.video" => {
- let widget = self.create_video_widget(thread_pool, url);
+ let widget = self.create_video_widget(session_client, url);
media_container.add(&widget.outer_box);
self.widget = Widget::Video(widget);
media_container.show_all();
@@ -348,17 +349,16 @@ impl Data {
self.set_nav_btn_visibility();
}
- fn create_video_widget(&self, thread_pool: ThreadPool, url: Url) -> VideoWidget {
+ fn create_video_widget(&self, session_client: MatrixClient, url: Url) -> VideoWidget {
let with_controls = true;
let player = VideoPlayerWidget::new(with_controls);
let bx = gtk::Box::new(gtk::Orientation::Vertical, 0);
let start_playing = true;
PlayerExt::initialize_stream(
- &player,
+ player.clone(),
+ session_client,
url,
- self.server_url.clone(),
- thread_pool,
- &bx,
+ bx.clone(),
start_playing,
);
@@ -642,7 +642,11 @@ impl MediaViewer {
}
}
- pub fn create(&mut self, thread_pool: ThreadPool) -> Option<(gtk::Box, gtk::Box)> {
+ pub fn create(
+ &mut self,
+ session_client: MatrixClient,
+ thread_pool: ThreadPool,
+ ) -> Option<(gtk::Box, gtk::Box)> {
let body = self
.builder
.get_object::<gtk::Box>("media_viewer_box")
@@ -651,14 +655,14 @@ impl MediaViewer {
.builder
.get_object::<gtk::Box>("media_viewer_headerbar_box")
.expect("Can't find media_viewer_headerbar in ui file.");
- self.connect_media_viewer_headerbar(thread_pool.clone());
- self.connect_media_viewer_box(thread_pool);
+ self.connect_media_viewer_headerbar(session_client.clone());
+ self.connect_media_viewer_box(session_client, thread_pool);
self.connect_stop_video_when_leaving();
Some((body, header))
}
- pub fn display_media_viewer(&mut self, thread_pool: ThreadPool, media_msg: Message) {
+ pub fn display_media_viewer(&mut self, session_client: MatrixClient, media_msg: Message) {
let url = unwrap_or_unit_return!(media_msg.url.clone());
let previous_media_revealer = self
@@ -686,7 +690,7 @@ impl MediaViewer {
image::Image::new(self.data.borrow().server_url.clone(), Either::Left(url))
.shrink_to_fit(true)
.center(true)
- .build(thread_pool);
+ .build(session_client);
media_container.add(&image.widget);
media_container.show_all();
@@ -694,7 +698,7 @@ impl MediaViewer {
self.data.borrow_mut().widget = Widget::Image(image);
}
"m.video" => {
- let video_widget = self.data.borrow().create_video_widget(thread_pool, url);
+ let video_widget = self.data.borrow().create_video_widget(session_client, url);
media_container.add(&video_widget.outer_box);
media_container.show_all();
@@ -708,7 +712,7 @@ impl MediaViewer {
}
/* connect media viewer headerbar */
- pub fn connect_media_viewer_headerbar(&self, thread_pool: ThreadPool) {
+ pub fn connect_media_viewer_headerbar(&self, session_client: MatrixClient) {
let own = &self.data;
let full_screen_button = self
.builder
@@ -718,15 +722,19 @@ impl MediaViewer {
let main_window = own.borrow().main_window.clone();
if let Some(win) = main_window.get_window() {
if !win.get_state().contains(gdk::WindowState::FULLSCREEN) {
- own.borrow_mut().enter_full_screen(thread_pool.clone());
+ own.borrow_mut().enter_full_screen(session_client.clone());
} else {
- own.borrow_mut().leave_full_screen(thread_pool.clone())
+ own.borrow_mut().leave_full_screen(session_client.clone());
}
}
}));
}
- pub fn connect_media_viewer_box(&mut self, thread_pool: ThreadPool) {
+ pub fn connect_media_viewer_box(
+ &mut self,
+ session_client: MatrixClient,
+ thread_pool: ThreadPool,
+ ) {
let full_screen_button = self
.builder
.get_object::<gtk::Button>("full_screen_button")
@@ -883,10 +891,11 @@ impl MediaViewer {
.builder
.get_object::<gtk::Button>("previous_media_button")
.expect("Cant find previous_media_button in ui file.");
+ let s_client = session_client.clone();
let t_pool = thread_pool.clone();
previous_media_button.connect_clicked(clone!(@weak data => move |_| {
- if !data.borrow_mut().previous_media(t_pool.clone()) {
- load_more_media(t_pool.clone(), data, builder.clone());
+ if !data.borrow_mut().previous_media(s_client.clone()) {
+ load_more_media(s_client.clone(), t_pool.clone(), data, builder.clone());
}
}));
@@ -895,7 +904,7 @@ impl MediaViewer {
.get_object::<gtk::Button>("next_media_button")
.expect("Cant find next_media_button in ui file.");
next_media_button.connect_clicked(clone!(@weak data => move |_| {
- data.borrow_mut().next_media(thread_pool.clone());
+ data.borrow_mut().next_media(session_client.clone());
}));
let media_container = self
@@ -1014,7 +1023,12 @@ fn loading_state(ui: >k::Builder, val: bool) -> bool {
val
}
-fn load_more_media(thread_pool: ThreadPool, data: Rc<RefCell<Data>>, builder: gtk::Builder) {
+fn load_more_media(
+ session_client: MatrixClient,
+ thread_pool: ThreadPool,
+ data: Rc<RefCell<Data>>,
+ builder: gtk::Builder,
+) {
data.borrow_mut().loading_more_media = loading_state(&builder, true);
let msg = data.borrow().media_list[data.borrow().current_media_index].clone();
@@ -1067,10 +1081,10 @@ fn load_more_media(thread_pool: ThreadPool, data: Rc<RefCell<Data>>, builder: gt
data.borrow_mut().media_list = new_media_list;
data.borrow_mut().prev_batch = Some(prev_batch);
if img_msgs_count == 0 {
- load_more_media(thread_pool, data, builder.clone());
+ load_more_media(session_client.clone(), thread_pool, data, builder.clone());
} else {
data.borrow_mut().current_media_index += img_msgs_count;
- data.borrow_mut().previous_media(thread_pool);
+ data.borrow_mut().previous_media(session_client.clone());
data.borrow_mut().loading_more_media = loading_state(&ui, false);
}
diff --git a/fractal-gtk/src/widgets/member.rs b/fractal-gtk/src/widgets/member.rs
index 24efad61..1977ba60 100644
--- a/fractal-gtk/src/widgets/member.rs
+++ b/fractal-gtk/src/widgets/member.rs
@@ -58,9 +58,9 @@ impl<'a> MemberBox<'a> {
);
if let Some(login_data) = self.op.login_data.clone() {
download_to_cache(
+ login_data.session_client.clone(),
self.op.thread_pool.clone(),
self.op.user_info_cache.clone(),
- login_data.session_client.homeserver().clone(),
login_data.access_token,
self.member.uid.clone(),
data,
@@ -103,9 +103,9 @@ impl<'a> MemberBox<'a> {
);
if let Some(login_data) = self.op.login_data.clone() {
download_to_cache(
+ login_data.session_client.clone(),
self.op.thread_pool.clone(),
self.op.user_info_cache.clone(),
- login_data.session_client.homeserver().clone(),
login_data.access_token,
self.member.uid.clone(),
data,
diff --git a/fractal-gtk/src/widgets/message.rs b/fractal-gtk/src/widgets/message.rs
index d7b0548a..2dda58fb 100644
--- a/fractal-gtk/src/widgets/message.rs
+++ b/fractal-gtk/src/widgets/message.rs
@@ -7,6 +7,7 @@ use chrono::prelude::*;
use either::Either;
use fractal_api::r0::AccessToken;
use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
use glib::clone;
use gtk::{prelude::*, ButtonExt, ContainerExt, LabelExt, Overlay, WidgetExt};
use std::cmp::max;
@@ -71,6 +72,7 @@ impl MessageBox {
/* create the message row with or without a header */
pub fn create(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
msg: &Message,
@@ -84,7 +86,7 @@ impl MessageBox {
RowType::Emote => {
self.row.set_margin_top(12);
self.header = false;
- self.small_widget(thread_pool, msg)
+ self.small_widget(session_client, msg)
}
RowType::Video if is_temp => {
upload_attachment_msg
@@ -108,11 +110,11 @@ impl MessageBox {
_ if has_header => {
self.row.set_margin_top(12);
self.header = true;
- self.widget(thread_pool, user_info_cache, msg)
+ self.widget(session_client, thread_pool, user_info_cache, msg)
}
_ => {
self.header = false;
- self.small_widget(thread_pool, msg)
+ self.small_widget(session_client, msg)
}
};
@@ -128,11 +130,19 @@ impl MessageBox {
pub fn tmpwidget(
mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
msg: &Message,
) -> MessageBox {
- self.create(thread_pool, user_info_cache, msg, true, true);
+ self.create(
+ session_client,
+ thread_pool,
+ user_info_cache,
+ msg,
+ true,
+ true,
+ );
{
let w = self.get_listbox_row();
w.get_style_context().add_class("msg-tmp");
@@ -142,6 +152,7 @@ impl MessageBox {
pub fn update_header(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
msg: Message,
@@ -150,13 +161,13 @@ impl MessageBox {
let w = if has_header && msg.mtype != RowType::Emote {
self.row.set_margin_top(12);
self.header = true;
- self.widget(thread_pool, user_info_cache, &msg)
+ self.widget(session_client, thread_pool, user_info_cache, &msg)
} else {
if let RowType::Emote = msg.mtype {
self.row.set_margin_top(12);
}
self.header = false;
- self.small_widget(thread_pool, &msg)
+ self.small_widget(session_client, &msg)
};
if let Some(eb) = self.eventbox.get_child() {
self.eventbox.remove(&eb);
@@ -167,6 +178,7 @@ impl MessageBox {
fn widget(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
msg: &Message,
@@ -176,9 +188,9 @@ impl MessageBox {
// | avatar | content |
// +--------+---------+
let msg_widget = gtk::Box::new(gtk::Orientation::Horizontal, 10);
- let content = self.build_room_msg_content(thread_pool.clone(), msg, false);
+ let content = self.build_room_msg_content(session_client.clone(), msg, false);
/* Todo: make build_room_msg_avatar() faster (currently ~1ms) */
- let avatar = self.build_room_msg_avatar(thread_pool, user_info_cache, msg);
+ let avatar = self.build_room_msg_avatar(session_client, thread_pool, user_info_cache, msg);
msg_widget.pack_start(&avatar, false, false, 0);
msg_widget.pack_start(&content, true, true, 0);
@@ -186,13 +198,13 @@ impl MessageBox {
msg_widget
}
- fn small_widget(&mut self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
+ fn small_widget(&mut self, session_client: MatrixClient, msg: &Message) -> gtk::Box {
// msg
// +--------+---------+
// | | content |
// +--------+---------+
let msg_widget = gtk::Box::new(gtk::Orientation::Horizontal, 5);
- let content = self.build_room_msg_content(thread_pool, msg, true);
+ let content = self.build_room_msg_content(session_client, msg, true);
content.set_margin_start(50);
msg_widget.pack_start(&content, true, true, 0);
@@ -202,7 +214,7 @@ impl MessageBox {
fn build_room_msg_content(
&mut self,
- thread_pool: ThreadPool,
+ session_client: MatrixClient,
msg: &Message,
small: bool,
) -> gtk::Box {
@@ -221,13 +233,13 @@ impl MessageBox {
content.pack_start(&info, false, false, 0);
}
- let body_bx = self.build_room_msg_body_bx(thread_pool, msg);
+ let body_bx = self.build_room_msg_body_bx(session_client, msg);
content.pack_start(&body_bx, true, true, 0);
content
}
- fn build_room_msg_body_bx(&mut self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
+ fn build_room_msg_body_bx(&mut self, session_client: MatrixClient, msg: &Message) -> gtk::Box {
// body_bx
// +------+-----------+
// | body | edit_mark |
@@ -235,11 +247,11 @@ impl MessageBox {
let body_bx = gtk::Box::new(gtk::Orientation::Horizontal, 0);
let body = match msg.mtype {
- RowType::Sticker => self.build_room_msg_sticker(thread_pool, msg),
- RowType::Image => self.build_room_msg_image(thread_pool, msg),
+ RowType::Sticker => self.build_room_msg_sticker(session_client, msg),
+ RowType::Image => self.build_room_msg_image(session_client, msg),
RowType::Emote => self.build_room_msg_emote(msg),
- RowType::Audio => self.build_room_audio_player(thread_pool, msg),
- RowType::Video => self.build_room_video_player(thread_pool, msg),
+ RowType::Audio => self.build_room_audio_player(session_client, msg),
+ RowType::Video => self.build_room_video_player(session_client, msg),
RowType::File => self.build_room_msg_file(msg),
_ => self.build_room_msg_body(msg),
};
@@ -262,6 +274,7 @@ impl MessageBox {
fn build_room_msg_avatar(
&self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
msg: &Message,
@@ -285,9 +298,9 @@ impl MessageBox {
}
download_to_cache(
+ session_client,
thread_pool,
user_info_cache,
- self.server_url.clone(),
self.access_token.clone(),
uid.clone(),
data.clone(),
@@ -408,7 +421,7 @@ impl MessageBox {
msg_part
}
- fn build_room_msg_image(&mut self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
+ fn build_room_msg_image(&mut self, session_client: MatrixClient, msg: &Message) -> gtk::Box {
let bx = gtk::Box::new(gtk::Orientation::Horizontal, 0);
// If the thumbnail is not a valid URL we use the msg.url
@@ -423,7 +436,7 @@ impl MessageBox {
if let Some(img_path) = img {
let image = widgets::image::Image::new(self.server_url.clone(), img_path)
.size(Some(globals::MAX_IMAGE_SIZE))
- .build(thread_pool);
+ .build(session_client);
image.widget.get_style_context().add_class("image-widget");
@@ -436,12 +449,12 @@ impl MessageBox {
bx
}
- fn build_room_msg_sticker(&self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
+ fn build_room_msg_sticker(&self, session_client: MatrixClient, msg: &Message) -> gtk::Box {
let bx = gtk::Box::new(gtk::Orientation::Horizontal, 0);
if let Some(url) = msg.url.clone() {
let image = widgets::image::Image::new(self.server_url.clone(), Either::Left(url))
.size(Some(globals::MAX_STICKER_SIZE))
- .build(thread_pool);
+ .build(session_client);
image.widget.set_tooltip_text(Some(&msg.body[..]));
bx.add(&image.widget);
@@ -450,18 +463,17 @@ impl MessageBox {
bx
}
- fn build_room_audio_player(&self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
+ fn build_room_audio_player(&self, session_client: MatrixClient, msg: &Message) -> gtk::Box {
let bx = gtk::Box::new(gtk::Orientation::Horizontal, 6);
if let Some(url) = msg.url.clone() {
let player = AudioPlayerWidget::new();
let start_playing = false;
PlayerExt::initialize_stream(
- &player,
+ player.clone(),
+ session_client,
url,
- self.server_url.clone(),
- thread_pool,
- &bx,
+ bx.clone(),
start_playing,
);
@@ -496,7 +508,7 @@ impl MessageBox {
outer_box
}
- fn build_room_video_player(&mut self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
+ fn build_room_video_player(&mut self, session_client: MatrixClient, msg: &Message) -> gtk::Box {
let bx = gtk::Box::new(gtk::Orientation::Vertical, 6);
if let Some(url) = msg.url.clone() {
@@ -504,11 +516,10 @@ impl MessageBox {
let player = VideoPlayerWidget::new(with_controls);
let start_playing = false;
PlayerExt::initialize_stream(
- &player,
+ player.clone(),
+ session_client,
url,
- self.server_url.clone(),
- thread_pool,
- &bx,
+ bx.clone(),
start_playing,
);
diff --git a/fractal-gtk/src/widgets/room.rs b/fractal-gtk/src/widgets/room.rs
index c2577c62..bed88bc3 100644
--- a/fractal-gtk/src/widgets/room.rs
+++ b/fractal-gtk/src/widgets/room.rs
@@ -13,7 +13,7 @@ use crate::backend::HandleError;
use crate::widgets;
use crate::widgets::AvatarExt;
-use fractal_api::identifiers::RoomIdOrAliasId;
+use fractal_api::identifiers::{RoomAliasId, RoomIdOrAliasId};
use gtk::WidgetExt;
const AVATAR_SIZE: i32 = 60;
@@ -59,18 +59,18 @@ impl<'a> RoomBox<'a> {
let details_box = gtk::Box::new(gtk::Orientation::Vertical, 6);
- let name = match room.name {
- ref n if n.is_none() || n.clone().unwrap().is_empty() => room.alias.clone(),
- ref n => n.clone(),
- };
+ let name = room
+ .name
+ .as_ref()
+ .filter(|n| !n.is_empty())
+ .map(String::as_str)
+ .or(room.alias.as_ref().map(RoomAliasId::as_str))
+ .unwrap_or_default();
let name_label = gtk::Label::new(None);
name_label.set_line_wrap(true);
name_label.set_line_wrap_mode(pango::WrapMode::WordChar);
- name_label.set_markup(&format!(
- "<b>{}</b>",
- markup_text(&name.unwrap_or_default())
- ));
+ name_label.set_markup(&format!("<b>{}</b>", markup_text(name)));
name_label.set_justify(gtk::Justification::Left);
name_label.set_halign(gtk::Align::Start);
name_label.set_valign(gtk::Align::Start);
@@ -94,7 +94,10 @@ impl<'a> RoomBox<'a> {
alias_label.set_line_wrap_mode(pango::WrapMode::WordChar);
alias_label.set_markup(&format!(
"<span alpha=\"60%\">{}</span>",
- room.alias.clone().unwrap_or_default()
+ room.alias
+ .as_ref()
+ .map(RoomAliasId::as_str)
+ .unwrap_or_default()
));
alias_label.set_justify(gtk::Justification::Left);
alias_label.set_halign(gtk::Align::Start);
diff --git a/fractal-gtk/src/widgets/room_history.rs b/fractal-gtk/src/widgets/room_history.rs
index 29b0f0e3..6126b01c 100644
--- a/fractal-gtk/src/widgets/room_history.rs
+++ b/fractal-gtk/src/widgets/room_history.rs
@@ -19,7 +19,7 @@ use crate::widgets;
use crate::widgets::{PlayerExt, VideoPlayerWidget};
use fractal_api::identifiers::RoomId;
use fractal_api::r0::AccessToken;
-use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
use gio::ActionMapExt;
use gio::SimpleActionGroup;
use glib::clone;
@@ -272,7 +272,6 @@ pub struct RoomHistory {
/* Contains a list of msg ids to keep track of the displayed messages */
rows: Rc<RefCell<List>>,
access_token: AccessToken,
- server_url: Url,
source_id: Rc<RefCell<Option<source::SourceId>>>,
queue: Rc<RefCell<VecDeque<MessageContent>>>,
edit_buffer: Rc<RefCell<VecDeque<MessageContent>>>,
@@ -301,7 +300,6 @@ impl RoomHistory {
let mut rh = RoomHistory {
rows: Rc::new(RefCell::new(List::new(scroll))),
access_token: login_data.access_token,
- server_url: login_data.session_client.homeserver().clone(),
source_id: Rc::new(RefCell::new(None)),
queue: Rc::new(RefCell::new(VecDeque::new())),
edit_buffer: Rc::new(RefCell::new(VecDeque::new())),
@@ -315,6 +313,7 @@ impl RoomHistory {
pub fn create(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
mut messages: Vec<MessageContent>,
@@ -328,9 +327,14 @@ impl RoomHistory {
}
let bottom = messages.split_off(position);
messages.reverse();
- self.add_old_messages_in_batch(thread_pool.clone(), user_info_cache.clone(), messages);
+ self.add_old_messages_in_batch(
+ session_client.clone(),
+ thread_pool.clone(),
+ user_info_cache.clone(),
+ messages,
+ );
/* Add the rest of the messages after the new message divider */
- self.add_new_messages_in_batch(thread_pool, user_info_cache, bottom);
+ self.add_new_messages_in_batch(session_client, thread_pool, user_info_cache, bottom);
let rows = &self.rows;
let id = glib::timeout_add_local(
@@ -446,7 +450,12 @@ impl RoomHistory {
}));
}
- fn run_queue(&mut self, thread_pool: ThreadPool, user_info_cache: UserInfoCache) -> Option<()> {
+ fn run_queue(
+ &mut self,
+ session_client: MatrixClient,
+ thread_pool: ThreadPool,
+ user_info_cache: UserInfoCache,
+ ) -> Option<()> {
let queue = self.queue.clone();
let edit_buffer = self.edit_buffer.clone();
let rows = self.rows.clone();
@@ -460,7 +469,6 @@ impl RoomHistory {
} else {
/* Lazy load initial messages */
let source_id = self.source_id.clone();
- let server_url = self.server_url.clone();
let access_token = self.access_token.clone();
*self.source_id.borrow_mut() = Some(glib::idle_add_local(move || {
let mut data = queue.borrow_mut();
@@ -517,11 +525,11 @@ impl RoomHistory {
rows.borrow_mut().new_divider_index = Some(new_divider_index);
}
item.widget = Some(create_row(
+ session_client.clone(),
thread_pool.clone(),
user_info_cache.clone(),
item.clone(),
has_header,
- server_url.clone(),
access_token.clone(),
&rows,
));
@@ -555,12 +563,13 @@ impl RoomHistory {
/* This adds new incomming messages at then end of the list */
pub fn add_new_message(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
mut item: MessageContent,
) -> Option<()> {
if item.msg.replace.is_some() {
- self.replace_message(thread_pool, user_info_cache, item);
+ self.replace_message(session_client, thread_pool, user_info_cache, item);
return None;
}
let mut rows = self.rows.borrow_mut();
@@ -593,11 +602,11 @@ impl RoomHistory {
}
let b = create_row(
+ session_client,
thread_pool,
user_info_cache,
item.clone(),
has_header,
- self.server_url.clone(),
self.access_token.clone(),
&self.rows,
);
@@ -608,6 +617,7 @@ impl RoomHistory {
pub fn replace_message(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
mut item: MessageContent,
@@ -631,11 +641,11 @@ impl RoomHistory {
let msg_widget = msg.widget.clone()?;
item.widget = Some(create_row(
+ session_client,
thread_pool,
user_info_cache,
item.clone(),
msg_widget.header,
- self.server_url.clone(),
self.access_token.clone(),
&self.rows,
));
@@ -645,6 +655,7 @@ impl RoomHistory {
pub fn remove_message(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
item: MessageContent,
@@ -691,7 +702,13 @@ impl RoomHistory {
msg_next_cloned.redactable && msg_next_cloned.sender == msg_sender
})
{
- msg_widget.update_header(thread_pool, user_info_cache, msg_next_cloned, true);
+ msg_widget.update_header(
+ session_client,
+ thread_pool,
+ user_info_cache,
+ msg_next_cloned,
+ true,
+ );
}
}
None
@@ -699,19 +716,26 @@ impl RoomHistory {
pub fn add_new_messages_in_batch(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
messages: Vec<MessageContent>,
) -> Option<()> {
/* TODO: use lazy loading */
for item in messages {
- self.add_new_message(thread_pool.clone(), user_info_cache.clone(), item);
+ self.add_new_message(
+ session_client.clone(),
+ thread_pool.clone(),
+ user_info_cache.clone(),
+ item,
+ );
}
None
}
pub fn add_old_messages_in_batch(
&mut self,
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
messages: Vec<MessageContent>,
@@ -721,7 +745,7 @@ impl RoomHistory {
self.queue
.borrow_mut()
.append(&mut VecDeque::from(messages));
- self.run_queue(thread_pool, user_info_cache);
+ self.run_queue(session_client, thread_pool, user_info_cache);
None
}
@@ -743,18 +767,20 @@ impl RoomHistory {
/* This function creates the content for a Row based on the content of msg */
fn create_row(
+ session_client: MatrixClient,
thread_pool: ThreadPool,
user_info_cache: UserInfoCache,
row: MessageContent,
has_header: bool,
- server_url: Url,
access_token: AccessToken,
rows: &Rc<RefCell<List>>,
) -> widgets::MessageBox {
+ let server_url = session_client.homeserver().clone();
/* 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(server_url, access_token);
mb.create(
+ session_client,
thread_pool,
user_info_cache,
&row,
diff --git a/fractal-gtk/src/widgets/room_settings.rs b/fractal-gtk/src/widgets/room_settings.rs
index b3e42f89..4ff08658 100644
--- a/fractal-gtk/src/widgets/room_settings.rs
+++ b/fractal-gtk/src/widgets/room_settings.rs
@@ -1,6 +1,7 @@
use crate::backend::{room, HandleError};
use fractal_api::identifiers::UserId;
use fractal_api::r0::AccessToken;
+use fractal_api::Client as MatrixClient;
use glib::clone;
use std::cell::RefCell;
use std::rc::Rc;
@@ -67,7 +68,7 @@ impl RoomSettings {
/* creates a empty list with members.len() rows, the content will be loaded when the row is
* drawn */
- pub fn create(&mut self) -> Option<gtk::Box> {
+ pub fn create(&mut self, session_client: MatrixClient) -> Option<gtk::Box> {
let page = self
.builder
.get_object::<gtk::Box>("room_settings_box")
@@ -86,7 +87,7 @@ impl RoomSettings {
stack.set_visible_child_name("info")
}
- self.init_room_settings();
+ self.init_room_settings(session_client);
self.connect();
Some(page)
@@ -198,7 +199,7 @@ impl RoomSettings {
self.switch_handler = Some(Rc::new(switch_handler));
}
- fn init_room_settings(&mut self) {
+ fn init_room_settings(&mut self, session_client: MatrixClient) {
let name = self.room.name.clone();
let topic = self.room.topic.clone();
let mut is_room = true;
@@ -228,7 +229,7 @@ impl RoomSettings {
))
};
- self.room_settings_show_avatar(edit);
+ self.room_settings_show_avatar(session_client, edit);
self.room_settings_show_room_name(name, edit);
self.room_settings_show_room_topic(topic, is_room, edit);
self.room_settings_show_room_type(description);
@@ -421,7 +422,7 @@ impl RoomSettings {
None
}
- fn room_settings_show_avatar(&self, edit: bool) {
+ fn room_settings_show_avatar(&self, session_client: MatrixClient, edit: bool) {
let container = self
.builder
.get_object::<gtk::Box>("room_settings_avatar_box")
@@ -437,11 +438,10 @@ impl RoomSettings {
}
}
- let server = self.server_url.clone();
let access_token = self.access_token.clone();
let room_id = self.room.id.clone();
thread::spawn(
- move || match room::get_room_avatar(server, access_token, room_id) {
+ move || match room::get_room_avatar(session_client, access_token, room_id) {
Ok((room, avatar)) => {
APPOP!(set_room_avatar, (room, avatar));
}
diff --git a/fractal-matrix-api/src/meson.build b/fractal-matrix-api/src/meson.build
index 9d60f08a..282d497c 100644
--- a/fractal-matrix-api/src/meson.build
+++ b/fractal-matrix-api/src/meson.build
@@ -17,10 +17,7 @@ api_sources = files(
'r0/contact/request_verification_token_email.rs',
'r0/contact/request_verification_token_msisdn.rs',
'r0/context/get_context.rs',
- 'r0/directory/post_public_rooms.rs',
'r0/media/create_content.rs',
- 'r0/media/get_content.rs',
- 'r0/media/get_content_thumbnail.rs',
'r0/message/create_message_event.rs',
'r0/message/get_message_events.rs',
'r0/profile/get_display_name.rs',
@@ -43,7 +40,6 @@ api_sources = files(
'r0/config.rs',
'r0/contact.rs',
'r0/context.rs',
- 'r0/directory.rs',
'r0/filter.rs',
'r0/media.rs',
'r0/message.rs',
diff --git a/fractal-matrix-api/src/r0.rs b/fractal-matrix-api/src/r0.rs
index 4d46e6b8..e66e4dd0 100644
--- a/fractal-matrix-api/src/r0.rs
+++ b/fractal-matrix-api/src/r0.rs
@@ -2,7 +2,6 @@ pub mod account;
pub mod config;
pub mod contact;
pub mod context;
-pub mod directory;
pub mod filter;
pub mod media;
pub mod message;
diff --git a/fractal-matrix-api/src/r0/context/get_context.rs
b/fractal-matrix-api/src/r0/context/get_context.rs
index f5b39f93..7f666700 100644
--- a/fractal-matrix-api/src/r0/context/get_context.rs
+++ b/fractal-matrix-api/src/r0/context/get_context.rs
@@ -45,7 +45,7 @@ pub fn request(
"_matrix/client/r0/rooms/{}/context/{}",
room_id, event_id,
))
- .expect("Malformed URL in post_public_rooms");
+ .expect("Malformed URL in get_context");
Client::new().get(url).query(params).build()
}
diff --git a/fractal-matrix-api/src/r0/media.rs b/fractal-matrix-api/src/r0/media.rs
index eccd2e8e..1be1daed 100644
--- a/fractal-matrix-api/src/r0/media.rs
+++ b/fractal-matrix-api/src/r0/media.rs
@@ -1,3 +1 @@
pub mod create_content;
-pub mod get_content;
-pub mod get_content_thumbnail;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]