mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
a7e8567e81
commit
0fa8df100d
12 changed files with 184 additions and 149 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
|
@ -1294,9 +1294,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.12"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
|
|
@ -1527,18 +1527,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.186"
|
||||
version = "1.0.188"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1"
|
||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.186"
|
||||
version = "1.0.188"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670"
|
||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
|||
|
|
@ -87,9 +87,8 @@ impl App {
|
|||
|
||||
fn dispatch_resize(&mut self) {
|
||||
self.cx.manager.current_mut().set_page(true);
|
||||
self.cx.manager.active_mut().preview_reset_image();
|
||||
// TODO: use peek
|
||||
self.cx.manager.preview(self.cx.image_layer());
|
||||
self.cx.manager.active_mut().preview_reset();
|
||||
self.cx.manager.peek(true, self.cx.image_layer());
|
||||
emit!(Render);
|
||||
}
|
||||
|
||||
|
|
@ -101,8 +100,6 @@ impl App {
|
|||
} else {
|
||||
self.term = Some(Term::start().unwrap());
|
||||
self.signals.stop_term(false);
|
||||
// TODO: use peek
|
||||
self.cx.manager.preview(self.cx.image_layer());
|
||||
emit!(Render);
|
||||
emit!(Hover);
|
||||
}
|
||||
|
|
@ -154,21 +151,24 @@ impl App {
|
|||
Event::Mimetype(mimes) => {
|
||||
if manager.update_mimetype(mimes, tasks) {
|
||||
emit!(Render);
|
||||
self.cx.manager.preview(self.cx.image_layer());
|
||||
emit!(Peek);
|
||||
}
|
||||
}
|
||||
Event::Hover(file) => {
|
||||
if file.map(|f| manager.current_mut().hover_force(f)).unwrap_or(false) {
|
||||
if manager.update_hover(file) {
|
||||
emit!(Render);
|
||||
}
|
||||
self.cx.manager.preview(self.cx.image_layer());
|
||||
emit!(Peek);
|
||||
}
|
||||
Event::Preview(path, mime, data) => {
|
||||
manager.update_preview(path, mime, data);
|
||||
emit!(Render);
|
||||
Event::Peek(skip, sequent) => {
|
||||
let b = sequent.is_some();
|
||||
manager.active_mut().update_peek(skip as isize, sequent);
|
||||
self.cx.manager.peek(b, self.cx.image_layer());
|
||||
}
|
||||
Event::Peek(path, skip) => {
|
||||
manager.update_peek(path, skip);
|
||||
Event::Preview(lock) => {
|
||||
if manager.active_mut().update_preview(lock) {
|
||||
emit!(Render);
|
||||
}
|
||||
}
|
||||
|
||||
Event::Select(opt, tx) => {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ impl Executor {
|
|||
}
|
||||
"peek" => {
|
||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
||||
cx.manager.active_mut().peek(step)
|
||||
cx.manager.active_mut().update_peek(step, None);
|
||||
cx.manager.peek(true, cx.image_layer())
|
||||
}
|
||||
"leave" => cx.manager.active_mut().leave(),
|
||||
"enter" => cx.manager.active_mut().enter(),
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ impl<'a> Widget for Preview<'a> {
|
|||
return;
|
||||
}
|
||||
|
||||
match &preview.data {
|
||||
PreviewData::None => {}
|
||||
match &preview.lock.as_ref().unwrap().data {
|
||||
PreviewData::Folder => {
|
||||
if let Some(folder) = manager.active().history(hovered) {
|
||||
Folder::new(self.cx, folder).with_preview(true).render(area, buf);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ use crossterm::event::KeyEvent;
|
|||
use shared::RoCell;
|
||||
use tokio::sync::{mpsc::UnboundedSender, oneshot};
|
||||
|
||||
use super::{files::{File, FilesOp}, input::InputOpt, manager::PreviewData, select::SelectOpt};
|
||||
use super::{files::{File, FilesOp}, input::InputOpt, select::SelectOpt};
|
||||
use crate::manager::PreviewLock;
|
||||
|
||||
static TX: RoCell<UnboundedSender<Event>> = RoCell::new();
|
||||
|
||||
|
|
@ -26,8 +27,8 @@ pub enum Event {
|
|||
Pages(usize),
|
||||
Mimetype(BTreeMap<PathBuf, String>),
|
||||
Hover(Option<File>),
|
||||
Preview(PathBuf, String, PreviewData),
|
||||
Peek(PathBuf, usize),
|
||||
Peek(usize, Option<PathBuf>),
|
||||
Preview(PreviewLock),
|
||||
|
||||
// Input
|
||||
Select(SelectOpt, oneshot::Sender<Result<usize>>),
|
||||
|
|
@ -88,11 +89,14 @@ macro_rules! emit {
|
|||
(Hover($file:expr)) => {
|
||||
$crate::Event::Hover(Some($file)).emit();
|
||||
};
|
||||
(Preview($path:expr, $mime:expr, $data:expr)) => {
|
||||
$crate::Event::Preview($path, $mime, $data).emit();
|
||||
(Peek) => {
|
||||
$crate::Event::Peek(0, None).emit();
|
||||
};
|
||||
(Peek($path:expr, $skip:expr)) => {
|
||||
$crate::Event::Peek($path, $skip).emit();
|
||||
(Peek($skip:expr, $path:expr)) => {
|
||||
$crate::Event::Peek($skip, Some($path)).emit();
|
||||
};
|
||||
(Preview($lock:expr)) => {
|
||||
$crate::Event::Preview($lock).emit();
|
||||
};
|
||||
|
||||
(Select($opt:expr)) => {{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use config::{BOOT, OPEN};
|
|||
use shared::{max_common_root, Defer, Term, MIME_DIR};
|
||||
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
|
||||
|
||||
use super::{PreviewData, Tab, Tabs, Watcher};
|
||||
use super::{Tab, Tabs, Watcher};
|
||||
use crate::{emit, external::{self, ShellOpt}, files::{File, FilesOp}, input::InputOpt, manager::Folder, select::SelectOpt, tasks::Tasks, Event, BLOCKER};
|
||||
|
||||
pub struct Manager {
|
||||
|
|
@ -52,7 +52,7 @@ impl Manager {
|
|||
self.watcher.watch(to_watch);
|
||||
}
|
||||
|
||||
pub fn preview(&mut self, show_image: bool) -> bool {
|
||||
pub fn peek(&mut self, sequent: bool, show_image: bool) -> bool {
|
||||
let Some(hovered) = self.hovered().cloned() else {
|
||||
return self.active_mut().preview.reset();
|
||||
};
|
||||
|
|
@ -61,19 +61,23 @@ impl Manager {
|
|||
self.active_mut().preview_reset_image();
|
||||
}
|
||||
|
||||
if hovered.meta.is_dir() {
|
||||
self.active_mut().preview.go(&hovered.path, MIME_DIR, show_image);
|
||||
if let Some(offset) = self.active().history(&hovered.path).map(|f| f.offset()) {
|
||||
emit!(Peek(hovered.path, offset));
|
||||
}
|
||||
} else if let Some(mime) = self.mimetype.get(&hovered.path).cloned() {
|
||||
self.active_mut().preview.go(&hovered.path, &mime, show_image);
|
||||
let mime = if hovered.meta.is_dir() {
|
||||
MIME_DIR.to_owned()
|
||||
} else if let Some(m) = self.mimetype.get(&hovered.path).cloned() {
|
||||
m
|
||||
} else {
|
||||
tokio::spawn(async move {
|
||||
if let Ok(mimes) = external::file(&[hovered.path]).await {
|
||||
emit!(Mimetype(mimes));
|
||||
}
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
if sequent {
|
||||
self.active_mut().preview.sequent(&hovered.path, &mime, show_image);
|
||||
} else {
|
||||
self.active_mut().preview.go(&hovered.path, &mime, show_image);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
@ -393,39 +397,16 @@ impl Manager {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn update_preview(&mut self, path: PathBuf, mime: String, data: PreviewData) -> bool {
|
||||
let Some(hovered) = self.hovered().map(|h| &h.path) else {
|
||||
return self.active_mut().preview.reset();
|
||||
pub fn update_hover(&mut self, file: Option<File>) -> bool {
|
||||
let b = file.map(|f| self.current_mut().hover_force(f)).unwrap_or(false);
|
||||
let Some(hovered) = self.hovered() else {
|
||||
return b;
|
||||
};
|
||||
|
||||
if path != *hovered {
|
||||
return false;
|
||||
if hovered.meta.is_dir() {
|
||||
self.watcher.trigger_dirs(&[&hovered.path]);
|
||||
}
|
||||
|
||||
let preview = &mut self.active_mut().preview;
|
||||
preview.lock = Some((path, mime));
|
||||
preview.data = data;
|
||||
true
|
||||
}
|
||||
|
||||
pub fn update_peek(&mut self, path: PathBuf, skip: usize) -> bool {
|
||||
if !matches!(self.hovered(), Some(f) if f.path == path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.active().preview.lock.is_some() {
|
||||
self.active_mut().preview.peek(skip);
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.active().history(&path).is_some() {
|
||||
let preview = &mut self.active_mut().preview;
|
||||
preview.lock = Some((path, MIME_DIR.to_string()));
|
||||
preview.data = PreviewData::Folder;
|
||||
}
|
||||
|
||||
self.active_mut().preview.peek(skip);
|
||||
false
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
use std::{mem, path::{Path, PathBuf}, sync::atomic::Ordering};
|
||||
use std::{path::{Path, PathBuf}, sync::atomic::Ordering};
|
||||
|
||||
use adaptor::Adaptor;
|
||||
use config::MANAGER;
|
||||
use shared::{MimeKind, PeekError};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
use super::{provider::INCR, Provider};
|
||||
use super::{Provider, INCR};
|
||||
use crate::emit;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Preview {
|
||||
pub lock: Option<(PathBuf, String)>,
|
||||
pub data: PreviewData,
|
||||
pub lock: Option<PreviewLock>,
|
||||
skip: usize,
|
||||
|
||||
handle: Option<JoinHandle<()>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
pub struct PreviewLock {
|
||||
pub path: PathBuf,
|
||||
pub mime: String,
|
||||
pub skip: usize,
|
||||
pub data: PreviewData,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PreviewData {
|
||||
#[default]
|
||||
None,
|
||||
Folder,
|
||||
Text(String),
|
||||
Image,
|
||||
|
|
@ -29,50 +33,67 @@ pub enum PreviewData {
|
|||
impl Preview {
|
||||
pub fn go(&mut self, path: &Path, mime: &str, show_image: bool) {
|
||||
let kind = MimeKind::new(mime);
|
||||
if !show_image && matches!(kind, MimeKind::Image | MimeKind::Video) {
|
||||
if !show_image && kind.show_as_image() {
|
||||
return;
|
||||
} else if self.same(path, mime) {
|
||||
return;
|
||||
} else {
|
||||
self.reset();
|
||||
}
|
||||
|
||||
self.reset();
|
||||
if !self.same_path(path) {
|
||||
self.skip = 0;
|
||||
}
|
||||
|
||||
let (path, mime, skip) = (path.to_path_buf(), mime.to_owned(), self.skip);
|
||||
self.handle = Some(tokio::spawn(async move {
|
||||
let result = Provider::auto(kind, &path, skip).await;
|
||||
emit!(Preview(path, mime, result.unwrap_or_default()));
|
||||
match Provider::auto(kind, &path, skip).await {
|
||||
Ok(data) => {
|
||||
emit!(Preview(PreviewLock { path, mime, skip, data }));
|
||||
}
|
||||
Err(PeekError::Exceed(max)) => {
|
||||
emit!(Peek(max, path));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn peek(&mut self, skip: usize) {
|
||||
let Some((path, kind, mime)) = self.lock.clone().map(|(p, m)| (p, MimeKind::new(&m), m)) else {
|
||||
pub fn sequent(&mut self, path: &Path, mime: &str, show_image: bool) {
|
||||
let kind = MimeKind::new(mime);
|
||||
if !show_image && kind.show_as_image() {
|
||||
return;
|
||||
};
|
||||
} else if self.same(path, mime) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.handle.take().map(|h| h.abort());
|
||||
INCR.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
self.skip = skip;
|
||||
let (path, mime, skip) = (path.to_path_buf(), mime.to_owned(), self.skip);
|
||||
self.handle = Some(tokio::spawn(async move {
|
||||
match Provider::auto(kind, &path, skip).await {
|
||||
Ok(result) => {
|
||||
emit!(Preview(path, mime, result));
|
||||
Ok(data) => {
|
||||
emit!(Preview(PreviewLock { path, mime, skip, data }));
|
||||
}
|
||||
Err(PeekError::Exceed(max)) => {
|
||||
emit!(Peek(path, max));
|
||||
emit!(Peek(max, path));
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn peek_step(&mut self, step: isize) -> usize {
|
||||
let Some(kind) = self.lock.clone().map(|(_, m)| MimeKind::new(&m)) else {
|
||||
return 0;
|
||||
};
|
||||
pub fn arrow(&mut self, step: isize, absolute: bool) -> bool {
|
||||
let old = self.skip;
|
||||
if absolute {
|
||||
self.skip = step.unsigned_abs();
|
||||
} else if let Some(kind) = self.lock.as_ref().map(|l| MimeKind::new(&l.mime)) {
|
||||
let size = Provider::step_size(kind, step.unsigned_abs());
|
||||
self.skip = if step < 0 { old.saturating_sub(size) } else { old + size };
|
||||
}
|
||||
|
||||
Provider::step_size(kind, step.unsigned_abs())
|
||||
self.skip != old
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) -> bool {
|
||||
|
|
@ -80,12 +101,9 @@ impl Preview {
|
|||
INCR.fetch_add(1, Ordering::Relaxed);
|
||||
Adaptor::image_hide(MANAGER.layout.preview_rect()).ok();
|
||||
|
||||
let b = matches!(&self.lock, Some(l) if !l.is_image());
|
||||
self.lock = None;
|
||||
self.skip = 0;
|
||||
!matches!(
|
||||
mem::replace(&mut self.data, PreviewData::None),
|
||||
PreviewData::None | PreviewData::Image
|
||||
)
|
||||
b
|
||||
}
|
||||
|
||||
pub fn reset_image(&mut self) -> bool {
|
||||
|
|
@ -93,26 +111,41 @@ impl Preview {
|
|||
INCR.fetch_add(1, Ordering::Relaxed);
|
||||
Adaptor::image_hide(MANAGER.layout.preview_rect()).ok();
|
||||
|
||||
if self.data == PreviewData::Image {
|
||||
if matches!(&self.lock, Some(l) if l.is_image()) {
|
||||
self.lock = None;
|
||||
self.data = PreviewData::None;
|
||||
self.skip = 0;
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Preview {
|
||||
#[inline]
|
||||
pub fn lock(&self) -> &Option<PreviewLock> { &self.lock }
|
||||
|
||||
#[inline]
|
||||
pub fn skip(&self) -> usize { self.skip }
|
||||
|
||||
#[inline]
|
||||
pub fn same(&self, path: &Path, mime: &str) -> bool {
|
||||
self.lock.as_ref().map(|(p, m)| p == path && m == mime).unwrap_or(false)
|
||||
if let Some(ref lock) = self.lock {
|
||||
return lock.path == path && lock.mime == mime && lock.skip == self.skip;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn same_path(&self, path: &Path) -> bool {
|
||||
self.lock.as_ref().map(|(p, _)| p == path).unwrap_or(false)
|
||||
if let Some(ref lock) = self.lock {
|
||||
return lock.path == path;
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl PreviewLock {
|
||||
#[inline]
|
||||
pub fn is_image(&self) -> bool { matches!(self.data, PreviewData::Image) }
|
||||
|
||||
#[inline]
|
||||
pub fn is_folder(&self) -> bool { matches!(self.data, PreviewData::Folder) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ impl Provider {
|
|||
skip: usize,
|
||||
) -> Result<PreviewData, PeekError> {
|
||||
match kind {
|
||||
MimeKind::Empty => Ok(PreviewData::None),
|
||||
MimeKind::Empty => Err("Empty file".into()),
|
||||
MimeKind::Archive => Provider::archive(path, skip).await.map(PreviewData::Text),
|
||||
MimeKind::Dir => Provider::folder(path).await,
|
||||
MimeKind::Image => Provider::image(path).await,
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ use std::{collections::{BTreeMap, BTreeSet}, ffi::{OsStr, OsString}, mem, path::
|
|||
use anyhow::{Error, Result};
|
||||
use config::{open::Opener, MANAGER};
|
||||
use futures::StreamExt;
|
||||
use shared::{Defer, MIME_DIR};
|
||||
use shared::Defer;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
use super::{Folder, Mode, Preview};
|
||||
use super::{Folder, Mode, Preview, PreviewLock};
|
||||
use crate::{emit, external::{self, FzfOpt, ZoxideOpt}, files::{File, Files, FilesOp}, input::InputOpt, Event, BLOCKER};
|
||||
|
||||
pub struct Tab {
|
||||
|
|
@ -76,32 +76,6 @@ impl Tab {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn peek(&mut self, step: isize) -> bool {
|
||||
let size = self.preview.peek_step(step);
|
||||
let old = self.preview.skip();
|
||||
let new = if step < 0 { old.saturating_sub(size) } else { old + size };
|
||||
if new == old {
|
||||
return false;
|
||||
}
|
||||
|
||||
if !matches!(&self.preview.lock, Some((_, m)) if m == MIME_DIR) {
|
||||
self.preview.peek(new);
|
||||
return false;
|
||||
};
|
||||
|
||||
let path = self.preview.lock.as_ref().unwrap().0.clone();
|
||||
if let Some(folder) = self.history(&path) {
|
||||
let max = folder.files.len().saturating_sub(MANAGER.layout.preview_height());
|
||||
if new > max {
|
||||
emit!(Peek(path, max));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
self.preview.peek(new);
|
||||
false
|
||||
}
|
||||
|
||||
pub async fn cd(&mut self, mut target: PathBuf) -> bool {
|
||||
let Ok(file) = File::from(&target).await else {
|
||||
return false;
|
||||
|
|
@ -335,6 +309,42 @@ impl Tab {
|
|||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn update_peek(&mut self, step: isize, path: Option<PathBuf>) {
|
||||
let Some(ref hovered) = self.current.hovered else {
|
||||
return;
|
||||
};
|
||||
|
||||
if path.as_ref().map(|p| *p != hovered.path).unwrap_or(false) {
|
||||
return;
|
||||
} else if !self.preview.lock.as_ref().map(|l| l.path == hovered.path).unwrap_or(false) {
|
||||
return;
|
||||
} else if !self.preview.arrow(step, path.is_some()) {
|
||||
return;
|
||||
} else if !hovered.meta.is_dir() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(folder) = self.history(&hovered.path) {
|
||||
let max = folder.files.len().saturating_sub(MANAGER.layout.preview_height());
|
||||
if self.preview.skip() > max {
|
||||
self.preview.arrow(max as isize, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_preview(&mut self, lock: PreviewLock) -> bool {
|
||||
let Some(hovered) = self.current.hovered.as_ref().map(|h| &h.path) else {
|
||||
return self.preview.reset();
|
||||
};
|
||||
|
||||
if lock.path != *hovered {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.preview.lock = Some(lock);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
|
@ -388,6 +398,9 @@ impl Tab {
|
|||
#[inline]
|
||||
pub fn preview(&self) -> &Preview { &self.preview }
|
||||
|
||||
#[inline]
|
||||
pub fn preview_reset(&mut self) -> bool { self.preview.reset() }
|
||||
|
||||
#[inline]
|
||||
pub fn preview_reset_image(&mut self) -> bool { self.preview.reset_image() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ impl Tasks {
|
|||
|
||||
pub fn toggle(&mut self) -> bool {
|
||||
self.visible = !self.visible;
|
||||
emit!(Hover); // Show/hide preview for images
|
||||
emit!(Peek); // Show/hide preview for images
|
||||
true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,6 @@ impl Which {
|
|||
#[inline]
|
||||
fn switch(&mut self, state: bool) {
|
||||
self.visible = state;
|
||||
emit!(Hover); // Show/hide preview for images
|
||||
emit!(Peek); // Show/hide preview for images
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,21 +18,6 @@ pub enum MimeKind {
|
|||
}
|
||||
|
||||
impl MimeKind {
|
||||
pub fn valid(s: &str) -> bool {
|
||||
if s == "inode/x-empty" {
|
||||
return true;
|
||||
}
|
||||
|
||||
let parts = s.split('/').collect::<Vec<_>>();
|
||||
if parts.len() != 2 {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
let b = matches!(parts[0], "application" | "audio" | "example" | "font" | "image" | "message" | "model" | "multipart" | "text" | "video");
|
||||
b && !parts[1].is_empty()
|
||||
}
|
||||
|
||||
pub fn new(s: &str) -> Self {
|
||||
if s == MIME_DIR {
|
||||
Self::Dir
|
||||
|
|
@ -61,4 +46,23 @@ impl MimeKind {
|
|||
Self::Others
|
||||
}
|
||||
}
|
||||
|
||||
pub fn valid(s: &str) -> bool {
|
||||
if s == "inode/x-empty" {
|
||||
return true;
|
||||
}
|
||||
|
||||
let parts = s.split('/').collect::<Vec<_>>();
|
||||
if parts.len() != 2 {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
let b = matches!(parts[0], "application" | "audio" | "example" | "font" | "image" | "message" | "model" | "multipart" | "text" | "video");
|
||||
b && !parts[1].is_empty()
|
||||
}
|
||||
|
||||
pub fn show_as_image(&self) -> bool {
|
||||
matches!(self, MimeKind::Image | MimeKind::Video | MimeKind::PDF)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue