diff --git a/lua/browser.lua b/lua/browser.lua index 48c3895f..ce89d5ab 100644 --- a/lua/browser.lua +++ b/lua/browser.lua @@ -9,6 +9,7 @@ local playback = require("playback") local theme = require("theme") local screen = require("screen") local database = require("database") +local img = require("images") return screen:new{ create_ui = function(self) @@ -54,43 +55,66 @@ return screen:new{ } end - local buttons = header:Object({ - flex = { - flex_direction = "row", - flex_wrap = "wrap", - justify_content = "space-between", - align_items = "center", - align_content = "center" - }, - w = lvgl.PCT(100), - h = lvgl.SIZE_CONTENT, - pad_column = 4 - }) - local original_iterator = self.iterator:clone() - local enqueue = widgets.IconBtn(buttons, "//lua/img/enqueue.png", "Enqueue") - enqueue:onClicked(function() - queue.add(original_iterator) - playback.playing:set(true) - end) - local shuffle_play = widgets.IconBtn(buttons, "//lua/img/shuffleplay.png", "Shuffle") - shuffle_play:onClicked(function() - queue.clear() - queue.random:set(true) - queue.add(original_iterator) - playback.playing:set(true) - backstack.push(playing:new()) - end) - -- enqueue:add_flag(lvgl.FLAG.HIDDEN) - local play = widgets.IconBtn(buttons, "//lua/img/play_small.png", "Play") - play:onClicked(function() - queue.clear() - queue.random:set(false) - queue.add(original_iterator) - playback.playing:set(true) - backstack.push(playing:new()) - end) + if (self.mediatype == database.MediaTypes.Music) then + local buttons = header:Object({ + flex = { + flex_direction = "row", + flex_wrap = "wrap", + justify_content = "space-between", + align_items = "center", + align_content = "center" + }, + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + pad_column = 4 + }) + local original_iterator = self.iterator:clone() + local enqueue = widgets.IconBtn(buttons, "//lua/img/enqueue.png", "Enqueue") + enqueue:onClicked(function() + queue.add(original_iterator) + playback.playing:set(true) + end) + local shuffle_play = widgets.IconBtn(buttons, "//lua/img/shuffleplay.png", "Shuffle") + shuffle_play:onClicked(function() + queue.clear() + queue.random:set(true) + queue.add(original_iterator) + playback.playing:set(true) + backstack.push(playing:new()) + end) + -- enqueue:add_flag(lvgl.FLAG.HIDDEN) + local play = widgets.IconBtn(buttons, "//lua/img/play_small.png", "Play") + play:onClicked(function() + queue.clear() + queue.random:set(false) + queue.add(original_iterator) + playback.playing:set(true) + backstack.push(playing:new()) + end) + end + + local get_icon_func = nil + local show_listened = self.mediatype == database.MediaTypes.Audiobook or self.mediatype == database.MediaTypes.Podcast + if show_listened then + get_icon_func = function (item) + local contents = item:contents() + if type(contents) == "userdata" then + return + else + local track = database.track_by_id(contents) + if not track then return end + if (track.play_count > 0) then + return img.listened + else + return img.unlistened + end + end + + end + end widgets.InfiniteList(self.root, self.iterator, { + get_icon = get_icon_func, callback = function(item) return function() local contents = item:contents() @@ -98,6 +122,7 @@ return screen:new{ backstack.push(require("browser"):new{ title = self.title, iterator = contents, + mediatype = self.mediatype, breadcrumb = tostring(item) }) else diff --git a/lua/images.lua b/lua/images.lua index 84853a52..42a4a3fd 100644 --- a/lua/images.lua +++ b/lua/images.lua @@ -17,6 +17,8 @@ local img = { settings = lvgl.ImgData("//lua/img/settings.png"), chevron = lvgl.ImgData("//lua/img/chevron.png"), usb = lvgl.ImgData("//lua/img/usb.png"), + listened = lvgl.ImgData("//lua/img/listened.png"), + unlistened = lvgl.ImgData("//lua/img/unlistened.png"), } return img diff --git a/lua/img/listened.png b/lua/img/listened.png new file mode 100644 index 00000000..6c23423e Binary files /dev/null and b/lua/img/listened.png differ diff --git a/lua/img/unlistened.png b/lua/img/unlistened.png new file mode 100644 index 00000000..df0c5b82 Binary files /dev/null and b/lua/img/unlistened.png differ diff --git a/lua/main_menu.lua b/lua/main_menu.lua index c4445762..ca228102 100644 --- a/lua/main_menu.lua +++ b/lua/main_menu.lua @@ -117,6 +117,7 @@ return widgets.MenuScreen:new { backstack.push(browser:new { title = tostring(idx), iterator = idx:iter(), + mediatype = idx:type(), }) end) btn:add_style(styles.list_item) diff --git a/lua/theme_dark.lua b/lua/theme_dark.lua index ac1044c6..560b6849 100644 --- a/lua/theme_dark.lua +++ b/lua/theme_dark.lua @@ -55,6 +55,12 @@ local theme_dark = { }}, }, listbutton = { + {lvgl.PART.MAIN, lvgl.Style { + image_recolor_opa = 255, + image_recolor = text_color, + flex_cross_place = lvgl.FLEX_ALIGN.CENTER, + pad_column = 4, + }}, {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style { bg_opa = lvgl.OPA(100), bg_color = highlight_color, diff --git a/lua/theme_hicon.lua b/lua/theme_hicon.lua index 59446bd7..a1a3dca3 100644 --- a/lua/theme_hicon.lua +++ b/lua/theme_hicon.lua @@ -61,10 +61,18 @@ local theme_hicon = { }}, }, listbutton = { + {lvgl.PART.MAIN, lvgl.Style { + image_recolor_opa = 255, + image_recolor = text_color, + flex_cross_place = lvgl.FLEX_ALIGN.CENTER, + pad_column = 4, + }}, {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style { bg_opa = lvgl.OPA(100), bg_color = text_color, text_color = background_color, + image_recolor_opa = 255, + image_recolor = background_color, }}, }, bar = { diff --git a/lua/theme_light.lua b/lua/theme_light.lua index 412fec25..5d18a9d1 100644 --- a/lua/theme_light.lua +++ b/lua/theme_light.lua @@ -63,10 +63,18 @@ local theme_light = { }}, }, listbutton = { + {lvgl.PART.MAIN, lvgl.Style { + image_recolor_opa = 255, + image_recolor = text_color, + flex_cross_place = lvgl.FLEX_ALIGN.CENTER, + pad_column = 4, + }}, {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style { bg_opa = lvgl.OPA(100), bg_color = highlight_color, - text_color = "#ffffff" + text_color = "#ffffff", + image_recolor_opa = 255, + image_recolor = "#ffffff", }}, }, bar = { diff --git a/lua/widgets.lua b/lua/widgets.lua index 8112b656..cfcaf628 100644 --- a/lua/widgets.lua +++ b/lua/widgets.lua @@ -313,7 +313,11 @@ function widgets.InfiniteList(parent, iterator, opts) add_to_top = true end if this_item > last_index then last_index = index end - local btn = infinite_list.root:add_btn(nil, tostring(item)) + local icon = nil + if opts.get_icon then + icon = opts.get_icon(item) + end + local btn = infinite_list.root:add_btn(icon, tostring(item)) if add_to_top then btn:move_to_index(0) end diff --git a/luals-stubs/database.lua b/luals-stubs/database.lua index a21f61be..9d6c4c48 100644 --- a/luals-stubs/database.lua +++ b/luals-stubs/database.lua @@ -67,6 +67,9 @@ local Index = {} --- @return string function Index:name() end +--- Returns the media type of this index +function Index:type() end + --- Returns a new iterator that can be used to access every record within the --- first level of this index. --- @return Iterator it An iterator that yields `Record`s. diff --git a/src/tangara/database/index.cpp b/src/tangara/database/index.cpp index 0ced27ed..1cdc0d07 100644 --- a/src/tangara/database/index.cpp +++ b/src/tangara/database/index.cpp @@ -60,7 +60,7 @@ const IndexInfo kPodcasts{ .id = 5, .type = MediaType::kPodcast, .name = "Podcasts", - .components = {Tag::kTitle}, + .components = {Tag::kAlbum, Tag::kTitle}, }; const IndexInfo kAudiobooks{ diff --git a/src/tangara/lua/lua_database.cpp b/src/tangara/lua/lua_database.cpp index 39179bf3..2a3ab59d 100644 --- a/src/tangara/lua/lua_database.cpp +++ b/src/tangara/lua/lua_database.cpp @@ -388,6 +388,24 @@ static auto lua_database(lua_State* state) -> int { luaL_setfuncs(state, kDbRecordFuncs, 0); luaL_newlib(state, kDatabaseFuncs); + + lua_pushliteral(state, "MediaTypes"); + lua_newtable(state); + lua_pushliteral(state, "Unknown"); + lua_pushinteger(state, (int)database::MediaType::kUnknown); + lua_rawset(state, -3); + lua_pushliteral(state, "Music"); + lua_pushinteger(state, (int)database::MediaType::kMusic); + lua_rawset(state, -3); + lua_pushliteral(state, "Podcast"); + lua_pushinteger(state, (int)database::MediaType::kPodcast); + lua_rawset(state, -3); + lua_pushliteral(state, "Audiobook"); + lua_pushinteger(state, (int)database::MediaType::kAudiobook); + lua_rawset(state, -3); + lua_rawset(state, -3); + + return 1; }