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_macro::render;
use yazi_shared::event::Cmd;
use crate::{app::App, lives::Lives, tasks::Progress};
use crate::app::App;
pub struct Opt {
progress: TasksProgress,
@ -19,41 +18,28 @@ impl TryFrom<Cmd> for Opt {
impl App {
pub(crate) fn update_progress(&mut self, opt: impl TryInto<Opt>) {
let Ok(opt) = opt.try_into() else {
return;
};
let Ok(opt) = opt.try_into() else { return };
// Update the progress of all tasks.
let tasks = &mut self.cx.tasks;
let progressed = tasks.progress != opt.progress;
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)
{
if tasks.summaries != new {
tasks.summaries = new;
tasks.arrow(0);
return render!();
}
}
// Otherwise, only partially update the progress.
let Some(term) = &mut self.term else {
return;
};
_ = 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(())
});
if !progressed {
} else if tasks.progress.total == 0 {
render!();
} else {
self.render_partially();
}
}
}

View file

@ -1,41 +1,23 @@
use std::mem;
use mlua::{AnyUserData, Table, TableExt};
use mlua::{Table, TableExt};
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
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;
impl Progress {
pub(crate) fn partial_render(
buf: &mut ratatui::buffer::Buffer,
) -> Vec<Vec<(u16, u16, ratatui::buffer::Cell)>> {
let mut patches = vec![];
impl Widget for Progress {
fn render(self, _: Rect, buf: &mut Buffer) {
let mut f = || {
let comp: Table = LUA.globals().raw_get("Progress")?;
for widget in comp.call_method::<_, Vec<AnyUserData>>("partial_redraw", ())? {
let Some(w) = cast_to_renderable(&widget) else { continue };
let area = yazi_plugin::elements::Rect::from(LAYOUT.get().progress);
let progress =
LUA.globals().raw_get::<_, Table>("Progress")?.call_method::<_, Table>("use", area)?;
let area = w.area();
w.render(buf);
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>(())
render_widgets(progress.call_method("redraw", ())?, buf);
Ok::<_, mlua::Error>(())
};
if let Err(e) = f() {
error!("{e}");
error!("Failed to redraw the `Progress` component:\n{e}");
}
patches
}
}