mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
added feature for multiple selection of folders, showing their size sum on top of the info of the shown folder
This commit is contained in:
parent
46ddb10a7a
commit
c24e42cf6f
2 changed files with 59 additions and 17 deletions
|
|
@ -51,8 +51,33 @@ end
|
||||||
|
|
||||||
function M:spot(job)
|
function M:spot(job)
|
||||||
self.size, self.last = 0, 0
|
self.size, self.last = 0, 0
|
||||||
|
self.selected_size = 0
|
||||||
|
self.folder_count = 0
|
||||||
|
|
||||||
|
-- Calculate selected folders sizes first if multiple are selected
|
||||||
|
if job.selected and #job.selected > 1 then
|
||||||
|
for _, file in ipairs(job.selected) do
|
||||||
|
local cha = fs.cha(file)
|
||||||
|
if cha and cha.is_dir then
|
||||||
|
local size = 0
|
||||||
|
local it = fs.calc_size(file)
|
||||||
|
while true do
|
||||||
|
local next = it:recv()
|
||||||
|
if next then
|
||||||
|
size = size + next
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.selected_size = self.selected_size + size
|
||||||
|
self.folder_count = self.folder_count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
self:spot_multi(job, false)
|
self:spot_multi(job, false)
|
||||||
|
|
||||||
|
-- Calculate current folder size
|
||||||
local url = job.file.url
|
local url = job.file.url
|
||||||
local it = fs.calc_size(url)
|
local it = fs.calc_size(url)
|
||||||
while true do
|
while true do
|
||||||
|
|
@ -77,11 +102,18 @@ function M:spot_multi(job, comp)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local rows = {
|
local rows = {}
|
||||||
ui.Row({ "Folder" }):style(ui.Style():fg("green")),
|
|
||||||
ui.Row { " Size:", ya.readable_size(self.size) .. (comp and "" or " (?)") },
|
-- Show selected folders sum if multiple are selected
|
||||||
ui.Row {},
|
if self.folder_count > 1 then
|
||||||
}
|
rows[#rows + 1] = ui.Row({ string.format("# Folders (%d)", self.folder_count) }):style(ui.Style():fg("green"))
|
||||||
|
rows[#rows + 1] = ui.Row { " Size:", ya.readable_size(self.selected_size) }
|
||||||
|
rows[#rows + 1] = ui.Row {}
|
||||||
|
end
|
||||||
|
|
||||||
|
rows[#rows + 1] = ui.Row({ "Folder" }):style(ui.Style():fg("green"))
|
||||||
|
rows[#rows + 1] = ui.Row { " Size:", ya.readable_size(self.size) .. (comp and "" or " (?)") }
|
||||||
|
rows[#rows + 1] = ui.Row {}
|
||||||
|
|
||||||
ya.spot_table(
|
ya.spot_table(
|
||||||
job,
|
job,
|
||||||
|
|
|
||||||
|
|
@ -102,22 +102,32 @@ end
|
||||||
|
|
||||||
function M:spot_base(job)
|
function M:spot_base(job)
|
||||||
local rows = {}
|
local rows = {}
|
||||||
|
|
||||||
-- Check if there are multiple selected files
|
-- Check if there are multiple selected files
|
||||||
if job.selected and #job.selected > 1 then
|
if job.selected and #job.selected > 1 then
|
||||||
-- Multi-file selection: show sum at the top
|
-- Multi-file selection: show sum at the top
|
||||||
local total_dur = 0
|
local total_dur = 0
|
||||||
local video_count = 0
|
local video_count = 0
|
||||||
|
|
||||||
-- Start all ffprobe commands concurrently
|
-- Start all ffprobe commands concurrently
|
||||||
local commands = {}
|
local commands = {}
|
||||||
for i, file in ipairs(job.selected) do
|
for i, file in ipairs(job.selected) do
|
||||||
commands[i] = Command("ffprobe")
|
commands[i] = Command("ffprobe")
|
||||||
:arg { "-v", "quiet", "-select_streams", "v", "-show_entries", "format=duration", "-of", "json=c=1", tostring(file.path) }
|
:arg({
|
||||||
|
"-v",
|
||||||
|
"quiet",
|
||||||
|
"-select_streams",
|
||||||
|
"v",
|
||||||
|
"-show_entries",
|
||||||
|
"format=duration",
|
||||||
|
"-of",
|
||||||
|
"json=c=1",
|
||||||
|
tostring(file.path),
|
||||||
|
})
|
||||||
:stdout(Command.PIPED)
|
:stdout(Command.PIPED)
|
||||||
:spawn()
|
:spawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Collect results
|
-- Collect results
|
||||||
for i, child in ipairs(commands) do
|
for i, child in ipairs(commands) do
|
||||||
local output, err = child:wait_with_output()
|
local output, err = child:wait_with_output()
|
||||||
|
|
@ -129,43 +139,43 @@ function M:spot_base(job)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Format total duration
|
-- Format total duration
|
||||||
local hours = math.floor(total_dur / 3600)
|
local hours = math.floor(total_dur / 3600)
|
||||||
local mins = math.floor((total_dur % 3600) / 60)
|
local mins = math.floor((total_dur % 3600) / 60)
|
||||||
local secs = math.floor(total_dur % 60)
|
local secs = math.floor(total_dur % 60)
|
||||||
|
|
||||||
local duration_str
|
local duration_str
|
||||||
if hours > 0 then
|
if hours > 0 then
|
||||||
duration_str = string.format("%d:%02d:%02d", hours, mins, secs)
|
duration_str = string.format("%d:%02d:%02d", hours, mins, secs)
|
||||||
else
|
else
|
||||||
duration_str = string.format("%d:%02d", mins, secs)
|
duration_str = string.format("%d:%02d", mins, secs)
|
||||||
end
|
end
|
||||||
|
|
||||||
rows[#rows + 1] = ui.Row({ string.format("# Videos (%d)", video_count) }):style(ui.Style():fg("green"))
|
rows[#rows + 1] = ui.Row({ string.format("# Videos (%d)", video_count) }):style(ui.Style():fg("green"))
|
||||||
rows[#rows + 1] = ui.Row { " Duration:", duration_str }
|
rows[#rows + 1] = ui.Row { " Duration:", duration_str }
|
||||||
rows[#rows + 1] = ui.Row {} -- Empty row separator
|
rows[#rows + 1] = ui.Row {} -- Empty row separator
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Show detailed info for the current hovered file
|
-- Show detailed info for the current hovered file
|
||||||
local meta, err = self.list_meta(job.file.path, "format=duration:stream=codec_name,codec_type,width,height")
|
local meta, err = self.list_meta(job.file.path, "format=duration:stream=codec_name,codec_type,width,height")
|
||||||
if not meta then
|
if not meta then
|
||||||
ya.err(tostring(err))
|
ya.err(tostring(err))
|
||||||
return rows -- Return at least the selection info if available
|
return rows -- Return at least the selection info if available
|
||||||
end
|
end
|
||||||
|
|
||||||
local dur = meta.format.duration or 0
|
local dur = meta.format.duration or 0
|
||||||
local hours = math.floor(dur / 3600)
|
local hours = math.floor(dur / 3600)
|
||||||
local mins = math.floor((dur % 3600) / 60)
|
local mins = math.floor((dur % 3600) / 60)
|
||||||
local secs = math.floor(dur % 60)
|
local secs = math.floor(dur % 60)
|
||||||
|
|
||||||
local duration_str
|
local duration_str
|
||||||
if hours > 0 then
|
if hours > 0 then
|
||||||
duration_str = string.format("%d:%02d:%02d", hours, mins, secs)
|
duration_str = string.format("%d:%02d:%02d", hours, mins, secs)
|
||||||
else
|
else
|
||||||
duration_str = string.format("%d:%02d", mins, secs)
|
duration_str = string.format("%d:%02d", mins, secs)
|
||||||
end
|
end
|
||||||
|
|
||||||
rows[#rows + 1] = ui.Row({ "Video" }):style(ui.Style():fg("green"))
|
rows[#rows + 1] = ui.Row({ "Video" }):style(ui.Style():fg("green"))
|
||||||
rows[#rows + 1] = ui.Row { " Duration:", duration_str }
|
rows[#rows + 1] = ui.Row { " Duration:", duration_str }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue