diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/preview_cursor_move.rs | 6 | ||||
-rw-r--r-- | src/config/clean/app/preview/config.rs | 12 | ||||
-rw-r--r-- | src/config/raw/app/display/preview.rs | 14 | ||||
-rw-r--r-- | src/context/app_context.rs | 48 | ||||
-rw-r--r-- | src/context/preview_context.rs | 198 | ||||
-rw-r--r-- | src/event/app_event.rs | 18 | ||||
-rw-r--r-- | src/event/process_event.rs | 45 | ||||
-rw-r--r-- | src/preview/preview_default.rs | 18 | ||||
-rw-r--r-- | src/preview/preview_file.rs | 107 | ||||
-rw-r--r-- | src/ui/views/tui_folder_view.rs | 73 |
10 files changed, 354 insertions, 185 deletions
diff --git a/src/commands/preview_cursor_move.rs b/src/commands/preview_cursor_move.rs index a59faa6..6959fb8 100644 --- a/src/commands/preview_cursor_move.rs +++ b/src/commands/preview_cursor_move.rs @@ -14,7 +14,7 @@ fn preview_cursor_move(context: &mut AppContext, new_index: usize) -> AppResult let preview_context = context.preview_context_mut(); if let Some(file_path) = file_path { - if let Some(PreviewFileState::Success { data }) = + if let Some(PreviewFileState::Success(data)) = preview_context.previews_mut().get_mut(&file_path) { data.index = new_index; @@ -32,7 +32,7 @@ pub fn preview_up(context: &mut AppContext, u: usize) -> AppResult { let preview_context = context.preview_context_ref(); if let Some(file_path) = file_path { - if let Some(PreviewFileState::Success { data }) = + if let Some(PreviewFileState::Success(data)) = preview_context.previews_ref().get(file_path) { if data.index < u { @@ -62,7 +62,7 @@ pub fn preview_down(context: &mut AppContext, u: usize) -> AppResult { let preview_context = context.preview_context_ref(); if let Some(file_path) = file_path { - if let Some(PreviewFileState::Success { data }) = + if let Some(PreviewFileState::Success(data)) = preview_context.previews_ref().get(file_path) { Some(data.index + u) diff --git a/src/config/clean/app/preview/config.rs b/src/config/clean/app/preview/config.rs index 2fd50e5..e14407e 100644 --- a/src/config/clean/app/preview/config.rs +++ b/src/config/clean/app/preview/config.rs @@ -1,18 +1,18 @@ use std::path; use crate::{ - config::{raw::app::display::preview::PreviewOptionRaw, search_directories}, + config::{ + raw::app::display::preview::{default_max_preview_size, PreviewOptionRaw, PreviewProtocol}, + search_directories, + }, util::unix, CONFIG_HIERARCHY, }; -const fn default_max_preview_size() -> u64 { - 2 * 1024 * 1024 // 2 MB -} - #[derive(Clone, Debug)] pub struct PreviewOption { pub max_preview_size: u64, + pub preview_protocol: PreviewProtocol, pub preview_script: Option<path::PathBuf>, pub preview_shown_hook_script: Option<path::PathBuf>, pub preview_removed_hook_script: Option<path::PathBuf>, @@ -22,6 +22,7 @@ impl std::default::Default for PreviewOption { fn default() -> Self { Self { max_preview_size: default_max_preview_size(), + preview_protocol: PreviewProtocol::Auto, preview_script: None, preview_shown_hook_script: None, preview_removed_hook_script: None, @@ -46,6 +47,7 @@ impl From<PreviewOptionRaw> for PreviewOption { Self { max_preview_size: raw.max_preview_size, + preview_protocol: raw.preview_protocol, preview_script, preview_shown_hook_script, preview_removed_hook_script, diff --git a/src/config/raw/app/display/preview.rs b/src/config/raw/app/display/preview.rs index 60bb032..ee3682e 100644 --- a/src/config/raw/app/display/preview.rs +++ b/src/config/raw/app/display/preview.rs @@ -1,14 +1,27 @@ +use ratatui_image::picker::ProtocolType; use serde::Deserialize; pub const fn default_max_preview_size() -> u64 { 2 * 1024 * 1024 // 2 MB } +#[derive(Clone, Debug, Deserialize, Default)] +#[serde(rename_all = "snake_case")] +pub enum PreviewProtocol { + #[default] + Auto, + Disabled, + #[serde(untagged)] + ProtocolType(ProtocolType), +} + #[derive(Clone, Debug, Deserialize)] pub struct PreviewOptionRaw { #[serde(default = "default_max_preview_size")] pub max_preview_size: u64, #[serde(default)] + pub preview_protocol: PreviewProtocol, + #[serde(default)] pub preview_script: Option<String>, #[serde(default)] pub preview_shown_hook_script: Option<String>, @@ -20,6 +33,7 @@ impl std::default::Default for PreviewOptionRaw { fn default() -> Self { Self { max_preview_size: default_max_preview_size(), + preview_protocol: PreviewProtocol::Auto, preview_script: None, preview_shown_hook_script: None, preview_removed_hook_script: None, diff --git a/src/context/app_context.rs b/src/context/app_context.rs index 35af553..0026a52 100644 --- a/src/context/app_context.rs +++ b/src/context/app_context.rs @@ -5,15 +5,17 @@ use std::thread; use crate::commands::quit::QuitAction; use crate::config::clean::app::AppConfig; +use crate::config::raw::app::display::preview::PreviewProtocol; use crate::context::{ CommandLineContext, LocalStateContext, MatchContext, MessageQueue, PreviewContext, TabContext, UiContext, WorkerContext, }; use crate::event::{AppEvent, Events}; -use crate::ui::views; -use crate::ui::PreviewArea; +use crate::preview::preview_file::PreviewFileState; +use crate::ui::{views, AppBackend, PreviewArea}; use crate::Args; use notify::{RecursiveMode, Watcher}; +use ratatui_image::picker::Picker; use std::path; pub struct AppContext { @@ -51,6 +53,28 @@ pub struct AppContext { impl AppContext { pub fn new(config: AppConfig, args: Args) -> Self { + let picker = if config + .preview_options_ref() + .preview_shown_hook_script + .is_none() + { + Picker::from_termios().ok().and_then(|mut picker| { + match config.preview_options_ref().preview_protocol { + PreviewProtocol::Auto => { + picker.guess_protocol(); // Must run before Events::new() because it makes ioctl calls. + Some(picker) + } + PreviewProtocol::Disabled => None, + PreviewProtocol::ProtocolType(protocol_type) => { + picker.protocol_type = protocol_type; + Some(picker) + } + } + }) + } else { + None + }; + let events = Events::new(); let event_tx = events.event_tx.clone(); @@ -66,6 +90,8 @@ impl AppContext { .unwrap(); let watched_paths = HashSet::with_capacity(3); + let preview_script = config.preview_options_ref().preview_script.clone(); + Self { quit: QuitAction::DoNot, events, @@ -74,8 +100,8 @@ impl AppContext { local_state: None, search_context: None, message_queue: MessageQueue::new(), - worker_context: WorkerContext::new(event_tx), - preview_context: PreviewContext::new(), + worker_context: WorkerContext::new(event_tx.clone()), + preview_context: PreviewContext::new(picker, preview_script, event_tx), ui_context: UiContext { layout: vec![] }, commandline_context, config, @@ -279,4 +305,18 @@ impl AppContext { pub fn commandline_context_mut(&mut self) -> &mut CommandLineContext { &mut self.commandline_context } + pub fn load_preview(&mut self, backend: &AppBackend, path: path::PathBuf) { + // always load image without cache + self.preview_context_mut().set_image_preview(None); + self.preview_context + .load_preview_image(self, backend, path.clone()); + + let previews = self.preview_context_mut().previews_mut(); + if previews.get(path.as_path()).is_none() { + // add to loading state + previews.insert(path.clone(), PreviewFileState::Loading); + self.preview_context + .load_preview_script(self, backend, path); + } + } } diff --git a/src/context/preview_context.rs b/src/context/preview_context.rs index 51e593d..57184a8 100644 --- a/src/context/preview_context.rs +++ b/src/context/preview_context.rs @@ -1,25 +1,215 @@ use std::collections::HashMap; -use std::path; +use std::error::Error; +use std::path::{self, PathBuf}; +use std::process::{Command, Stdio}; +use std::sync::mpsc::{self, Sender}; +use std::sync::Mutex; +use std::{io, thread}; -use crate::preview::preview_file::PreviewFileState; +use ratatui::layout::Rect; +use ratatui_image::picker::Picker; +use ratatui_image::protocol::Protocol; +use ratatui_image::Resize; + +use crate::config::clean::app::AppConfig; +use crate::event::{AppEvent, PreviewData}; +use crate::lazy_static; +use crate::preview::preview_file::{FilePreview, PreviewFileState}; +use crate::ui::{views, AppBackend}; +use crate::AppContext; + +lazy_static! { + static ref GUARD: Mutex<()> = Mutex::new(()); +} type FilePreviewMetadata = HashMap<path::PathBuf, PreviewFileState>; pub struct PreviewContext { previews: FilePreviewMetadata, + image_preview: Option<(PathBuf, Box<dyn Protocol>)>, + sender_script: Sender<(PathBuf, Rect)>, + sender_image: Option<Sender<(PathBuf, Rect)>>, + event_ts: Sender<AppEvent>, } impl PreviewContext { - pub fn new() -> Self { - Self { + pub fn new( + picker: Option<Picker>, + script: Option<PathBuf>, + event_ts: Sender<AppEvent>, + ) -> PreviewContext { + let (sender_script, receiver) = mpsc::channel::<(PathBuf, Rect)>(); + let thread_script_event_ts = event_ts.clone(); + thread::spawn(move || { + for (path, rect) in receiver { + if let Some(ref script) = script { + PreviewContext::spawn_command( + path.clone(), + script.to_path_buf(), + rect, + thread_script_event_ts.clone(), + ); + } + } + }); + + let (sender_image, receiver) = mpsc::channel::<(PathBuf, Rect)>(); + let sender_image = picker.map(|mut picker| { + let thread_image_event_ts = event_ts.clone(); + thread::spawn(move || loop { + // Get last, or block for next. + if let Some((path, rect)) = receiver + .try_iter() + .last() + .or_else(|| receiver.iter().next()) + { + let proto = image::io::Reader::open(path.as_path()) + .and_then(|reader| reader.decode().map_err(Self::map_io_err)) + .and_then(|dyn_img| { + picker + .new_protocol(dyn_img, rect, Resize::Fit) + .map_err(|err| { + io::Error::new(io::ErrorKind::Other, format!("{err}")) + }) + }); + if let Ok(proto) = proto { + let ev = AppEvent::PreviewFile { + path, + res: Ok(PreviewData::Image(proto)), + }; + let _ = thread_image_event_ts.send(ev); + } + } else { + // Closed. + return; + } + }); + sender_image + }); + + PreviewContext { previews: HashMap::new(), + image_preview: None, + sender_script, + sender_image, + event_ts, } } + fn spawn_command( + path: PathBuf, + script: PathBuf, + rect: Rect, + thread_event_ts: Sender<AppEvent>, + ) { + let output = Command::new(script) + .stdout(Stdio::piped()) + .stderr(Stdio::null()) + .arg("--path") + .arg(path.as_path()) + .arg("--preview-width") + .arg(rect.width.to_string()) + .arg("--preview-height") + .arg(rect.height.to_string()) + .output(); + + let res = match output { + Ok(output) => { + if output.status.success() { + let preview = FilePreview::from(output); + AppEvent::PreviewFile { + path, + res: Ok(PreviewData::Script(Box::new(preview))), + } + } else { + AppEvent::PreviewFile { + path, + res: Err(io::Error::new(io::ErrorKind::Other, "nonzero status")), + } + } + } + Err(err) => AppEvent::PreviewFile { + path, + res: Err(io::Error::new(io::ErrorKind::Other, format!("{err}"))), + }, + }; + let _ = thread_event_ts.send(res); + } + pub fn previews_ref(&self) -> &FilePreviewMetadata { &self.previews } pub fn previews_mut(&mut self) -> &mut FilePreviewMetadata { &mut self.previews } + pub fn image_preview_ref(&self, other: &path::Path) -> Option<&dyn Protocol> { + match &self.image_preview { + Some((path, protocol)) if path == other => Some(protocol.as_ref()), + _ => None, + } + } + pub fn set_image_preview(&mut self, preview: Option<(path::PathBuf, Box<dyn Protocol>)>) { + self.image_preview = preview; + } + + pub fn load_preview_script( + &self, + context: &AppContext, + backend: &AppBackend, + path: path::PathBuf, + ) { + if let Err(err) = Self::backend_rect(context.config_ref(), backend).and_then(|rect| { + self.sender_script + .send((path.clone(), rect)) + .map_err(Self::map_io_err) + }) { + let ev = AppEvent::PreviewFile { + path, + res: Err(err), + }; + let _ = self.event_ts.send(ev); + } + } + + pub fn load_preview_image( + &self, + context: &AppContext, + backend: &AppBackend, + path: path::PathBuf, + ) { + if let Some(sender) = &self.sender_image { + if let Err(err) = Self::backend_rect(context.config_ref(), backend) + .and_then(|rect| sender.send((path.clone(), rect)).map_err(Self::map_io_err)) + { + let ev = AppEvent::PreviewFile { + path, + res: Err(err), + }; + let _ = self.event_ts.send(ev); + } + } + } + + fn backend_rect(config: &AppConfig, backend: &AppBackend) -> io::Result<Rect> { + let area = backend.terminal_ref().size()?; + let area = Rect { + y: area.top() + 1, + height: area.height - 2, + ..area + }; + + let display_options = config.display_options_ref(); + let constraints = &display_options.default_layout; + let layout = if display_options.show_borders() { + views::calculate_layout_with_borders(area, constraints) + } else { + views::calculate_layout(area, constraints) + }; + Ok(layout[2]) + } + + #[inline] + fn map_io_err(err: impl Error) -> io::Error { + io::Error::new(io::ErrorKind::Other, format!("{err}")) + } } diff --git a/src/event/app_event.rs b/src/event/app_event.rs index d628517..f6d538b 100644 --- a/src/event/app_event.rs +++ b/src/event/app_event.rs @@ -1,8 +1,10 @@ +use std::fmt::Debug; use std::io; use std::path; use std::sync::mpsc; use std::thread; +use ratatui_image::protocol::Protocol; use signal_hook::consts::signal; use signal_hook::iterator::exfiltrator::SignalOnly; use signal_hook::iterator::SignalsInfo; @@ -17,6 +19,20 @@ use crate::fs::JoshutoDirList; use crate::io::FileOperationProgress; use crate::preview::preview_file::FilePreview; +pub enum PreviewData { + Script(Box<FilePreview>), + Image(Box<dyn Protocol>), +} + +impl Debug for PreviewData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Script(_) => f.debug_tuple("Script").field(&"_").finish(), + Self::Image(_) => f.debug_tuple("Image").field(&"_").finish(), + } + } +} + #[derive(Debug)] pub enum AppEvent { // User input events @@ -38,7 +54,7 @@ pub enum AppEvent { }, PreviewFile { path: path::PathBuf, - res: Box<io::Result<FilePreview>>, + res: io::Result<PreviewData>, }, // terminal size change events Signal(i32), diff --git a/src/event/process_event.rs b/src/event/process_event.rs index 6e308b7..0848dc8 100644 --- a/src/event/process_event.rs +++ b/src/event/process_event.rs @@ -13,12 +13,13 @@ use crate::config::clean::keymap::KeyMapping; use crate::context::AppContext; use crate::error::AppResult; use crate::event::AppEvent; +use crate::event::PreviewData; use crate::fs::JoshutoDirList; use crate::history::DirectoryHistory; use crate::io::FileOperationProgress; use crate::key_command::{AppExecute, Command, CommandKeybind}; use crate::preview::preview_dir::PreviewDirState; -use crate::preview::preview_file::{FilePreview, PreviewFileState}; +use crate::preview::preview_file::PreviewFileState; use crate::ui; use crate::ui::views::TuiCommandMenu; use crate::util::format; @@ -64,7 +65,7 @@ pub fn process_noninteractive(event: AppEvent, context: &mut AppContext) { AppEvent::FileOperationProgress(res) => process_worker_progress(context, res), AppEvent::IoWorkerResult(res) => process_finished_worker(context, res), AppEvent::PreviewDir { id, path, res } => process_dir_preview(context, id, path, *res), - AppEvent::PreviewFile { path, res } => process_file_preview(context, path, *res), + AppEvent::PreviewFile { path, res } => process_file_preview(context, path, res), AppEvent::Signal(signal::SIGWINCH) => {} AppEvent::Filesystem(e) => process_filesystem_event(e, context), AppEvent::ChildProcessComplete(child_id) => { @@ -173,33 +174,29 @@ pub fn process_dir_preview( pub fn process_file_preview( context: &mut AppContext, path: path::PathBuf, - res: io::Result<FilePreview>, + res: io::Result<PreviewData>, ) { + let preview_context = context.preview_context_mut(); match res { - Ok(preview) => { - if preview.status.code().is_some() { - context - .preview_context_mut() - .previews_mut() - .insert(path, PreviewFileState::Success { data: preview }); - } else { - context.preview_context_mut().previews_mut().insert( - path, - PreviewFileState::Error { - message: "Unknown error".to_string(), - }, - ); - } + Ok(PreviewData::Script(output)) if output.status.code().is_some() => { + preview_context + .previews_mut() + .insert(path, PreviewFileState::Success(*output)); + } + Ok(PreviewData::Script(_)) => { + preview_context + .previews_mut() + .insert(path, PreviewFileState::Error("status error".to_owned())); + } + Ok(PreviewData::Image(protocol)) => { + preview_context.set_image_preview(Some((path, protocol))); } Err(e) => { - context.preview_context_mut().previews_mut().insert( - path, - PreviewFileState::Error { - message: e.to_string(), - }, - ); + preview_context + .previews_mut() + .insert(path, PreviewFileState::Error(e.to_string())); } - } + }; } pub fn process_unsupported( diff --git a/src/preview/preview_default.rs b/src/preview/preview_default.rs index 28b85e1..35ced0c 100644 --- a/src/preview/preview_default.rs +++ b/src/preview/preview_default.rs @@ -2,11 +2,9 @@ use std::path; use crate::context::AppContext; use crate::fs::JoshutoMetadata; -use crate::preview::{preview_dir, preview_file}; +use crate::preview::preview_dir; use crate::ui::AppBackend; -use super::preview_file::PreviewFileState; - pub fn load_preview_path( context: &mut AppContext, backend: &mut AppBackend, @@ -33,19 +31,7 @@ pub fn load_preview_path( preview_dir::Background::load_preview(context, p); } } else if metadata.len() <= preview_options.max_preview_size { - let need_to_load = context - .preview_context_ref() - .previews_ref() - .get(p.as_path()) - .map(|data| match data { - PreviewFileState::Success { data } => data.modified < metadata.modified(), - _ => false, - }) - .unwrap_or(true); - - if need_to_load { - preview_file::Background::preview_path_with_script(context, backend, p); - } + context.load_preview(backend, p); } } diff --git a/src/preview/preview_file.rs b/src/preview/preview_file.rs index 9b4194a..ab73428 100644 --- a/src/preview/preview_file.rs +++ b/src/preview/preview_file.rs @@ -1,24 +1,20 @@ -use std::path; -use std::process::{Command, Output}; -use std::sync::Mutex; -use std::thread; -use std::time; - -use ratatui::layout::Rect; - -use crate::context::AppContext; -use crate::event::AppEvent; -use crate::lazy_static; -use crate::ui::{views, AppBackend}; - -lazy_static! { - static ref GUARD: Mutex<()> = Mutex::new(()); -} +use std::fmt::Debug; +use std::{process::Output, time}; pub enum PreviewFileState { Loading, - Error { message: String }, - Success { data: FilePreview }, + Error(String), + Success(FilePreview), +} + +impl Debug for PreviewFileState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Loading => f.debug_tuple("Loading").finish(), + Self::Error(message) => f.debug_tuple("Error").field(message).finish(), + Self::Success(_) => f.debug_tuple("Success").finish(), + } + } } #[derive(Clone, Debug)] @@ -43,78 +39,3 @@ impl std::convert::From<Output> for FilePreview { } } } - -pub struct Background {} - -impl Background { - pub fn preview_path_with_script( - context: &mut AppContext, - backend: &mut AppBackend, - path: path::PathBuf, - ) { - let preview_options = context.config_ref().preview_options_ref(); - if let Some(script) = preview_options.preview_script.as_ref() { - if let Ok(area) = backend.terminal_ref().size() { - let area = Rect { - y: area.top() + 1, - height: area.height - 2, - ..area - }; - - let config = context.config_ref(); - let display_options = config.display_options_ref(); - let constraints = &display_options.default_layout; - let layout = if display_options.show_borders() { - views::calculate_layout_with_borders(area, constraints) - } else { - views::calculate_layout(area, constraints) - }; - let layout_rect = layout[2]; - let preview_width = layout_rect.width; - let preview_height = layout_rect.height; - - if preview_width == 0 || preview_height == 0 { - return; - } - - let script = script.clone(); - let event_tx = context.clone_event_tx(); - context - .preview_context_mut() - .previews_mut() - .insert(path.clone(), PreviewFileState::Loading); - - let _ = thread::spawn(move || { - let _locked = GUARD.lock().unwrap(); - let file_full_path = path.as_path(); - - let res = Command::new(script) - .arg("--path") - .arg(file_full_path) - .arg("--preview-width") - .arg(preview_width.to_string()) - .arg("--preview-height") - .arg(preview_height.to_string()) - .output(); - match res { - Ok(output) => { - let preview = FilePreview::from(output); - let res = AppEvent::PreviewFile { - path, - res: Box::new(Ok(preview)), - }; - let _ = event_tx.send(res); - } - Err(e) => { - let res = AppEvent::PreviewFile { - path, - res: Box::new(Err(e)), - }; - let _ = event_tx.send(res); - } - } - }); - } - } - } -} diff --git a/src/ui/views/tui_folder_view.rs b/src/ui/views/tui_folder_view.rs index 68b94ad..2d9538c 100644 --- a/src/ui/views/tui_folder_view.rs +++ b/src/ui/views/tui_folder_view.rs @@ -4,6 +4,7 @@ use ratatui::style::{Color, Style}; use ratatui::symbols::line::{HORIZONTAL_DOWN, HORIZONTAL_UP}; use ratatui::text::Span; use ratatui::widgets::{Block, Borders, Paragraph, Widget, Wrap}; +use ratatui_image::Image; use crate::context::AppContext; use crate::preview::preview_dir::PreviewDirState; @@ -195,21 +196,32 @@ impl<'a> Widget for TuiFolderView<'a> { .render(layout_rect[2], buf); } None => { - let preview_area = calculate_preview(self.context, layout_rect[2]); - if let Some(preview_area) = preview_area { - let area = Rect { - x: preview_area.preview_area.x, - y: preview_area.preview_area.y, - width: preview_area.preview_area.width, - height: preview_area.preview_area.height, - }; - if let Some(PreviewFileState::Success { data }) = preview_context - .previews_ref() - .get(&preview_area.file_preview_path) - { + let image_offset = match preview_context.image_preview_ref(entry.file_path()) { + Some(protocol) => { + let area = layout_rect[2]; + Image::new(protocol).render(area, buf); + protocol.rect().height + } + _ => 0, + }; + + if let Some(PreviewFileState::Success(data)) = + preview_context.previews_ref().get(entry.file_path()) + { + let preview_area = calculate_preview(self.context, layout_rect[2]); + if let Some(preview_area) = preview_area { + let area = Rect { + x: preview_area.preview_area.x, + y: preview_area.preview_area.y + image_offset, + width: preview_area.preview_area.width, + height: preview_area + .preview_area + .height + .saturating_sub(image_offset), + }; TuiFilePreview::new(data).render(area, buf); } - } + }; } } } else { @@ -268,11 +280,8 @@ pub fn get_constraints(context: &AppContext) -> &[Constraint; 3] { &display_options.default_layout } Some(entry) => match preview_context.previews_ref().get(entry.file_path()) { - Some(PreviewFileState::Success { data }) if data.status.code() != Some(1) => { - &display_options.default_layout - } - Some(PreviewFileState::Loading) => &display_options.default_layout, - _ => &display_options.no_preview_layout, + None => &display_options.no_preview_layout, + _ => &display_options.default_layout, }, }, } @@ -327,24 +336,18 @@ pub fn calculate_preview(context: &AppContext, rect: Rect) -> Option<PreviewArea if child_list.as_ref().is_some() { None } else if let Some(entry) = curr_entry { - if let Some(PreviewFileState::Success { data }) = - preview_context.previews_ref().get(entry.file_path()) - { - match data.status.code() { - Some(1) | None => None, - _ => { - let file_preview_path = entry.file_path_buf(); - let preview_area = ui::Rect { - x: rect.x, - y: rect.y, - width: rect.width, - height: rect.height, - }; - Some(PreviewArea::new(file_preview_path, preview_area)) - } + match preview_context.previews_ref().get(entry.file_path()) { + None | Some(PreviewFileState::Loading) | Some(PreviewFileState::Error(_)) => None, + _ => { + let file_preview_path = entry.file_path_buf(); + let preview_area = ui::Rect { + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height, + }; + Some(PreviewArea::new(file_preview_path, preview_area)) } - } else { - None } } else { None |