components_tvshows_TVEpisodes.bs
import "pkg:/source/api/baserequest.bs"
import "pkg:/source/api/Image.bs"
import "pkg:/source/api/sdk.bs"
import "pkg:/source/utils/config.bs"
import "pkg:/source/utils/misc.bs"
sub init()
m.top.optionsAvailable = false
m.rows = m.top.findNode("picker")
m.poster = m.top.findNode("seasonPoster")
m.shuffle = m.top.findNode("shuffle")
m.extras = m.top.findNode("extras")
m.tvEpisodeRow = m.top.findNode("tvEpisodeRow")
m.unplayedCount = m.top.findNode("unplayedCount")
m.unplayedEpisodeCount = m.top.findNode("unplayedEpisodeCount")
m.rows.observeField("doneLoading", "updateSeason")
m.isFirstRun = true
end sub
' Updates the visibility of the Extras button based on if this season has any extra features
sub setExtraButtonVisibility()
if isValid(m.top.extrasObjects) and isValidAndNotEmpty(m.top.extrasObjects.items)
m.extras.visible = true
end if
end sub
sub updateSeason()
if not isValid(m.top.seasonData) then return
if isValid(m.top.seasonData.UserData)
userData = m.top.seasonData.UserData
if isValid(userData.UnplayedItemCount)
m.poster.unplayedCount = userData.UnplayedItemCount
end if
end if
imgParams = { "maxHeight": 450, "maxWidth": 300 }
m.poster.uri = ImageURL(m.top.seasonData.Id, "Primary", imgParams)
m.shuffle.visible = true
m.top.overhangTitle = m.top.seasonData.SeriesName + " - " + m.top.seasonData.name
' Set season/series backdrop
setSeasonBackdrop()
end sub
' setSeasonBackdrop: Sets backdrop for season view
' Priority 1: Season's own backdrop
' Priority 2: Parent series backdrop
' Priority 3: Transparent (no backdrop available)
sub setSeasonBackdrop()
if not isValid(m.top.seasonData) then return
localDevice = m.global.device
backdropWidth = localDevice.uiResolution[0]
backdropHeight = localDevice.uiResolution[1]
' Priority 1: Try season's own backdrop first
if isValid(m.top.seasonData.BackdropImageTags) and isValidAndNotEmpty(m.top.seasonData.BackdropImageTags[0])
backdropParams = { "tag": m.top.seasonData.BackdropImageTags[0], "maxHeight": backdropHeight, "maxWidth": backdropWidth }
backdropUrl = ImageURL(m.top.seasonData.Id, "Backdrop", backdropParams)
m.global.sceneManager.callFunc("setBackgroundImage", backdropUrl)
return
end if
' Priority 2: Fallback to parent series backdrop
if isValid(m.top.seasonData.ParentBackdropImageTags) and isValidAndNotEmpty(m.top.seasonData.ParentBackdropImageTags[0]) and isValid(m.top.seasonData.SeriesId)
backdropParams = { "tag": m.top.seasonData.ParentBackdropImageTags[0], "maxHeight": backdropHeight, "maxWidth": backdropWidth }
backdropUrl = ImageURL(m.top.seasonData.SeriesId, "Backdrop", backdropParams)
m.global.sceneManager.callFunc("setBackgroundImage", backdropUrl)
return
end if
' No backdrop available - set transparent
m.global.sceneManager.callFunc("setBackgroundImage", "")
end sub
' get the currently focused item
function getFocusedItem() as dynamic
if not isValid(m.top.focusedChild) or not isValid(m.top.focusedChild.focusedChild)
return invalid
end if
focusedChild = m.top.focusedChild.focusedChild
if not isValid(focusedChild.content) then return invalid
m.top.lastFocus = focusedChild
if isValidAndNotEmpty(focusedChild.rowItemFocused)
itemToPlay = focusedChild.content.getChild(focusedChild.rowItemFocused[0]).getChild(0)
if isValid(itemToPlay) and isValidAndNotEmpty(itemToPlay.id)
return itemToPlay
end if
end if
return invalid
end function
' OnScreenShown: Callback function when view is presented on screen
'
sub OnScreenShown()
' Set backdrop from season data (only if seasonData is already loaded)
' This handles the case when returning to an already-loaded screen
if isValid(m.top.seasonData)
setSeasonBackdrop()
end if
' If seasonData not loaded, backdrop will be set in updateSeason()
if m.isFirstRun
m.isFirstRun = false
' Set initial focus to episode row on first run
m.tvEpisodeRow.setFocus(true)
m.top.lastFocus = m.tvEpisodeRow
return
end if
' Restore focus to previously focused element
if isValid(m.top.lastFocus)
m.top.lastFocus.setFocus(true)
else
m.tvEpisodeRow.setFocus(true)
end if
m.top.refreshSeasonDetailsData = not m.top.refreshSeasonDetailsData
end sub
' Handle navigation input from the remote and act on it
function onKeyEvent(key as string, _press as boolean) as boolean
if key = "left" and m.tvEpisodeRow.hasFocus()
m.shuffle.setFocus(true)
return true
end if
if key = "right" and (m.shuffle.hasFocus() or m.extras.hasFocus())
m.tvEpisodeRow.setFocus(true)
return true
end if
if m.extras.visible and key = "up" and m.extras.hasFocus()
m.shuffle.setFocus(true)
return true
end if
if m.extras.visible and key = "down" and m.shuffle.hasFocus()
m.extras.setFocus(true)
return true
end if
if key = "OK"
if m.tvEpisodeRow.isInFocusChain()
focusedItem = getFocusedItem()
if isValid(focusedItem)
m.top.selectedItem = focusedItem
'Prevent the selected item event from double firing
m.top.selectedItem = invalid
end if
return true
end if
if m.shuffle.hasFocus()
episodeList = m.rows.getChild(0).objects.items
for i = 0 to episodeList.count() - 1
j = Rnd(episodeList.count() - 1)
temp = episodeList[i]
episodeList[i] = episodeList[j]
episodeList[j] = temp
end for
m.global.queueManager.callFunc("set", episodeList)
m.global.queueManager.callFunc("playQueue")
return true
end if
if m.extras.visible and m.extras.hasFocus()
if LCase(m.extras.text.trim()) = LCase(tr("Extras"))
m.extras.text = tr("Episodes")
m.top.objects = m.top.extrasObjects
else
m.extras.text = tr("Extras")
m.top.objects = m.top.episodeObjects
end if
end if
end if
if key = "play"
focusedItem = getFocusedItem()
if isValid(focusedItem)
m.top.quickPlayNode = focusedItem
end if
return true
end if
return false
end function