feat(w-engine): Add favorite section (#270)
* feat!: add favorite section * fix: change visual for 1 scroll: wallpaper and favorite wallpaper * feat!: update for v1.2.0 * fix: rm line downgrade quality * fix: add downgrade quality for improve storage cache * feat!: update thumbnail * feat!: add favorites list in data.json * feat!: add save favorites list across start plugin
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
id = "tadomika_ari/w-engine"
|
||||
name = "W Engine"
|
||||
version = "1.1.1"
|
||||
version = "1.2.0"
|
||||
# Tile and control callbacks are Luau closures rather than named globals, which
|
||||
# the host resolves from plugin API 9 onwards.
|
||||
plugin_api = 9
|
||||
|
||||
+3
-1
@@ -27,6 +27,7 @@ local data = {
|
||||
saved_wallpaper = {}, -- output -> the Noctalia wallpaper from before we took over
|
||||
options = {}, -- id -> { engine = {...}, properties = {...} }, see buildLaunchArgs
|
||||
defaults = {}, -- { engine = {...} } applied to every wallpaper, see optionsFor
|
||||
favorites = {}, -- favorites wallpapers list
|
||||
}
|
||||
|
||||
-- linux-wallpaperengine switches that take no value. Stored as booleans; the
|
||||
@@ -103,6 +104,7 @@ local function loadData()
|
||||
data.saved_wallpaper = asTable(decoded.saved_wallpaper)
|
||||
data.options = asTable(decoded.options)
|
||||
data.defaults = asTable(decoded.defaults)
|
||||
data.favorites = asTable(decoded.favorites)
|
||||
end
|
||||
|
||||
local function saveData()
|
||||
@@ -233,7 +235,7 @@ local function resolveColorSource(id, callback)
|
||||
-- names contain spaces and non-ASCII, so paths are quoted.
|
||||
local cmd = "ffmpeg -y -loglevel error -ss 1 -i "
|
||||
.. shellQuote(dir .. file)
|
||||
.. " -frames:v 1 -vf scale=960:-2 "
|
||||
.. " -frames:v 1 -vf scale=960:-2"
|
||||
.. shellQuote(frame)
|
||||
noctalia.runAsync(cmd, function(result)
|
||||
-- A wallpaper shorter than the seek offset produces no output and no error,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 56 KiB |
@@ -1170,12 +1170,83 @@ local function tilePreview(item, isSelected, isCurrent)
|
||||
})
|
||||
end
|
||||
|
||||
-- Favorite list
|
||||
|
||||
local FavoriteList = {}
|
||||
|
||||
local function getDataPath()
|
||||
return noctalia.pluginDataDir() .. "/data.json"
|
||||
end
|
||||
|
||||
local function loadData()
|
||||
local raw = noctalia.readFile(getDataPath())
|
||||
if not raw then
|
||||
return {}
|
||||
end
|
||||
local ok, decoded = pcall(function()
|
||||
return noctalia.json.decode(raw)
|
||||
end)
|
||||
if not ok or type(decoded) ~= "table" then
|
||||
return {}
|
||||
end
|
||||
return decoded
|
||||
end
|
||||
|
||||
local function saveData(data)
|
||||
return noctalia.writeFile(getDataPath(), noctalia.json.encode(data))
|
||||
end
|
||||
|
||||
local function loadFavoriteList()
|
||||
local data = loadData()
|
||||
FavoriteList = data.favorites or {}
|
||||
end
|
||||
|
||||
local function persistFavoriteList()
|
||||
local data = loadData() -- récupère les autres clés existantes (ex: settingsPath)
|
||||
data.favorites = FavoriteList
|
||||
saveData(data)
|
||||
end
|
||||
|
||||
local function addFavoriteList(item)
|
||||
noctalia.notify("Add Favorite")
|
||||
table.insert(FavoriteList, item)
|
||||
persistFavoriteList()
|
||||
end
|
||||
|
||||
local function removeFavoriteList(item, nb)
|
||||
noctalia.notify("Remove Favorite")
|
||||
table.remove(FavoriteList, nb)
|
||||
persistFavoriteList()
|
||||
end
|
||||
|
||||
local function checkInFavoriteList(item)
|
||||
local nb = 1
|
||||
for _, entryName in ipairs(FavoriteList) do
|
||||
if entryName.name == item.name then
|
||||
removeFavoriteList(item, nb)
|
||||
return
|
||||
end
|
||||
nb = nb + 1
|
||||
end
|
||||
addFavoriteList(item)
|
||||
end
|
||||
|
||||
local function tileCaption(item, index, isSelected)
|
||||
-- Numbered to show rotation order.
|
||||
local caption = isSelected and (tostring(index) .. ". " .. item.name) or item.name
|
||||
|
||||
-- A fixed label width keeps every tile the same size; long titles truncate.
|
||||
return ui.row({ gap = 2, align = "center" }, {
|
||||
ui.button({
|
||||
glyph = "star",
|
||||
variant = "ghost",
|
||||
controlSize = "sm",
|
||||
tooltip = "Add at your favorite wallpaper",
|
||||
onClick = function()
|
||||
checkInFavoriteList(item)
|
||||
render()
|
||||
end
|
||||
}),
|
||||
ui.label({
|
||||
text = caption,
|
||||
fontSize = 11,
|
||||
@@ -1239,15 +1310,45 @@ render = function()
|
||||
if #catalog == 0 then
|
||||
table.insert(body, ui.label({ text = tr("panel.no_wallpapers"), fontSize = 12, color = "on_surface_variant" }))
|
||||
end
|
||||
-- paddingRight keeps the last column clear of the scrollbar.
|
||||
table.insert(
|
||||
body,
|
||||
ui.scroll({ key = "grid-scroll", gap = 12, paddingRight = 8, align = "stretch", flexGrow = 1 }, rows)
|
||||
)
|
||||
|
||||
local favoriteRows = {}
|
||||
local favoriteRow = {}
|
||||
for index, item in ipairs(FavoriteList) do
|
||||
table.insert(favoriteRow, tile(item, state))
|
||||
if #favoriteRow == columns or index == #FavoriteList then
|
||||
table.insert(favoriteRows, ui.row({ gap = 12, align = "start" }, favoriteRow))
|
||||
favoriteRow = {}
|
||||
end
|
||||
end
|
||||
|
||||
-- Single scroll for all list (Wallpaper and Favorite Wallpaper)
|
||||
local scrollContent = {}
|
||||
table.insert(scrollContent, ui.label({ text = "Favorites", fontSize = 13, fontWeight = "bold", color = "on_surface" }))
|
||||
if #FavoriteList == 0 then
|
||||
table.insert(scrollContent, ui.label({ text = "No favorite", fontSize = 12, color = "on_surface_variant" }))
|
||||
else
|
||||
for _, r in ipairs(favoriteRows) do
|
||||
table.insert(scrollContent, r)
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(scrollContent,
|
||||
ui.separator({ spacing = 12 }
|
||||
))
|
||||
|
||||
table.insert(scrollContent,
|
||||
ui.label({ text = "All wallpapers", fontSize = 13, fontWeight = "bold", color = "on_surface" }
|
||||
))
|
||||
|
||||
for _, r in ipairs(rows) do
|
||||
table.insert(scrollContent, r)
|
||||
end
|
||||
|
||||
table.insert(body,
|
||||
ui.scroll({ key = "grid-scroll", gap = 12, paddingRight = 8, align = "stretch", flexGrow = 1 }, scrollContent))
|
||||
|
||||
panel.render(ui.column({ flexGrow = 1, gap = 12 }, body))
|
||||
end
|
||||
|
||||
-- ── Handlers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
-- Adopts the service's view of this output. Selection, interval and order are
|
||||
@@ -1291,6 +1392,7 @@ end
|
||||
|
||||
function onOpen(_context)
|
||||
isOpen = true
|
||||
loadFavoriteList()
|
||||
outputName = noctalia.focusedOutputName() or outputName
|
||||
if not outputName then
|
||||
local outputs = noctalia.outputs()
|
||||
|
||||
Reference in New Issue
Block a user