mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: add support portrait orientation preview for EXIF image (#1412)
Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
parent
cc50f94de6
commit
cda7d3f2ea
10 changed files with 34 additions and 38 deletions
|
|
@ -1 +1 @@
|
||||||
{"flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM"],"language":"en","version":"0.2"}
|
{"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek"],"version":"0.2","language":"en","flagWords":[]}
|
||||||
|
|
@ -92,7 +92,7 @@ fetchers = [
|
||||||
]
|
]
|
||||||
preloaders = [
|
preloaders = [
|
||||||
# Image
|
# Image
|
||||||
{ mime = "image/{avif,heic,jxl,svg+xml}", run = "magick" },
|
{ mime = "image/{avif,hei?,jxl,svg+xml}", run = "magick" },
|
||||||
{ mime = "image/*", run = "image" },
|
{ mime = "image/*", run = "image" },
|
||||||
# Video
|
# Video
|
||||||
{ mime = "video/*", run = "video" },
|
{ mime = "video/*", run = "video" },
|
||||||
|
|
@ -110,7 +110,7 @@ previewers = [
|
||||||
# JSON
|
# JSON
|
||||||
{ mime = "application/{json,x-ndjson}", run = "json" },
|
{ mime = "application/{json,x-ndjson}", run = "json" },
|
||||||
# Image
|
# Image
|
||||||
{ mime = "image/{avif,heic,jxl,svg+xml}", run = "magick" },
|
{ mime = "image/{avif,hei?,jxl,svg+xml}", run = "magick" },
|
||||||
{ mime = "image/*", run = "image" },
|
{ mime = "image/*", run = "image" },
|
||||||
# Video
|
# Video
|
||||||
{ mime = "video/*", run = "video" },
|
{ mime = "video/*", run = "video" },
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ impl Manager {
|
||||||
self.current_mut().tracing = true;
|
self.current_mut().tracing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-peek
|
// Repeek
|
||||||
self.peek(false);
|
self.peek(false);
|
||||||
|
|
||||||
// Refresh watcher
|
// Refresh watcher
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,12 @@ impl Manager {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let repeek = self.hovered().is_some_and(|f| updates.contains_key(&f.url));
|
||||||
self.mimetype.extend(updates);
|
self.mimetype.extend(updates);
|
||||||
self.peek(false);
|
|
||||||
|
|
||||||
|
if repeek {
|
||||||
|
self.peek(false);
|
||||||
|
}
|
||||||
tasks.prework_affected(&affected, &self.mimetype);
|
tasks.prework_affected(&affected, &self.mimetype);
|
||||||
render!();
|
render!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ impl Watcher {
|
||||||
|
|
||||||
async fn fan_out(rx: UnboundedReceiver<Url>) {
|
async fn fan_out(rx: UnboundedReceiver<Url>) {
|
||||||
// TODO: revert this once a new notification is implemented
|
// TODO: revert this once a new notification is implemented
|
||||||
let rx = UnboundedReceiverStream::new(rx).chunks_timeout(1000, Duration::from_millis(50));
|
let rx = UnboundedReceiverStream::new(rx).chunks_timeout(1000, Duration::from_millis(100));
|
||||||
pin!(rx);
|
pin!(rx);
|
||||||
|
|
||||||
while let Some(chunk) = rx.next().await {
|
while let Some(chunk) = rx.next().await {
|
||||||
|
|
|
||||||
|
|
@ -89,25 +89,11 @@ impl Preview {
|
||||||
matches!(self.lock, Some(ref lock) if lock.url == *url)
|
matches!(self.lock, Some(ref lock) if lock.url == *url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn content_unchanged(&self, url: &Url, cha: &Cha) -> bool {
|
fn content_unchanged(&self, url: &Url, cha: &Cha) -> bool {
|
||||||
let Some(lock) = &self.lock else {
|
match &self.lock {
|
||||||
return false;
|
Some(l) => *url == l.url && self.skip == l.skip && cha.hits(l.cha),
|
||||||
};
|
None => false,
|
||||||
|
}
|
||||||
*url == lock.url
|
|
||||||
&& self.skip == lock.skip
|
|
||||||
&& cha.len == lock.cha.len
|
|
||||||
&& cha.mtime == lock.cha.mtime
|
|
||||||
&& cha.kind == lock.cha.kind
|
|
||||||
&& {
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
cha.perm == lock.cha.perm
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -264,19 +264,18 @@ impl Files {
|
||||||
|
|
||||||
macro_rules! go {
|
macro_rules! go {
|
||||||
($dist:expr, $src:expr, $inc:literal) => {
|
($dist:expr, $src:expr, $inc:literal) => {
|
||||||
let mut b = false;
|
let mut b = true;
|
||||||
for i in 0..$dist.len() {
|
for i in 0..$dist.len() {
|
||||||
if let Some(f) = $src.remove(&$dist[i].url) {
|
if let Some(f) = $src.remove(&$dist[i].url) {
|
||||||
if $dist[i] != f {
|
b &= $dist[i].cha.hits(f.cha);
|
||||||
b = true;
|
$dist[i] = f;
|
||||||
$dist[i] = f;
|
|
||||||
}
|
|
||||||
if $src.is_empty() {
|
if $src.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.revision += if b { $inc } else { 0 };
|
self.revision += if b { 0 } else { $inc };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ function M:preload()
|
||||||
string.format("%dx%d^", PREVIEW.max_width, PREVIEW.max_height),
|
string.format("%dx%d^", PREVIEW.max_width, PREVIEW.max_height),
|
||||||
"-quality",
|
"-quality",
|
||||||
tostring(PREVIEW.image_quality),
|
tostring(PREVIEW.image_quality),
|
||||||
|
"-auto-orient",
|
||||||
"JPG:" .. tostring(cache),
|
"JPG:" .. tostring(cache),
|
||||||
}):spawn()
|
}):spawn()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,20 @@ impl Cha {
|
||||||
self.kind |= kind;
|
self.kind |= kind;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn hits(self, c: Self) -> bool {
|
||||||
|
self.len == c.len && self.mtime == c.mtime && self.ctime == c.ctime && self.kind == c.kind && {
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
self.perm == c.perm
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cha {
|
impl Cha {
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,6 @@ impl AsRef<File> for File {
|
||||||
fn as_ref(&self) -> &File { self }
|
fn as_ref(&self) -> &File { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for File {
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.cha == other.cha && self.url == other.url && self.link_to == other.link_to
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl File {
|
impl File {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn from(url: Url) -> Result<Self> {
|
pub async fn from(url: Url) -> Result<Self> {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue