Add setting to match web's home sections

This commit is contained in:
1hitsong 2023-11-23 08:52:44 -05:00
parent 06af8b2030
commit 867667f516
7 changed files with 90 additions and 26 deletions

View File

@ -18,4 +18,4 @@
"docs/api/**": true "docs/api/**": true
}, },
"brightscriptcomment.addExtraAtStartAndEnd": false "brightscriptcomment.addExtraAtStartAndEnd": false
} }

5
components/ImageSizes.bs Normal file
View File

@ -0,0 +1,5 @@
namespace imageSizes
const WIDE_POSTER = [464, 331]
const MOVIE_POSTER = [188, 331]
const MUSIC_ALBUM = [261, 331]
end namespace

View File

@ -1,4 +1,9 @@
import "pkg:/source/utils/misc.bs" import "pkg:/source/utils/misc.bs"
import "pkg:/components/ImageSizes.bs"
' The maximum number of seconds we will show the loading spinner and delay the user from using the home view while the content loads
' We use this to wait for the rows to load so we can reset focus to the row/item once it loads
const MAX_TIME_HOME_LOADING_SPINNER_SHOWN = 1
sub init() sub init()
m.top.itemComponentName = "HomeItem" m.top.itemComponentName = "HomeItem"
@ -14,6 +19,11 @@ sub init()
m.homeSections = {} m.homeSections = {}
m.loadingTimer = createObject("roSGNode", "Timer")
m.loadingTimer.duration = MAX_TIME_HOME_LOADING_SPINNER_SHOWN
m.loadingTimer.repeat = true
m.loadingTimer.observeField("fire", "stopLoadingSpinner")
updateSize() updateSize()
m.top.setfocus(true) m.top.setfocus(true)
@ -190,7 +200,7 @@ sub createLibraryRow(content as dynamic)
mediaRow.title = tr("My Media") mediaRow.title = tr("My Media")
m.homeSections.AddReplace("library", { m.homeSections.AddReplace("library", {
imageSize: [464, 331], imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count() index: m.homeSections.count()
}) })
@ -212,12 +222,12 @@ sub createLatestInRows(content as dynamic)
latestInRow = content.CreateChild("HomeRow") latestInRow = content.CreateChild("HomeRow")
latestInRow.title = tr("Latest in") + " " + lib.name + " >" latestInRow.title = tr("Latest in") + " " + lib.name + " >"
imagesize = [464, 331] imagesize = imageSizes.WIDE_POSTER
if LCase(lib.collectionType) = "movies" if LCase(lib.collectionType) = "movies"
imagesize = [188, 331] imagesize = imageSizes.MOVIE_POSTER
else if LCase(lib.collectionType) = "music" else if LCase(lib.collectionType) = "music"
imagesize = [261, 331] imagesize = imageSizes.MUSIC_ALBUM
end if end if
m.homeSections.AddReplace("latestin" + LCase(lib.name).Replace(" ", ""), { m.homeSections.AddReplace("latestin" + LCase(lib.name).Replace(" ", ""), {
@ -244,7 +254,7 @@ sub createLiveTVRow(content as dynamic)
contentRow = content.CreateChild("HomeRow") contentRow = content.CreateChild("HomeRow")
contentRow.title = tr("On Now") contentRow.title = tr("On Now")
m.homeSections.AddReplace("livetv", { m.homeSections.AddReplace("livetv", {
imageSize: [464, 331], imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count() index: m.homeSections.count()
}) })
@ -257,7 +267,7 @@ sub createContinueWatchingRow(content as dynamic)
continueWatchingRow = content.CreateChild("HomeRow") continueWatchingRow = content.CreateChild("HomeRow")
continueWatchingRow.title = tr("Continue Watching") continueWatchingRow.title = tr("Continue Watching")
m.homeSections.AddReplace("resume", { m.homeSections.AddReplace("resume", {
imageSize: [464, 331], imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count() index: m.homeSections.count()
}) })
@ -271,7 +281,7 @@ sub createNextUpRow(content as dynamic)
nextUpRow = content.CreateChild("HomeRow") nextUpRow = content.CreateChild("HomeRow")
nextUpRow.title = tr("Next Up >") nextUpRow.title = tr("Next Up >")
m.homeSections.AddReplace("nextup", { m.homeSections.AddReplace("nextup", {
imageSize: [464, 331], imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count() index: m.homeSections.count()
}) })
@ -286,7 +296,7 @@ sub createFavoritesRow(content as dynamic)
favoritesRow.title = tr("Favorites") favoritesRow.title = tr("Favorites")
m.homeSections.AddReplace("favorites", { m.homeSections.AddReplace("favorites", {
imageSize: [464, 331], imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count() index: m.homeSections.count()
}) })
@ -297,6 +307,7 @@ end sub
' Update home row data ' Update home row data
sub updateHomeRows() sub updateHomeRows()
startMediaLoadingSpinner()
content = processUserSections() content = processUserSections()
setRowItemSizes() setRowItemSizes()
m.top.content = content m.top.content = content
@ -375,6 +386,7 @@ sub updateNextUpItems()
itemData = m.LoadNextUpTask.content itemData = m.LoadNextUpTask.content
m.LoadNextUpTask.unobserveField("content") m.LoadNextUpTask.unobserveField("content")
m.LoadNextUpTask.content = [] m.LoadNextUpTask.content = []
m.LoadNextUpTask.control = "STOP"
if itemData = invalid then return if itemData = invalid then return
@ -444,14 +456,14 @@ sub updateLatestItems(msg)
row.usePoster = true row.usePoster = true
' Handle specific types with different item widths ' Handle specific types with different item widths
if node.metadata.contentType = "movies" if node.metadata.contentType = "movies"
row.imageWidth = 180 row.imageWidth = imageSizes.MOVIE_POSTER[0]
itemSize = [188, 331] itemSize = imageSizes.MOVIE_POSTER
else if node.metadata.contentType = "music" else if node.metadata.contentType = "music"
row.imageWidth = 261 row.imageWidth = imageSizes.MUSIC_ALBUM[0]
itemSize = [261, 331] itemSize = imageSizes.MUSIC_ALBUM
else else
row.imageWidth = 464 row.imageWidth = imageSizes.WIDE_POSTER[0]
itemSize = [464, 331] itemSize = imageSizes.WIDE_POSTER
end if end if
for each item in itemData for each item in itemData
@ -512,9 +524,21 @@ end sub
' setFocusToPreviousFocusedItem: Sets the cursor focus to the row and item previously selected ' setFocusToPreviousFocusedItem: Sets the cursor focus to the row and item previously selected
' '
sub setFocusToPreviousFocusedItem() sub setFocusToPreviousFocusedItem()
m.loadingTimer.control = "start"
if isValid(m.selectedRowItem) if isValid(m.selectedRowItem)
if isValid(m.homeSections[m.selectedRowItem[0]]) ' Set focus to row if it exists
m.top.jumpToRowItem = [m.homeSections[m.selectedRowItem[0]].index, m.selectedRowItem[1]] itemRow = m.top.content.getChild(m.top.rowItemSelected[0])
if isValid(itemRow)
m.top.jumpToItem = m.top.rowItemSelected[0]
' Set focus to column if it exists
itemColumn = itemRow.getChild(m.top.rowItemSelected[1])
if isValid(itemColumn)
m.top.jumpToRowItem = [m.selectedRowItem[0], m.selectedRowItem[1]]
m.loadingTimer.control = "stop"
stopLoadingSpinner()
end if
end if end if
end if end if
end sub end sub
@ -533,16 +557,18 @@ sub updateOnNowItems()
' remake row using the new data ' remake row using the new data
row = CreateObject("roSGNode", "HomeRow") row = CreateObject("roSGNode", "HomeRow")
row.title = tr("On Now") row.title = tr("On Now")
'itemSize = [464, 331] row.imageWidth = imageSizes.WIDE_POSTER[0]
row.imageWidth = 464
for each item in itemData for each item in itemData
row.usePoster = false row.usePoster = false
if (not isValid(item.thumbnailURL) or item.thumbnailURL = "") and isValid(item.json) and isValid(item.json.imageURL) if (not isValid(item.thumbnailURL) or item.thumbnailURL = "") and isValid(item.json) and isValid(item.json.imageURL)
item.thumbnailURL = item.json.imageURL item.thumbnailURL = item.json.imageURL
row.usePoster = true row.usePoster = true
row.imageWidth = 180 row.imageWidth = imageSizes.MOVIE_POSTER[0]
'itemSize = [188, 331]
m.homeSections.livetv.imageSize = imageSizes.MOVIE_POSTER
end if end if
item.usePoster = row.usePoster item.usePoster = row.usePoster
item.imageWidth = row.imageWidth item.imageWidth = row.imageWidth
row.appendChild(item) row.appendChild(item)
@ -553,15 +579,14 @@ sub updateOnNowItems()
' Set focus on previously focused item ' Set focus on previously focused item
setFocusToPreviousFocusedItem() setFocusToPreviousFocusedItem()
' We may now have different poster sizes. Reset the row item sizes
setRowItemSizes()
end if end if
end sub end sub
sub itemSelected() sub itemSelected()
for each section in m.homeSections m.selectedRowItem = m.top.rowItemSelected
if m.homeSections[section].index = m.top.rowItemSelected[0]
m.selectedRowItem = [section, m.top.rowItemSelected[1]]
end if
end for
m.top.selectedItem = m.top.content.getChild(m.top.rowItemSelected[0]).getChild(m.top.rowItemSelected[1]) m.top.selectedItem = m.top.content.getChild(m.top.rowItemSelected[0]).getChild(m.top.rowItemSelected[1])

View File

@ -1231,5 +1231,15 @@
<translation>No Chapter Data Found</translation> <translation>No Chapter Data Found</translation>
<extracomment>Message shown in OSD when no chapter data is returned by the API</extracomment> <extracomment>Message shown in OSD when no chapter data is returned by the API</extracomment>
</message> </message>
<message>
<source>Use Web's Home Section Arrangement</source>
<translation>Use Web's Home Section Arrangement</translation>
<extracomment>User Setting - Setting title</extracomment>
</message>
<message>
<source>Make the arrangement of the Roku home view sections match the web's home screen. Jellyfin will need to be closed and reopened for change to take effect.</source>
<translation>Make the arrangement of the Roku home view sections match the web's home screen. Jellyfin will need to be closed and reopened for change to take effect.</translation>
<extracomment>User Setting - Setting description</extracomment>
</message>
</context> </context>
</TS> </TS>

View File

@ -231,6 +231,13 @@
"settingName": "ui.home.splashBackground", "settingName": "ui.home.splashBackground",
"type": "bool", "type": "bool",
"default": "false" "default": "false"
},
{
"title": "Use Web's Home Section Arrangement",
"description": "Make the arrangement of the Roku home view sections match the web's home screen. Jellyfin will need to be closed and reopened for change to take effect.",
"settingName": "ui.home.useWebSectionArrangement",
"type": "bool",
"default": "false"
} }
] ]
}, },

View File

@ -459,6 +459,9 @@ sub startLoadingSpinner()
end sub end sub
sub startMediaLoadingSpinner() sub startMediaLoadingSpinner()
if not isValid(m.scene)
m.scene = m.top.getScene()
end if
dialog = createObject("roSGNode", "ProgressDialog") dialog = createObject("roSGNode", "ProgressDialog")
dialog.id = "invisibiledialog" dialog.id = "invisibiledialog"
dialog.visible = false dialog.visible = false

View File

@ -226,6 +226,20 @@ namespace session
userPreferences = customPrefs userPreferences = customPrefs
rowTypes = [] rowTypes = []
' If this is a first time user, set the useWebSectionArrangement setting to true
' This way the home view for upgrading users is not changed without them opting in
if not isValid(m.global.app.lastRunVersion)
set_user_setting("ui.home.useWebSectionArrangement", "true")
end if
useWebSectionArrangement = m.global.session.user.settings["ui.home.useWebSectionArrangement"]
if isValid(useWebSectionArrangement)
if not useWebSectionArrangement
userPreferences.delete("homesection0")
end if
end if
' If user has no section preferences, use default settings ' If user has no section preferences, use default settings
if not userPreferences.doesExist("homesection0") if not userPreferences.doesExist("homesection0")
userPreferences = { userPreferences = {