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