This commit is contained in:
sxyazi 2024-11-01 19:48:10 +08:00
parent 067fe71429
commit 4b029018c6
No known key found for this signature in database
2 changed files with 22 additions and 54 deletions

View file

@ -1,9 +1,8 @@
use ratatui::backend::Backend;
use yazi_core::tasks::TasksProgress; use yazi_core::tasks::TasksProgress;
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::Cmd; use yazi_shared::event::Cmd;
use crate::{app::App, lives::Lives, tasks::Progress}; use crate::app::App;
pub struct Opt { pub struct Opt {
progress: TasksProgress, progress: TasksProgress,
@ -19,41 +18,28 @@ impl TryFrom<Cmd> for Opt {
impl App { impl App {
pub(crate) fn update_progress(&mut self, opt: impl TryInto<Opt>) { pub(crate) fn update_progress(&mut self, opt: impl TryInto<Opt>) {
let Ok(opt) = opt.try_into() else { let Ok(opt) = opt.try_into() else { return };
return;
};
// Update the progress of all tasks. // Update the progress of all tasks.
let tasks = &mut self.cx.tasks; let tasks = &mut self.cx.tasks;
let progressed = tasks.progress != opt.progress;
tasks.progress = opt.progress; tasks.progress = opt.progress;
// If the task manager is visible, update the summaries with a complete render. // If the task manager is visible, update the summaries with a complete render.
if tasks.visible { if tasks.visible {
let new = tasks.paginate(); let new = tasks.paginate();
if new.len() != tasks.summaries.len() if tasks.summaries != new {
|| new.iter().zip(&tasks.summaries).any(|(a, b)| a.name != b.name)
{
tasks.summaries = new; tasks.summaries = new;
tasks.arrow(0); tasks.arrow(0);
return render!(); return render!();
} }
} }
// Otherwise, only partially update the progress. if !progressed {
let Some(term) = &mut self.term else { } else if tasks.progress.total == 0 {
return; render!();
}; } else {
self.render_partially();
_ = Lives::scope(&self.cx, |_| { }
for patch in Progress::partial_render(term.current_buffer_mut()) {
term.backend_mut().draw(patch.iter().map(|(x, y, cell)| (*x, *y, cell)))?;
if let Some(pos) = self.cx.cursor() {
term.show_cursor()?;
term.set_cursor_position(pos)?;
}
term.backend_mut().flush()?;
}
Ok(())
});
} }
} }

View file

@ -1,41 +1,23 @@
use std::mem; use mlua::{Table, TableExt};
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
use mlua::{AnyUserData, Table, TableExt};
use tracing::error; use tracing::error;
use yazi_plugin::{LUA, cast_to_renderable}; use yazi_config::LAYOUT;
use yazi_plugin::{LUA, elements::render_widgets};
pub(crate) struct Progress; pub(crate) struct Progress;
impl Progress { impl Widget for Progress {
pub(crate) fn partial_render( fn render(self, _: Rect, buf: &mut Buffer) {
buf: &mut ratatui::buffer::Buffer,
) -> Vec<Vec<(u16, u16, ratatui::buffer::Cell)>> {
let mut patches = vec![];
let mut f = || { let mut f = || {
let comp: Table = LUA.globals().raw_get("Progress")?; let area = yazi_plugin::elements::Rect::from(LAYOUT.get().progress);
for widget in comp.call_method::<_, Vec<AnyUserData>>("partial_redraw", ())? { let progress =
let Some(w) = cast_to_renderable(&widget) else { continue }; LUA.globals().raw_get::<_, Table>("Progress")?.call_method::<_, Table>("use", area)?;
let area = w.area(); render_widgets(progress.call_method("redraw", ())?, buf);
w.render(buf); Ok::<_, mlua::Error>(())
let mut patch = Vec::with_capacity(area.width as usize * area.height as usize);
for y in area.top()..area.bottom() {
for x in area.left()..area.right() {
patch.push((x, y, mem::take(&mut buf[(x, y)])));
}
}
buf.reset();
patches.push(patch);
}
Ok::<_, anyhow::Error>(())
}; };
if let Err(e) = f() { if let Err(e) = f() {
error!("{e}"); error!("Failed to redraw the `Progress` component:\n{e}");
} }
patches
} }
} }