jf-roku/components/home/HomeRows.bs

593 lines
18 KiB
Plaintext
Raw Normal View History

import "pkg:/source/utils/misc.bs"
sub init()
2021-07-09 20:08:32 +00:00
m.top.itemComponentName = "HomeItem"
' how many rows are visible on the screen
m.top.numRows = 2
2021-07-09 20:08:32 +00:00
m.top.rowFocusAnimationStyle = "fixedFocusWrap"
m.top.vertFocusAnimationStyle = "fixedFocus"
2021-07-09 20:08:32 +00:00
m.top.showRowLabel = [true]
m.top.rowLabelOffset = [0, 20]
m.top.showRowCounter = [true]
2023-09-30 21:36:16 +00:00
m.homeSectionIndexes = {
count: 0
}
2021-07-09 20:08:32 +00:00
updateSize()
2021-07-09 20:08:32 +00:00
m.top.setfocus(true)
2021-07-09 20:08:32 +00:00
m.top.observeField("rowItemSelected", "itemSelected")
2020-04-04 22:24:47 +00:00
2021-07-09 20:08:32 +00:00
' Load the Libraries from API via task
m.LoadLibrariesTask = createObject("roSGNode", "LoadItemsTask")
m.LoadLibrariesTask.observeField("content", "onLibrariesLoaded")
2022-11-05 00:37:54 +00:00
' set up tesk nodes for other rows
m.LoadContinueWatchingTask = createObject("roSGNode", "LoadItemsTask")
m.LoadContinueWatchingTask.itemsToLoad = "continue"
2022-11-05 00:37:54 +00:00
2021-07-09 20:08:32 +00:00
m.LoadNextUpTask = createObject("roSGNode", "LoadItemsTask")
m.LoadNextUpTask.itemsToLoad = "nextUp"
2022-11-05 00:37:54 +00:00
2021-12-18 06:31:28 +00:00
m.LoadOnNowTask = createObject("roSGNode", "LoadItemsTask")
2021-12-20 14:57:22 +00:00
m.LoadOnNowTask.itemsToLoad = "onNow"
2022-11-05 00:37:54 +00:00
m.LoadFavoritesTask = createObject("roSGNode", "LoadItemsTask")
m.LoadFavoritesTask.itemsToLoad = "favorites"
end sub
sub loadLibraries()
2021-07-09 20:08:32 +00:00
m.LoadLibrariesTask.control = "RUN"
end sub
sub updateSize()
2021-07-09 20:08:32 +00:00
m.top.translation = [111, 180]
itemHeight = 330
2021-07-09 20:08:32 +00:00
'Set width of Rows to cut off at edge of Safe Zone
m.top.itemSize = [1703, itemHeight]
2021-07-09 20:08:32 +00:00
' spacing between rows
m.top.itemSpacing = [0, 105]
2021-07-09 20:08:32 +00:00
' spacing between items in a row
m.top.rowItemSpacing = [20, 0]
2021-07-09 20:08:32 +00:00
m.top.visible = true
end sub
2020-03-24 07:37:45 +00:00
sub onLibrariesLoaded()
' save data for other functions
2021-07-09 20:08:32 +00:00
m.libraryData = m.LoadLibrariesTask.content
m.LoadLibrariesTask.unobserveField("content")
m.LoadLibrariesTask.content = []
2023-09-30 21:36:16 +00:00
2021-07-09 20:08:32 +00:00
content = CreateObject("roSGNode", "ContentNode")
2023-09-30 21:36:16 +00:00
sizeArray = []
loadedSections = 0
2023-09-30 21:36:16 +00:00
' Add sections in order based on user settings
for i = 0 to 6
sectionName = LCase(m.global.session.user.settings["homesection" + i.toStr()])
sectionLoaded = addHomeSection(content, sizeArray, sectionName)
' Count how many sections with data are loaded
if sectionLoaded then loadedSections++
' If 2 sections with data are loaded or we're at the end of the web client section data, consider the home view loaded
if loadedSections = 2 or i = 6
if not m.global.app_loaded
m.top.signalBeacon("AppLaunchComplete") ' Roku Performance monitoring
m.global.app_loaded = true
end if
end if
2023-09-30 21:36:16 +00:00
end for
' Favorites isn't an option on Web settings, so we must manually add it for now
addHomeSection(content, sizeArray, "favorites")
m.top.rowItemSize = sizeArray
m.top.content = content
end sub
' Removes a home section from the home rows
sub removeHomeSection(sectionType as string)
sectionName = LCase(sectionType)
removedSectionIndex = m.homeSectionIndexes[sectionName]
if not isValid(removedSectionIndex) then return
2023-09-30 21:36:16 +00:00
for each section in m.homeSectionIndexes
if m.homeSectionIndexes[section] > removedSectionIndex
m.homeSectionIndexes[section]--
2023-09-30 21:36:16 +00:00
end if
end for
m.homeSectionIndexes.Delete(sectionName)
m.top.content.removeChildIndex(removedSectionIndex)
end sub
' Adds a new home section to the home rows.
' Returns a boolean indicating whether the section was handled.
function addHomeSection(content as dynamic, sizeArray as dynamic, sectionName as string) as boolean
2023-09-30 21:36:16 +00:00
' Poster size library items
if sectionName = "livetv"
createLiveTVRow(content, sizeArray)
return true
2023-09-30 21:36:16 +00:00
end if
' Poster size library items
if sectionName = "smalllibrarytiles"
createLibraryRow(content, sizeArray)
return true
2023-09-30 21:36:16 +00:00
end if
' Continue Watching items
if sectionName = "resume"
createContinueWatchingRow(content, sizeArray)
return true
2023-09-30 21:36:16 +00:00
end if
' Next Up items
if sectionName = "nextup"
createNextUpRow(content, sizeArray)
return true
2023-09-30 21:36:16 +00:00
end if
' Latest items in each library
if sectionName = "latestmedia"
createLatestInRows(content, sizeArray)
return true
2023-09-30 21:36:16 +00:00
end if
' Favorite Items
if sectionName = "favorites"
createFavoritesRow(content, sizeArray)
return true
2023-09-30 21:36:16 +00:00
end if
return false
end function
2023-09-30 21:36:16 +00:00
' Create a row displaying the user's libraries
sub createLibraryRow(content as dynamic, sizeArray as dynamic)
' Ensure we have data
if not isValidAndNotEmpty(m.libraryData) then return
2023-01-10 00:38:50 +00:00
mediaRow = content.CreateChild("HomeRow")
mediaRow.title = tr("My Media")
2023-01-10 00:38:50 +00:00
2023-09-30 21:36:16 +00:00
m.homeSectionIndexes.AddReplace("library", m.homeSectionIndexes.count)
m.homeSectionIndexes.count++
2023-01-10 00:38:50 +00:00
2023-09-30 21:36:16 +00:00
sizeArray.push([464, 331])
2022-11-05 00:37:54 +00:00
2023-09-30 21:36:16 +00:00
filteredMedia = filterNodeArray(m.libraryData, "id", m.global.session.user.configuration.MyMediaExcludes)
for each item in filteredMedia
mediaRow.appendChild(item)
end for
end sub
2022-11-05 00:37:54 +00:00
2023-09-30 21:36:16 +00:00
' Create a row displaying latest items in each of the user's libraries
sub createLatestInRows(content as dynamic, sizeArray as dynamic)
' Ensure we have data
if not isValidAndNotEmpty(m.libraryData) then return
2022-11-05 00:37:54 +00:00
2023-09-30 21:36:16 +00:00
' create a "Latest In" row for each library
filteredLatest = filterNodeArray(m.libraryData, "id", m.global.session.user.configuration.LatestItemsExcludes)
for each lib in filteredLatest
if lib.collectionType <> "boxsets" and lib.collectionType <> "livetv" and lib.json.CollectionType <> "Program"
latestInRow = content.CreateChild("HomeRow")
latestInRow.title = tr("Latest in") + " " + lib.name + " >"
2021-07-09 20:08:32 +00:00
2023-09-30 21:36:16 +00:00
m.homeSectionIndexes.AddReplace("latestin" + LCase(lib.name).Replace(" ", ""), m.homeSectionIndexes.count)
m.homeSectionIndexes.count++
sizeArray.Push([464, 331])
loadLatest = createObject("roSGNode", "LoadItemsTask")
loadLatest.itemsToLoad = "latest"
loadLatest.itemId = lib.id
metadata = { "title": lib.name }
metadata.Append({ "contentType": lib.json.CollectionType })
loadLatest.metadata = metadata
loadLatest.observeField("content", "updateLatestItems")
loadLatest.control = "RUN"
end if
end for
end sub
' Create a row displaying the live tv now on section
sub createLiveTVRow(content as dynamic, sizeArray as dynamic)
contentRow = content.CreateChild("HomeRow")
contentRow.title = tr("On Now")
m.homeSectionIndexes.AddReplace("livetv", m.homeSectionIndexes.count)
m.homeSectionIndexes.count++
sizeArray.push([464, 331])
m.LoadOnNowTask.observeField("content", "updateOnNowItems")
m.LoadOnNowTask.control = "RUN"
end sub
' Create a row displaying items the user can continue watching
sub createContinueWatchingRow(content as dynamic, sizeArray as dynamic)
continueWatchingRow = content.CreateChild("HomeRow")
continueWatchingRow.title = tr("Continue Watching")
2023-09-30 21:36:16 +00:00
m.homeSectionIndexes.AddReplace("resume", m.homeSectionIndexes.count)
m.homeSectionIndexes.count++
sizeArray.push([464, 331])
2023-04-13 19:41:11 +00:00
' Load the Continue Watching Data
m.LoadContinueWatchingTask.observeField("content", "updateContinueWatchingItems")
m.LoadContinueWatchingTask.control = "RUN"
2023-09-30 21:36:16 +00:00
end sub
' Create a row displaying next episodes up to watch
sub createNextUpRow(content as dynamic, sizeArray as dynamic)
nextUpRow = content.CreateChild("HomeRow")
nextUpRow.title = tr("Next Up >")
m.homeSectionIndexes.AddReplace("nextup", m.homeSectionIndexes.count)
m.homeSectionIndexes.count++
sizeArray.push([464, 331])
' Load the Next Up Data
m.LoadNextUpTask.observeField("content", "updateNextUpItems")
m.LoadNextUpTask.control = "RUN"
end sub
' Create a row displaying items from the user's favorites list
sub createFavoritesRow(content as dynamic, sizeArray as dynamic)
favoritesRow = content.CreateChild("HomeRow")
favoritesRow.title = tr("Favorites")
sizeArray.Push([464, 331])
m.homeSectionIndexes.AddReplace("favorites", m.homeSectionIndexes.count)
m.homeSectionIndexes.count++
2023-04-13 19:41:11 +00:00
' Load the Favorites Data
m.LoadFavoritesTask.observeField("content", "updateFavoritesItems")
m.LoadFavoritesTask.control = "RUN"
end sub
2023-09-30 21:36:16 +00:00
' Update home row data
sub updateHomeRows()
2023-09-30 21:36:16 +00:00
' If resume section exists, reload row's data
if m.homeSectionIndexes.doesExist("resume")
m.LoadContinueWatchingTask.observeField("content", "updateContinueWatchingItems")
m.LoadContinueWatchingTask.control = "RUN"
2023-09-30 21:36:16 +00:00
end if
' If next up section exists, reload row's data
if m.homeSectionIndexes.doesExist("nextup")
m.LoadNextUpTask.observeField("content", "updateNextUpItems")
m.LoadNextUpTask.control = "RUN"
end if
' If favorites section exists, reload row's data
if m.homeSectionIndexes.doesExist("favorites")
m.LoadFavoritesTask.observeField("content", "updateFavoritesItems")
m.LoadFavoritesTask.control = "RUN"
end if
' If live tv's on now section exists, reload row's data
if m.homeSectionIndexes.doesExist("livetv")
m.LoadOnNowTask.observeField("content", "updateOnNowItems")
m.LoadOnNowTask.control = "RUN"
end if
' If latest in library section exists, reload row's data
hasLatestHomeSection = false
for each section in m.homeSectionIndexes
if LCase(Left(section, 6)) = "latest"
hasLatestHomeSection = true
exit for
end if
end for
if hasLatestHomeSection
updateLatestInRows()
end if
end sub
2022-11-05 00:37:54 +00:00
sub updateFavoritesItems()
itemData = m.LoadFavoritesTask.content
m.LoadFavoritesTask.unobserveField("content")
m.LoadFavoritesTask.content = []
if itemData = invalid then return
2023-09-30 21:36:16 +00:00
rowIndex = m.homeSectionIndexes.favorites
2022-11-05 00:37:54 +00:00
if itemData.count() < 1
2023-09-30 21:36:16 +00:00
removeHomeSection("favorites")
return
2022-11-05 00:37:54 +00:00
else
' remake row using the new data
row = CreateObject("roSGNode", "HomeRow")
row.title = tr("Favorites")
for each item in itemData
usePoster = true
if lcase(item.type) = "episode" or lcase(item.type) = "audio" or lcase(item.type) = "musicartist"
usePoster = false
end if
item.usePoster = usePoster
item.imageWidth = row.imageWidth
row.appendChild(item)
end for
2023-09-30 21:36:16 +00:00
' replace the old row
m.top.content.replaceChild(row, rowIndex)
2022-11-05 00:37:54 +00:00
end if
end sub
sub updateContinueWatchingItems()
itemData = m.LoadContinueWatchingTask.content
m.LoadContinueWatchingTask.unobserveField("content")
m.LoadContinueWatchingTask.content = []
2020-03-24 07:37:45 +00:00
if itemData = invalid then return
if itemData.count() < 1
2023-09-30 21:36:16 +00:00
removeHomeSection("resume")
return
end if
2023-09-30 21:36:16 +00:00
' remake row using the new data
row = CreateObject("roSGNode", "HomeRow")
row.title = tr("Continue Watching")
2020-03-24 07:37:45 +00:00
2023-09-30 21:36:16 +00:00
for each item in itemData
if isValid(item.json) and isValid(item.json.UserData) and isValid(item.json.UserData.PlayedPercentage)
item.PlayedPercentage = item.json.UserData.PlayedPercentage
2021-07-09 20:08:32 +00:00
end if
2023-04-13 19:41:11 +00:00
2023-09-30 21:36:16 +00:00
item.usePoster = row.usePoster
item.imageWidth = row.imageWidth
row.appendChild(item)
end for
' replace the old row
m.top.content.replaceChild(row, m.homeSectionIndexes.resume)
end sub
sub updateNextUpItems()
itemData = m.LoadNextUpTask.content
m.LoadNextUpTask.unobserveField("content")
m.LoadNextUpTask.content = []
if itemData = invalid then return
if itemData.count() < 1
2023-09-30 21:36:16 +00:00
removeHomeSection("nextup")
return
else
' remake row using the new data
row = CreateObject("roSGNode", "HomeRow")
row.title = tr("Next Up") + " >"
for each item in itemData
item.usePoster = row.usePoster
item.imageWidth = row.imageWidth
row.appendChild(item)
end for
2023-09-30 21:36:16 +00:00
' replace the old row
m.top.content.replaceChild(row, m.homeSectionIndexes.nextup)
2020-03-24 07:37:45 +00:00
end if
end sub
2021-07-09 20:08:32 +00:00
' Iterate over user's libraries and update data for each Latest In section
sub updateLatestInRows()
' Ensure we have data
if not isValidAndNotEmpty(m.libraryData) then return
2023-01-26 22:45:20 +00:00
' Load new data for each library
filteredLatest = filterNodeArray(m.libraryData, "id", m.global.session.user.configuration.LatestItemsExcludes)
2023-04-13 19:41:11 +00:00
for each lib in filteredLatest
if lib.collectionType <> "boxsets" and lib.collectionType <> "livetv" and lib.json.CollectionType <> "Program"
2023-04-13 19:41:11 +00:00
loadLatest = createObject("roSGNode", "LoadItemsTask")
loadLatest.itemsToLoad = "latest"
loadLatest.itemId = lib.id
2023-11-11 04:34:19 +00:00
metadata = {
"title": lib.name,
"contentType": lib.json.CollectionType
}
2023-04-13 19:41:11 +00:00
2023-11-11 04:34:19 +00:00
loadLatest.metadata = metadata
2023-04-13 19:41:11 +00:00
loadLatest.observeField("content", "updateLatestItems")
loadLatest.control = "RUN"
end if
end for
end sub
sub updateLatestItems(msg)
2021-07-09 20:08:32 +00:00
itemData = msg.GetData()
2020-03-24 07:37:45 +00:00
2021-07-09 20:08:32 +00:00
node = msg.getRoSGNode()
node.unobserveField("content")
node.content = []
if itemData = invalid then return
2020-03-24 07:37:45 +00:00
2023-09-30 21:36:16 +00:00
sectionName = "latestin" + LCase(node.metadata.title).Replace(" ", "")
if itemData.count() < 1
2023-09-30 21:36:16 +00:00
removeHomeSection(sectionName)
return
else
' remake row using new data
row = CreateObject("roSGNode", "HomeRow")
row.title = tr("Latest in") + " " + node.metadata.title + " >"
row.usePoster = true
' Handle specific types with different item widths
if node.metadata.contentType = "movies"
row.imageWidth = 180
itemSize = [188, 331]
else if node.metadata.contentType = "music"
row.imageWidth = 261
itemSize = [261, 331]
else
row.imageWidth = 464
itemSize = [464, 331]
2021-07-09 20:08:32 +00:00
end if
for each item in itemData
item.usePoster = row.usePoster
item.imageWidth = row.imageWidth
row.appendChild(item)
2021-07-09 20:08:32 +00:00
end for
2023-11-11 04:34:19 +00:00
rowIndex = m.homeSectionIndexes[sectionName]
' Replace the old row
if isValid(rowIndex)
updateSizeArray(itemSize, rowIndex, "replace")
m.top.content.replaceChild(row, rowIndex)
return
end if
' Determine highest index of a Lastest In section so we can append the new section after it
highestLatestHomeSectionIndex = 0
for each section in m.homeSectionIndexes
if LCase(Left(section, 6)) = "latest"
if m.homeSectionIndexes[section] > highestLatestHomeSectionIndex
highestLatestHomeSectionIndex = m.homeSectionIndexes[section]
end if
end if
end for
' We have data for a section that doesn't currently exist
rowIndex = highestLatestHomeSectionIndex + 1
' Advance all the indexes greater than or equal than our new row
for each section in m.homeSectionIndexes
if m.homeSectionIndexes[section] >= rowIndex
m.homeSectionIndexes[section]++
end if
end for
m.homeSectionIndexes.AddReplace(sectionName, rowIndex)
m.top.content.insertChild(row, rowIndex)
updateSizeArray(itemSize, rowIndex)
return
2020-03-24 07:37:45 +00:00
end if
end sub
sub updateOnNowItems()
itemData = m.LoadOnNowTask.content
m.LoadOnNowTask.unobserveField("content")
m.LoadOnNowTask.content = []
if itemData = invalid then return
if itemData.count() < 1
2023-09-30 21:36:16 +00:00
removeHomeSection("livetv")
return
else
' remake row using the new data
row = CreateObject("roSGNode", "HomeRow")
row.title = tr("On Now")
2023-11-12 14:45:13 +00:00
itemSize = [464, 331]
row.imageWidth = 464
for each item in itemData
row.usePoster = false
if (not isValid(item.thumbnailURL) or item.thumbnailURL = "") and isValid(item.json) and isValid(item.json.imageURL)
item.thumbnailURL = item.json.imageURL
row.usePoster = true
2023-11-12 14:45:13 +00:00
row.imageWidth = 180
itemSize = [188, 331]
end if
item.usePoster = row.usePoster
item.imageWidth = row.imageWidth
row.appendChild(item)
end for
2023-09-30 21:36:16 +00:00
' replace the old row
2023-11-12 14:45:13 +00:00
updateSizeArray(itemSize, m.homeSectionIndexes.livetv, "replace")
2023-09-30 21:36:16 +00:00
m.top.content.replaceChild(row, m.homeSectionIndexes.livetv)
end if
end sub
2020-12-06 04:59:32 +00:00
sub updateSizeArray(rowItemSize, rowIndex = invalid, action = "insert")
2021-07-09 20:08:32 +00:00
sizeArray = m.top.rowItemSize
' append by default
if rowIndex = invalid
rowIndex = sizeArray.count()
2020-03-24 07:37:45 +00:00
end if
2021-07-09 20:08:32 +00:00
newSizeArray = []
for i = 0 to sizeArray.count()
if rowIndex = i
if action = "replace"
newSizeArray.Push(rowItemSize)
2021-07-09 20:08:32 +00:00
else if action = "insert"
newSizeArray.Push(rowItemSize)
if isValid(sizeArray[i])
newSizeArray.Push(sizeArray[i])
2021-07-09 20:08:32 +00:00
end if
end if
else if isValid(sizeArray[i])
newSizeArray.Push(sizeArray[i])
2021-07-09 20:08:32 +00:00
end if
end for
m.top.rowItemSize = newSizeArray
end sub
sub itemSelected()
2021-07-09 20:08:32 +00:00
m.top.selectedItem = m.top.content.getChild(m.top.rowItemSelected[0]).getChild(m.top.rowItemSelected[1])
'Prevent the selected item event from double firing
m.top.selectedItem = invalid
end sub
2020-04-04 22:24:47 +00:00
function onKeyEvent(key as string, press as boolean) as boolean
2021-07-09 20:08:32 +00:00
if press
if key = "play"
print "play was pressed from homerow"
2021-07-09 20:08:32 +00:00
itemToPlay = m.top.content.getChild(m.top.rowItemFocused[0]).getChild(m.top.rowItemFocused[1])
if isValid(itemToPlay)
2021-07-09 20:08:32 +00:00
m.top.quickPlayNode = itemToPlay
end if
return true
else if key = "replay"
m.top.jumpToRowItem = [m.top.rowItemFocused[0], 0]
return true
end if
end if
return false
2020-04-04 22:24:47 +00:00
end function
2020-12-06 04:59:32 +00:00
function filterNodeArray(nodeArray as object, nodeKey as string, excludeArray as object) as object
2021-07-09 20:08:32 +00:00
if excludeArray.IsEmpty() then return nodeArray
newNodeArray = []
for each node in nodeArray
excludeThisNode = false
for each exclude in excludeArray
if node[nodeKey] = exclude
excludeThisNode = true
end if
end for
if excludeThisNode = false
newNodeArray.Push(node)
end if
2020-12-06 04:59:32 +00:00
end for
2021-07-09 20:08:32 +00:00
return newNodeArray
2022-05-30 12:57:40 +00:00
end function