diff options
author | DLFW <daniel@llin.info> | 2024-05-20 04:22:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-19 22:22:30 -0400 |
commit | e458ac3fbf4bcd2dfa775d990c2931916e09cddc (patch) | |
tree | 8c38aef92c013d858d1f90fde673970690859e8f /src/context | |
parent | 1245124fcd264e25becfd75258840708d7b8b4bb (diff) |
This implements a cache for thumbnails and image previews for non-image
file formats, like videos and PDFs.
This patch extends the inbuilt image preview feature (285df85) by
integrating the `allmytoes` crate and using its thumbnails instead of
the actual file being previewed.
The image-preview feature uses the XDG-(freedesktop.org-) specified
thumbnail-cache to re-use existing thumbs and to store newly created
thumbs.
(https://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html)
This increases performance for the image-preview because the preview
does not need to load the full-sized version of the image and does not
need to scale it down every time, once the thumbnail has been created.
Also, thumbnails are now shared with other programs that use the
XDG-thumb cache.
Furthermore, the new way to obtain thumbs allows to show image-previews
for file types other than images. Existing thumbnails are shown for any
file type. New thumbnails can be created for many video formats, PDF
files, Postscript files, and SVGs. Users can also add “providers” for
other file-types by configuring `allmytoes`.
The XDG-thumb feature can be disabled, and the thumbnail-size can be
changed, both in `joshuto.toml`. The documentation has been extended,
the whole image-preview page has been enhanced a little.
Diffstat (limited to 'src/context')
-rw-r--r-- | src/context/app_context.rs | 15 | ||||
-rw-r--r-- | src/context/preview_context.rs | 15 |
2 files changed, 28 insertions, 2 deletions
diff --git a/src/context/app_context.rs b/src/context/app_context.rs index db8e17a..f7abef6 100644 --- a/src/context/app_context.rs +++ b/src/context/app_context.rs @@ -12,6 +12,7 @@ use crate::event::{AppEvent, Events}; use crate::preview::preview_file::PreviewFileState; use crate::ui::AppBackend; use crate::Args; +use allmytoes::{AMTConfiguration, AMT}; use notify::{RecursiveMode, Watcher}; use ratatui_image::picker::Picker; use std::path; @@ -88,6 +89,12 @@ impl AppContext { let watched_paths = HashSet::with_capacity(3); let preview_script = config.preview_options_ref().preview_script.clone(); + let allmytoes = if config.preview_options_ref().use_xdg_thumbs { + Some(AMT::new(&AMTConfiguration::default())) + } else { + None + }; + let xdg_thumb_size = config.preview_options_ref().xdg_thumb_size; Self { quit: QuitAction::DoNot, @@ -99,7 +106,13 @@ impl AppContext { search_context: None, message_queue: MessageQueue::new(), worker_context: WorkerContext::new(event_tx.clone()), - preview_context: PreviewContext::new(picker, preview_script, event_tx), + preview_context: PreviewContext::new( + picker, + preview_script, + allmytoes, + xdg_thumb_size, + event_tx, + ), ui_context: UiContext { layout: vec![] }, commandline_context, watcher, diff --git a/src/context/preview_context.rs b/src/context/preview_context.rs index ad49cfc..143dc7c 100644 --- a/src/context/preview_context.rs +++ b/src/context/preview_context.rs @@ -6,6 +6,7 @@ use std::sync::mpsc::{self, Sender}; use std::sync::Mutex; use std::{io, thread}; +use allmytoes::{ThumbSize, AMT}; use ratatui::layout::Rect; use ratatui_image::picker::Picker; use ratatui_image::protocol::Protocol; @@ -44,6 +45,8 @@ impl PreviewContext { pub fn new( picker: Option<Picker>, script: Option<PathBuf>, + allmytoes: Option<AMT>, + xdg_thumb_size: ThumbSize, event_ts: Sender<AppEvent>, ) -> PreviewContext { let (sender_script, receiver) = mpsc::channel::<(PathBuf, Rect)>(); @@ -71,7 +74,17 @@ impl PreviewContext { .last() .or_else(|| receiver.iter().next()) { - let proto = image::io::Reader::open(path.as_path()) + let thumb_path = if let Some(amt) = &allmytoes { + let thumb_result = amt.get(&path, xdg_thumb_size); + if let Ok(thumb) = thumb_result { + PathBuf::from(thumb.path) + } else { + path.clone() + } + } else { + path.clone() + }; + let proto = image::io::Reader::open(thumb_path.as_path()) .and_then(|reader| reader.decode().map_err(Self::map_io_err)) .and_then(|dyn_img| { picker |