From d754044aae037ffb30085497c383a03deae5795e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Tue, 6 Feb 2024 08:35:50 +0800 Subject: [PATCH] fix: task manager not re-rendering after progress update (#633) --- yazi-adaptor/src/kitty.rs | 2 +- yazi-adaptor/src/kitty_old.rs | 2 +- yazi-config/preset/yazi.toml | 8 ++--- yazi-config/src/theme/filetype.rs | 2 +- yazi-config/src/theme/icon.rs | 2 +- yazi-core/src/input/snap.rs | 4 +-- yazi-core/src/tasks/commands/arrow.rs | 33 ++++++++------------- yazi-core/src/tasks/commands/toggle.rs | 6 ++++ yazi-core/src/tasks/mod.rs | 1 + yazi-core/src/tasks/tasks.rs | 12 ++++---- yazi-fm/src/app/commands/update_progress.rs | 20 +++++++++++-- yazi-fm/src/completion/completion.rs | 4 +-- yazi-fm/src/help/bindings.rs | 12 ++++---- yazi-fm/src/select/select.rs | 4 +-- yazi-fm/src/tasks/layout.rs | 3 +- yazi-fm/src/widgets/clear.rs | 4 +-- 16 files changed, 68 insertions(+), 51 deletions(-) diff --git a/yazi-adaptor/src/kitty.rs b/yazi-adaptor/src/kitty.rs index 5462a635..07579528 100644 --- a/yazi-adaptor/src/kitty.rs +++ b/yazi-adaptor/src/kitty.rs @@ -357,7 +357,7 @@ impl Kitty { async fn encode(img: DynamicImage) -> Result> { fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result> { - let b64 = general_purpose::STANDARD.encode(raw).chars().collect::>(); + let b64: Vec<_> = general_purpose::STANDARD.encode(raw).chars().collect(); let mut it = b64.chunks(4096).peekable(); let mut buf = Vec::with_capacity(b64.len() + it.len() * 50); diff --git a/yazi-adaptor/src/kitty_old.rs b/yazi-adaptor/src/kitty_old.rs index b44d4c59..3c422277 100644 --- a/yazi-adaptor/src/kitty_old.rs +++ b/yazi-adaptor/src/kitty_old.rs @@ -35,7 +35,7 @@ impl KittyOld { async fn encode(img: DynamicImage) -> Result> { fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result> { - let b64 = general_purpose::STANDARD.encode(raw).chars().collect::>(); + let b64: Vec<_> = general_purpose::STANDARD.encode(raw).chars().collect(); let mut it = b64.chunks(4096).peekable(); let mut buf = Vec::with_capacity(b64.len() + it.len() * 50); diff --git a/yazi-config/preset/yazi.toml b/yazi-config/preset/yazi.toml index 5ff959be..789263cc 100644 --- a/yazi-config/preset/yazi.toml +++ b/yazi-config/preset/yazi.toml @@ -4,10 +4,10 @@ [manager] ratio = [ 1, 4, 3 ] -sort_by = "modified" -sort_sensitive = true -sort_reverse = true -sort_dir_first = true +sort_by = "alphabetical" +sort_sensitive = false +sort_reverse = false +sort_dir_first = false linemode = "none" show_hidden = false show_symlink = true diff --git a/yazi-config/src/theme/filetype.rs b/yazi-config/src/theme/filetype.rs index f6bfd8ee..94ffbed0 100644 --- a/yazi-config/src/theme/filetype.rs +++ b/yazi-config/src/theme/filetype.rs @@ -97,7 +97,7 @@ impl Filetype { } .into(), }) - .collect::>(), + .collect(), ) } } diff --git a/yazi-config/src/theme/icon.rs b/yazi-config/src/theme/icon.rs index 17c5a99d..3898334b 100644 --- a/yazi-config/src/theme/icon.rs +++ b/yazi-config/src/theme/icon.rs @@ -35,7 +35,7 @@ impl Icon { text: r.text, style: StyleShadow { fg: r.fg, ..Default::default() }.into(), }) - .collect::>(), + .collect(), ) } } diff --git a/yazi-core/src/input/snap.rs b/yazi-core/src/input/snap.rs index 59d405b9..e6f98232 100644 --- a/yazi-core/src/input/snap.rs +++ b/yazi-core/src/input/snap.rs @@ -72,7 +72,7 @@ impl InputSnap { #[inline] pub(super) fn find_window(s: &str, offset: usize, limit: usize) -> Range { let mut width = 0; - let v = s + let v: Vec<_> = s .chars() .enumerate() .skip(offset) @@ -80,7 +80,7 @@ impl InputSnap { width += c.width().unwrap_or(0); if width < limit { Some(i) } else { None } }) - .collect::>(); + .collect(); if v.is_empty() { return 0..0; diff --git a/yazi-core/src/tasks/commands/arrow.rs b/yazi-core/src/tasks/commands/arrow.rs index 763c7e43..9b68c9fe 100644 --- a/yazi-core/src/tasks/commands/arrow.rs +++ b/yazi-core/src/tasks/commands/arrow.rs @@ -12,30 +12,21 @@ impl From for Opt { } } +impl From for Opt { + fn from(step: isize) -> Self { Self { step } } +} + impl Tasks { - #[allow(clippy::should_implement_trait)] - fn next(&mut self) { - let limit = Self::limit().min(self.len()); - - let old = self.cursor; - self.cursor = limit.saturating_sub(1).min(self.cursor + 1); - - render!(old != self.cursor); - } - - fn prev(&mut self) { - let old = self.cursor; - self.cursor = self.cursor.saturating_sub(1); - - render!(old != self.cursor); - } - pub fn arrow(&mut self, opt: impl Into) { - let opt = opt.into() as Opt; - if opt.step > 0 { - self.next(); + let old = self.cursor; + if opt.into().step > 0 { + self.cursor += 1; } else { - self.prev(); + self.cursor = self.cursor.saturating_sub(1); } + + let max = Self::limit().min(self.summaries.len()); + self.cursor = self.cursor.min(max.saturating_sub(1)); + render!(self.cursor != old); } } diff --git a/yazi-core/src/tasks/commands/toggle.rs b/yazi-core/src/tasks/commands/toggle.rs index 88a89fcc..1ffc9a56 100644 --- a/yazi-core/src/tasks/commands/toggle.rs +++ b/yazi-core/src/tasks/commands/toggle.rs @@ -14,6 +14,12 @@ impl From<()> for Opt { impl Tasks { pub fn toggle(&mut self, _: impl Into) { self.visible = !self.visible; + + if self.visible { + self.summaries = self.paginate(); + self.arrow(0); + } + render!(); } } diff --git a/yazi-core/src/tasks/mod.rs b/yazi-core/src/tasks/mod.rs index 32ea75be..d8475836 100644 --- a/yazi-core/src/tasks/mod.rs +++ b/yazi-core/src/tasks/mod.rs @@ -5,5 +5,6 @@ mod tasks; pub use progress::*; pub use tasks::*; +pub const TASKS_BORDER: u16 = 2; pub const TASKS_PADDING: u16 = 2; pub const TASKS_PERCENT: u16 = 80; diff --git a/yazi-core/src/tasks/tasks.rs b/yazi-core/src/tasks/tasks.rs index 4d71677b..7ae426d3 100644 --- a/yazi-core/src/tasks/tasks.rs +++ b/yazi-core/src/tasks/tasks.rs @@ -7,15 +7,16 @@ use yazi_plugin::ValueSendable; use yazi_scheduler::{Scheduler, TaskSummary}; use yazi_shared::{emit, event::Cmd, fs::{File, Url}, term::Term, Layer, MIME_DIR}; -use super::{TasksProgress, TASKS_PADDING, TASKS_PERCENT}; +use super::{TasksProgress, TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT}; use crate::{folder::Files, input::Input}; pub struct Tasks { pub(super) scheduler: Arc, - pub visible: bool, - pub cursor: usize, - pub progress: TasksProgress, + pub visible: bool, + pub cursor: usize, + pub progress: TasksProgress, + pub summaries: Vec, } impl Tasks { @@ -25,6 +26,7 @@ impl Tasks { visible: false, cursor: 0, progress: Default::default(), + summaries: Default::default(), }; let running = tasks.scheduler.running.clone(); @@ -46,7 +48,7 @@ impl Tasks { #[inline] pub fn limit() -> usize { - (Term::size().rows * TASKS_PERCENT / 100).saturating_sub(TASKS_PADDING) as usize + (Term::size().rows * TASKS_PERCENT / 100).saturating_sub(TASKS_BORDER + TASKS_PADDING) as usize } pub fn paginate(&self) -> Vec { diff --git a/yazi-fm/src/app/commands/update_progress.rs b/yazi-fm/src/app/commands/update_progress.rs index d6a57fe4..2ab49a79 100644 --- a/yazi-fm/src/app/commands/update_progress.rs +++ b/yazi-fm/src/app/commands/update_progress.rs @@ -1,6 +1,6 @@ use ratatui::backend::Backend; use yazi_core::tasks::TasksProgress; -use yazi_shared::event::Cmd; +use yazi_shared::{event::Cmd, render}; use crate::{app::App, components::Progress, lives::Lives}; @@ -22,7 +22,23 @@ impl App { return; }; - self.cx.tasks.progress = opt.progress; + // Update the progress of all tasks. + let tasks = &mut self.cx.tasks; + tasks.progress = opt.progress; + + // If the task manager is visible, update the summaries with a complete render. + if tasks.visible { + let new = tasks.paginate(); + if new.len() != tasks.summaries.len() + || new.iter().zip(&tasks.summaries).any(|(a, b)| a.name != b.name) + { + tasks.summaries = new; + tasks.arrow(0); + return render!(); + } + } + + // Otherwise, only partially update the progress. let Some(term) = &mut self.term else { return; }; diff --git a/yazi-fm/src/completion/completion.rs b/yazi-fm/src/completion/completion.rs index 7a7b16e6..05936da1 100644 --- a/yazi-fm/src/completion/completion.rs +++ b/yazi-fm/src/completion/completion.rs @@ -15,7 +15,7 @@ impl<'a> Completion<'a> { impl<'a> Widget for Completion<'a> { fn render(self, rect: Rect, buf: &mut Buffer) { - let items = self + let items: Vec<_> = self .cx .completion .window() @@ -37,7 +37,7 @@ impl<'a> Widget for Completion<'a> { item }) - .collect::>(); + .collect(); let input_area = self.cx.area(&self.cx.input.position); let mut area = Position::sticky(input_area, Offset { diff --git a/yazi-fm/src/help/bindings.rs b/yazi-fm/src/help/bindings.rs index 82121020..431aa4b8 100644 --- a/yazi-fm/src/help/bindings.rs +++ b/yazi-fm/src/help/bindings.rs @@ -19,18 +19,18 @@ impl Widget for Bindings<'_> { } // On - let col1 = - bindings.iter().map(|c| ListItem::new(c.on()).style(THEME.help.on)).collect::>(); + let col1: Vec<_> = + bindings.iter().map(|c| ListItem::new(c.on()).style(THEME.help.on)).collect(); // Exec - let col2 = - bindings.iter().map(|c| ListItem::new(c.exec()).style(THEME.help.exec)).collect::>(); + let col2: Vec<_> = + bindings.iter().map(|c| ListItem::new(c.exec()).style(THEME.help.exec)).collect(); // Desc - let col3 = bindings + let col3: Vec<_> = bindings .iter() .map(|c| ListItem::new(c.desc.as_deref().unwrap_or("-")).style(THEME.help.desc)) - .collect::>(); + .collect(); let chunks = layout::Layout::horizontal([ Constraint::Ratio(2, 10), diff --git a/yazi-fm/src/select/select.rs b/yazi-fm/src/select/select.rs index 5a09f228..52eed6e3 100644 --- a/yazi-fm/src/select/select.rs +++ b/yazi-fm/src/select/select.rs @@ -16,7 +16,7 @@ impl<'a> Widget for Select<'a> { let select = &self.cx.select; let area = self.cx.area(&select.position); - let items = select + let items: Vec<_> = select .window() .iter() .enumerate() @@ -27,7 +27,7 @@ impl<'a> Widget for Select<'a> { ListItem::new(format!(" {v}")).style(THEME.select.active) }) - .collect::>(); + .collect(); widgets::Clear.render(area, buf); List::new(items) diff --git a/yazi-fm/src/tasks/layout.rs b/yazi-fm/src/tasks/layout.rs index 84b2613c..ac1cf6ab 100644 --- a/yazi-fm/src/tasks/layout.rs +++ b/yazi-fm/src/tasks/layout.rs @@ -43,8 +43,9 @@ impl<'a> Widget for Layout<'a> { let tasks = &self.cx.tasks; let items = tasks - .paginate() + .summaries .iter() + .take(area.height.saturating_sub(2) as usize) .enumerate() .map(|(i, v)| { let mut item = ListItem::new(v.name.clone()); diff --git a/yazi-fm/src/widgets/clear.rs b/yazi-fm/src/widgets/clear.rs index ec4ed5c7..bf6532ee 100644 --- a/yazi-fm/src/widgets/clear.rs +++ b/yazi-fm/src/widgets/clear.rs @@ -34,8 +34,8 @@ impl Widget for Clear { ADAPTOR.image_erase(r).ok(); COLLISION.store(true, Ordering::Relaxed); - for x in r.left()..r.right() { - for y in r.top()..r.bottom() { + for x in area.left()..area.right() { + for y in area.top()..area.bottom() { buf.get_mut(x, y).set_skip(true); } }