From 867667f5168d1619f290682c6ad1a6db8cba32d1 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Thu, 23 Nov 2023 08:52:44 -0500
Subject: [PATCH] Add setting to match web's home sections
---
.vscode/settings.json | 2 +-
components/ImageSizes.bs | 5 +++
components/home/HomeRows.bs | 75 ++++++++++++++++++++++++------------
locale/en_US/translations.ts | 10 +++++
settings/settings.json | 7 ++++
source/utils/misc.bs | 3 ++
source/utils/session.bs | 14 +++++++
7 files changed, 90 insertions(+), 26 deletions(-)
create mode 100644 components/ImageSizes.bs
diff --git a/.vscode/settings.json b/.vscode/settings.json
index a005ef42..746c772b 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -18,4 +18,4 @@
"docs/api/**": true
},
"brightscriptcomment.addExtraAtStartAndEnd": false
-}
+}
\ No newline at end of file
diff --git a/components/ImageSizes.bs b/components/ImageSizes.bs
new file mode 100644
index 00000000..2371a30f
--- /dev/null
+++ b/components/ImageSizes.bs
@@ -0,0 +1,5 @@
+namespace imageSizes
+ const WIDE_POSTER = [464, 331]
+ const MOVIE_POSTER = [188, 331]
+ const MUSIC_ALBUM = [261, 331]
+end namespace
diff --git a/components/home/HomeRows.bs b/components/home/HomeRows.bs
index 9ab20876..f5895e88 100644
--- a/components/home/HomeRows.bs
+++ b/components/home/HomeRows.bs
@@ -1,4 +1,9 @@
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()
m.top.itemComponentName = "HomeItem"
@@ -14,6 +19,11 @@ sub init()
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()
m.top.setfocus(true)
@@ -190,7 +200,7 @@ sub createLibraryRow(content as dynamic)
mediaRow.title = tr("My Media")
m.homeSections.AddReplace("library", {
- imageSize: [464, 331],
+ imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count()
})
@@ -212,12 +222,12 @@ sub createLatestInRows(content as dynamic)
latestInRow = content.CreateChild("HomeRow")
latestInRow.title = tr("Latest in") + " " + lib.name + " >"
- imagesize = [464, 331]
+ imagesize = imageSizes.WIDE_POSTER
if LCase(lib.collectionType) = "movies"
- imagesize = [188, 331]
+ imagesize = imageSizes.MOVIE_POSTER
else if LCase(lib.collectionType) = "music"
- imagesize = [261, 331]
+ imagesize = imageSizes.MUSIC_ALBUM
end if
m.homeSections.AddReplace("latestin" + LCase(lib.name).Replace(" ", ""), {
@@ -244,7 +254,7 @@ sub createLiveTVRow(content as dynamic)
contentRow = content.CreateChild("HomeRow")
contentRow.title = tr("On Now")
m.homeSections.AddReplace("livetv", {
- imageSize: [464, 331],
+ imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count()
})
@@ -257,7 +267,7 @@ sub createContinueWatchingRow(content as dynamic)
continueWatchingRow = content.CreateChild("HomeRow")
continueWatchingRow.title = tr("Continue Watching")
m.homeSections.AddReplace("resume", {
- imageSize: [464, 331],
+ imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count()
})
@@ -271,7 +281,7 @@ sub createNextUpRow(content as dynamic)
nextUpRow = content.CreateChild("HomeRow")
nextUpRow.title = tr("Next Up >")
m.homeSections.AddReplace("nextup", {
- imageSize: [464, 331],
+ imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count()
})
@@ -286,7 +296,7 @@ sub createFavoritesRow(content as dynamic)
favoritesRow.title = tr("Favorites")
m.homeSections.AddReplace("favorites", {
- imageSize: [464, 331],
+ imageSize: imageSizes.WIDE_POSTER,
index: m.homeSections.count()
})
@@ -297,6 +307,7 @@ end sub
' Update home row data
sub updateHomeRows()
+ startMediaLoadingSpinner()
content = processUserSections()
setRowItemSizes()
m.top.content = content
@@ -375,6 +386,7 @@ sub updateNextUpItems()
itemData = m.LoadNextUpTask.content
m.LoadNextUpTask.unobserveField("content")
m.LoadNextUpTask.content = []
+ m.LoadNextUpTask.control = "STOP"
if itemData = invalid then return
@@ -444,14 +456,14 @@ sub updateLatestItems(msg)
row.usePoster = true
' Handle specific types with different item widths
if node.metadata.contentType = "movies"
- row.imageWidth = 180
- itemSize = [188, 331]
+ row.imageWidth = imageSizes.MOVIE_POSTER[0]
+ itemSize = imageSizes.MOVIE_POSTER
else if node.metadata.contentType = "music"
- row.imageWidth = 261
- itemSize = [261, 331]
+ row.imageWidth = imageSizes.MUSIC_ALBUM[0]
+ itemSize = imageSizes.MUSIC_ALBUM
else
- row.imageWidth = 464
- itemSize = [464, 331]
+ row.imageWidth = imageSizes.WIDE_POSTER[0]
+ itemSize = imageSizes.WIDE_POSTER
end if
for each item in itemData
@@ -512,9 +524,21 @@ end sub
' setFocusToPreviousFocusedItem: Sets the cursor focus to the row and item previously selected
'
sub setFocusToPreviousFocusedItem()
+ m.loadingTimer.control = "start"
+
if isValid(m.selectedRowItem)
- if isValid(m.homeSections[m.selectedRowItem[0]])
- m.top.jumpToRowItem = [m.homeSections[m.selectedRowItem[0]].index, m.selectedRowItem[1]]
+ ' Set focus to row if it exists
+ 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 sub
@@ -533,16 +557,18 @@ sub updateOnNowItems()
' remake row using the new data
row = CreateObject("roSGNode", "HomeRow")
row.title = tr("On Now")
- 'itemSize = [464, 331]
- row.imageWidth = 464
+ row.imageWidth = imageSizes.WIDE_POSTER[0]
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
- row.imageWidth = 180
- 'itemSize = [188, 331]
+ row.imageWidth = imageSizes.MOVIE_POSTER[0]
+
+ m.homeSections.livetv.imageSize = imageSizes.MOVIE_POSTER
end if
+
item.usePoster = row.usePoster
item.imageWidth = row.imageWidth
row.appendChild(item)
@@ -553,15 +579,14 @@ sub updateOnNowItems()
' Set focus on previously focused item
setFocusToPreviousFocusedItem()
+ ' We may now have different poster sizes. Reset the row item sizes
+ setRowItemSizes()
+
end if
end sub
sub itemSelected()
- for each section in m.homeSections
- if m.homeSections[section].index = m.top.rowItemSelected[0]
- m.selectedRowItem = [section, m.top.rowItemSelected[1]]
- end if
- end for
+ m.selectedRowItem = m.top.rowItemSelected
m.top.selectedItem = m.top.content.getChild(m.top.rowItemSelected[0]).getChild(m.top.rowItemSelected[1])
diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts
index eccdff59..54af561b 100644
--- a/locale/en_US/translations.ts
+++ b/locale/en_US/translations.ts
@@ -1231,5 +1231,15 @@
No Chapter Data FoundMessage shown in OSD when no chapter data is returned by the API
+
+
+ Use Web's Home Section Arrangement
+ User Setting - Setting title
+
+
+
+ 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.
+ User Setting - Setting description
+
\ No newline at end of file
diff --git a/settings/settings.json b/settings/settings.json
index 497202f6..bbe71386 100644
--- a/settings/settings.json
+++ b/settings/settings.json
@@ -231,6 +231,13 @@
"settingName": "ui.home.splashBackground",
"type": "bool",
"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"
}
]
},
diff --git a/source/utils/misc.bs b/source/utils/misc.bs
index 3cb48ed9..e9d2c5f8 100644
--- a/source/utils/misc.bs
+++ b/source/utils/misc.bs
@@ -459,6 +459,9 @@ sub startLoadingSpinner()
end sub
sub startMediaLoadingSpinner()
+ if not isValid(m.scene)
+ m.scene = m.top.getScene()
+ end if
dialog = createObject("roSGNode", "ProgressDialog")
dialog.id = "invisibiledialog"
dialog.visible = false
diff --git a/source/utils/session.bs b/source/utils/session.bs
index d252661b..14518d35 100644
--- a/source/utils/session.bs
+++ b/source/utils/session.bs
@@ -226,6 +226,20 @@ namespace session
userPreferences = customPrefs
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 not userPreferences.doesExist("homesection0")
userPreferences = {