diff --git a/flatpak/org.gnome.Fractal.json b/flatpak/org.gnome.Fractal.json index 88f38f6c3a11252afd6dfa4122f8a042ae28286d..3a430cbf5920a07235b4c86c1fca5e3161652b3d 100644 --- a/flatpak/org.gnome.Fractal.json +++ b/flatpak/org.gnome.Fractal.json @@ -89,7 +89,7 @@ { "type" : "git", "url" : "https://gitlab.freedesktop.org/gstreamer/gst-editing-services.git", - "branch" : "1.12" + "branch" : "1.14" } ] }, diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs index 2f8cd850e1101f57e0d2fad7ec2c51282ed195e6..95f2ff183061ee0a2b6b13cba710c8ebba585161 100644 --- a/fractal-gtk/src/appop/message.rs +++ b/fractal-gtk/src/appop/message.rs @@ -1,5 +1,6 @@ use comrak::{markdown_to_html, ComrakOptions}; use gdk_pixbuf::Pixbuf; +use gdk_pixbuf::PixbufExt; use gio::prelude::{FileExt, FileInfoExt}; use gstreamer_editing_services::prelude::*; use gstreamer_editing_services::UriClipAsset; @@ -7,6 +8,10 @@ use gtk; use gtk::prelude::*; use lazy_static::lazy_static; use log::error; +use rand::Rng; +use serde_json::json; +use serde_json::Value as JsonValue; +use std::env::temp_dir; use std::fs; use std::path::PathBuf; @@ -21,9 +26,6 @@ use crate::widgets; use crate::types::Message; -use serde_json::json; -use serde_json::Value as JsonValue; - pub struct TmpMsg { pub msg: Message, pub widget: Option, @@ -485,31 +487,37 @@ fn create_ui_message( } } -/// This function open the image and fill the info data as a Json value -/// If something fails this will returns None -/// -/// The output json will look like: -/// -/// { -/// "info": { -/// "h": 296, -/// "w": 296, -/// "size": 8796, -/// "orientation": 0, -/// "mimetype": "image/png" -/// } -/// } +/// This function opens the image, creates a thumbnail +/// and populates the info Json with the information it has + fn get_image_media_info(file: &str, mimetype: &str) -> Option { - let (_, w, h) = Pixbuf::get_file_info(file)?; - let size = fs::metadata(file).ok()?.len(); + let (_, w, h) = Pixbuf::get_file_info(&file)?; + let size = fs::metadata(&file).ok()?.len(); + + // make thumbnail max 800x600 + let thumb = Pixbuf::new_from_file_at_scale(&file, 800, 600, true).ok()?; + let mut rng = rand::thread_rng(); + let x: u64 = rng.gen_range(1, 9223372036854775807); + let thumb_path = format!( + "{}/fractal_{}.png", + temp_dir().to_str().unwrap_or_default(), + x.to_string() + ); + thumb.savev(&thumb_path, "png", &[]).ok()?; let info = json!({ "info": { + "thumbnail_url": thumb_path, + "thumbnail_info": { + "w": thumb.get_width(), + "h": thumb.get_height(), + "mimetype": "image/png" + }, "w": w, "h": h, "size": size, "mimetype": mimetype, - "orientation": 0, + "orientation": 0 } }); diff --git a/fractal-matrix-api/src/backend/room.rs b/fractal-matrix-api/src/backend/room.rs index 8699e7bd9eab1a820fdff21efe59343d2347ae12..2349509dee8cad73900818f8ae278bfde542b371 100644 --- a/fractal-matrix-api/src/backend/room.rs +++ b/fractal-matrix-api/src/backend/room.rs @@ -22,6 +22,7 @@ use crate::backend::types::BKResponse; use crate::backend::types::Backend; use crate::backend::types::RoomType; +use crate::types::ExtraContent; use crate::types::Member; use crate::types::Message; use crate::types::RoomEventFilter; @@ -462,37 +463,48 @@ pub fn set_room_avatar(bk: &Backend, roomid: &str, avatar: &str) -> Result<(), E Ok(()) } -pub fn attach_file(bk: &Backend, msg: Message) -> Result<(), Error> { +pub fn attach_file(bk: &Backend, 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(); + let thumb = extra_content.info.thumbnail_url.clone().unwrap_or_default(); - if fname.starts_with("mxc://") { + 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); } - let mut file = File::open(&fname)?; - let mut contents: Vec = vec![]; - file.read_to_end(&mut contents)?; - - let baseu = bk.get_base_url(); - let tk = bk.data.lock().unwrap().access_token.clone(); - let params = &[("access_token", tk.clone())]; - let mediaurl = media_url(&baseu, "upload", params)?; - - let mut m = msg.clone(); - let tx = bk.tx.clone(); - let itx = bk.internal_tx.clone(); thread::spawn(move || { - match put_media(mediaurl.as_str(), contents) { + if thumb != "" { + match upload_file(&tk, &baseu, &thumb) { + Err(err) => { + tx.send(BKResponse::AttachFileError(err)).unwrap(); + } + Ok(thumb_uri) => { + msg.thumb = Some(thumb_uri.to_string()); + extra_content.info.thumbnail_url = Some(thumb_uri); + msg.extra_content = Some(serde_json::to_value(&extra_content).unwrap()); + } + } + if let Err(_e) = std::fs::remove_file(&thumb) { + error!("Can't remove thumbnail: {}", thumb); + } + } + + match upload_file(&tk, &baseu, &fname) { Err(err) => { tx.send(BKResponse::AttachFileError(err)).unwrap(); } - Ok(js) => { - let uri = js["content_uri"].as_str().unwrap_or_default(); - m.url = Some(uri.to_string()); + Ok(uri) => { + msg.url = Some(uri.to_string()); if let Some(t) = itx { - t.send(BKCommand::SendMsg(m.clone())).unwrap(); + t.send(BKCommand::SendMsg(msg.clone())).unwrap(); } - tx.send(BKResponse::AttachedFile(m)).unwrap(); + tx.send(BKResponse::AttachedFile(msg)).unwrap(); } }; }); @@ -500,6 +512,20 @@ pub fn attach_file(bk: &Backend, msg: Message) -> Result<(), Error> { Ok(()) } +fn upload_file(tk: &str, baseu: &Url, fname: &str) -> Result { + let mut file = File::open(fname)?; + let mut contents: Vec = vec![]; + file.read_to_end(&mut contents)?; + + let params = &[("access_token", tk.to_string())]; + let mediaurl = media_url(&baseu, "upload", params)?; + + match put_media(mediaurl.as_str(), contents) { + Err(err) => Err(err), + Ok(js) => Ok(js["content_uri"].as_str().unwrap_or_default().to_string()), + } +} + pub fn new_room( bk: &Backend, name: &str, diff --git a/fractal-matrix-api/src/model/fileinfo.rs b/fractal-matrix-api/src/model/fileinfo.rs new file mode 100644 index 0000000000000000000000000000000000000000..b69fef7c5ee58d55a4b4a7647140df820cc0d8ce --- /dev/null +++ b/fractal-matrix-api/src/model/fileinfo.rs @@ -0,0 +1,18 @@ +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Info { + pub thumbnail_url: Option, + pub thumbnail_info: Option, + pub w: Option, + pub h: Option, + pub size: u32, + pub mimetype: String, + pub orientation: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ExtraContent { + pub info: Info, +} diff --git a/fractal-matrix-api/src/model/mod.rs b/fractal-matrix-api/src/model/mod.rs index 93ed1579cf8f8b097621324091c34967c6e761fe..758a0e2785fd1dc2b1fe23c6e5b30071ee08159a 100644 --- a/fractal-matrix-api/src/model/mod.rs +++ b/fractal-matrix-api/src/model/mod.rs @@ -1,4 +1,5 @@ pub mod event; +pub mod fileinfo; pub mod filter; pub mod member; pub mod message; diff --git a/fractal-matrix-api/src/types.rs b/fractal-matrix-api/src/types.rs index fce0a4a49ada62e8d36bfc999cbf832b0201eff0..3742967d859507f5daf483b4c83c6885aa061950 100644 --- a/fractal-matrix-api/src/types.rs +++ b/fractal-matrix-api/src/types.rs @@ -1,4 +1,6 @@ pub use crate::model::event::Event; +pub use crate::model::fileinfo::ExtraContent; +pub use crate::model::fileinfo::Info; pub use crate::model::filter::EventFilter; pub use crate::model::filter::Filter; pub use crate::model::filter::RoomEventFilter;