From c96190f0468be451aa9c774a17065e81346efcaa Mon Sep 17 00:00:00 2001 From: sxyazi Date: Wed, 2 Aug 2023 10:27:39 +0800 Subject: [PATCH] .. --- Cargo.lock | 577 ++---------------- Cargo.toml | 3 +- README.md | 4 +- adaptor/Cargo.toml | 21 + {core/src/adaptor => adaptor/src}/adaptor.rs | 14 +- adaptor/src/image.rs | 56 ++ {core/src/adaptor => adaptor/src}/iterm2.rs | 2 +- {core/src/adaptor => adaptor/src}/kitty.rs | 2 +- adaptor/src/lib.rs | 13 + adaptor/src/sixel.rs | 97 +++ {core/src/adaptor => adaptor/src}/ueberzug.rs | 0 app/Cargo.toml | 19 +- app/src/app.rs | 2 +- app/src/main.rs | 2 +- app/src/manager/folder.rs | 2 +- app/src/manager/mod.rs | 2 +- app/src/signals.rs | 35 +- app/src/tasks/clear.rs | 2 +- config/Cargo.toml | 15 +- config/src/preview/adaptor.rs | 3 +- core/Cargo.toml | 42 +- core/src/adaptor/image.rs | 31 - core/src/adaptor/mod.rs | 7 - core/src/lib.rs | 1 - core/src/manager/preview.rs | 12 +- core/src/tasks/precache.rs | 33 +- shared/Cargo.toml | 5 +- 27 files changed, 332 insertions(+), 670 deletions(-) create mode 100644 adaptor/Cargo.toml rename {core/src/adaptor => adaptor/src}/adaptor.rs (74%) create mode 100644 adaptor/src/image.rs rename {core/src/adaptor => adaptor/src}/iterm2.rs (94%) rename {core/src/adaptor => adaptor/src}/kitty.rs (95%) create mode 100644 adaptor/src/lib.rs create mode 100644 adaptor/src/sixel.rs rename {core/src/adaptor => adaptor/src}/ueberzug.rs (100%) delete mode 100644 core/src/adaptor/image.rs delete mode 100644 core/src/adaptor/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 1adee121..98e737fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adaptor" +version = "0.1.0" +dependencies = [ + "anyhow", + "base64", + "color_quant", + "config", + "image", + "md5", + "once_cell", + "ratatui", + "shared", + "tokio", + "tracing", +] + [[package]] name = "addr2line" version = "0.20.0" @@ -17,15 +34,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aho-corasick" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" -dependencies = [ - "memchr", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -62,6 +70,7 @@ checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" name = "app" version = "0.1.0" dependencies = [ + "adaptor", "ansi-to-tui", "anyhow", "config", @@ -89,68 +98,12 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-trait" -version = "0.1.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "axum" -version = "0.6.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a1de45611fdb535bfde7b7de4fd54f4fd2b17b1737c0a59b69bf9b92074b8c" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - [[package]] name = "backtrace" version = "0.3.68" @@ -166,12 +119,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.2" @@ -237,9 +184,12 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "51f1226cd9da55587234753d1245dd5b132343ea240f26b6a9003d68706141ba" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -290,57 +240,17 @@ dependencies = [ "xdg", ] -[[package]] -name = "console-api" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" -dependencies = [ - "prost", - "prost-types", - "tonic", - "tracing-core", -] - -[[package]] -name = "console-subscriber" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" -dependencies = [ - "console-api", - "crossbeam-channel", - "crossbeam-utils", - "futures", - "hdrhistogram", - "humantime", - "prost-types", - "serde", - "serde_json", - "thread_local", - "tokio", - "tokio-stream", - "tonic", - "tracing", - "tracing-core", - "tracing-subscriber", -] - [[package]] name = "core" version = "0.1.0" dependencies = [ + "adaptor", "anyhow", "async-channel", - "base64 0.21.2", "config", - "console-subscriber", "crossterm", "futures", - "image", "indexmap 2.0.0", - "libc", - "md5", "notify", "once_cell", "parking_lot", @@ -445,6 +355,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "deranged" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8810e7e2cf385b1e9b50d68264908ec367ba642c96d02edfe61c39e88e2a3c01" + [[package]] name = "either" version = "1.9.0" @@ -603,7 +519,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn", ] [[package]] @@ -671,25 +587,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "h2" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 1.9.3", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "2.2.1" @@ -711,101 +608,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" -[[package]] -name = "hdrhistogram" -version = "7.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" -dependencies = [ - "base64 0.13.1", - "byteorder", - "flate2", - "nom", - "num-traits", -] - [[package]] name = "hermit-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" -[[package]] -name = "http" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - [[package]] name = "iana-time-zone" version = "0.1.57" @@ -904,15 +712,6 @@ dependencies = [ "libc", ] -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.9" @@ -1015,21 +814,6 @@ dependencies = [ "libc", ] -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matchit" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67827e6ea8ee8a7c4a72227ef4fc08957040acffdb5f122733b24fa12daff41b" - [[package]] name = "md5" version = "0.7.0" @@ -1051,12 +835,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1275,7 +1053,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn", ] [[package]] @@ -1302,7 +1080,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdc0001cfea3db57a2e24bc0d818e9e20e554b5f97fabb9bc231dc240269ae06" dependencies = [ - "base64 0.21.2", + "base64", "indexmap 1.9.3", "line-wrap", "quick-xml", @@ -1323,12 +1101,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - [[package]] name = "proc-macro2" version = "1.0.66" @@ -1338,38 +1110,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost", -] - [[package]] name = "qoi" version = "0.4.1" @@ -1397,36 +1137,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "ratatui" version = "0.22.0" @@ -1482,44 +1192,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "regex" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.3.4", - "regex-syntax 0.7.4", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.7.4", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.7.4" @@ -1532,12 +1204,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - [[package]] name = "ryu" version = "1.0.15" @@ -1567,22 +1233,22 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.178" +version = "1.0.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348" +checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.178" +version = "1.0.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b" +checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn", ] [[package]] @@ -1710,49 +1376,30 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.109" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn" -version = "2.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "syntect" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8" +checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91" dependencies = [ "bincode", "bitflags 1.3.2", "flate2", "fnv", - "lazy_static", "once_cell", "onig", "plist", - "regex-syntax 0.6.29", + "regex-syntax", "serde", - "serde_derive", "serde_json", "thiserror", "walkdir", @@ -1776,7 +1423,7 @@ checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn", ] [[package]] @@ -1802,10 +1449,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +checksum = "b79eabcd964882a646b3584543ccabeae7869e9ac32a46f6f22b7a5bd405308b" dependencies = [ + "deranged", "itoa", "serde", "time-core", @@ -1820,9 +1468,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -1859,20 +1507,9 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "tracing", "windows-sys 0.48.0", ] -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.1.0" @@ -1881,32 +1518,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", -] - -[[package]] -name = "tokio-stream" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", + "syn", ] [[package]] @@ -1944,66 +1556,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64 0.21.2", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.37" @@ -2035,7 +1587,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn", ] [[package]] @@ -2065,14 +1617,10 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ - "matchers", "nu-ansi-term", - "once_cell", - "regex", "sharded-slab", "smallvec", "thread_local", - "tracing", "tracing-core", "tracing-log", ] @@ -2093,12 +1641,6 @@ dependencies = [ "windows 0.44.0", ] -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -2159,15 +1701,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2195,7 +1728,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.27", + "syn", "wasm-bindgen-shared", ] @@ -2217,7 +1750,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2417,9 +1950,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7" +checksum = "f46aab759304e4d7b2075a9aecba26228bb073ee8c50db796b2c72c676b5d807" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index f2703f04..7f2c7137 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "adaptor", "app", "config", "core", @@ -8,6 +9,6 @@ members = [ ] [profile.release] -strip = true lto = true +strip = true panic = "abort" diff --git a/README.md b/README.md index 809f6fda..aea19cfe 100644 --- a/README.md +++ b/README.md @@ -91,8 +91,8 @@ If you want to use your own config, copy the [config folder](https://github.com/ | WezTerm | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in | | Konsole | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in | | iTerm2 | [Inline Images Protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in | -| Hyper | Sixel | ☑️ Überzug++ required | -| foot | Sixel | ☑️ Überzug++ required | +| Hyper | Sixel | ✅ Built-in | +| foot | Sixel | ✅ Built-in | | X11 / Wayland | Window system protocol | ☑️ Überzug++ required | | Fallback | [Chafa](https://hpjansson.org/chafa/) | ☑️ Überzug++ required | diff --git a/adaptor/Cargo.toml b/adaptor/Cargo.toml new file mode 100644 index 00000000..12a801b5 --- /dev/null +++ b/adaptor/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "adaptor" +version = "0.1.0" +edition = "2021" + +[dependencies] +config = { path = "../config" } +shared = { path = "../shared" } + +# External dependencies +anyhow = "^1" +base64 = "^0" +color_quant = "^1" +image = "^0" +md5 = "^0" +once_cell = "^1" +ratatui = "^0" +tokio = { version = "^1", features = [ "parking_lot" ] } + +# Logging +tracing = "^0" diff --git a/core/src/adaptor/adaptor.rs b/adaptor/src/adaptor.rs similarity index 74% rename from core/src/adaptor/adaptor.rs rename to adaptor/src/adaptor.rs index 085743ce..f5a96de0 100644 --- a/core/src/adaptor/adaptor.rs +++ b/adaptor/src/adaptor.rs @@ -4,9 +4,10 @@ use anyhow::Result; use config::{preview::PreviewAdaptor, PREVIEW}; use once_cell::sync::Lazy; use ratatui::prelude::Rect; -use tokio::sync::mpsc::UnboundedSender; +use tokio::{fs, sync::mpsc::UnboundedSender}; -use super::{iterm2::Iterm2, kitty::Kitty, ueberzug::Ueberzug}; +use super::{Iterm2, Kitty, Ueberzug}; +use crate::{Image, Sixel}; static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false); @@ -18,14 +19,20 @@ pub struct Adaptor; impl Adaptor { pub fn init() { Lazy::force(&UEBERZUG); } - pub async fn image_show(path: &Path, rect: Rect) -> Result<()> { + pub async fn image_show(mut path: &Path, rect: Rect) -> Result<()> { if IMAGE_SHOWN.swap(true, Ordering::Relaxed) { Self::image_hide(rect); } + let cache = Image::cache(path); + if fs::metadata(&cache).await.is_ok() { + path = cache.as_path(); + } + match PREVIEW.adaptor { PreviewAdaptor::Kitty => Kitty::image_show(path, rect).await, PreviewAdaptor::Iterm2 => Iterm2::image_show(path, rect).await, + PreviewAdaptor::Sixel => Sixel::image_show(path, rect).await, _ => { if let Some(tx) = &*UEBERZUG { tx.send(Some((path.to_path_buf(), rect))).ok(); @@ -43,6 +50,7 @@ impl Adaptor { match PREVIEW.adaptor { PreviewAdaptor::Kitty => Kitty::image_hide(), PreviewAdaptor::Iterm2 => Iterm2::image_hide(rect), + PreviewAdaptor::Sixel => Sixel::image_hide(rect), _ => { if let Some(tx) = &*UEBERZUG { tx.send(None).ok(); diff --git a/adaptor/src/image.rs b/adaptor/src/image.rs new file mode 100644 index 00000000..cc645bdc --- /dev/null +++ b/adaptor/src/image.rs @@ -0,0 +1,56 @@ +use std::path::{Path, PathBuf}; + +use anyhow::{Error, Result}; +use config::PREVIEW; +use image::{imageops::FilterType, DynamicImage, ImageFormat}; +use shared::tty_ratio; +use tokio::fs; + +pub struct Image; + +impl Image { + pub(super) async fn crop(path: &Path, size: (u16, u16)) -> Result { + let (w, h) = { + let r = tty_ratio(); + let (w, h) = ((size.0 as f64 * r.0) as u32, (size.1 as f64 * r.1) as u32); + (w.min(PREVIEW.max_width), h.min(PREVIEW.max_height)) + }; + + let img = fs::read(path).await?; + let img = tokio::task::spawn_blocking(move || -> Result { + let img = image::load_from_memory(&img)?; + Ok(if img.width() > w || img.height() > h { + img.resize(w, h, FilterType::Triangle) + } else { + img + }) + }); + + Ok(img.await??) + } + + pub async fn precache(path: &Path) -> Result<()> { + let cache = Self::cache(path); + if fs::metadata(&cache).await.is_ok() { + return Ok(()); + } + + let img = fs::read(&path).await?; + let result = tokio::task::spawn_blocking(move || { + let img = image::load_from_memory(&img)?; + let (w, h) = (PREVIEW.max_width, PREVIEW.max_height); + + if img.width() > w || img.height() > h { + img.resize(w, h, FilterType::Triangle).save_with_format(cache, ImageFormat::Jpeg)?; + } + Ok::<(), Error>(()) + }); + + Ok(result.await??) + } + + #[inline] + pub fn cache(path: &Path) -> PathBuf { + format!("/tmp/yazi/{:x}", md5::compute(path.to_string_lossy().as_bytes())).into() + } +} diff --git a/core/src/adaptor/iterm2.rs b/adaptor/src/iterm2.rs similarity index 94% rename from core/src/adaptor/iterm2.rs rename to adaptor/src/iterm2.rs index 570e3319..de00a740 100644 --- a/core/src/adaptor/iterm2.rs +++ b/adaptor/src/iterm2.rs @@ -12,7 +12,7 @@ pub(super) struct Iterm2; impl Iterm2 { pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> { - let img = Image::resize(path, (rect.width, rect.height)).await?; + let img = Image::crop(path, (rect.width, rect.height)).await?; let b = Self::encode(img).await?; Term::move_to(rect.x, rect.y).ok(); diff --git a/core/src/adaptor/kitty.rs b/adaptor/src/kitty.rs similarity index 95% rename from core/src/adaptor/kitty.rs rename to adaptor/src/kitty.rs index 53d4985d..a533f1ac 100644 --- a/core/src/adaptor/kitty.rs +++ b/adaptor/src/kitty.rs @@ -12,7 +12,7 @@ pub(super) struct Kitty; impl Kitty { pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> { - let img = Image::resize(path, (rect.width, rect.height)).await?; + let img = Image::crop(path, (rect.width, rect.height)).await?; let b = Self::encode(img).await?; Term::move_to(rect.x, rect.y).ok(); diff --git a/adaptor/src/lib.rs b/adaptor/src/lib.rs new file mode 100644 index 00000000..60a9d09c --- /dev/null +++ b/adaptor/src/lib.rs @@ -0,0 +1,13 @@ +mod adaptor; +mod image; +mod iterm2; +mod kitty; +mod sixel; +mod ueberzug; + +pub use adaptor::*; +pub use image::*; +pub(self) use iterm2::*; +pub(self) use kitty::*; +pub(self) use sixel::*; +pub(self) use ueberzug::*; diff --git a/adaptor/src/sixel.rs b/adaptor/src/sixel.rs new file mode 100644 index 00000000..9110553f --- /dev/null +++ b/adaptor/src/sixel.rs @@ -0,0 +1,97 @@ +use std::{io::{stdout, Write}, path::Path}; + +use anyhow::{bail, Result}; +use color_quant::NeuQuant; +use image::DynamicImage; +use ratatui::prelude::Rect; +use shared::Term; + +use crate::Image; + +pub(super) struct Sixel; + +impl Sixel { + pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> { + let img = Image::crop(path, (rect.width, rect.height)).await?; + let b = Self::encode(img).await?; + + Term::move_to(rect.x, rect.y).ok(); + stdout().write_all(&b).ok(); + Ok(()) + } + + #[inline] + pub(super) fn image_hide(rect: Rect) { + let s = " ".repeat(rect.width as usize); + for y in rect.top()..=rect.bottom() { + Term::move_to(rect.x, y).ok(); + stdout().write_all(s.as_bytes()).ok(); + } + } + + async fn encode(img: DynamicImage) -> Result> { + let alpha = img.color().has_alpha(); + if img.width() == 0 || img.height() == 0 { + bail!("image is empty"); + } + + tokio::task::spawn_blocking(move || { + let img = img.into_rgba8(); + let nq = NeuQuant::new(10, 256 - alpha as usize, &img); + + let mut buf: Vec = Vec::with_capacity(1 << 16); + write!(buf, "\x1bP0;0;8q\"1;1;{};{}", img.width(), img.height())?; + + // Palette + for (i, c) in nq.color_map_rgba().chunks(4).enumerate() { + write!( + buf, + "#{};2;{};{};{}", + i + alpha as usize, + c[0] as u16 * 100 / 255, + c[1] as u16 * 100 / 255, + c[2] as u16 * 100 / 255 + )?; + } + + for y in 0..img.height() { + let c = (b'?' + (1 << (y % 6))) as u8 as char; + + let mut last = 0; + let mut repeat = 0usize; + for x in 0..img.width() { + let pixel = img.get_pixel(x, y).0; + let idx = if pixel[3] == 0 { 0 } else { nq.index_of(&pixel) as u8 + alpha as u8 }; + + if idx == last || repeat == 0 { + (last, repeat) = (idx, repeat + 1); + continue; + } + + if repeat > 1 { + write!(buf, "#{}!{}{}", last, repeat, c)?; + } else { + write!(buf, "#{}{}", last, c)?; + } + + (last, repeat) = (idx, 1); + } + + if repeat > 1 { + write!(buf, "#{}!{}{}", last, repeat, c)?; + } else { + write!(buf, "#{}{}", last, c)?; + } + + write!(buf, "$")?; + if y % 6 == 5 { + write!(buf, "-")?; + } + } + + write!(buf, "\x1b\\")?; + Ok(buf) + }) + .await? + } +} diff --git a/core/src/adaptor/ueberzug.rs b/adaptor/src/ueberzug.rs similarity index 100% rename from core/src/adaptor/ueberzug.rs rename to adaptor/src/ueberzug.rs diff --git a/app/Cargo.toml b/app/Cargo.toml index 33778401..dc0f145a 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -4,19 +4,20 @@ version = "0.1.0" edition = "2021" [dependencies] -config = { path = "../config" } -core = { path = "../core" } -shared = { path = "../shared" } +adaptor = { path = "../adaptor" } +config = { path = "../config" } +core = { path = "../core" } +shared = { path = "../shared" } # External dependencies -anyhow = "^1" -tokio = { version = "^1", features = [ "parking_lot" ] } -crossterm = { version = "^0", features = [ "event-stream" ] } -ratatui = { version = "^0" } ansi-to-tui = "^3" -signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] } -libc = "^0" +anyhow = "^1" +crossterm = { version = "^0", features = [ "event-stream" ] } futures = "^0" +libc = "^0" +ratatui = "^0" +signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] } +tokio = { version = "^1", features = [ "parking_lot" ] } # Logging tracing = "^0" diff --git a/app/src/app.rs b/app/src/app.rs index ba3e5b1e..821d549b 100644 --- a/app/src/app.rs +++ b/app/src/app.rs @@ -22,7 +22,7 @@ impl App { let signals = Signals::start()?; let mut app = Self { cx: Ctx::new(), term: Some(term), signals }; - while let Some(event) = app.signals.rx.recv().await { + while let Some(event) = app.signals.recv().await { match event { Event::Quit => break, Event::Key(key) => app.dispatch_key(key), diff --git a/app/src/main.rs b/app/src/main.rs index dcf02c17..049ddd3f 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -25,7 +25,7 @@ async fn main() -> anyhow::Result<()> { config::init(); - core::adaptor::Adaptor::init(); + adaptor::Adaptor::init(); App::run().await } diff --git a/app/src/manager/folder.rs b/app/src/manager/folder.rs index f91cc917..53738ca4 100644 --- a/app/src/manager/folder.rs +++ b/app/src/manager/folder.rs @@ -6,7 +6,7 @@ use shared::readable_path; use crate::Ctx; -pub struct Folder<'a> { +pub(super) struct Folder<'a> { cx: &'a Ctx, folder: &'a core::manager::Folder, is_preview: bool, diff --git a/app/src/manager/mod.rs b/app/src/manager/mod.rs index 207ca124..3a32499f 100644 --- a/app/src/manager/mod.rs +++ b/app/src/manager/mod.rs @@ -2,6 +2,6 @@ mod folder; mod layout; mod preview; -pub(super) use folder::*; +pub(self) use folder::*; pub(super) use layout::*; pub(self) use preview::*; diff --git a/app/src/signals.rs b/app/src/signals.rs index 28f8e7a1..94e696ea 100644 --- a/app/src/signals.rs +++ b/app/src/signals.rs @@ -7,8 +7,8 @@ use libc::{SIGHUP, SIGINT, SIGQUIT, SIGTERM}; use tokio::{select, sync::{mpsc::{self, UnboundedReceiver, UnboundedSender}, oneshot}, task::JoinHandle}; pub(super) struct Signals { - pub tx: UnboundedSender, - pub rx: UnboundedReceiver, + tx: UnboundedSender, + rx: UnboundedReceiver, term_stop_tx: Option>, term_stop_rx: Option>, @@ -29,6 +29,23 @@ impl Signals { Ok(signals) } + #[inline] + pub(super) async fn recv(&mut self) -> Option { self.rx.recv().await } + + pub(super) fn stop_term(&mut self, state: bool) { + if state == self.term_stop_tx.is_none() { + return; + } + + if let Some(tx) = self.term_stop_tx.take() { + tx.send(()).ok(); + } else { + let (tx, rx) = oneshot::channel(); + (self.term_stop_tx, self.term_stop_rx) = (Some(tx), Some(rx)); + self.spawn_crossterm_task(); + } + } + fn spawn_system_task(&self) -> Result> { let tx = self.tx.clone(); let mut signals = signal_hook_tokio::Signals::new([SIGHUP, SIGTERM, SIGINT, SIGQUIT])?; @@ -72,18 +89,4 @@ impl Signals { } }) } - - pub(super) fn stop_term(&mut self, state: bool) { - if state == self.term_stop_tx.is_none() { - return; - } - - if let Some(tx) = self.term_stop_tx.take() { - tx.send(()).ok(); - } else { - let (tx, rx) = oneshot::channel(); - (self.term_stop_tx, self.term_stop_rx) = (Some(tx), Some(rx)); - self.spawn_crossterm_task(); - } - } } diff --git a/app/src/tasks/clear.rs b/app/src/tasks/clear.rs index d9526402..2aaa073e 100644 --- a/app/src/tasks/clear.rs +++ b/app/src/tasks/clear.rs @@ -1,6 +1,6 @@ use ratatui::{buffer::Buffer, layout::Rect, widgets::{self, Widget}}; -pub struct Clear; +pub(super) struct Clear; impl Widget for Clear { fn render(self, mut area: Rect, buf: &mut Buffer) { diff --git a/config/Cargo.toml b/config/Cargo.toml index 70c99be3..f259b1ef 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -4,16 +4,15 @@ version = "0.1.0" edition = "2021" [dependencies] - shared = { path = "../shared" } # External dependencies +anyhow = "^1" +crossterm = "^0" +futures = "^0" +glob = "^0" +once_cell = "^1" +ratatui = "^0" +serde = { version = "^1", features = [ "derive" ] } toml = { version = "^0", features = [ "preserve_order" ] } xdg = "^2" -serde = { version = "^1", features = [ "derive" ] } -once_cell = "^1" -crossterm = { version = "^0" } -anyhow = "^1" -ratatui = "^0" -glob = "^0" -futures = "^0" diff --git a/config/src/preview/adaptor.rs b/config/src/preview/adaptor.rs index 282c3d36..f961026f 100644 --- a/config/src/preview/adaptor.rs +++ b/config/src/preview/adaptor.rs @@ -4,9 +4,9 @@ use std::env; pub enum PreviewAdaptor { Kitty, Iterm2, + Sixel, // Supported by Überzug++ - Sixel, X11, Wayland, Chafa, @@ -59,6 +59,7 @@ impl PreviewAdaptor { match self { PreviewAdaptor::Kitty => false, PreviewAdaptor::Iterm2 => false, + PreviewAdaptor::Sixel => false, _ => true, } } diff --git a/core/Cargo.toml b/core/Cargo.toml index 12c7013e..ffb73f4d 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -4,28 +4,24 @@ version = "0.1.0" edition = "2021" [dependencies] -config = { path = "../config" } -shared = { path = "../shared" } +adaptor = { path = "../adaptor" } +config = { path = "../config" } +shared = { path = "../shared" } # External dependencies -serde = { version = "^1" } -anyhow = "^1" -async-channel = "^1" -base64 = "^0" -console-subscriber = "^0" -crossterm = { version = "^0" } -futures = "^0" -image = "^0" -indexmap = "^2" -libc = "^0" -md5 = "^0" -notify = { version = "^6", default-features = false, features = [ "macos_fsevent" ] } -parking_lot = "^0" -ratatui = "^0" -serde_json = "^1" -syntect = "^5" -tokio = { version = "^1", features = [ "parking_lot", "macros", "rt-multi-thread", "sync", "fs", "process", "io-std", "io-util" ] } -trash = "^3" -unicode-width = "^0" -once_cell = "^1" -tracing = "^0" +anyhow = "^1" +async-channel = "^1" +crossterm = "^0" +futures = "^0" +indexmap = "^2" +notify = { version = "^6", default-features = false, features = [ "macos_fsevent" ] } +once_cell = "^1" +parking_lot = "^0" +ratatui = "^0" +serde = "^1" +serde_json = "^1" +syntect = "^5" +tokio = { version = "^1", features = [ "parking_lot", "macros", "rt-multi-thread", "sync", "time", "fs", "process", "io-util" ] } +tracing = "^0" +trash = "^3" +unicode-width = "^0" diff --git a/core/src/adaptor/image.rs b/core/src/adaptor/image.rs deleted file mode 100644 index a20a8522..00000000 --- a/core/src/adaptor/image.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::path::Path; - -use anyhow::Result; -use config::PREVIEW; -use image::{imageops::FilterType, DynamicImage}; -use shared::tty_ratio; -use tokio::fs; - -pub(super) struct Image; - -impl Image { - pub(super) async fn resize(path: &Path, size: (u16, u16)) -> Result { - let (w, h) = { - let r = tty_ratio(); - let (w, h) = ((size.0 as f64 * r.0) as u32, (size.1 as f64 * r.1) as u32); - (w.min(PREVIEW.max_width), h.min(PREVIEW.max_height)) - }; - - let img = fs::read(path).await?; - let img = tokio::task::spawn_blocking(move || -> Result { - let img = image::load_from_memory(&img)?; - Ok(if img.width() > w || img.height() > h { - img.resize(w, h, FilterType::Triangle) - } else { - img - }) - }); - - Ok(img.await??) - } -} diff --git a/core/src/adaptor/mod.rs b/core/src/adaptor/mod.rs deleted file mode 100644 index 1c99201e..00000000 --- a/core/src/adaptor/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod adaptor; -mod image; -mod iterm2; -mod kitty; -mod ueberzug; - -pub use adaptor::*; diff --git a/core/src/lib.rs b/core/src/lib.rs index f2843f2d..a2a124e9 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,4 +1,3 @@ -pub mod adaptor; mod blocker; mod event; pub mod external; diff --git a/core/src/manager/preview.rs b/core/src/manager/preview.rs index 1f52569e..b634cb12 100644 --- a/core/src/manager/preview.rs +++ b/core/src/manager/preview.rs @@ -1,5 +1,6 @@ use std::{fs::File, io::{BufRead, BufReader}, mem, path::{Path, PathBuf}, sync::OnceLock}; +use adaptor::{Adaptor, Image}; use anyhow::{anyhow, Result}; use config::{PREVIEW, THEME}; use ratatui::prelude::Rect; @@ -8,7 +9,7 @@ use syntect::{easy::HighlightFile, highlighting::{Theme, ThemeSet}, parsing::Syn use tokio::{fs, task::JoinHandle}; use super::{ALL_RATIO, CURRENT_RATIO, PARENT_RATIO, PREVIEW_BORDER, PREVIEW_MARGIN, PREVIEW_RATIO}; -use crate::{adaptor::Adaptor, emit, external, files::{Files, FilesOp}, tasks::Precache}; +use crate::{emit, external, files::{Files, FilesOp}}; static SYNTECT_SYNTAX: OnceLock = OnceLock::new(); static SYNTECT_THEME: OnceLock = OnceLock::new(); @@ -102,18 +103,13 @@ impl Preview { Ok(PreviewData::Folder) } - pub async fn image(mut path: &Path) -> Result { - let cache = Precache::cache(path); - if fs::metadata(&cache).await.is_ok() { - path = cache.as_path(); - } - + pub async fn image(path: &Path) -> Result { Adaptor::image_show(path, Self::rect()).await?; Ok(PreviewData::Image) } pub async fn video(path: &Path) -> Result { - let cache = Precache::cache(path); + let cache = Image::cache(path); if fs::metadata(&cache).await.is_err() { external::ffmpegthumbnailer(path, &cache).await?; } diff --git a/core/src/tasks/precache.rs b/core/src/tasks/precache.rs index ecb6cf13..60340779 100644 --- a/core/src/tasks/precache.rs +++ b/core/src/tasks/precache.rs @@ -1,8 +1,7 @@ -use std::{collections::{BTreeMap, BTreeSet}, path::{Path, PathBuf}, sync::Arc}; +use std::{collections::{BTreeMap, BTreeSet}, path::PathBuf, sync::Arc}; -use anyhow::{Error, Result}; -use config::PREVIEW; -use image::{imageops::FilterType, ImageFormat}; +use adaptor::Image; +use anyhow::Result; use parking_lot::Mutex; use shared::{calculate_size, Throttle}; use tokio::{fs, sync::mpsc}; @@ -67,28 +66,11 @@ impl Precache { pub(super) async fn work(&self, task: &mut PrecacheOp) -> Result<()> { match task { PrecacheOp::Image(task) => { - let cache = Self::cache(&task.target); - if fs::metadata(&cache).await.is_ok() { - return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?); - } - - let img = fs::read(&task.target).await; - tokio::task::spawn_blocking(move || { - let img = image::load_from_memory(&img?)?; - let (w, h) = (PREVIEW.max_width, PREVIEW.max_height); - - if img.width() > w || img.height() > h { - img.resize(w, h, FilterType::Triangle).save_with_format(&cache, ImageFormat::Jpeg).ok(); - } - Ok::<(), Error>(()) - }) - .await - .ok(); - + Image::precache(&task.target).await.ok(); self.sch.send(TaskOp::Adv(task.id, 1, 0))?; } PrecacheOp::Video(task) => { - let cache = Self::cache(&task.target); + let cache = Image::cache(&task.target); if fs::metadata(&cache).await.is_ok() { return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?); } @@ -151,9 +133,4 @@ impl Precache { } self.done(id) } - - #[inline] - pub fn cache(path: &Path) -> PathBuf { - format!("/tmp/yazi/{:x}", md5::compute(path.to_string_lossy().as_bytes())).into() - } } diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 92f1981a..e07b4d20 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -4,10 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] - anyhow = "^1" +crossterm = "^0" libc = "^0" -tokio = { version = "^1", features = [ "parking_lot" ] } parking_lot = "^0" -crossterm = { version = "^0" } ratatui = { version = "^0" } +tokio = { version = "^1", features = [ "parking_lot" ] }