Plugins can register retained-mode full-screen views using the following lifecycle:
- Register:
spotatui.register_screen(name, spec)name: Unique, non-empty string.spec: A table containing title (optional), on_key(key) (required), and on_open()/on_close() (optional).
- Publish Content:
spotatui.set_screen(name, widgets)widgets: An array of layout/UI tables.
- Navigate:
spotatui.show_screen(name) to open, or spotatui.close_screen(name) to leave.
Widget Types:
paragraph: Styled text. Supports lines (same format as popups) and scroll (boolean).list: A bordered list. Fields: items (array), title?, selected? (1-based index).gauge: A progress bar. Fields: ratio (0..1), label?.cover_art: Renders current track artwork. Fields: source (only "current" allowed), fit ("contain" or "scale"). Only one cover_art widget is allowed per screen.row / column: Layout containers that stack children horizontally or vertically.
-- Example: A minimal interactive screen
spotatui.require_api(5)
local selected = 1
local names = {}
local function render()
spotatui.set_screen("my_playlists", {
{ type = "paragraph", lines = { { text = "j/k to move, Esc to leave", italic = true } }, height = 2 },
{ type = "list", title = "Playlists", items = names, selected = selected },
})
end
spotatui.register_screen("my_playlists", {
title = "My Playlists",
on_key = function(key)
if key == "j" and selected < #names then selected = selected + 1 end
if key == "k" and selected > 1 then selected = selected - 1 end
render()
end,
on_open = function()
spotatui.get_playlists(function(playlists, err)
names = {}
for _, p in ipairs(playlists or {}) do
names[#names + 1] = p.name
end
render()
end)
end,
})
spotatui.register_command("my_playlists", function()
spotatui.show_screen("my_playlists")
end)