Initial Changes to Support Next-Up Behavior

This commit is contained in:
Reynolds 2024-10-11 10:28:06 -04:00
parent 9086dd867d
commit 34b0978a7d
11 changed files with 124 additions and 14 deletions

View File

@ -686,6 +686,7 @@ end sub
sub itemSelected()
m.selectedRowItem = m.top.rowItemSelected
m.global.launchSource = "home"
m.top.selectedItem = m.top.content.getChild(m.top.rowItemSelected[0]).getChild(m.top.rowItemSelected[1])
'Prevent the selected item event from double firing

View File

@ -6,11 +6,28 @@ sub init()
m.top.showRowLabel = [false]
m.top.observeField("selectItemId", "onItemSelected")
updateSize()
m.top.setFocus(true)
end sub
sub onItemSelected()
Id = m.top.selectItemId
if Id <> invalid and Id <> "" and m.top.objects <> invalid
for i = 0 to m.top.objects.items.count() - 1
item = m.top.objects.items[i]
if item.id = Id
m.top.jumpToItem = i
return
end if
end for
end if
end sub
sub updateSize()
m.top.translation = [450, 180]

View File

@ -4,5 +4,8 @@
<field id="objects" type="assocarray" onChange="setupRows" />
<field id="escapeButton" type="string" alwaysNotify="true" />
<field id="doneLoading" type="boolean" />
<field id="selectItemId" type="string" />
<function name="onItemSelected" />
</interface>
</component>

View File

@ -4,9 +4,15 @@ sub init()
m.rows = m.top.findNode("tvEpisodeRow")
m.tvListOptions = m.top.findNode("tvListOptions")
m.top.observeField("selectItemId", "onItemSelected")
m.rows.observeField("doneLoading", "rowsDoneLoading")
end sub
sub onItemSelected()
Id = m.top.selectItemId
m.rows.selectItemId = Id
end sub
sub setupRows()
objects = m.top.objects
m.rows.objects = objects

View File

@ -8,5 +8,8 @@
<field id="objects" type="assocarray" onChange="setupRows" />
<field id="itemSelected" type="integer" />
<field id="doneLoading" type="boolean" />
<field id="selectItemId" type="string" />
<function name="onItemSelected" />
</interface>
</component>

View File

@ -6,6 +6,7 @@ import "pkg:/source/api/sdk.bs"
sub init()
m.top.optionsAvailable = false
m.top.observeField("selectItemId", "onItemSelected")
m.rows = m.top.findNode("picker")
m.poster = m.top.findNode("seasonPoster")
@ -25,6 +26,11 @@ sub setSeasonLoading()
m.top.overhangTitle = tr("Loading...")
end sub
sub onItemSelected()
Id = m.top.selectItemId
m.rows.selectItemId = Id
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)
@ -73,6 +79,7 @@ end function
' OnScreenShown: Callback function when view is presented on screen
'
sub OnScreenShown()
if m.isFirstRun
m.isFirstRun = false
return
@ -80,6 +87,7 @@ sub OnScreenShown()
m.tvEpisodeRow.setFocus(true)
m.top.refreshSeasonDetailsData = not m.top.refreshSeasonDetailsData
end sub
' Handle navigation input from the remote and act on it

View File

@ -19,6 +19,9 @@
<field id="objects" alias="picker.objects" />
<field id="episodeObjects" type="assocarray" />
<field id="extrasObjects" type="assocarray" onChange="setExtraButtonVisibility" />
<field id="selectItemId" type="string" />
<function name="updateSeason" />
<function name="onItemSelected" />
</interface>
</component>

View File

@ -1321,5 +1321,30 @@
<translation>Use Show Image</translation>
<extracomment>User Setting - Setting option title</extracomment>
</message>
<message>
<source>Episode Next Up Behavior</source>
<translation>Episode Next Up Behavior</translation>
<extracomment>User Setting - Setting option title</extracomment>
</message>
<message>
<source>What should clicking a Next Up episode do.</source>
<translation>What should clicking a Next Up episode do.</translation>
<extracomment>User Setting - Setting description</extracomment>
</message>
<message>
<source>Play Episode Immediately</source>
<translation>Play Episode Immediately</translation>
<extracomment>User Setting - Setting option title</extracomment>
</message>
<message>
<source>View Episode Details</source>
<translation>View Episode Details</translation>
<extracomment>User Setting - Setting option title</extracomment>
</message>
<message>
<source>View Season Details</source>
<translation>View Season Details</translation>
<extracomment>User Setting - Setting option title</extracomment>
</message>
</context>
</TS>
</TS>

View File

@ -262,6 +262,27 @@
}
]
},
{
"title": "Episode Next Up Behavior",
"description": "What should clicking a Next Up episode do.",
"settingName": "ui.general.episodenextupbehavior",
"type": "radio",
"default": "play",
"options": [
{
"title": "Play Episode Immediately",
"id": "play"
},
{
"title": "View Episode Details",
"id": "episode"
},
{
"title": "View Season Details",
"id": "season"
}
]
},
{
"title": "Hide Clock",
"description": "Hide all clocks in Jellyfin. Jellyfin will need to be closed and reopened for changes to take effect.",

View File

@ -36,7 +36,7 @@ sub Main (args as dynamic) as void
sceneManager = CreateObject("roSGNode", "SceneManager")
sceneManager.observeField("dataReturned", m.port)
m.global.addFields({ app_loaded: false, playstateTask: playstateTask, sceneManager: sceneManager })
m.global.addFields({ app_loaded: false, playstateTask: playstateTask, sceneManager: sceneManager, launchSource: "" })
m.global.addFields({ queueManager: CreateObject("roSGNode", "QueueManager") })
m.global.addFields({ audioPlayer: CreateObject("roSGNode", "AudioPlayer") })
@ -304,22 +304,39 @@ sub Main (args as dynamic) as void
audio_stream_idx = selectedItem.selectedAudioStreamIndex
end if
launchSource = m.global.launchSource
m.global.launchSource = ""
selectedItem.selectedAudioStreamIndex = audio_stream_idx
' Display playback options dialog
if selectedItem.json.userdata.PlaybackPositionTicks > 0
m.global.queueManager.callFunc("hold", selectedItem)
playbackOptionDialog(selectedItem.json.userdata.PlaybackPositionTicks, selectedItem.json)
else
m.global.queueManager.callFunc("clear")
m.global.queueManager.callFunc("push", selectedItem)
m.global.queueManager.callFunc("playQueue")
localGlobal = m.global
' we only use this special steering logic from the home screen
if localGlobal.session.user.settings["ui.general.episodenextupbehavior"] = "play" or launchSource <> "home"
' Display playback options dialog
if selectedItem.json.userdata.PlaybackPositionTicks > 0
m.global.queueManager.callFunc("hold", selectedItem)
playbackOptionDialog(selectedItem.json.userdata.PlaybackPositionTicks, selectedItem.json)
else
m.global.queueManager.callFunc("clear")
m.global.queueManager.callFunc("push", selectedItem)
m.global.queueManager.callFunc("playQueue")
end if
else if localGlobal.session.user.settings["ui.general.episodenextupbehavior"] = "episode"
group = CreateMovieDetailsGroup(selectedItem)
else if localGlobal.session.user.settings["ui.general.episodenextupbehavior"] = "season"
group = CreateSeasonDetailsGroupByID(selectedItem.json.SeriesId, selectedItem.json.SeasonId, selectedItem.id)
end if
else if selectedItemType = "Series"
group = CreateSeriesDetailsGroup(selectedItem.json.id)
else if selectedItemType = "Season"
if isValid(selectedItem.json) and isValid(selectedItem.json.SeriesId) and isValid(selectedItem.id)
group = CreateSeasonDetailsGroupByID(selectedItem.json.SeriesId, selectedItem.id)
group = CreateSeasonDetailsGroupByID(selectedItem.json.SeriesId, selectedItem.id, "")
else
stopLoadingSpinner()
message_dialog(tr("Error loading Season"))
@ -860,7 +877,7 @@ sub Main (args as dynamic) as void
else if popupNode.returnData.indexselected = 3
' User chose Go to season
if isValid(selectedItem[0].json) and isValid(selectedItem[0].json.SeriesId) and isValid(selectedItem[0].json.seasonID)
CreateSeasonDetailsGroupByID(selectedItem[0].json.SeriesId, selectedItem[0].json.seasonID)
CreateSeasonDetailsGroupByID(selectedItem[0].json.SeriesId, selectedItem[0].json.seasonID, "")
else
stopLoadingSpinner()
message_dialog(tr("Error loading Season"))

View File

@ -646,7 +646,7 @@ function CreateSeriesDetailsGroup(seriesID as string) as dynamic
' Divert to season details if user setting goStraightToEpisodeListing is enabled and only one season exists.
if seasonData <> invalid and m.global.session.user.settings["ui.tvshows.goStraightToEpisodeListing"] and seasonData.Items.Count() = 1
stopLoadingSpinner()
return CreateSeasonDetailsGroupByID(seriesID, seasonData.Items[0].id)
return CreateSeasonDetailsGroupByID(seriesID, seasonData.Items[0].id, "")
end if
' start building SeriesDetails view
group = CreateObject("roSGNode", "TVShowDetails")
@ -793,7 +793,7 @@ function CreateSeasonDetailsGroup(series as object, season as object) as dynamic
return group
end function
function CreateSeasonDetailsGroupByID(seriesID as string, seasonID as string) as dynamic
function CreateSeasonDetailsGroupByID(seriesID as string, seasonID as string, selectId as string) as dynamic
' validate parameters
if seriesID = "" or seasonID = "" then return invalid
@ -805,9 +805,11 @@ function CreateSeasonDetailsGroupByID(seriesID as string, seasonID as string) as
stopLoadingSpinner()
return invalid
end if
' start building SeasonDetails view
group = CreateObject("roSGNode", "TVEpisodes")
group.optionsAvailable = false
' push scene asap (to prevent extra button presses when retriving series/movie info)
group.seasonData = seasonMetaData.json
group.objects = TVEpisodes(seriesID, seasonID)
@ -821,6 +823,10 @@ function CreateSeasonDetailsGroupByID(seriesID as string, seasonID as string) as
' check for specials/extras for this season
group.extrasObjects = TVSeasonExtras(seasonID)
group.observeField("sceneReady", "onSceneReady")
group.selectItemId = selectId
' finished building SeasonDetails view
return group
end function