diff --git a/Cargo.lock b/Cargo.lock index 39a3f1a..b65eb9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "ansi-to-tui" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c4af0bef1b514c9b6a32a773caf604c1390fa7913f4eaa23bfe76f251d6a42" +checksum = "67555e1f1ece39d737e28c8a017721287753af3f93225e4a445b29ccb0f5912c" dependencies = [ "nom", "ratatui", @@ -796,7 +796,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -1086,12 +1086,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - [[package]] name = "ecdsa" version = "0.14.8" @@ -1617,7 +1611,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -1694,6 +1688,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "infer" version = "0.16.0" @@ -2227,7 +2227,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2420,38 +2420,39 @@ dependencies = [ [[package]] name = "ratatui" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" +checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ "bitflags 2.6.0", "cassowary", "compact_str", "crossterm", + "indoc", "instability", "itertools 0.13.0", "lru", "paste", "strum", - "strum_macros", "unicode-segmentation", "unicode-truncate", - "unicode-width", + "unicode-width 0.2.0", ] [[package]] name = "ratatui-image" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb525a8d7c50ca224a238ae3bb3caf5ec357292ff91fcac28748a27b66dcacb" +checksum = "e3a07161c498ddd5066a444a869f27fd97cfc164dbee8c0bdb5ff803b8bb54ce" dependencies = [ "base64", - "dyn-clone", "icy_sixel", "image", "rand", "ratatui", "rustix", + "thiserror", + "windows", ] [[package]] @@ -3134,7 +3135,7 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ "smawk", "unicode-linebreak", - "unicode-width", + "unicode-width 0.1.13", ] [[package]] @@ -3382,12 +3383,12 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tui-input" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd137780d743c103a391e06fe952487f914b299a4fe2c3626677f6a6339a7c6b" +checksum = "ffde6d8fcffe86b617018ca9b2171d673b41def44ebf802de203d2f2c598d3de" dependencies = [ "ratatui", - "unicode-width", + "unicode-width 0.2.0", ] [[package]] @@ -3447,7 +3448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5fbabedabe362c618c714dbefda9927b5afc8e2a8102f47f081089a9019226" dependencies = [ "itertools 0.12.1", - "unicode-width", + "unicode-width 0.1.13", ] [[package]] @@ -3456,6 +3457,12 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "untrusted" version = "0.9.0" @@ -3642,13 +3649,77 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -3666,7 +3737,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -3686,18 +3757,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3708,9 +3779,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3720,9 +3791,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3732,15 +3803,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3750,9 +3821,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3762,9 +3833,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3774,9 +3845,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3786,9 +3857,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" diff --git a/Cargo.toml b/Cargo.toml index 8cf78e7..0ea72b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.79.0" exclude = ["/.github", "/img", "/tool", "go.work*", "Makefile", "_config.yml"] [dependencies] -ansi-to-tui = "6.0.0" +ansi-to-tui = "7.0.0" anyhow = "1.0.91" arboard = "3.4.1" aws-config = "1.5.9" @@ -30,8 +30,8 @@ infer = "0.16.0" itsuki = "0.2.0" once_cell = "1.20.2" open = "5.3.0" -ratatui = { version = "0.28.1", features = ["unstable-widget-ref"] } -ratatui-image = "2.0.1" +ratatui = { version = "0.29.0", features = ["unstable-widget-ref"] } +ratatui-image = "3.0.0" serde = { version = "1.0.213", features = ["derive"] } smart-default = "0.7.1" syntect = { version = "5.2.0", default-features = false, features = [ @@ -43,7 +43,7 @@ toml = "0.8.19" tracing = "0.1.40" tracing-log = "0.2.0" tracing-subscriber = { version = "0.3.18", features = ["chrono"] } -tui-input = "0.10.1" +tui-input = "0.11.0" umbra = "0.1.0" [dev-dependencies] diff --git a/img/object-preview-image.png b/img/object-preview-image.png index ebcfc79..b33f0c5 100644 Binary files a/img/object-preview-image.png and b/img/object-preview-image.png differ diff --git a/src/app.rs b/src/app.rs index 45defcf..ed10445 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5,6 +5,7 @@ use crate::{ client::Client, color::ColorTheme, config::Config, + environment::Environment, error::{AppError, Result}, event::{ AppEventType, CompleteDownloadObjectResult, CompleteInitializeResult, @@ -58,18 +59,27 @@ pub struct App { app_objects: AppObjects, client: Option>, config: Config, + env: Environment, pub theme: ColorTheme, tx: Sender, } impl App { - pub fn new(config: Config, theme: ColorTheme, tx: Sender, width: usize, height: usize) -> App { + pub fn new( + config: Config, + env: Environment, + theme: ColorTheme, + tx: Sender, + width: usize, + height: usize, + ) -> App { App { app_view_state: AppViewState::new(width, height), app_objects: AppObjects::default(), page_stack: PageStack::new(theme.clone(), tx.clone()), client: None, config, + env, theme, tx, } @@ -533,6 +543,7 @@ impl App { path.to_string_lossy().into(), current_object_key, self.config.preview.clone(), + self.env.clone(), self.theme.clone(), self.tx.clone(), ); diff --git a/src/environment.rs b/src/environment.rs new file mode 100644 index 0000000..e6b9a79 --- /dev/null +++ b/src/environment.rs @@ -0,0 +1,51 @@ +use crate::config::Config; + +#[derive(Debug, Default, Clone)] +pub struct Environment { + pub image_picker: ImagePicker, +} + +impl Environment { + pub fn new(config: &Config) -> Environment { + Environment { + image_picker: build_image_picker(config.preview.image), + } + } +} + +#[allow(dead_code)] +#[derive(Debug, Default, Clone)] +pub enum ImagePicker { + #[default] + Disabled, + Ok(ratatui_image::picker::Picker), + Error(String), +} + +#[cfg(not(feature = "imggen"))] +fn build_image_picker(image_preview_enabled: bool) -> ImagePicker { + if image_preview_enabled { + match ratatui_image::picker::Picker::from_query_stdio() { + Ok(picker) => { + if let ratatui_image::picker::ProtocolType::Halfblocks = picker.protocol_type() { + ImagePicker::Error("This terminal does not support any protocol".into()) + } else { + ImagePicker::Ok(picker) + } + } + Err(e) => ImagePicker::Error(e.to_string()), + } + } else { + ImagePicker::Disabled + } +} + +#[cfg(feature = "imggen")] +fn build_image_picker(_image_preview_enabled: bool) -> ImagePicker { + // - font size cannot be obtained with xterm.js + // - want to fix the protocol to iterm2 + // so changed the settings with the imggen feature + let mut picker = ratatui_image::picker::Picker::from_fontsize((10, 20)); + picker.set_protocol_type(ratatui_image::picker::ProtocolType::Iterm2); + ImagePicker::Ok(picker) +} diff --git a/src/main.rs b/src/main.rs index e1de6e4..a623aa1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod client; mod color; mod config; mod constant; +mod environment; mod error; mod event; mod file; @@ -27,6 +28,7 @@ use crate::app::App; use crate::client::Client; use crate::color::ColorTheme; use crate::config::Config; +use crate::environment::Environment; #[derive(Debug, Clone, Copy, ValueEnum)] enum PathStyle { @@ -78,12 +80,13 @@ struct Args { async fn main() -> anyhow::Result<()> { let args = Args::parse(); let config = Config::load()?; + let env = Environment::new(&config); let theme = ColorTheme::default(); initialize_debug_log(&args, &config)?; let mut terminal = ratatui::try_init()?; - let ret = run(&mut terminal, args, config, theme).await; + let ret = run(&mut terminal, args, config, env, theme).await; ratatui::try_restore()?; @@ -94,13 +97,14 @@ async fn run( terminal: &mut Terminal, args: Args, config: Config, + env: Environment, theme: ColorTheme, ) -> anyhow::Result<()> { let (tx, rx) = event::new(); let (width, height) = get_frame_size(terminal); let default_region_fallback = config.default_region.clone(); - let mut app = App::new(config, theme, tx.clone(), width, height); + let mut app = App::new(config, env, theme, tx.clone(), width, height); spawn(async move { let client = Client::new( diff --git a/src/pages/object_preview.rs b/src/pages/object_preview.rs index fde69c9..202fd64 100644 --- a/src/pages/object_preview.rs +++ b/src/pages/object_preview.rs @@ -7,12 +7,13 @@ use ratatui::{ use crate::{ color::ColorTheme, config::PreviewConfig, + environment::{Environment, ImagePicker}, event::{AppEventType, Sender}, key_code, key_code_char, object::{FileDetail, ObjectKey, RawObject}, pages::util::{build_helps, build_short_helps}, widget::{ - ImagePreview, ImagePreviewState, InputDialog, InputDialogState, TextPreview, + self, ImagePreview, ImagePreviewState, InputDialog, InputDialogState, TextPreview, TextPreviewState, }, }; @@ -54,11 +55,12 @@ impl ObjectPreviewPage { path: String, object_key: ObjectKey, preview_config: PreviewConfig, + env: Environment, theme: ColorTheme, tx: Sender, ) -> Self { let preview_type = if infer::is_image(&object.bytes) { - let (state, msg) = ImagePreviewState::new(&object.bytes, preview_config.image); + let (state, msg) = ImagePreviewState::new(&object.bytes, env.image_picker.into()); if let Some(msg) = msg { tx.send(AppEventType::NotifyWarn(msg)); } @@ -318,6 +320,16 @@ impl ObjectPreviewPage { } } +impl From for widget::ImagePicker { + fn from(value: ImagePicker) -> Self { + match value { + ImagePicker::Disabled => widget::ImagePicker::Disabled, + ImagePicker::Ok(picker) => widget::ImagePicker::Ok(picker), + ImagePicker::Error(e) => widget::ImagePicker::Error(e), + } + } +} + #[cfg(test)] mod tests { use crate::{event, set_cells}; @@ -335,6 +347,7 @@ mod tests { #[test] fn test_render_without_scroll() -> std::io::Result<()> { let theme = ColorTheme::default(); + let env = Environment::default(); let (tx, _) = event::new(); let mut terminal = setup_terminal()?; @@ -360,6 +373,7 @@ mod tests { file_path, object_key, preview_config, + env, theme, tx, ); @@ -392,6 +406,7 @@ mod tests { #[test] fn test_render_with_scroll() -> std::io::Result<()> { let theme = ColorTheme::default(); + let env = Environment::default(); let (tx, _) = event::new(); let mut terminal = setup_terminal()?; @@ -412,6 +427,7 @@ mod tests { file_path, object_key, preview_config, + env, theme, tx, ); @@ -444,6 +460,7 @@ mod tests { #[test] fn test_render_save_dialog_without_scroll() -> std::io::Result<()> { let theme = ColorTheme::default(); + let env = Environment::default(); let (tx, _) = event::new(); let mut terminal = setup_terminal()?; @@ -469,6 +486,7 @@ mod tests { file_path, object_key, preview_config, + env, theme, tx, ); diff --git a/src/pages/page.rs b/src/pages/page.rs index 529ff7c..a2ae27d 100644 --- a/src/pages/page.rs +++ b/src/pages/page.rs @@ -3,6 +3,7 @@ use ratatui::{crossterm::event::KeyEvent, layout::Rect, Frame}; use crate::{ color::ColorTheme, config::{PreviewConfig, UiConfig}, + environment::Environment, event::Sender, object::{BucketItem, FileDetail, ObjectItem, ObjectKey, RawObject}, pages::{ @@ -121,6 +122,7 @@ impl Page { path: String, object_key: ObjectKey, preview_config: PreviewConfig, + env: Environment, theme: ColorTheme, tx: Sender, ) -> Self { @@ -131,6 +133,7 @@ impl Page { path, object_key, preview_config, + env, theme, tx, ))) diff --git a/src/widget.rs b/src/widget.rs index 9f44554..5c3af99 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -16,7 +16,7 @@ pub use copy_detail_dialog::{CopyDetailDialog, CopyDetailDialogState}; pub use dialog::Dialog; pub use divider::Divider; pub use header::Header; -pub use image_preview::{ImagePreview, ImagePreviewState}; +pub use image_preview::{ImagePicker, ImagePreview, ImagePreviewState}; pub use input_dialog::{InputDialog, InputDialogState}; pub use scroll::ScrollBar; pub use scroll_lines::{ScrollLines, ScrollLinesOptions, ScrollLinesState}; diff --git a/src/widget/image_preview.rs b/src/widget/image_preview.rs index 2fc2ca6..6017f19 100644 --- a/src/widget/image_preview.rs +++ b/src/widget/image_preview.rs @@ -14,7 +14,7 @@ use ratatui_image::{picker::Picker, protocol::StatefulProtocol, StatefulImage}; use crate::ui::common::format_version; pub struct ImagePreviewState { - protocol: Option>, + protocol: Option, // to control image rendering when dialogs are overlapped... render: bool, } @@ -25,9 +25,15 @@ impl Debug for ImagePreviewState { } } +pub enum ImagePicker { + Disabled, + Ok(Picker), + Error(String), +} + impl ImagePreviewState { - pub fn new(bytes: &[u8], enabled: bool) -> (Self, Option) { - match build_image_protocol(bytes, enabled) { + pub fn new(bytes: &[u8], image_picker: ImagePicker) -> (Self, Option) { + match build_image_protocol(bytes, image_picker) { Ok(protocol) => { let state = ImagePreviewState { protocol: Some(protocol), @@ -50,38 +56,23 @@ impl ImagePreviewState { } } -fn build_image_protocol(bytes: &[u8], enabled: bool) -> Result, String> { - if !enabled { - return Err("Image preview is disabled".to_string()); +fn build_image_protocol( + bytes: &[u8], + image_picker: ImagePicker, +) -> Result { + match image_picker { + ImagePicker::Ok(mut picker) => { + let reader = ImageReader::new(Cursor::new(bytes)) + .with_guessed_format() + .map_err(|e| format!("Failed to guess image format: {e}"))?; + let img: DynamicImage = reader + .decode() + .map_err(|e| format!("Failed to decode image: {e}"))?; + Ok(picker.new_resize_protocol(img)) + } + ImagePicker::Error(e) => Err(format!("Failed to create picker: {e}")), + ImagePicker::Disabled => Err("Image preview is disabled".into()), } - - let reader = ImageReader::new(Cursor::new(bytes)) - .with_guessed_format() - .map_err(|e| format!("Failed to guess image format: {e}"))?; - - let img: DynamicImage = reader - .decode() - .map_err(|e| format!("Failed to decode image: {e}"))?; - - let mut picker = build_picker()?; - Ok(picker.new_resize_protocol(img)) -} - -#[cfg(not(feature = "imggen"))] -fn build_picker() -> Result { - let mut picker = Picker::from_termios().map_err(|e| format!("Failed to create picker: {e}"))?; - picker.guess_protocol(); - Ok(picker) -} - -#[cfg(feature = "imggen")] -fn build_picker() -> Result { - // - font size cannot be obtained with xterm.js - // - want to fix the protocol to iterm2 - // so changed the settings with the imggen feature - let mut picker = Picker::new((10, 20)); - picker.protocol_type = ratatui_image::picker::ProtocolType::Iterm2; - Ok(picker) } #[derive(Debug)]