Browse Source

media: Use gio::File::new_tmp() to store temp files

merge-requests/1327/merge
Kévin Commaille 3 years ago committed by Kévin Commaille
parent
commit
6466d76ad1
  1. 5
      src/components/video_player.rs
  2. 13
      src/session/content/room_history/message_row/audio.rs
  3. 18
      src/session/content/room_history/message_row/media.rs
  4. 10
      src/session/media_viewer.rs
  5. 17
      src/utils/mod.rs

5
src/components/video_player.rs

@ -26,6 +26,8 @@ mod imp {
pub timestamp: TemplateChild<gtk::Label>,
#[template_child]
pub player: TemplateChild<GstPlay>,
/// The file that is currently played.
pub file: RefCell<Option<gio::File>>,
}
#[glib::object_subclass]
@ -141,7 +143,8 @@ impl VideoPlayer {
}
/// Set the file to display.
pub fn play_media_file(&self, file: &gio::File) {
pub fn play_media_file(&self, file: gio::File) {
self.imp().file.replace(Some(file.clone()));
self.duration_changed(None);
let player = self.player();
player.set_uri(Some(file.uri().as_ref()));

13
src/session/content/room_history/message_row/audio.rs

@ -6,14 +6,13 @@ use gtk::{
CompositeTemplate,
};
use log::warn;
use matrix_sdk::{media::MediaEventContent, ruma::events::room::message::AudioMessageEventContent};
use matrix_sdk::ruma::events::room::message::AudioMessageEventContent;
use super::{media::MediaState, ContentFormat};
use crate::{
components::{AudioPlayer, Spinner},
session::Session,
spawn, spawn_tokio,
utils::media::media_type_uid,
};
mod imp {
@ -196,15 +195,6 @@ impl MessageAudio {
self.set_state(MediaState::Loading);
let mut path = glib::tmp_dir();
path.push(media_type_uid(audio.source()));
let file = gio::File::for_path(path);
if file.query_exists(gio::Cancellable::NONE) {
self.display_file(file);
return;
}
let client = session.client();
let handle = spawn_tokio!(async move { client.media().get_file(audio, true).await });
@ -216,6 +206,7 @@ impl MessageAudio {
// The GStreamer backend doesn't work with input streams so
// we need to store the file.
// See: https://gitlab.gnome.org/GNOME/gtk/-/issues/4062
let (file, _) = gio::File::new_tmp(Option::<String>::None).unwrap();
file.replace_contents(
&data,
None,

18
src/session/content/room_history/message_row/media.rs

@ -22,7 +22,7 @@ use crate::{
components::{ImagePaintable, Spinner, VideoPlayer},
session::Session,
spawn, spawn_tokio,
utils::{cache_dir, media::media_type_uid, uint_to_i32},
utils::uint_to_i32,
};
const MAX_THUMBNAIL_WIDTH: i32 = 600;
@ -391,11 +391,9 @@ impl MessageMedia {
};
if let Some(data) = thumbnail {
let id = media_type_uid(content.thumbnail_source());
Ok((Some(data), id))
Ok(Some(data))
} else {
let id = media_type_uid(content.source());
media.get_file(content, true).await.map(|data| (data, id))
media.get_file(content, true).await
}
});
@ -405,7 +403,7 @@ impl MessageMedia {
let imp = obj.imp();
match handle.await.unwrap() {
Ok((Some(data), id)) => {
Ok(Some(data)) => {
match media_type {
MediaType::Image | MediaType::Sticker => {
match ImagePaintable::from_bytes(&glib::Bytes::from(&data), None)
@ -442,9 +440,7 @@ impl MessageMedia {
// The GStreamer backend of GtkVideo doesn't work with input streams so
// we need to store the file.
// See: https://gitlab.gnome.org/GNOME/gtk/-/issues/4062
let mut path = cache_dir();
path.push(format!("{id}_{}", body.unwrap_or_default()));
let file = gio::File::for_path(path);
let (file, _) = gio::File::new_tmp(Option::<String>::None).unwrap();
file.replace_contents(
&data,
None,
@ -464,13 +460,13 @@ impl MessageMedia {
child
};
child.set_compact(obj.compact());
child.play_media_file(&file)
child.play_media_file(file)
}
};
obj.set_state(MediaState::Ready);
}
Ok((None, _)) => {
Ok(None) => {
warn!("Could not retrieve invalid media file");
imp.overlay_error.set_tooltip_text(Some(&gettext("Could not retrieve media")));
obj.set_state(MediaState::Error);

10
src/session/media_viewer.rs

@ -7,9 +7,7 @@ use super::room::{EventActions, EventTexture};
use crate::{
components::{ContentType, ImagePaintable, MediaContentViewer, ScaleRevealer},
session::room::Event,
spawn,
utils::cache_dir,
Window,
spawn, Window,
};
const ANIMATION_DURATION: u32 = 250;
@ -373,13 +371,11 @@ impl MediaViewer {
let imp = obj.imp();
match event.get_media_content().await {
Ok((uid, filename, data)) => {
Ok((_, _, data)) => {
// The GStreamer backend of GtkVideo doesn't work with input streams so
// we need to store the file.
// See: https://gitlab.gnome.org/GNOME/gtk/-/issues/4062
let mut path = cache_dir();
path.push(format!("{uid}_{filename}"));
let file = gio::File::for_path(path);
let (file, _) = gio::File::new_tmp(Option::<String>::None).unwrap();
file.replace_contents(
&data,
None,

17
src/utils/mod.rs

@ -10,7 +10,6 @@ pub mod template_callbacks;
use std::{
cell::RefCell,
path::PathBuf,
rc::{Rc, Weak},
};
@ -60,22 +59,6 @@ pub fn not_expr<E: AsRef<gtk::Expression>>(a_expr: E) -> gtk::ClosureExpression
gtk::ClosureExpression::new::<bool>(&[a_expr], closure!(|_: Option<Object>, a: bool| { !a }))
}
/// Get the cache directory.
///
/// If it doesn't exist, this method creates it.
pub fn cache_dir() -> PathBuf {
let mut path = glib::user_cache_dir();
path.push("fractal");
if !path.exists() {
let dir = gio::File::for_path(path.clone());
dir.make_directory_with_parents(gio::Cancellable::NONE)
.unwrap();
}
path
}
/// Converts a `UInt` to `i32`.
///
/// Returns `-1` if the conversion didn't work.

Loading…
Cancel
Save