components_music_PlaylistView.bs
import "pkg:/source/roku_modules/log/LogMixin.brs"
import "pkg:/source/utils/itemImageUrl.bs"
import "pkg:/source/utils/misc.bs"
sub init()
m.log = log.Logger("PlaylistView")
m.top.optionsAvailable = false
setupMainNode()
m.buttons = m.top.findNode("buttons")
m.albumCover = m.top.findNode("albumCover")
m.songList = m.top.findNode("songList")
m.infoGroup = m.top.FindNode("infoGroup")
m.songListRect = m.top.FindNode("songListRect")
m.songList.observeField("doneLoading", "onDoneLoading")
' Observe item focus to update backdrop for ANY focused item type
m.songList.observeField("itemFocused", "onPlaylistItemFocused")
m.dscr = m.top.findNode("overview")
m.dscr.ellipsisText = tr("... (Press * to read more)")
' Set initial focus to song list
m.top.lastFocus = m.songList
end sub
sub setupMainNode()
main = m.top.findNode("toplevel")
main.translation = [96, 175]
end sub
sub OnScreenShown()
' Start with transparent backdrop for playlists
' Backdrop updates based on focused item as user navigates
m.global.sceneManager.callFunc("setBackgroundImage", "")
' Restore focus to previously focused element
if isValid(m.top.lastFocus)
m.top.lastFocus.setFocus(true)
else
m.top.setFocus(true)
end if
end sub
' Set values for displayed values on screen
sub pageContentChanged()
item = m.top.pageContent
' Start with transparent for playlists
' Backdrop updates based on focused item as user navigates
m.global.sceneManager.callFunc("setBackgroundImage", "")
setPosterImage(getItemPosterUrl(item))
setScreenTitle(item)
setOnScreenTextValues(item)
end sub
' onPlaylistItemFocused: Update backdrop when playlist item is focused
sub onPlaylistItemFocused()
if not isValid(m.songList.itemFocused) or m.songList.itemFocused = -1
return
end if
' Get focused playlist item (Audio, Video, Episode, Movie, etc.)
focusedItem = m.songList.content.getChild(m.songList.itemFocused)
' Update backdrop if item has one, otherwise clear to transparent
if isValid(focusedItem)
deviceRes = m.global.device.uiResolution
backdropUrl = getItemBackdropUrl(focusedItem, { width: deviceRes[0], height: deviceRes[1] })
m.global.sceneManager.callFunc("setBackgroundImage", backdropUrl)
end if
end sub
' Set poster image on screen
sub setPosterImage(posterURL)
if isValidAndNotEmpty(posterURL)
m.albumCover.uri = posterURL
else
m.albumCover.uri = "pkg:/images/icons/playlist.png"
end if
end sub
' Set screen's title text
sub setScreenTitle(item as object)
newTitle = ""
if item.albumArtist <> "" and item.name <> ""
newTitle = item.albumArtist + " / " + item.name
else if item.name <> ""
newTitle = item.name
end if
m.top.overhangTitle = newTitle
end sub
' Adjust scene by removing overview node and showing more songs
sub adjustScreenForNoOverview()
m.infoGroup.removeChild(m.dscr)
m.songListRect.height = 800
m.songList.numRows = 12
end sub
' Populate on screen text variables
sub setOnScreenTextValues(item as object)
if item.overview <> ""
setFieldTextValue("overview", item.overview)
else
adjustScreenForNoOverview()
end if
setFieldTextValue("numberofsongs", stri(item.childCount) + " Tracks")
if item.productionYear > 0
setFieldTextValue("released", "Released " + stri(item.productionYear))
end if
if item.genres.count() > 0
setFieldTextValue("genres", item.genres.join(", "))
end if
if item.runTimeTicks > 0
setFieldTextValue("runtime", stri(getMinutes(item.runTimeTicks)) + " mins")
end if
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if key = "options"
if m.dscr.isTextEllipsized
createFullDscrDlg()
return true
end if
return false
end if
if key = "right" and m.buttons.isInFocusChain()
m.songList.setFocus(true)
return true
else if key = "left" and m.songList.hasFocus()
m.buttons.setFocus(true)
return true
end if
return false
end function
sub createFullDscrDlg()
dlg = CreateObject("roSGNode", "OverviewDialog")
dlg.title = tr("Overview")
dlg.overview = m.dscr.text
m.global.sceneManager.callFunc("pushScene", dlg)
end sub
sub onDoneLoading()
m.songList.unobservefield("doneLoading")
stopLoadingSpinner()
end sub
' destroy: Full teardown releasing all resources before component removal
' Called automatically by SceneManager.popScene() / clearScenes()
sub destroy()
m.log.verbose("destroy")
' Unobserve child node observers (doneLoading may already be cleared by onDoneLoading())
m.songList.unobserveField("doneLoading")
m.songList.unobserveField("itemFocused")
' Clear node references
m.buttons = invalid
m.albumCover = invalid
m.songList = invalid
m.infoGroup = invalid
m.songListRect = invalid
m.dscr = invalid
end sub