Files
community-plugins/nextboot-selector/panel.luau
T

149 lines
3.1 KiB
Luau

function tr(key)
return noctalia.tr(key)
end
function cfg(key)
return noctalia.getConfig(key)
end
local excludedKeywords = cfg("excluded_keywords")
local privilegeCmd = cfg("privilege_command")
local closeOnSelect = cfg("close_on_select")
local rebootOnSelect = cfg("reboot_on_select")
local rebootCmd = cfg("reboot_command")
function parseEntries(output)
local entries = {}
local bootNext = output:match("BootNext:%s*(%x+)")
local bootCurrent = output:match("BootCurrent:%s*(%x+)")
local selectedId = bootNext or bootCurrent
if selectedId then
selectedId = selectedId:upper()
end
for line in output:gmatch("[^\r\n]+") do
local id, active, name = line:match("^Boot(%x%x%x%x)(%*?)%s+([^\t]+)")
if id then
id = id:upper()
table.insert(entries, {
id = id,
name = name,
isActive = active == "*",
isSelected = selectedId ~= nil and id == selectedId,
})
end
end
return entries
end
function excludeEntries(entries, keywords)
local filtered = {}
for _, entry in ipairs(entries) do
local haystack = entry.name:lower()
local excluded = false
for _, word in ipairs(keywords) do
if haystack:find(word:lower(), 1, true) then
excluded = true
break
end
end
if not excluded then
table.insert(filtered, entry)
end
end
return filtered
end
function resetBootNext()
noctalia.runAsync(`{privilegeCmd} efibootmgr --delete-bootnext`, function(result)
load()
end, 5000)
end
function render(entries)
local entriesButton = {}
for _, entry in ipairs(entries) do
local bootEntry = entry
local callBackFn = function()
noctalia.runAsync(`{privilegeCmd} efibootmgr --bootnext {bootEntry.id}`, function(result)
if not result.timedOut then
if result.exitCode == 0 then
load()
if rebootOnSelect then
noctalia.runAsync(rebootCmd)
end
if closeOnSelect then
panel.close()
end
else
noctalia.notify(tr("notification.failed_to_set_next_boot"), result.stderr)
end
else
noctalia.notify(tr("notification.failed_to_set_next_boot"), tr("notification.timed_out"))
end
end, 60 * 1000)
end
table.insert(
entriesButton,
ui.button({
text = bootEntry.name,
selected = bootEntry.isSelected,
enabled = bootEntry.isActive,
onClick = callBackFn,
contentAlign = "start",
glyph = if bootEntry.isSelected then "circle-check" else "circle",
glyphSize = 18,
})
)
end
panel.render(ui.column({
flexGrow = 1,
}, {
ui.row({
justify = "space_between",
align = "center"
}, {
ui.label({
text = tr("panel.title"),
fontSize = 16
}),
ui.button({
text = tr("panel.reset"),
glyph = "reload",
variant = "ghost",
controlSize = "sm",
onClick = "resetBootNext"
})
}),
ui.separator({
thickness = 2,
orientation = "horizontal",
spacing = 8,
}),
ui.scroll({
flexGrow = 1,
gap = 8,
}, entriesButton),
}))
end
function load()
noctalia.runAsync("efibootmgr", function(result)
if result.exitCode == 0 then
local entries = parseEntries(result.stdout)
render(excludeEntries(entries, excludedKeywords))
end
end, 5000)
end
function onOpen()
load()
end