mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: progress of each task (#3121)
Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
parent
b997e56a60
commit
49910fcfe7
5 changed files with 109 additions and 16 deletions
|
|
@ -202,7 +202,7 @@ icon_command = ""
|
|||
[tasks]
|
||||
border = { fg = "blue" }
|
||||
title = {}
|
||||
hovered = { fg = "magenta", underline = true }
|
||||
hovered = { fg = "magenta", bold = true }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ icon_command = ""
|
|||
[tasks]
|
||||
border = { fg = "blue" }
|
||||
title = {}
|
||||
hovered = { fg = "magenta", underline = true }
|
||||
hovered = { fg = "magenta", bold = true }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,8 +54,9 @@ impl Tasks {
|
|||
}
|
||||
|
||||
pub fn limit() -> usize {
|
||||
(Dimension::available().rows * TASKS_PERCENT / 100).saturating_sub(TASKS_BORDER + TASKS_PADDING)
|
||||
as usize
|
||||
((Dimension::available().rows * TASKS_PERCENT / 100)
|
||||
.saturating_sub(TASKS_BORDER + TASKS_PADDING) as usize)
|
||||
/ 3
|
||||
}
|
||||
|
||||
pub fn paginate(&self) -> Vec<TaskSnap> {
|
||||
|
|
|
|||
|
|
@ -2,21 +2,113 @@ Tasks = {
|
|||
_id = "tasks",
|
||||
}
|
||||
|
||||
function Tasks:new(area) return setmetatable({ _area = area }, { __index = self }) end
|
||||
function Tasks:new(area)
|
||||
local me = setmetatable({ _area = area }, { __index = self })
|
||||
me:layout()
|
||||
return me
|
||||
end
|
||||
|
||||
function Tasks:layout()
|
||||
self._area = self._area:pad(ui.Pad(1, 1, 1, 3))
|
||||
self._chunks = ui.Layout()
|
||||
:direction(ui.Layout.HORIZONTAL)
|
||||
:constraints({
|
||||
ui.Constraint.Percentage(60),
|
||||
ui.Constraint.Percentage(40),
|
||||
})
|
||||
:split(self._area)
|
||||
end
|
||||
|
||||
function Tasks:reflow() return { self } end
|
||||
|
||||
function Tasks:redraw()
|
||||
local rows = {}
|
||||
for _, snap in ipairs(cx.tasks.snaps) do
|
||||
rows[#rows + 1] = ui.Row { snap.name }
|
||||
local elements = {}
|
||||
for i, snap in ipairs(cx.tasks.snaps) do
|
||||
local y = self._area.y + (i - 1) * 3
|
||||
if y >= self._area.bottom then
|
||||
break
|
||||
end
|
||||
|
||||
elements[#elements + 1] = ui.Line({ self:icon(snap), snap.name }):area(ui.Rect {
|
||||
x = self._area.x,
|
||||
y = y,
|
||||
w = self._area.w,
|
||||
h = 1,
|
||||
})
|
||||
|
||||
if i == cx.tasks.cursor + 1 then
|
||||
elements[#elements] = elements[#elements]:style(th.tasks.hovered)
|
||||
end
|
||||
|
||||
for _, e in ipairs(self:progress_redraw(snap, y + 1)) do
|
||||
elements[#elements + 1] = e
|
||||
end
|
||||
|
||||
elements[#elements + 1] = ui.Bar(ui.Edge.LEFT)
|
||||
:area(ui.Rect {
|
||||
x = math.max(0, self._area.x - 2),
|
||||
y = y,
|
||||
w = self._area.w,
|
||||
h = 2,
|
||||
})
|
||||
:symbol("┃")
|
||||
|
||||
if i == cx.tasks.cursor + 1 then
|
||||
elements[#elements] = elements[#elements]:style(th.tasks.hovered)
|
||||
end
|
||||
end
|
||||
|
||||
local tbl = ui.Table(rows)
|
||||
:area(self._area:pad(ui.Pad.x(1)))
|
||||
:row(cx.tasks.cursor)
|
||||
:row_style(th.tasks.hovered)
|
||||
:widths { ui.Constraint.Fill(1) }
|
||||
|
||||
return { tbl }
|
||||
return elements
|
||||
end
|
||||
|
||||
function Tasks:icon(snap)
|
||||
if snap.prog.kind == "FilePaste" then
|
||||
return " "
|
||||
elseif snap.prog.kind == "FileDelete" then
|
||||
return " "
|
||||
else
|
||||
return " "
|
||||
end
|
||||
end
|
||||
|
||||
function Tasks:progress_redraw(snap, y)
|
||||
local kind = snap.prog.kind
|
||||
if kind == "FilePaste" or kind == "FileDelete" then
|
||||
local label = string.format(
|
||||
"%3d%% - %s / %s",
|
||||
math.floor(snap.percent),
|
||||
ya.readable_size(snap.prog.processed_bytes),
|
||||
ya.readable_size(snap.prog.total_bytes)
|
||||
)
|
||||
|
||||
local style = th.status.progress_normal
|
||||
if snap.prog.failed_files > 0 then
|
||||
style = th.status.progress_error
|
||||
end
|
||||
|
||||
return {
|
||||
ui.Gauge()
|
||||
:area(ui.Rect { x = self._chunks[1].x, y = y, w = self._chunks[1].w, h = 1 })
|
||||
:percent(snap.percent)
|
||||
:label(ui.Span(label):style(th.status.progress_label))
|
||||
:gauge_style(style),
|
||||
|
||||
ui.Line(string.format("%d/%d", snap.prog.success_files, snap.prog.total_files))
|
||||
:fg("gray")
|
||||
:area(ui.Rect { x = self._chunks[2].x, y = y, w = self._chunks[2].w, h = 1 })
|
||||
:align(ui.Align.RIGHT),
|
||||
}
|
||||
else
|
||||
local text
|
||||
if snap.running then
|
||||
text = "Running…"
|
||||
elseif snap.success then
|
||||
text = "Completing…"
|
||||
else
|
||||
text = "Failed, press Enter to view log…"
|
||||
end
|
||||
return {
|
||||
ui.Line(text):fg("gray"):area(ui.Rect { x = self._chunks[1].x, y = y, w = self._chunks[1].w, h = 1 }),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ mod tests {
|
|||
|
||||
for (path, expected) in cases {
|
||||
let path: UrlBuf = path.parse()?;
|
||||
assert_eq!(path.parent().map(|u| format!("{:?}", u)).as_deref(), expected);
|
||||
assert_eq!(path.parent().map(|u| format!("{u:?}")).as_deref(), expected);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue