From e343ffee5a4663374a77073a3e4370041f2fc431 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 1 Feb 2025 17:23:24 +0000 Subject: Add playlist browser Add a menu item to main menu and associated browser for playlist files in the root of the SD card --- lua/playlist_browser.lua | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 lua/playlist_browser.lua (limited to 'lua/playlist_browser.lua') 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 +} + + -- cgit v1.2.3 From 10ba00951be79d843c560e4199ac8325f3315f72 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 1 Feb 2025 17:26:23 +0000 Subject: Remove unused imports --- lua/playlist_browser.lua | 5 ----- 1 file changed, 5 deletions(-) (limited to 'lua/playlist_browser.lua') diff --git a/lua/playlist_browser.lua b/lua/playlist_browser.lua index da50f4c8..d29899ad 100644 --- a/lua/playlist_browser.lua +++ b/lua/playlist_browser.lua @@ -4,17 +4,12 @@ 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") -- cgit v1.2.3 From 844b3f733ec30eff41c3b3d48c74561d7b11da8e Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 3 Feb 2025 20:13:23 +0000 Subject: Use Playlist subdirectory Target /Playlists, display and browse sub directories and playlists within --- lua/playlist_browser.lua | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'lua/playlist_browser.lua') diff --git a/lua/playlist_browser.lua b/lua/playlist_browser.lua index d29899ad..4824b581 100644 --- a/lua/playlist_browser.lua +++ b/lua/playlist_browser.lua @@ -13,6 +13,7 @@ local theme = require("theme") local playback = require("playback") local queue = require("queue") local table_iterator = require("table_iterator") +local img = require("images") return screen:new { @@ -59,28 +60,49 @@ return screen:new { } end - local playlists = {} - -- Find playlists - local fs_iter = filesystem.iterator("") - for item in fs_iter do + local is_playlist = function(item) + return item:filepath():match("%.playlist$") + or item:filepath():match("%.m3u8?$") + end + + local get_icon_func = function(item) + if item:is_directory() then + return img.files + else + return img.enqueue + end + end + + local playlists_and_dirs = {}; + for item in self.iterator do if - item:filepath():match("%.playlist$") or - item:filepath():match("%.m3u8?$") then - table.insert(playlists, item) + is_playlist(item) or + item:is_directory() then + table.insert(playlists_and_dirs, item) end end - widgets.InfiniteList(self.root, table_iterator:create(playlists), { + widgets.InfiniteList(self.root, table_iterator:create(playlists_and_dirs), { focus_first_item = true, + get_icon = get_icon_func, callback = function(item) return function() - queue.open_playlist(item:filepath()) - playback.playing:set(true) - backstack.push(playing:new()) + if item:is_directory() then + backstack.push( + require("playlist_browser"):new { + title = self.title, + iterator = filesystem.iterator(item:filepath()), + breadcrumb = item:filepath() + }) + elseif + is_playlist(item) then + -- TODO: playlist viewer + queue.open_playlist(item:filepath()) + playback.playing:set(true) + backstack.push(playing:new()) + end end end }) end } - - -- cgit v1.2.3 From ff733e8f0c827e3d2d91bb7db29a85807867ab5e Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 4 Feb 2025 21:13:52 +0000 Subject: Wrap filesystem iterator Change to wrapping the filesystem iterator rather than iterating over table values. Also centralise the is_playlist check and hide Playlists menu if none are present --- lua/playlist_browser.lua | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'lua/playlist_browser.lua') diff --git a/lua/playlist_browser.lua b/lua/playlist_browser.lua index 4824b581..0339d59b 100644 --- a/lua/playlist_browser.lua +++ b/lua/playlist_browser.lua @@ -12,7 +12,7 @@ local font = require("font") local theme = require("theme") local playback = require("playback") local queue = require("queue") -local table_iterator = require("table_iterator") +local playlist_iterator = require("playlist_iterator") local img = require("images") @@ -60,11 +60,6 @@ return screen:new { } end - local is_playlist = function(item) - return item:filepath():match("%.playlist$") - or item:filepath():match("%.m3u8?$") - end - local get_icon_func = function(item) if item:is_directory() then return img.files @@ -73,16 +68,7 @@ return screen:new { end end - local playlists_and_dirs = {}; - for item in self.iterator do - if - is_playlist(item) or - item:is_directory() then - table.insert(playlists_and_dirs, item) - end - end - - widgets.InfiniteList(self.root, table_iterator:create(playlists_and_dirs), { + widgets.InfiniteList(self.root, playlist_iterator:create(self.iterator), { focus_first_item = true, get_icon = get_icon_func, callback = function(item) @@ -95,7 +81,7 @@ return screen:new { breadcrumb = item:filepath() }) elseif - is_playlist(item) then + playlist_iterator:is_playlist(item) then -- TODO: playlist viewer queue.open_playlist(item:filepath()) playback.playing:set(true) -- cgit v1.2.3