From e343ffee5a4663374a77073a3e4370041f2fc431 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 1 Feb 2025 17:23:24 +0000 Subject: [PATCH] Add playlist browser Add a menu item to main menu and associated browser for playlist files in the root of the SD card --- lua/main_menu.lua | 8 ++++ lua/playlist_browser.lua | 91 ++++++++++++++++++++++++++++++++++++++++ lua/table_iterator.lua | 27 ++++++++++++ lua/widgets.lua | 2 +- 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 lua/playlist_browser.lua create mode 100644 lua/table_iterator.lua diff --git a/lua/main_menu.lua b/lua/main_menu.lua index cc7874d7..80d5b599 100644 --- a/lua/main_menu.lua +++ b/lua/main_menu.lua @@ -131,6 +131,14 @@ return widgets.MenuScreen:new { }) end + local playlist_btn = indexes_list:add_btn(nil, "Playlists") + playlist_btn:onClicked(function() + backstack.push(require("playlist_browser"):new { + title = "Playlists", + }) + end) + playlist_btn:add_style(styles.list_item) + local function show_no_indexes(msg) indexes_list:add_flag(lvgl.FLAG.HIDDEN) no_indexes_container:clear_flag(lvgl.FLAG.HIDDEN) diff --git a/lua/playlist_browser.lua b/lua/playlist_browser.lua new file mode 100644 index 00000000..da50f4c8 --- /dev/null +++ b/lua/playlist_browser.lua @@ -0,0 +1,91 @@ +-- SPDX-FileCopyrightText: 2025 Sam Lord +-- +-- SPDX-License-Identifier: GPL-3.0-only + +local lvgl = require("lvgl") +local widgets = require("widgets") +local database = require("database") +local sd_card = require("sd_card") +local backstack = require("backstack") +local browser = require("browser") +local playing = require("playing") +local styles = require("styles") +local filesystem = require("filesystem") +local screen = require("screen") +local font = require("font") +local theme = require("theme") +local img = require("images") +local playback = require("playback") +local queue = require("queue") +local table_iterator = require("table_iterator") + + +return screen:new { + create_ui = function(self) + self.root = lvgl.Object(nil, { + flex = { + flex_direction = "column", + flex_wrap = "wrap", + justify_content = "flex-start", + align_items = "flex-start", + align_content = "flex-start" + }, + w = lvgl.HOR_RES(), + h = lvgl.VER_RES() + }) + self.root:center() + + self.status_bar = widgets.StatusBar(self, { + back_cb = backstack.pop, + title = self.title + }) + + local header = self.root:Object { + flex = { + flex_direction = "column", + flex_wrap = "wrap", + justify_content = "flex-start", + align_items = "flex-start", + align_content = "flex-start" + }, + w = lvgl.HOR_RES(), + h = lvgl.SIZE_CONTENT, + pad_left = 4, + pad_right = 4, + pad_bottom = 2, + scrollbar_mode = lvgl.SCROLLBAR_MODE.OFF + } + theme.set_subject(header, "header") + + if self.breadcrumb then + header:Label { + text = self.breadcrumb, + text_font = font.fusion_10 + } + end + + local playlists = {} + -- Find playlists + local fs_iter = filesystem.iterator("") + for item in fs_iter do + if + item:filepath():match("%.playlist$") or + item:filepath():match("%.m3u8?$") then + table.insert(playlists, item) + end + end + + widgets.InfiniteList(self.root, table_iterator:create(playlists), { + focus_first_item = true, + callback = function(item) + return function() + queue.open_playlist(item:filepath()) + playback.playing:set(true) + backstack.push(playing:new()) + end + end + }) + end +} + + diff --git a/lua/table_iterator.lua b/lua/table_iterator.lua new file mode 100644 index 00000000..5bacada6 --- /dev/null +++ b/lua/table_iterator.lua @@ -0,0 +1,27 @@ + +local TableIterator = {} + +function TableIterator:create(table) + local iterator = {}; + iterator.index = 0; + iterator.table = table; + + function iterator:clone() + return TableIterator:create(table) + end + + function iterator:next() + self.index = self.index + 1 + return self.table[self.index] + end + + function iterator:prev() + self.index = self.index - 1 + return self.table[self.index] + end + + return iterator +end + + +return TableIterator \ No newline at end of file diff --git a/lua/widgets.lua b/lua/widgets.lua index 0aac7705..20f0cd2a 100644 --- a/lua/widgets.lua +++ b/lua/widgets.lua @@ -361,7 +361,7 @@ function widgets.InfiniteList(parent, iterator, opts) end for idx = 0, 8 do - local val = fwd_iterator() + local val = fwd_iterator:next() if not val then break end