mirror of
https://github.com/jellyfin/jellyfin-roku.git
synced 2024-11-23 06:09:41 +00:00
Merge remote-tracking branch 'upstream/master' into next-up-behavior-configuration
This commit is contained in:
commit
7cad83592d
2
Makefile
2
Makefile
@ -3,7 +3,7 @@
|
||||
# If you want to get_images, you'll also need convert from ImageMagick
|
||||
##########################################################################
|
||||
|
||||
VERSION := 2.1.7
|
||||
VERSION := 2.2.0
|
||||
|
||||
## usage
|
||||
|
||||
|
@ -42,10 +42,10 @@ end sub
|
||||
|
||||
sub itemContentChanged()
|
||||
m.backdrop.blendColor = "#00a4db" ' set default in case global var is invalid
|
||||
localGlobal = m.global
|
||||
myGlobal = m.global
|
||||
|
||||
if isValid(localGlobal) and isValid(localGlobal.constants) and isValid(localGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = localGlobal.constants.poster_bg_pallet
|
||||
if isValid(myGlobal) and isValid(myGlobal.constants) and isValid(myGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = myGlobal.constants.poster_bg_pallet
|
||||
m.backdrop.blendColor = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
end if
|
||||
|
||||
@ -62,8 +62,8 @@ sub itemContentChanged()
|
||||
m.itemIcon.uri = itemData.iconUrl
|
||||
m.itemText.text = itemData.Title
|
||||
else if itemData.type = "Series"
|
||||
if isValid(localGlobal) and isValid(localGlobal.session) and isValid(localGlobal.session.user) and isValid(localGlobal.session.user.settings)
|
||||
if localGlobal.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"] = false
|
||||
if isValid(myGlobal) and isValid(myGlobal.session) and isValid(myGlobal.session.user) and isValid(myGlobal.session.user.settings)
|
||||
if myGlobal.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"] = false
|
||||
if isValid(itemData.json) and isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
|
@ -7,9 +7,11 @@ import "pkg:/source/roku_modules/log/LogMixin.brs"
|
||||
sub init()
|
||||
m.log = log.Logger("ItemGrid")
|
||||
m.log.debug("start init()")
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
m.options = m.top.findNode("options")
|
||||
|
||||
m.showItemCount = m.global.session.user.settings["itemgrid.showItemCount"]
|
||||
m.showItemCount = userSettings["itemgrid.showItemCount"]
|
||||
|
||||
m.tvGuide = invalid
|
||||
m.channelFocused = invalid
|
||||
@ -68,9 +70,9 @@ sub init()
|
||||
m.alphaMenu = m.alpha.findNode("alphaMenu")
|
||||
|
||||
'Get reset folder setting
|
||||
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
|
||||
m.resetGrid = userSettings["itemgrid.reset"]
|
||||
|
||||
m.top.gridTitles = m.global.session.user.settings["itemgrid.gridTitles"]
|
||||
m.top.gridTitles = userSettings["itemgrid.gridTitles"]
|
||||
m.log.debug("end init()")
|
||||
end sub
|
||||
|
||||
@ -84,6 +86,7 @@ sub loadInitialItems()
|
||||
m.log.debug("start loadInitialItems()")
|
||||
m.loadItemsTask.control = "stop"
|
||||
startLoadingSpinner()
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if m.top.parentItem.json.Type = "CollectionFolder" 'or m.top.parentItem.json.Type = "Folder"
|
||||
m.top.HomeLibraryItem = m.top.parentItem.Id
|
||||
@ -96,25 +99,25 @@ sub loadInitialItems()
|
||||
' Read view/sort/filter settings
|
||||
if m.top.parentItem.collectionType = "livetv"
|
||||
' Translate between app and server nomenclature
|
||||
viewSetting = m.global.session.user.settings["display.livetv.landing"]
|
||||
viewSetting = userSettings["display.livetv.landing"]
|
||||
if viewSetting = "guide"
|
||||
m.view = "tvGuide"
|
||||
else
|
||||
m.view = "livetv"
|
||||
end if
|
||||
m.sortField = m.global.session.user.settings["display.livetv.sortField"]
|
||||
sortAscendingStr = m.global.session.user.settings["display.livetv.sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display.livetv.filter"]
|
||||
m.sortField = userSettings["display.livetv.sortField"]
|
||||
sortAscendingStr = userSettings["display.livetv.sortAscending"]
|
||||
m.filter = userSettings["display.livetv.filter"]
|
||||
else if m.top.parentItem.collectionType = "music"
|
||||
m.view = m.global.session.user.settings["display.music.view"]
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = userSettings["display.music.view"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
else
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = m.global.session.user.settings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = userSettings["display." + m.top.parentItem.Id + ".landing"]
|
||||
end if
|
||||
|
||||
if m.sortField = invalid
|
||||
@ -180,7 +183,7 @@ sub loadInitialItems()
|
||||
m.loadItemsTask.itemType = "MusicArtist"
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
|
||||
m.view = m.global.session.user.settings["display.music.view"]
|
||||
m.view = userSettings["display.music.view"]
|
||||
|
||||
if m.view = "music-album"
|
||||
m.loadItemsTask.itemType = "MusicAlbum"
|
||||
@ -191,7 +194,7 @@ sub loadInitialItems()
|
||||
' For LiveTV, we want to "Fit" the item images, not zoom
|
||||
m.top.imageDisplayMode = "scaleToFit"
|
||||
|
||||
if m.global.session.user.settings["display.livetv.landing"] = "guide" and m.options.view <> "livetv"
|
||||
if userSettings["display.livetv.landing"] = "guide" and m.options.view <> "livetv"
|
||||
showTvGuide()
|
||||
end if
|
||||
else if m.top.parentItem.collectionType = "CollectionFolder" or m.top.parentItem.type = "CollectionFolder" or m.top.parentItem.collectionType = "boxsets" or m.top.parentItem.Type = "Boxset" or m.top.parentItem.Type = "Boxsets" or m.top.parentItem.Type = "Folder" or m.top.parentItem.Type = "Channel"
|
||||
|
@ -18,21 +18,23 @@ sub init()
|
||||
end sub
|
||||
|
||||
sub loadItems()
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' Reset intro tracker in case task gets reused
|
||||
m.top.isIntro = false
|
||||
|
||||
' Only show preroll once per queue
|
||||
if m.global.queueManager.callFunc("isPrerollActive")
|
||||
if queueManager.callFunc("isPrerollActive")
|
||||
' Prerolls not allowed if we're resuming video
|
||||
if m.global.queueManager.callFunc("getCurrentItem").startingPoint = 0
|
||||
if queueManager.callFunc("getCurrentItem").startingPoint = 0
|
||||
preRoll = GetIntroVideos(m.top.itemId)
|
||||
if isValid(preRoll) and preRoll.TotalRecordCount > 0 and isValid(preRoll.items[0])
|
||||
' If an error is thrown in the Intros plugin, instead of passing the error they pass the entire rick roll music video.
|
||||
' Bypass the music video and treat it as an error message
|
||||
if lcase(preRoll.items[0].name) <> "rick roll'd"
|
||||
m.global.queueManager.callFunc("push", m.global.queueManager.callFunc("getCurrentItem"))
|
||||
queueManager.callFunc("push", queueManager.callFunc("getCurrentItem"))
|
||||
m.top.itemId = preRoll.items[0].id
|
||||
m.global.queueManager.callFunc("setPrerollStatus", false)
|
||||
queueManager.callFunc("setPrerollStatus", false)
|
||||
m.top.isIntro = true
|
||||
end if
|
||||
end if
|
||||
@ -40,7 +42,7 @@ sub loadItems()
|
||||
end if
|
||||
|
||||
if m.top.selectedAudioStreamIndex = 0
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = queueManager.callFunc("getCurrentItem")
|
||||
if isValid(currentItem) and isValid(currentItem.json)
|
||||
m.top.selectedAudioStreamIndex = FindPreferredAudioStream(currentItem.json.MediaStreams)
|
||||
end if
|
||||
@ -78,6 +80,10 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
|
||||
return
|
||||
end if
|
||||
|
||||
queueManager = m.global.queueManager
|
||||
userSession = m.global.session.user
|
||||
userSettings = userSession.settings
|
||||
|
||||
session.video.Update(meta)
|
||||
|
||||
if isValid(meta.json.MediaSources[0].RunTimeTicks)
|
||||
@ -132,15 +138,14 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
|
||||
end if
|
||||
|
||||
if LCase(m.top.itemType) = "episode"
|
||||
userSession = m.global.session.user
|
||||
if userSession.settings["playback.playnextepisode"] = "enabled" or userSession.settings["playback.playnextepisode"] = "webclient" and userSession.Configuration.EnableNextEpisodeAutoPlay
|
||||
if userSettings["playback.playnextepisode"] = "enabled" or userSettings["playback.playnextepisode"] = "webclient" and userSession.Configuration.EnableNextEpisodeAutoPlay
|
||||
addNextEpisodesToQueue(video.showID)
|
||||
end if
|
||||
end if
|
||||
|
||||
playbackPosition = 0!
|
||||
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = queueManager.callFunc("getCurrentItem")
|
||||
|
||||
if isValid(currentItem) and isValid(currentItem.startingPoint)
|
||||
playbackPosition = currentItem.startingPoint
|
||||
@ -220,8 +225,8 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
|
||||
' transcode is that the Encoding Level is not supported, then try to direct play but silently
|
||||
' fall back to the transcode if that fails.
|
||||
if m.playbackInfo.MediaSources[0].MediaStreams.Count() > 0 and meta.live = false
|
||||
tryDirectPlay = m.global.session.user.settings["playback.tryDirect.h264ProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
|
||||
tryDirectPlay = tryDirectPlay or (m.global.session.user.settings["playback.tryDirect.hevcProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "hevc")
|
||||
tryDirectPlay = userSettings["playback.tryDirect.h264ProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
|
||||
tryDirectPlay = tryDirectPlay or (userSettings["playback.tryDirect.hevcProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "hevc")
|
||||
if tryDirectPlay and isValid(m.playbackInfo.MediaSources[0].TranscodingUrl) and forceTranscoding = false
|
||||
transcodingReasons = getTranscodeReasons(m.playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
if transcodingReasons.Count() = 1 and transcodingReasons[0] = "VideoLevelNotSupported"
|
||||
@ -261,7 +266,8 @@ end sub
|
||||
' @param {dynamic} videoID - id of video user is playing
|
||||
' @return {integer} indicating the default track's server-side index. Defaults to {SubtitleSelection.none} is one is not found
|
||||
function defaultSubtitleTrackFromVid(videoID) as integer
|
||||
if m.global.session.user.configuration.SubtitleMode = "None"
|
||||
userSession = m.global.session.user
|
||||
if userSession.configuration.SubtitleMode = "None"
|
||||
return SubtitleSelection.none ' No subtitles desired: return none
|
||||
end if
|
||||
|
||||
@ -287,7 +293,7 @@ function defaultSubtitleTrackFromVid(videoID) as integer
|
||||
return defaultTextSubs
|
||||
end if
|
||||
|
||||
if not m.global.session.user.settings["playback.subs.onlytext"]
|
||||
if not userSession.settings["playback.subs.onlytext"]
|
||||
return defaultSubtitleTrack(subtitles["all"], selectedAudioLanguage) ' if no appropriate text subs exist, allow non-text
|
||||
end if
|
||||
|
||||
@ -491,6 +497,8 @@ end function
|
||||
|
||||
' Add next episodes to the playback queue
|
||||
sub addNextEpisodesToQueue(showID)
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' Don't queue next episodes if we already have a playback queue
|
||||
maxQueueCount = 1
|
||||
|
||||
@ -498,13 +506,13 @@ sub addNextEpisodesToQueue(showID)
|
||||
maxQueueCount = 2
|
||||
end if
|
||||
|
||||
if m.global.queueManager.callFunc("getCount") > maxQueueCount then return
|
||||
if queueManager.callFunc("getCount") > maxQueueCount then return
|
||||
|
||||
videoID = m.top.itemId
|
||||
|
||||
' If first item is an intro video, use the next item in the queue
|
||||
if m.top.isIntro
|
||||
currentVideo = m.global.queueManager.callFunc("getItemByIndex", 1)
|
||||
currentVideo = queueManager.callFunc("getItemByIndex", 1)
|
||||
|
||||
if isValid(currentVideo) and isValid(currentVideo.id)
|
||||
videoID = currentVideo.id
|
||||
@ -526,7 +534,7 @@ sub addNextEpisodesToQueue(showID)
|
||||
|
||||
if isValid(data) and data.Items.Count() > 1
|
||||
for i = 1 to data.Items.Count() - 1
|
||||
m.global.queueManager.callFunc("push", data.Items[i])
|
||||
queueManager.callFunc("push", data.Items[i])
|
||||
end for
|
||||
end if
|
||||
end sub
|
||||
@ -585,8 +593,9 @@ function sortSubtitles(id as string, MediaStreams)
|
||||
end function
|
||||
|
||||
function FindPreferredAudioStream(streams as dynamic) as integer
|
||||
preferredLanguage = m.global.session.user.Configuration.AudioLanguagePreference
|
||||
playDefault = m.global.session.user.Configuration.PlayDefaultAudioTrack
|
||||
userConfig = m.global.session.user.configuration
|
||||
preferredLanguage = userConfig.AudioLanguagePreference
|
||||
playDefault = userConfig.PlayDefaultAudioTrack
|
||||
|
||||
if playDefault <> invalid and playDefault = true
|
||||
return 1
|
||||
|
@ -30,6 +30,7 @@ end sub
|
||||
|
||||
sub init()
|
||||
setupNodes()
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
m.overhang.isVisible = false
|
||||
|
||||
@ -39,7 +40,7 @@ sub init()
|
||||
alphaMicText = m.alpha.findNode("alphaMicText")
|
||||
alphaMicText.visible = false
|
||||
|
||||
m.showItemCount = m.global.session.user.settings["itemgrid.showItemCount"]
|
||||
m.showItemCount = userSettings["itemgrid.showItemCount"]
|
||||
|
||||
m.swapAnimation.observeField("state", "swapDone")
|
||||
|
||||
@ -86,7 +87,7 @@ sub init()
|
||||
m.loadItemsTask.totalRecordCount = 0
|
||||
|
||||
'Get reset folder setting
|
||||
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
|
||||
m.resetGrid = userSettings["itemgrid.reset"]
|
||||
end sub
|
||||
|
||||
sub OnScreenHidden()
|
||||
@ -112,6 +113,7 @@ end sub
|
||||
sub loadInitialItems()
|
||||
m.loadItemsTask.control = "stop"
|
||||
startLoadingSpinner(false)
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if m.top.parentItem.json.Type = "CollectionFolder"
|
||||
m.top.HomeLibraryItem = m.top.parentItem.Id
|
||||
@ -123,15 +125,15 @@ sub loadInitialItems()
|
||||
SetBackground("")
|
||||
end if
|
||||
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.filterOptions = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filterOptions"]
|
||||
m.view = m.global.session.user.settings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortAscending = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.filterOptions = userSettings["display." + m.top.parentItem.Id + ".filterOptions"]
|
||||
m.view = userSettings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortAscending = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
|
||||
' If user has not set a preferred view for this folder, check if they've set a default view
|
||||
if not isValid(m.view)
|
||||
m.view = m.global.session.user.settings["itemgrid.movieDefaultView"]
|
||||
m.view = userSettings["itemgrid.movieDefaultView"]
|
||||
end if
|
||||
|
||||
if not isValid(m.sortField) then m.sortField = "SortName"
|
||||
@ -200,7 +202,7 @@ sub loadInitialItems()
|
||||
m.itemGrid.numRows = "3"
|
||||
m.selectedMovieOverview.visible = false
|
||||
m.infoGroup.visible = false
|
||||
m.top.showItemTitles = m.global.session.user.settings["itemgrid.gridTitles"]
|
||||
m.top.showItemTitles = userSettings["itemgrid.gridTitles"]
|
||||
if LCase(m.top.showItemTitles) = "hidealways"
|
||||
m.itemGrid.itemSize = "[230, 315]"
|
||||
m.itemGrid.rowHeights = "[315]"
|
||||
|
@ -25,6 +25,7 @@ end sub
|
||||
|
||||
sub init()
|
||||
setupNodes()
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
m.overhang.isVisible = false
|
||||
|
||||
@ -34,7 +35,7 @@ sub init()
|
||||
alphaMicText = m.alpha.findNode("alphaMicText")
|
||||
alphaMicText.visible = false
|
||||
|
||||
m.showItemCount = m.global.session.user.settings["itemgrid.showItemCount"]
|
||||
m.showItemCount = userSettings["itemgrid.showItemCount"]
|
||||
|
||||
m.swapAnimation.observeField("state", "swapDone")
|
||||
|
||||
@ -80,7 +81,7 @@ sub init()
|
||||
m.loadItemsTask.totalRecordCount = 0
|
||||
|
||||
'Get reset folder setting
|
||||
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
|
||||
m.resetGrid = userSettings["itemgrid.reset"]
|
||||
end sub
|
||||
|
||||
sub OnScreenHidden()
|
||||
@ -106,6 +107,7 @@ end sub
|
||||
sub loadInitialItems()
|
||||
m.loadItemsTask.control = "stop"
|
||||
startLoadingSpinner(false)
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if LCase(m.top.parentItem.json.Type) = "collectionfolder"
|
||||
m.top.HomeLibraryItem = m.top.parentItem.Id
|
||||
@ -117,17 +119,17 @@ sub loadInitialItems()
|
||||
SetBackground("")
|
||||
end if
|
||||
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.sortAscending = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = m.global.session.user.settings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.sortAscending = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = userSettings["display." + m.top.parentItem.Id + ".landing"]
|
||||
|
||||
if not isValid(m.sortField) then m.sortField = "SortName"
|
||||
if not isValid(m.filter) then m.filter = "All"
|
||||
if not isValid(m.view) then m.view = "ArtistsPresentation"
|
||||
if not isValid(m.sortAscending) then m.sortAscending = true
|
||||
|
||||
m.top.showItemTitles = m.global.session.user.settings["itemgrid.gridTitles"]
|
||||
m.top.showItemTitles = userSettings["itemgrid.gridTitles"]
|
||||
|
||||
if LCase(m.top.parentItem.json.type) = "musicgenre"
|
||||
m.itemGrid.translation = "[96, 60]"
|
||||
|
@ -13,7 +13,8 @@ sub init()
|
||||
m.top.transcodeReasons = []
|
||||
m.bufferCheckTimer.duration = 30
|
||||
|
||||
if m.global.session.user.settings["ui.design.hideclock"] = true
|
||||
userSettings = m.global.session.user.settings
|
||||
if userSettings["ui.design.hideclock"]
|
||||
clockNode = findNodeBySubtype(m.top, "clock")
|
||||
if clockNode[0] <> invalid then clockNode[0].parent.removeChild(clockNode[0].node)
|
||||
end if
|
||||
@ -22,7 +23,7 @@ sub init()
|
||||
m.nextEpisodeButton = m.top.findNode("nextEpisode")
|
||||
m.nextEpisodeButton.text = tr("Next Episode")
|
||||
m.nextEpisodeButton.setFocus(false)
|
||||
m.nextupbuttonseconds = m.global.session.user.settings["playback.nextupbuttonseconds"].ToInt()
|
||||
m.nextupbuttonseconds = userSettings["playback.nextupbuttonseconds"].ToInt()
|
||||
|
||||
m.showNextEpisodeButtonAnimation = m.top.findNode("showNextEpisodeButton")
|
||||
m.hideNextEpisodeButtonAnimation = m.top.findNode("hideNextEpisodeButton")
|
||||
|
@ -17,10 +17,10 @@ sub init()
|
||||
|
||||
' Randomize the background colors
|
||||
backdropColor = "#00a4db" ' set default in case global var is invalid
|
||||
localGlobal = m.global
|
||||
myGlobal = m.global
|
||||
|
||||
if isValid(localGlobal) and isValid(localGlobal.constants) and isValid(localGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = localGlobal.constants.poster_bg_pallet
|
||||
if isValid(myGlobal) and isValid(myGlobal.constants) and isValid(myGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = myGlobal.constants.poster_bg_pallet
|
||||
backdropColor = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
end if
|
||||
|
||||
@ -65,8 +65,9 @@ sub itemContentChanged() as void
|
||||
m.poster = m.top.findNode("poster")
|
||||
itemData = m.top.itemContent
|
||||
m.title.text = itemData.title
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"] = false
|
||||
if not userSettings["ui.tvshows.disableUnwatchedEpisodeCount"]
|
||||
if isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
@ -94,7 +95,7 @@ sub itemContentChanged() as void
|
||||
|
||||
imageUrl = itemData.posterURL
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.blurunwatched"] = true
|
||||
if userSettings["ui.tvshows.blurunwatched"]
|
||||
if itemData.json.lookup("Type") = "Episode" and isValid(itemData.json.userdata)
|
||||
if not itemData.json.userdata.played
|
||||
imageUrl = imageUrl + "&blur=15"
|
||||
@ -116,7 +117,7 @@ sub focusChanged()
|
||||
m.staticTitle.visible = false
|
||||
m.title.visible = true
|
||||
' text to speech for accessibility
|
||||
if m.global.device.isAudioGuideEnabled = true
|
||||
if m.global.device.isAudioGuideEnabled
|
||||
txt2Speech = CreateObject("roTextToSpeech")
|
||||
txt2Speech.Flush()
|
||||
txt2Speech.Say(m.title.text)
|
||||
|
@ -1,11 +1,12 @@
|
||||
sub init()
|
||||
m.content = m.top.findNode("content")
|
||||
appVersion = m.global.app.version
|
||||
|
||||
setPalette()
|
||||
|
||||
m.top.id = "OKDialog"
|
||||
m.top.height = 900
|
||||
m.top.title = tr("Welcome to version") + " " + m.global.app.version
|
||||
m.top.title = tr("Welcome to version") + " " + appVersion
|
||||
m.top.buttons = [tr("OK")]
|
||||
|
||||
dialogStyles = {
|
||||
@ -27,7 +28,7 @@ sub init()
|
||||
|
||||
textLine = m.content.CreateChild("StdDlgMultiStyleTextItem")
|
||||
textLine.drawingStyles = dialogStyles
|
||||
textLine.text = tr("To view a complete list of changes visit") + " <url>https://github.com/jellyfin/jellyfin-roku/releases/tag/v" + m.global.app.version + "</url>"
|
||||
textLine.text = tr("To view a complete list of changes visit") + " <url>https://github.com/jellyfin/jellyfin-roku/releases/tag/v" + appVersion + "</url>"
|
||||
end sub
|
||||
|
||||
sub setPalette()
|
||||
|
@ -22,10 +22,10 @@ sub init()
|
||||
|
||||
' Randomize the background colors
|
||||
backdropColor = "#00a4db" ' set default in case global var is invalid
|
||||
localGlobal = m.global
|
||||
myGlobal = m.global
|
||||
|
||||
if isValid(localGlobal) and isValid(localGlobal.constants) and isValid(localGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = localGlobal.constants.poster_bg_pallet
|
||||
if isValid(myGlobal) and isValid(myGlobal.constants) and isValid(myGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = myGlobal.constants.poster_bg_pallet
|
||||
backdropColor = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
end if
|
||||
|
||||
@ -62,7 +62,7 @@ sub itemContentChanged()
|
||||
if isValid(m.unplayedCount) then m.unplayedCount.visible = false
|
||||
itemData = m.top.itemContent
|
||||
if itemData = invalid then return
|
||||
localGlobal = m.global
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
itemData.Title = itemData.name ' Temporarily required while we move from "HomeItem" to "JFContentItem"
|
||||
|
||||
@ -79,9 +79,9 @@ sub itemContentChanged()
|
||||
m.itemTextExtra.width = itemData.imageWidth
|
||||
m.itemTextExtra.visible = true
|
||||
m.itemTextExtra.text = ""
|
||||
|
||||
m.backdrop.width = itemData.imageWidth
|
||||
|
||||
|
||||
if isValid(itemData.iconUrl)
|
||||
m.itemIcon.uri = itemData.iconUrl
|
||||
end if
|
||||
@ -92,8 +92,8 @@ sub itemContentChanged()
|
||||
m.playedIndicator.visible = false
|
||||
|
||||
if LCase(itemData.type) = "series"
|
||||
if isValid(localGlobal) and isValid(localGlobal.session) and isValid(localGlobal.session.user) and isValid(localGlobal.session.user.settings)
|
||||
unwatchedEpisodeCountSetting = localGlobal.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"]
|
||||
if isValid(userSettings)
|
||||
unwatchedEpisodeCountSetting = userSettings["ui.tvshows.disableUnwatchedEpisodeCount"]
|
||||
if isValid(unwatchedEpisodeCountSetting) and not unwatchedEpisodeCountSetting
|
||||
if isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
@ -164,16 +164,16 @@ sub itemContentChanged()
|
||||
drawProgressBar(itemData)
|
||||
end if
|
||||
|
||||
if localGlobal.session.user.settings["ui.general.episodeimagesnextup"] = "webclient"
|
||||
tmpSetting = localGlobal.session.user.Configuration.useEpisodeImagesInNextUpAndResume
|
||||
if userSettings["ui.general.episodeimagesnextup"] = "webclient"
|
||||
tmpSetting = m.global.session.user.Configuration.useEpisodeImagesInNextUpAndResume
|
||||
if isValid(tmpSetting) and tmpSetting
|
||||
m.itemPoster.uri = itemData.thumbnailURL
|
||||
else
|
||||
m.itemPoster.uri = itemData.widePosterURL
|
||||
end if
|
||||
else if localGlobal.session.user.settings["ui.general.episodeimagesnextup"] = "show"
|
||||
else if userSettings["ui.general.episodeimagesnextup"] = "show"
|
||||
m.itemPoster.uri = itemData.widePosterURL
|
||||
else if localGlobal.session.user.settings["ui.general.episodeimagesnextup"] = "episode"
|
||||
else if userSettings["ui.general.episodeimagesnextup"] = "episode"
|
||||
m.itemPoster.uri = itemData.thumbnailURL
|
||||
end if
|
||||
|
||||
|
@ -76,10 +76,11 @@ sub processUserSections()
|
||||
m.processedRowCount = 0
|
||||
|
||||
sessionUser = m.global.session.user
|
||||
userSettings = sessionUser.settings
|
||||
|
||||
' calculate expected row count by processing homesections
|
||||
for i = 0 to 6
|
||||
userSection = sessionUser.settings["homesection" + i.toStr()]
|
||||
userSection = userSettings["homesection" + i.toStr()]
|
||||
sectionName = userSection ?? "none"
|
||||
sectionName = LCase(sectionName)
|
||||
|
||||
@ -99,7 +100,7 @@ sub processUserSections()
|
||||
' Add home sections in order based on user settings
|
||||
loadedSections = 0
|
||||
for i = 0 to 6
|
||||
userSection = sessionUser.settings["homesection" + i.toStr()]
|
||||
userSection = userSettings["homesection" + i.toStr()]
|
||||
sectionName = userSection ?? "none"
|
||||
sectionName = LCase(sectionName)
|
||||
|
||||
@ -149,10 +150,10 @@ function getOriginalSectionIndex(sectionName as string) as integer
|
||||
sectionIndex = 0
|
||||
indexLatestMediaSection = 0
|
||||
|
||||
sessionUser = m.global.session.user
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
for i = 0 to 6
|
||||
userSection = sessionUser.settings["homesection" + i.toStr()]
|
||||
userSection = userSettings["homesection" + i.toStr()]
|
||||
settingSectionName = userSection ?? "none"
|
||||
settingSectionName = LCase(settingSectionName)
|
||||
|
||||
|
@ -60,6 +60,7 @@ sub loadItems()
|
||||
|
||||
' Load Next Up
|
||||
else if m.top.itemsToLoad = "nextUp"
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
url = "Shows/NextUp"
|
||||
params = {}
|
||||
@ -68,12 +69,12 @@ sub loadItems()
|
||||
params["SortOrder"] = "Descending"
|
||||
params["ImageTypeLimit"] = 1
|
||||
params["UserId"] = m.global.session.user.id
|
||||
params["EnableRewatching"] = m.global.session.user.settings["ui.details.enablerewatchingnextup"]
|
||||
params["EnableRewatching"] = userSettings["ui.details.enablerewatchingnextup"]
|
||||
params["DisableFirstEpisode"] = false
|
||||
params["limit"] = 24
|
||||
params["EnableTotalRecordCount"] = false
|
||||
|
||||
maxDaysInNextUp = m.global.session.user.settings["ui.details.maxdaysnextup"].ToInt()
|
||||
maxDaysInNextUp = userSettings["ui.details.maxdaysnextup"].ToInt()
|
||||
if isValid(maxDaysInNextUp)
|
||||
if maxDaysInNextUp > 0
|
||||
dateToday = CreateObject("roDateTime")
|
||||
|
@ -58,9 +58,9 @@ sub onSelectAudioPressed()
|
||||
|
||||
audioData.data.push(audioStreamItem)
|
||||
end for
|
||||
|
||||
m.global.sceneManager.callFunc("radioDialog", tr("Select Audio"), audioData)
|
||||
m.global.sceneManager.observeField("returnData", "onSelectionMade")
|
||||
sceneManager = m.global.sceneManager
|
||||
sceneManager.callFunc("radioDialog", tr("Select Audio"), audioData)
|
||||
sceneManager.observeField("returnData", "onSelectionMade")
|
||||
end sub
|
||||
|
||||
' User requested subtitle selection popup
|
||||
@ -110,23 +110,25 @@ sub onSelectSubtitlePressed()
|
||||
"Type": "subtitleselection"
|
||||
})
|
||||
|
||||
m.global.sceneManager.callFunc("radioDialog", tr("Select Subtitles"), subtitleData)
|
||||
m.global.sceneManager.observeField("returnData", "onSelectionMade")
|
||||
sceneManager = m.global.sceneManager
|
||||
sceneManager.callFunc("radioDialog", tr("Select Subtitles"), subtitleData)
|
||||
sceneManager.observeField("returnData", "onSelectionMade")
|
||||
end sub
|
||||
|
||||
' User has selected something from the radioDialog popup
|
||||
sub onSelectionMade()
|
||||
m.global.sceneManager.unobserveField("returnData")
|
||||
sceneManager = m.global.sceneManager
|
||||
sceneManager.unobserveField("returnData")
|
||||
|
||||
if not isValid(m.global.sceneManager.returnData) then return
|
||||
if not isValid(m.global.sceneManager.returnData.type) then return
|
||||
if not isValid(sceneManager.returnData) then return
|
||||
if not isValid(sceneManager.returnData.type) then return
|
||||
|
||||
if LCase(m.global.sceneManager.returnData.type) = "subtitleselection"
|
||||
if LCase(sceneManager.returnData.type) = "subtitleselection"
|
||||
processSubtitleSelection()
|
||||
return
|
||||
end if
|
||||
|
||||
if LCase(m.global.sceneManager.returnData.type) = "audioselection"
|
||||
if LCase(sceneManager.returnData.type) = "audioselection"
|
||||
processAudioSelection()
|
||||
return
|
||||
end if
|
||||
@ -216,21 +218,24 @@ end sub
|
||||
' Playback state change event handlers
|
||||
sub onStateChange()
|
||||
if LCase(m.view.state) = "finished"
|
||||
sceneManager = m.global.sceneManager
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' Close any open dialogs
|
||||
if m.global.sceneManager.callFunc("isDialogOpen")
|
||||
m.global.sceneManager.callFunc("dismissDialog")
|
||||
if sceneManager.callFunc("isDialogOpen")
|
||||
sceneManager.callFunc("dismissDialog")
|
||||
end if
|
||||
|
||||
' If there is something next in the queue, play it
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
if queueManager.callFunc("getPosition") < queueManager.callFunc("getCount") - 1
|
||||
sceneManager.callFunc("clearPreviousScene")
|
||||
queueManager.callFunc("moveForward")
|
||||
queueManager.callFunc("playQueue")
|
||||
return
|
||||
end if
|
||||
|
||||
' Playback completed, return user to previous screen
|
||||
m.global.sceneManager.callFunc("popScene")
|
||||
sceneManager.callFunc("popScene")
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
end if
|
||||
end sub
|
||||
|
@ -97,6 +97,7 @@ sub itemContentChanged()
|
||||
' Updates video metadata
|
||||
item = m.top.itemContent
|
||||
if isValid(item) and isValid(item.json)
|
||||
userSettings = m.global.session.user.settings
|
||||
itemData = item.json
|
||||
m.top.id = itemData.id
|
||||
m.top.findNode("moviePoster").uri = m.top.itemContent.posterURL
|
||||
@ -120,7 +121,7 @@ sub itemContentChanged()
|
||||
m.infoGroup.removeChild(m.top.findNode("officialRating"))
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.movies.showRatings"]
|
||||
if userSettings["ui.movies.showRatings"]
|
||||
if isValid(itemData.communityRating)
|
||||
setFieldText("communityRating", int(itemData.communityRating * 10) / 10)
|
||||
else
|
||||
@ -145,7 +146,7 @@ sub itemContentChanged()
|
||||
|
||||
if type(itemData.RunTimeTicks) = "LongInteger"
|
||||
setFieldText("runtime", stri(getRuntime()) + " mins")
|
||||
if m.global.session.user.settings["ui.design.hideclock"] <> true
|
||||
if userSettings["ui.design.hideclock"] <> true
|
||||
setFieldText("ends-at", tr("Ends at %1").Replace("%1", getEndTime()))
|
||||
end if
|
||||
end if
|
||||
@ -173,7 +174,7 @@ sub itemContentChanged()
|
||||
m.top.findNode("details").removeChild(m.top.findNode("director"))
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.details.hidetagline"] = false
|
||||
if userSettings["ui.details.hidetagline"] = false
|
||||
if itemData.taglines.count() > 0
|
||||
setFieldText("tagline", itemData.taglines[0])
|
||||
end if
|
||||
|
@ -9,9 +9,14 @@ sub init()
|
||||
m.lastRecordedPositionTimestamp = 0
|
||||
m.scrubTimestamp = -1
|
||||
|
||||
m.playlistTypeCount = m.global.queueManager.callFunc("getQueueUniqueTypes").count()
|
||||
m.queueManager = m.global.queueManager
|
||||
m.playlistTypeCount = m.queueManager.callFunc("getQueueUniqueTypes").count()
|
||||
|
||||
m.audioPlayer = m.global.audioPlayer
|
||||
m.audioPlayer.observeField("state", "audioStateChanged")
|
||||
m.audioPlayer.observeField("position", "audioPositionChanged")
|
||||
m.audioPlayer.observeField("bufferingStatus", "bufferPositionChanged")
|
||||
|
||||
setupAudioNode()
|
||||
setupAnimationTasks()
|
||||
setupButtons()
|
||||
setupInfoNodes()
|
||||
@ -91,13 +96,6 @@ sub setupDataTasks()
|
||||
m.LoadScreenSaverTimeoutTask = CreateObject("roSGNode", "LoadScreenSaverTimeoutTask")
|
||||
end sub
|
||||
|
||||
' Creates audio node used to play song(s)
|
||||
sub setupAudioNode()
|
||||
m.global.audioPlayer.observeField("state", "audioStateChanged")
|
||||
m.global.audioPlayer.observeField("position", "audioPositionChanged")
|
||||
m.global.audioPlayer.observeField("bufferingStatus", "bufferPositionChanged")
|
||||
end sub
|
||||
|
||||
' Setup playback buttons, default to Play button selected
|
||||
sub setupButtons()
|
||||
m.buttons = m.top.findNode("buttons")
|
||||
@ -149,10 +147,10 @@ end sub
|
||||
sub bufferPositionChanged()
|
||||
if m.inScrubMode then return
|
||||
|
||||
if not isValid(m.global.audioPlayer.bufferingStatus)
|
||||
if not isValid(m.audioPlayer.bufferingStatus)
|
||||
bufferPositionBarWidth = m.seekBar.width
|
||||
else
|
||||
bufferPositionBarWidth = m.seekBar.width * m.global.audioPlayer.bufferingStatus.percentage
|
||||
bufferPositionBarWidth = m.seekBar.width * m.audioPlayer.bufferingStatus.percentage
|
||||
end if
|
||||
|
||||
' Ensure position bar is never wider than the seek bar
|
||||
@ -168,16 +166,16 @@ end sub
|
||||
sub audioPositionChanged()
|
||||
stopLoadingSpinner()
|
||||
|
||||
if m.global.audioPlayer.position = 0
|
||||
if m.audioPlayer.position = 0
|
||||
m.playPosition.width = 0
|
||||
end if
|
||||
|
||||
if not isValid(m.global.audioPlayer.position)
|
||||
if not isValid(m.audioPlayer.position)
|
||||
playPositionBarWidth = 0
|
||||
else if not isValid(m.songDuration)
|
||||
playPositionBarWidth = 0
|
||||
else
|
||||
songPercentComplete = m.global.audioPlayer.position / m.songDuration
|
||||
songPercentComplete = m.audioPlayer.position / m.songDuration
|
||||
playPositionBarWidth = m.seekBar.width * songPercentComplete
|
||||
end if
|
||||
|
||||
@ -189,7 +187,7 @@ sub audioPositionChanged()
|
||||
if not m.inScrubMode
|
||||
moveSeekbarThumb(playPositionBarWidth)
|
||||
' Change the seek position timestamp
|
||||
m.seekTimestamp.text = secondsToHuman(m.global.audioPlayer.position, false)
|
||||
m.seekTimestamp.text = secondsToHuman(m.audioPlayer.position, false)
|
||||
end if
|
||||
|
||||
' Use animation to make the display smooth
|
||||
@ -197,9 +195,9 @@ sub audioPositionChanged()
|
||||
m.playPositionAnimation.control = "start"
|
||||
|
||||
' Update displayed position timestamp
|
||||
if isValid(m.global.audioPlayer.position)
|
||||
m.lastRecordedPositionTimestamp = m.global.audioPlayer.position
|
||||
m.positionTimestamp.text = secondsToHuman(m.global.audioPlayer.position, false)
|
||||
if isValid(m.audioPlayer.position)
|
||||
m.lastRecordedPositionTimestamp = m.audioPlayer.position
|
||||
m.positionTimestamp.text = secondsToHuman(m.audioPlayer.position, false)
|
||||
else
|
||||
m.lastRecordedPositionTimestamp = 0
|
||||
m.positionTimestamp.text = "0:00"
|
||||
@ -247,25 +245,24 @@ sub endScreenSaver()
|
||||
end sub
|
||||
|
||||
sub audioStateChanged()
|
||||
|
||||
' Song Finished, attempt to move to next song
|
||||
if m.global.audioPlayer.state = "finished"
|
||||
if m.audioPlayer.state = "finished"
|
||||
' User has enabled single song loop, play current song again
|
||||
if m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = "one"
|
||||
m.scrubTimestamp = -1
|
||||
playAction()
|
||||
exitScrubMode()
|
||||
return
|
||||
end if
|
||||
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
if m.queueManager.callFunc("getPosition") < m.queueManager.callFunc("getCount") - 1
|
||||
m.top.state = "finished"
|
||||
else
|
||||
' We are at the end of the song queue
|
||||
|
||||
' User has enabled loop for entire song queue, move back to first song
|
||||
if m.global.audioPlayer.loopMode = "all"
|
||||
m.global.queueManager.callFunc("setPosition", -1)
|
||||
if m.audioPlayer.loopMode = "all"
|
||||
m.queueManager.callFunc("setPosition", -1)
|
||||
LoadNextSong()
|
||||
return
|
||||
end if
|
||||
@ -277,18 +274,19 @@ sub audioStateChanged()
|
||||
end sub
|
||||
|
||||
function playAction() as boolean
|
||||
if m.global.audioPlayer.state = "playing"
|
||||
m.global.audioPlayer.control = "pause"
|
||||
|
||||
if m.audioPlayer.state = "playing"
|
||||
m.audioPlayer.control = "pause"
|
||||
' Allow screen to go to real screensaver
|
||||
WriteAsciiFile("tmp:/scene.temp", "nowplaying-paused")
|
||||
MoveFile("tmp:/scene.temp", "tmp:/scene")
|
||||
else if m.global.audioPlayer.state = "paused"
|
||||
m.global.audioPlayer.control = "resume"
|
||||
else if m.audioPlayer.state = "paused"
|
||||
m.audioPlayer.control = "resume"
|
||||
' Write screen tracker for screensaver
|
||||
WriteAsciiFile("tmp:/scene.temp", "nowplaying")
|
||||
MoveFile("tmp:/scene.temp", "tmp:/scene")
|
||||
else if m.global.audioPlayer.state = "finished"
|
||||
m.global.audioPlayer.control = "play"
|
||||
else if m.audioPlayer.state = "finished"
|
||||
m.audioPlayer.control = "play"
|
||||
' Write screen tracker for screensaver
|
||||
WriteAsciiFile("tmp:/scene.temp", "nowplaying")
|
||||
MoveFile("tmp:/scene.temp", "tmp:/scene")
|
||||
@ -298,20 +296,19 @@ function playAction() as boolean
|
||||
end function
|
||||
|
||||
function previousClicked() as boolean
|
||||
currentQueuePosition = m.global.queueManager.callFunc("getPosition")
|
||||
|
||||
currentQueuePosition = m.queueManager.callFunc("getPosition")
|
||||
if currentQueuePosition = 0 then return false
|
||||
|
||||
if m.playlistTypeCount > 1
|
||||
previousItem = m.global.queueManager.callFunc("getItemByIndex", currentQueuePosition - 1)
|
||||
previousItemType = m.global.queueManager.callFunc("getItemType", previousItem)
|
||||
previousItem = m.queueManager.callFunc("getItemByIndex", currentQueuePosition - 1)
|
||||
previousItemType = m.queueManager.callFunc("getItemType", previousItem)
|
||||
|
||||
if previousItemType <> "audio"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
m.audioPlayer.control = "stop"
|
||||
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveBack")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
m.queueManager.callFunc("moveBack")
|
||||
m.queueManager.callFunc("playQueue")
|
||||
return true
|
||||
end if
|
||||
end if
|
||||
@ -321,34 +318,33 @@ function previousClicked() as boolean
|
||||
m.lastRecordedPositionTimestamp = 0
|
||||
m.positionTimestamp.text = "0:00"
|
||||
|
||||
if m.global.audioPlayer.state = "playing"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
if m.audioPlayer.state = "playing"
|
||||
m.audioPlayer.control = "stop"
|
||||
end if
|
||||
|
||||
' Reset loop mode due to manual user interaction
|
||||
if m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = "one"
|
||||
resetLoopModeToDefault()
|
||||
end if
|
||||
|
||||
m.global.queueManager.callFunc("moveBack")
|
||||
m.queueManager.callFunc("moveBack")
|
||||
pageContentChanged()
|
||||
|
||||
return true
|
||||
end function
|
||||
|
||||
sub resetLoopModeToDefault()
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.loopMode = ""
|
||||
setLoopButtonImage()
|
||||
end sub
|
||||
|
||||
function loopClicked() as boolean
|
||||
|
||||
if m.global.audioPlayer.loopMode = ""
|
||||
m.global.audioPlayer.loopMode = "all"
|
||||
else if m.global.audioPlayer.loopMode = "all"
|
||||
m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.loopMode = "all"
|
||||
else if m.audioPlayer.loopMode = "all"
|
||||
m.audioPlayer.loopMode = "one"
|
||||
else
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.loopMode = ""
|
||||
end if
|
||||
|
||||
setLoopButtonImage()
|
||||
@ -357,10 +353,10 @@ function loopClicked() as boolean
|
||||
end function
|
||||
|
||||
sub setLoopButtonImage()
|
||||
if m.global.audioPlayer.loopMode = "all"
|
||||
if m.audioPlayer.loopMode = "all"
|
||||
m.loopIndicator.opacity = "1"
|
||||
m.loopIndicator.uri = m.loopIndicator.uri.Replace("-off", "-on")
|
||||
else if m.global.audioPlayer.loopMode = "one"
|
||||
else if m.audioPlayer.loopMode = "one"
|
||||
m.loopIndicator.uri = m.loopIndicator.uri.Replace("-on", "1-on")
|
||||
else
|
||||
m.loopIndicator.uri = m.loopIndicator.uri.Replace("1-on", "-off")
|
||||
@ -368,19 +364,20 @@ sub setLoopButtonImage()
|
||||
end sub
|
||||
|
||||
function nextClicked() as boolean
|
||||
if m.playlistTypeCount > 1
|
||||
currentQueuePosition = m.global.queueManager.callFunc("getPosition")
|
||||
if currentQueuePosition < m.global.queueManager.callFunc("getCount") - 1
|
||||
|
||||
nextItem = m.global.queueManager.callFunc("getItemByIndex", currentQueuePosition + 1)
|
||||
nextItemType = m.global.queueManager.callFunc("getItemType", nextItem)
|
||||
if m.playlistTypeCount > 1
|
||||
currentQueuePosition = m.queueManager.callFunc("getPosition")
|
||||
if currentQueuePosition < m.queueManager.callFunc("getCount") - 1
|
||||
|
||||
nextItem = m.queueManager.callFunc("getItemByIndex", currentQueuePosition + 1)
|
||||
nextItemType = m.queueManager.callFunc("getItemType", nextItem)
|
||||
|
||||
if nextItemType <> "audio"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
m.audioPlayer.control = "stop"
|
||||
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
m.queueManager.callFunc("moveForward")
|
||||
m.queueManager.callFunc("playQueue")
|
||||
return true
|
||||
end if
|
||||
end if
|
||||
@ -392,11 +389,11 @@ function nextClicked() as boolean
|
||||
m.positionTimestamp.text = "0:00"
|
||||
|
||||
' Reset loop mode due to manual user interaction
|
||||
if m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = "one"
|
||||
resetLoopModeToDefault()
|
||||
end if
|
||||
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
if m.queueManager.callFunc("getPosition") < m.queueManager.callFunc("getCount") - 1
|
||||
LoadNextSong()
|
||||
end if
|
||||
|
||||
@ -404,14 +401,14 @@ function nextClicked() as boolean
|
||||
end function
|
||||
|
||||
sub toggleShuffleEnabled()
|
||||
m.global.queueManager.callFunc("toggleShuffle")
|
||||
m.queueManager.callFunc("toggleShuffle")
|
||||
end sub
|
||||
|
||||
function findCurrentSongIndex(songList) as integer
|
||||
if not isValidAndNotEmpty(songList) then return 0
|
||||
|
||||
for i = 0 to songList.count() - 1
|
||||
if songList[i].id = m.global.queueManager.callFunc("getCurrentItem").id
|
||||
if songList[i].id = m.queueManager.callFunc("getCurrentItem").id
|
||||
return i
|
||||
end if
|
||||
end for
|
||||
@ -420,15 +417,14 @@ function findCurrentSongIndex(songList) as integer
|
||||
end function
|
||||
|
||||
function shuffleClicked() as boolean
|
||||
|
||||
currentSongIndex = findCurrentSongIndex(m.global.queueManager.callFunc("getUnshuffledQueue"))
|
||||
currentSongIndex = findCurrentSongIndex(m.queueManager.callFunc("getUnshuffledQueue"))
|
||||
|
||||
toggleShuffleEnabled()
|
||||
|
||||
if not m.global.queueManager.callFunc("getIsShuffled")
|
||||
if not m.queueManager.callFunc("getIsShuffled")
|
||||
m.shuffleIndicator.opacity = ".4"
|
||||
m.shuffleIndicator.uri = m.shuffleIndicator.uri.Replace("-on", "-off")
|
||||
m.global.queueManager.callFunc("setPosition", currentSongIndex)
|
||||
m.queueManager.callFunc("setPosition", currentSongIndex)
|
||||
setTrackNumberDisplay()
|
||||
return true
|
||||
end if
|
||||
@ -441,26 +437,26 @@ function shuffleClicked() as boolean
|
||||
end function
|
||||
|
||||
sub setShuffleIconState()
|
||||
if m.global.queueManager.callFunc("getIsShuffled")
|
||||
if m.queueManager.callFunc("getIsShuffled")
|
||||
m.shuffleIndicator.opacity = "1"
|
||||
m.shuffleIndicator.uri = m.shuffleIndicator.uri.Replace("-off", "-on")
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub setTrackNumberDisplay()
|
||||
setFieldTextValue("numberofsongs", "Track " + stri(m.global.queueManager.callFunc("getPosition") + 1) + "/" + stri(m.global.queueManager.callFunc("getCount")))
|
||||
setFieldTextValue("numberofsongs", "Track " + stri(m.queueManager.callFunc("getPosition") + 1) + "/" + stri(m.queueManager.callFunc("getCount")))
|
||||
end sub
|
||||
|
||||
sub LoadNextSong()
|
||||
if m.global.audioPlayer.state = "playing"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
if m.audioPlayer.state = "playing"
|
||||
m.audioPlayer.control = "stop"
|
||||
end if
|
||||
|
||||
exitScrubMode()
|
||||
|
||||
' Reset playPosition bar without animation
|
||||
m.playPosition.width = 0
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.queueManager.callFunc("moveForward")
|
||||
pageContentChanged()
|
||||
end sub
|
||||
|
||||
@ -469,7 +465,7 @@ sub pageContentChanged()
|
||||
|
||||
m.LoadAudioStreamTask.control = "STOP"
|
||||
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = m.queueManager.callFunc("getCurrentItem")
|
||||
|
||||
m.LoadAudioStreamTask.itemId = currentItem.id
|
||||
m.LoadAudioStreamTask.observeField("content", "onAudioStreamLoaded")
|
||||
@ -478,7 +474,7 @@ end sub
|
||||
|
||||
' If we have more and 1 song to play, fade in the next and previous controls
|
||||
sub loadButtons()
|
||||
if m.global.queueManager.callFunc("getCount") > 1
|
||||
if m.queueManager.callFunc("getCount") > 1
|
||||
m.shuffleIndicator.opacity = ".4"
|
||||
m.loopIndicator.opacity = ".4"
|
||||
m.displayButtonsAnimation.control = "start"
|
||||
@ -495,7 +491,7 @@ sub onAudioStreamLoaded()
|
||||
m.bufferPosition.width = 0
|
||||
|
||||
useMetaTask = false
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = m.queueManager.callFunc("getCurrentItem")
|
||||
|
||||
if not isValid(currentItem.RunTimeTicks)
|
||||
useMetaTask = true
|
||||
@ -531,9 +527,9 @@ sub onAudioStreamLoaded()
|
||||
m.totalLengthTimestamp.text = ticksToHuman(currentItem.RunTimeTicks)
|
||||
end if
|
||||
|
||||
m.global.audioPlayer.content = data
|
||||
m.global.audioPlayer.control = "none"
|
||||
m.global.audioPlayer.control = "play"
|
||||
m.audioPlayer.content = data
|
||||
m.audioPlayer.control = "none"
|
||||
m.audioPlayer.control = "play"
|
||||
end if
|
||||
end sub
|
||||
|
||||
@ -739,7 +735,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if m.inScrubMode
|
||||
startLoadingSpinner()
|
||||
m.inScrubMode = false
|
||||
m.global.audioPlayer.seek = m.scrubTimestamp
|
||||
m.audioPlayer.seek = m.scrubTimestamp
|
||||
return true
|
||||
end if
|
||||
|
||||
@ -773,15 +769,15 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
end if
|
||||
|
||||
if key = "back"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.control = "stop"
|
||||
m.audioPlayer.loopMode = ""
|
||||
else if key = "rewind"
|
||||
return previousClicked()
|
||||
else if key = "fastforward"
|
||||
return nextClicked()
|
||||
else if key = "left"
|
||||
if m.buttons.hasFocus()
|
||||
if m.global.queueManager.callFunc("getCount") = 1 then return false
|
||||
if m.queueManager.callFunc("getCount") = 1 then return false
|
||||
|
||||
if m.top.selectedButtonIndex > 0
|
||||
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
|
||||
@ -791,7 +787,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
end if
|
||||
else if key = "right"
|
||||
if m.buttons.hasFocus()
|
||||
if m.global.queueManager.callFunc("getCount") = 1 then return false
|
||||
if m.queueManager.callFunc("getCount") = 1 then return false
|
||||
|
||||
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
|
||||
if m.top.selectedButtonIndex < m.buttonCount - 1 then m.top.selectedButtonIndex = m.top.selectedButtonIndex + 1
|
||||
|
@ -10,8 +10,9 @@ sub init()
|
||||
m.textBackground = m.top.findNode("background")
|
||||
m.statusTimer = m.top.findNode("statusTimer")
|
||||
m.statusTimer.observeField("fire", "statusUpdate")
|
||||
m.slideshow = m.global.session.user.settings["photos.slideshow"]
|
||||
m.random = m.global.session.user.settings["photos.random"]
|
||||
userSettings = m.global.session.user.settings
|
||||
m.slideshow = userSettings["photos.slideshow"]
|
||||
m.random = userSettings["photos.random"]
|
||||
|
||||
m.showStatusAnimation = m.top.findNode("showStatusAnimation")
|
||||
m.hideStatusAnimation = m.top.findNode("hideStatusAnimation")
|
||||
|
@ -91,26 +91,28 @@ sub settingFocused()
|
||||
m.integerSetting.visible = false
|
||||
m.radioSetting.visible = false
|
||||
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if selectedSetting.type = invalid
|
||||
return
|
||||
else if selectedSetting.type = "bool"
|
||||
|
||||
m.boolSetting.visible = true
|
||||
|
||||
if m.global.session.user.settings[selectedSetting.settingName] = true
|
||||
if userSettings[selectedSetting.settingName] = true
|
||||
m.boolSetting.checkedItem = 1
|
||||
else
|
||||
m.boolSetting.checkedItem = 0
|
||||
end if
|
||||
else if selectedSetting.type = "integer"
|
||||
integerValue = m.global.session.user.settings[selectedSetting.settingName].ToStr()
|
||||
integerValue = userSettings[selectedSetting.settingName].ToStr()
|
||||
if isValid(integerValue)
|
||||
m.integerSetting.text = integerValue
|
||||
end if
|
||||
m.integerSetting.visible = true
|
||||
else if LCase(selectedSetting.type) = "radio"
|
||||
|
||||
selectedValue = m.global.session.user.settings[selectedSetting.settingName]
|
||||
selectedValue = userSettings[selectedSetting.settingName]
|
||||
|
||||
radioContent = CreateObject("roSGNode", "ContentNode")
|
||||
|
||||
@ -173,7 +175,6 @@ sub boolSettingChanged()
|
||||
set_setting(selectedSetting.settingName, "true")
|
||||
' setting specific triggers
|
||||
if selectedSetting.settingName = "global.rememberme"
|
||||
print "m.global.session.user.id=", m.global.session.user.id
|
||||
set_setting("active_user", m.global.session.user.id)
|
||||
end if
|
||||
else
|
||||
|
@ -21,13 +21,16 @@ end sub
|
||||
sub itemContentChanged()
|
||||
item = m.top.itemContent
|
||||
itemData = item.json
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
' Set default video source if user hasn't selected one yet
|
||||
if item.selectedVideoStreamId = "" and isValid(itemData.MediaSources)
|
||||
item.selectedVideoStreamId = itemData.MediaSources[0].id
|
||||
end if
|
||||
|
||||
if isValid(itemData.indexNumber)
|
||||
if isValid(itemData.parentIndexNumber) and itemData.parentIndexNumber = 0
|
||||
indexNumber = `${tr("Special")} - `
|
||||
else if isValid(itemData.indexNumber)
|
||||
indexNumber = `${itemData.indexNumber}. `
|
||||
if isValid(itemData.indexNumberEnd)
|
||||
indexNumber = `${itemData.indexNumber}-${itemData.indexNumberEnd}. `
|
||||
@ -46,7 +49,7 @@ sub itemContentChanged()
|
||||
|
||||
imageUrl = item.posterURL
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.blurunwatched"] = true
|
||||
if userSettings["ui.tvshows.blurunwatched"] = true
|
||||
if itemData.lookup("Type") = "Episode"
|
||||
if not itemData.userdata.played
|
||||
imageUrl = imageUrl + "&blur=15"
|
||||
@ -64,12 +67,12 @@ sub itemContentChanged()
|
||||
m.top.findNode("runtime").text = stri(runTime).trim() + " mins"
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.design.hideclock"] <> true
|
||||
if userSettings["ui.design.hideclock"] <> true
|
||||
m.top.findNode("endtime").text = tr("Ends at %1").Replace("%1", getEndTime())
|
||||
end if
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.disableCommunityRating"] = false
|
||||
if userSettings["ui.tvshows.disableCommunityRating"] = false
|
||||
if isValid(itemData.communityRating)
|
||||
m.top.findNode("star").visible = true
|
||||
m.top.findNode("communityRating").text = str(int(itemData.communityRating * 10) / 10)
|
||||
|
@ -181,9 +181,11 @@ end function
|
||||
|
||||
sub onShuffleEpisodeDataLoaded()
|
||||
m.getShuffleEpisodesTask.unobserveField("data")
|
||||
|
||||
if isValid(m.getShuffleEpisodesTask.data)
|
||||
m.global.queueManager.callFunc("set", m.getShuffleEpisodesTask.data.items)
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
queueManager = m.global.queueManager
|
||||
queueManager.callFunc("set", m.getShuffleEpisodesTask.data.items)
|
||||
queueManager.callFunc("playQueue")
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
@ -35,7 +35,6 @@ sub init()
|
||||
m.optionControls.buttonFocused = m.optionControls.getChildCount() - 1
|
||||
|
||||
m.videoControls.getChild(m.defaultButtonIndex).focus = true
|
||||
m.deviceInfo = CreateObject("roDeviceInfo")
|
||||
end sub
|
||||
|
||||
' onProgressPercentageChanged: Handler for changes to m.top.progressPercentage param
|
||||
@ -221,7 +220,8 @@ sub inactiveCheck()
|
||||
return
|
||||
end if
|
||||
|
||||
if m.deviceInfo.timeSinceLastKeypress() >= m.top.inactiveTimeout
|
||||
deviceInfo = CreateObject("roDeviceInfo")
|
||||
if deviceInfo.timeSinceLastKeypress() >= m.top.inactiveTimeout
|
||||
m.top.action = "hide"
|
||||
end if
|
||||
end sub
|
||||
|
@ -7,6 +7,7 @@ sub init()
|
||||
m.log = log.Logger("VideoPlayerView")
|
||||
' Hide the overhang on init to prevent showing 2 clocks
|
||||
m.top.getScene().findNode("overhang").visible = false
|
||||
userSettings = m.global.session.user.settings
|
||||
m.currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
|
||||
m.top.id = m.currentItem.id
|
||||
@ -46,7 +47,7 @@ sub init()
|
||||
m.top.transcodeReasons = []
|
||||
m.bufferCheckTimer.duration = 30
|
||||
|
||||
if m.global.session.user.settings["ui.design.hideclock"] = true
|
||||
if userSettings["ui.design.hideclock"] = true
|
||||
clockNode = findNodeBySubtype(m.top, "clock")
|
||||
if clockNode[0] <> invalid then clockNode[0].parent.removeChild(clockNode[0].node)
|
||||
end if
|
||||
@ -55,7 +56,7 @@ sub init()
|
||||
m.nextEpisodeButton = m.top.findNode("nextEpisode")
|
||||
m.nextEpisodeButton.text = tr("Next Episode")
|
||||
m.nextEpisodeButton.setFocus(false)
|
||||
m.nextupbuttonseconds = m.global.session.user.settings["playback.nextupbuttonseconds"].ToInt()
|
||||
m.nextupbuttonseconds = userSettings["playback.nextupbuttonseconds"].ToInt()
|
||||
|
||||
m.showNextEpisodeButtonAnimation = m.top.findNode("showNextEpisodeButton")
|
||||
m.hideNextEpisodeButtonAnimation = m.top.findNode("hideNextEpisodeButton")
|
||||
@ -100,26 +101,30 @@ end sub
|
||||
' @param {string} action - skip action to take
|
||||
sub handleItemSkipAction(action as string)
|
||||
if action = "itemnext"
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' If there is something next in the queue, play it
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
if queueManager.callFunc("getPosition") < queueManager.callFunc("getCount") - 1
|
||||
m.top.control = "stop"
|
||||
session.video.Delete()
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
queueManager.callFunc("moveForward")
|
||||
queueManager.callFunc("playQueue")
|
||||
end if
|
||||
|
||||
return
|
||||
end if
|
||||
|
||||
if action = "itemback"
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' If there is something previous in the queue, play it
|
||||
if m.global.queueManager.callFunc("getPosition") > 0
|
||||
if queueManager.callFunc("getPosition") > 0
|
||||
m.top.control = "stop"
|
||||
session.video.Delete()
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveBack")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
queueManager.callFunc("moveBack")
|
||||
queueManager.callFunc("playQueue")
|
||||
end if
|
||||
|
||||
return
|
||||
@ -523,9 +528,9 @@ sub showNextEpisodeButton()
|
||||
if m.top.content.contenttype <> 4 then return ' only display when content is type "Episode"
|
||||
if m.nextupbuttonseconds = 0 then return ' is the button disabled?
|
||||
if m.nextEpisodeButton.opacity <> 0 then return
|
||||
userSession = m.global.session.user
|
||||
if userSession.settings["playback.playnextepisode"] = "disabled" then return
|
||||
if userSession.settings["playback.playnextepisode"] = "webclient" and not userSession.Configuration.EnableNextEpisodeAutoPlay then return
|
||||
userSettings = m.global.session.user.settings
|
||||
if userSettings["playback.playnextepisode"] = "disabled" then return
|
||||
if userSettings["playback.playnextepisode"] = "webclient" and not m.global.session.user.Configuration.EnableNextEpisodeAutoPlay then return
|
||||
|
||||
m.nextEpisodeButton.visible = true
|
||||
m.showNextEpisodeButtonAnimation.control = "start"
|
||||
|
@ -44,10 +44,10 @@ end sub
|
||||
|
||||
sub itemContentChanged()
|
||||
m.backdrop.blendColor = "#00a4db" ' set default in case global var is invalid
|
||||
localGlobal = m.global
|
||||
myGlobal = m.global
|
||||
|
||||
if isValid(localGlobal) and isValid(localGlobal.constants) and isValid(localGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = localGlobal.constants.poster_bg_pallet
|
||||
if isValid(myGlobal) and isValid(myGlobal.constants) and isValid(myGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = myGlobal.constants.poster_bg_pallet
|
||||
m.backdrop.blendColor = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
end if
|
||||
|
||||
@ -64,8 +64,8 @@ sub itemContentChanged()
|
||||
m.itemIcon.uri = itemData.iconUrl
|
||||
m.itemText.text = itemData.Title
|
||||
else if itemData.type = "Series"
|
||||
if isValid(localGlobal) and isValid(localGlobal.session) and isValid(localGlobal.session.user) and isValid(localGlobal.session.user.settings)
|
||||
if localGlobal.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"] = false
|
||||
if isValid(myGlobal) and isValid(myGlobal.session) and isValid(myGlobal.session.user) and isValid(myGlobal.session.user.settings)
|
||||
if myGlobal.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"] = false
|
||||
if isValid(itemData.json) and isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
|
@ -9,9 +9,11 @@ import "pkg:/source/roku_modules/log/LogMixin.brs"
|
||||
sub init()
|
||||
m.log = log.Logger("ItemGrid")
|
||||
m.log.debug("start init()")
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
m.options = m.top.findNode("options")
|
||||
|
||||
m.showItemCount = m.global.session.user.settings["itemgrid.showItemCount"]
|
||||
m.showItemCount = userSettings["itemgrid.showItemCount"]
|
||||
|
||||
m.tvGuide = invalid
|
||||
m.channelFocused = invalid
|
||||
@ -70,9 +72,9 @@ sub init()
|
||||
m.alphaMenu = m.alpha.findNode("alphaMenu")
|
||||
|
||||
'Get reset folder setting
|
||||
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
|
||||
m.resetGrid = userSettings["itemgrid.reset"]
|
||||
|
||||
m.top.gridTitles = m.global.session.user.settings["itemgrid.gridTitles"]
|
||||
m.top.gridTitles = userSettings["itemgrid.gridTitles"]
|
||||
m.log.debug("end init()")
|
||||
end sub
|
||||
|
||||
@ -86,6 +88,7 @@ sub loadInitialItems()
|
||||
m.log.debug("start loadInitialItems()")
|
||||
m.loadItemsTask.control = "stop"
|
||||
startLoadingSpinner()
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if m.top.parentItem.json.Type = "CollectionFolder" 'or m.top.parentItem.json.Type = "Folder"
|
||||
m.top.HomeLibraryItem = m.top.parentItem.Id
|
||||
@ -98,25 +101,25 @@ sub loadInitialItems()
|
||||
' Read view/sort/filter settings
|
||||
if m.top.parentItem.collectionType = "livetv"
|
||||
' Translate between app and server nomenclature
|
||||
viewSetting = m.global.session.user.settings["display.livetv.landing"]
|
||||
viewSetting = userSettings["display.livetv.landing"]
|
||||
if viewSetting = "guide"
|
||||
m.view = "tvGuide"
|
||||
else
|
||||
m.view = "livetv"
|
||||
end if
|
||||
m.sortField = m.global.session.user.settings["display.livetv.sortField"]
|
||||
sortAscendingStr = m.global.session.user.settings["display.livetv.sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display.livetv.filter"]
|
||||
m.sortField = userSettings["display.livetv.sortField"]
|
||||
sortAscendingStr = userSettings["display.livetv.sortAscending"]
|
||||
m.filter = userSettings["display.livetv.filter"]
|
||||
else if m.top.parentItem.collectionType = "music"
|
||||
m.view = m.global.session.user.settings["display.music.view"]
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = userSettings["display.music.view"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
else
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = m.global.session.user.settings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
sortAscendingStr = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = userSettings["display." + m.top.parentItem.Id + ".landing"]
|
||||
end if
|
||||
|
||||
if m.sortField = invalid
|
||||
@ -182,7 +185,7 @@ sub loadInitialItems()
|
||||
m.loadItemsTask.itemType = "MusicArtist"
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
|
||||
m.view = m.global.session.user.settings["display.music.view"]
|
||||
m.view = userSettings["display.music.view"]
|
||||
|
||||
if m.view = "music-album"
|
||||
m.loadItemsTask.itemType = "MusicAlbum"
|
||||
@ -193,7 +196,7 @@ sub loadInitialItems()
|
||||
' For LiveTV, we want to "Fit" the item images, not zoom
|
||||
m.top.imageDisplayMode = "scaleToFit"
|
||||
|
||||
if m.global.session.user.settings["display.livetv.landing"] = "guide" and m.options.view <> "livetv"
|
||||
if userSettings["display.livetv.landing"] = "guide" and m.options.view <> "livetv"
|
||||
showTvGuide()
|
||||
end if
|
||||
else if m.top.parentItem.collectionType = "CollectionFolder" or m.top.parentItem.type = "CollectionFolder" or m.top.parentItem.collectionType = "boxsets" or m.top.parentItem.Type = "Boxset" or m.top.parentItem.Type = "Boxsets" or m.top.parentItem.Type = "Folder" or m.top.parentItem.Type = "Channel"
|
||||
|
@ -20,21 +20,23 @@ sub init()
|
||||
end sub
|
||||
|
||||
sub loadItems()
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' Reset intro tracker in case task gets reused
|
||||
m.top.isIntro = false
|
||||
|
||||
' Only show preroll once per queue
|
||||
if m.global.queueManager.callFunc("isPrerollActive")
|
||||
if queueManager.callFunc("isPrerollActive")
|
||||
' Prerolls not allowed if we're resuming video
|
||||
if m.global.queueManager.callFunc("getCurrentItem").startingPoint = 0
|
||||
if queueManager.callFunc("getCurrentItem").startingPoint = 0
|
||||
preRoll = GetIntroVideos(m.top.itemId)
|
||||
if isValid(preRoll) and preRoll.TotalRecordCount > 0 and isValid(preRoll.items[0])
|
||||
' If an error is thrown in the Intros plugin, instead of passing the error they pass the entire rick roll music video.
|
||||
' Bypass the music video and treat it as an error message
|
||||
if lcase(preRoll.items[0].name) <> "rick roll'd"
|
||||
m.global.queueManager.callFunc("push", m.global.queueManager.callFunc("getCurrentItem"))
|
||||
queueManager.callFunc("push", queueManager.callFunc("getCurrentItem"))
|
||||
m.top.itemId = preRoll.items[0].id
|
||||
m.global.queueManager.callFunc("setPrerollStatus", false)
|
||||
queueManager.callFunc("setPrerollStatus", false)
|
||||
m.top.isIntro = true
|
||||
end if
|
||||
end if
|
||||
@ -42,7 +44,7 @@ sub loadItems()
|
||||
end if
|
||||
|
||||
if m.top.selectedAudioStreamIndex = 0
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = queueManager.callFunc("getCurrentItem")
|
||||
if isValid(currentItem) and isValid(currentItem.json)
|
||||
m.top.selectedAudioStreamIndex = FindPreferredAudioStream(currentItem.json.MediaStreams)
|
||||
end if
|
||||
@ -80,6 +82,10 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
|
||||
return
|
||||
end if
|
||||
|
||||
queueManager = m.global.queueManager
|
||||
userSession = m.global.session.user
|
||||
userSettings = userSession.settings
|
||||
|
||||
session.video.Update(meta)
|
||||
|
||||
if isValid(meta.json.MediaSources[0].RunTimeTicks)
|
||||
@ -134,15 +140,14 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
|
||||
end if
|
||||
|
||||
if LCase(m.top.itemType) = "episode"
|
||||
userSession = m.global.session.user
|
||||
if userSession.settings["playback.playnextepisode"] = "enabled" or userSession.settings["playback.playnextepisode"] = "webclient" and userSession.Configuration.EnableNextEpisodeAutoPlay
|
||||
if userSettings["playback.playnextepisode"] = "enabled" or userSettings["playback.playnextepisode"] = "webclient" and userSession.Configuration.EnableNextEpisodeAutoPlay
|
||||
addNextEpisodesToQueue(video.showID)
|
||||
end if
|
||||
end if
|
||||
|
||||
playbackPosition = 0!
|
||||
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = queueManager.callFunc("getCurrentItem")
|
||||
|
||||
if isValid(currentItem) and isValid(currentItem.startingPoint)
|
||||
playbackPosition = currentItem.startingPoint
|
||||
@ -222,8 +227,8 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
|
||||
' transcode is that the Encoding Level is not supported, then try to direct play but silently
|
||||
' fall back to the transcode if that fails.
|
||||
if m.playbackInfo.MediaSources[0].MediaStreams.Count() > 0 and meta.live = false
|
||||
tryDirectPlay = m.global.session.user.settings["playback.tryDirect.h264ProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
|
||||
tryDirectPlay = tryDirectPlay or (m.global.session.user.settings["playback.tryDirect.hevcProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "hevc")
|
||||
tryDirectPlay = userSettings["playback.tryDirect.h264ProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
|
||||
tryDirectPlay = tryDirectPlay or (userSettings["playback.tryDirect.hevcProfileLevel"] and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "hevc")
|
||||
if tryDirectPlay and isValid(m.playbackInfo.MediaSources[0].TranscodingUrl) and forceTranscoding = false
|
||||
transcodingReasons = getTranscodeReasons(m.playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
if transcodingReasons.Count() = 1 and transcodingReasons[0] = "VideoLevelNotSupported"
|
||||
@ -263,7 +268,8 @@ end sub
|
||||
' @param {dynamic} videoID - id of video user is playing
|
||||
' @return {integer} indicating the default track's server-side index. Defaults to {SubtitleSelection.none} is one is not found
|
||||
function defaultSubtitleTrackFromVid(videoID) as integer
|
||||
if m.global.session.user.configuration.SubtitleMode = "None"
|
||||
userSession = m.global.session.user
|
||||
if userSession.configuration.SubtitleMode = "None"
|
||||
return SubtitleSelection.none ' No subtitles desired: return none
|
||||
end if
|
||||
|
||||
@ -289,7 +295,7 @@ function defaultSubtitleTrackFromVid(videoID) as integer
|
||||
return defaultTextSubs
|
||||
end if
|
||||
|
||||
if not m.global.session.user.settings["playback.subs.onlytext"]
|
||||
if not userSession.settings["playback.subs.onlytext"]
|
||||
return defaultSubtitleTrack(subtitles["all"], selectedAudioLanguage) ' if no appropriate text subs exist, allow non-text
|
||||
end if
|
||||
|
||||
@ -493,6 +499,8 @@ end function
|
||||
|
||||
' Add next episodes to the playback queue
|
||||
sub addNextEpisodesToQueue(showID)
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' Don't queue next episodes if we already have a playback queue
|
||||
maxQueueCount = 1
|
||||
|
||||
@ -500,13 +508,13 @@ sub addNextEpisodesToQueue(showID)
|
||||
maxQueueCount = 2
|
||||
end if
|
||||
|
||||
if m.global.queueManager.callFunc("getCount") > maxQueueCount then return
|
||||
if queueManager.callFunc("getCount") > maxQueueCount then return
|
||||
|
||||
videoID = m.top.itemId
|
||||
|
||||
' If first item is an intro video, use the next item in the queue
|
||||
if m.top.isIntro
|
||||
currentVideo = m.global.queueManager.callFunc("getItemByIndex", 1)
|
||||
currentVideo = queueManager.callFunc("getItemByIndex", 1)
|
||||
|
||||
if isValid(currentVideo) and isValid(currentVideo.id)
|
||||
videoID = currentVideo.id
|
||||
@ -528,7 +536,7 @@ sub addNextEpisodesToQueue(showID)
|
||||
|
||||
if isValid(data) and data.Items.Count() > 1
|
||||
for i = 1 to data.Items.Count() - 1
|
||||
m.global.queueManager.callFunc("push", data.Items[i])
|
||||
queueManager.callFunc("push", data.Items[i])
|
||||
end for
|
||||
end if
|
||||
end sub
|
||||
@ -587,8 +595,9 @@ function sortSubtitles(id as string, MediaStreams)
|
||||
end function
|
||||
|
||||
function FindPreferredAudioStream(streams as dynamic) as integer
|
||||
preferredLanguage = m.global.session.user.Configuration.AudioLanguagePreference
|
||||
playDefault = m.global.session.user.Configuration.PlayDefaultAudioTrack
|
||||
userConfig = m.global.session.user.configuration
|
||||
preferredLanguage = userConfig.AudioLanguagePreference
|
||||
playDefault = userConfig.PlayDefaultAudioTrack
|
||||
|
||||
if playDefault <> invalid and playDefault = true
|
||||
return 1
|
||||
|
@ -32,6 +32,7 @@ end sub
|
||||
|
||||
sub init()
|
||||
setupNodes()
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
m.overhang.isVisible = false
|
||||
|
||||
@ -41,7 +42,7 @@ sub init()
|
||||
alphaMicText = m.alpha.findNode("alphaMicText")
|
||||
alphaMicText.visible = false
|
||||
|
||||
m.showItemCount = m.global.session.user.settings["itemgrid.showItemCount"]
|
||||
m.showItemCount = userSettings["itemgrid.showItemCount"]
|
||||
|
||||
m.swapAnimation.observeField("state", "swapDone")
|
||||
|
||||
@ -88,7 +89,7 @@ sub init()
|
||||
m.loadItemsTask.totalRecordCount = 0
|
||||
|
||||
'Get reset folder setting
|
||||
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
|
||||
m.resetGrid = userSettings["itemgrid.reset"]
|
||||
end sub
|
||||
|
||||
sub OnScreenHidden()
|
||||
@ -114,6 +115,7 @@ end sub
|
||||
sub loadInitialItems()
|
||||
m.loadItemsTask.control = "stop"
|
||||
startLoadingSpinner(false)
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if m.top.parentItem.json.Type = "CollectionFolder"
|
||||
m.top.HomeLibraryItem = m.top.parentItem.Id
|
||||
@ -125,15 +127,15 @@ sub loadInitialItems()
|
||||
SetBackground("")
|
||||
end if
|
||||
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.filterOptions = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filterOptions"]
|
||||
m.view = m.global.session.user.settings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortAscending = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.filterOptions = userSettings["display." + m.top.parentItem.Id + ".filterOptions"]
|
||||
m.view = userSettings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortAscending = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
|
||||
' If user has not set a preferred view for this folder, check if they've set a default view
|
||||
if not isValid(m.view)
|
||||
m.view = m.global.session.user.settings["itemgrid.movieDefaultView"]
|
||||
m.view = userSettings["itemgrid.movieDefaultView"]
|
||||
end if
|
||||
|
||||
if not isValid(m.sortField) then m.sortField = "SortName"
|
||||
@ -202,7 +204,7 @@ sub loadInitialItems()
|
||||
m.itemGrid.numRows = "3"
|
||||
m.selectedMovieOverview.visible = false
|
||||
m.infoGroup.visible = false
|
||||
m.top.showItemTitles = m.global.session.user.settings["itemgrid.gridTitles"]
|
||||
m.top.showItemTitles = userSettings["itemgrid.gridTitles"]
|
||||
if LCase(m.top.showItemTitles) = "hidealways"
|
||||
m.itemGrid.itemSize = "[230, 315]"
|
||||
m.itemGrid.rowHeights = "[315]"
|
||||
|
@ -27,6 +27,7 @@ end sub
|
||||
|
||||
sub init()
|
||||
setupNodes()
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
m.overhang.isVisible = false
|
||||
|
||||
@ -36,7 +37,7 @@ sub init()
|
||||
alphaMicText = m.alpha.findNode("alphaMicText")
|
||||
alphaMicText.visible = false
|
||||
|
||||
m.showItemCount = m.global.session.user.settings["itemgrid.showItemCount"]
|
||||
m.showItemCount = userSettings["itemgrid.showItemCount"]
|
||||
|
||||
m.swapAnimation.observeField("state", "swapDone")
|
||||
|
||||
@ -82,7 +83,7 @@ sub init()
|
||||
m.loadItemsTask.totalRecordCount = 0
|
||||
|
||||
'Get reset folder setting
|
||||
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
|
||||
m.resetGrid = userSettings["itemgrid.reset"]
|
||||
end sub
|
||||
|
||||
sub OnScreenHidden()
|
||||
@ -108,6 +109,7 @@ end sub
|
||||
sub loadInitialItems()
|
||||
m.loadItemsTask.control = "stop"
|
||||
startLoadingSpinner(false)
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if LCase(m.top.parentItem.json.Type) = "collectionfolder"
|
||||
m.top.HomeLibraryItem = m.top.parentItem.Id
|
||||
@ -119,17 +121,17 @@ sub loadInitialItems()
|
||||
SetBackground("")
|
||||
end if
|
||||
|
||||
m.sortField = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.sortAscending = m.global.session.user.settings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = m.global.session.user.settings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = m.global.session.user.settings["display." + m.top.parentItem.Id + ".landing"]
|
||||
m.sortField = userSettings["display." + m.top.parentItem.Id + ".sortField"]
|
||||
m.sortAscending = userSettings["display." + m.top.parentItem.Id + ".sortAscending"]
|
||||
m.filter = userSettings["display." + m.top.parentItem.Id + ".filter"]
|
||||
m.view = userSettings["display." + m.top.parentItem.Id + ".landing"]
|
||||
|
||||
if not isValid(m.sortField) then m.sortField = "SortName"
|
||||
if not isValid(m.filter) then m.filter = "All"
|
||||
if not isValid(m.view) then m.view = "ArtistsPresentation"
|
||||
if not isValid(m.sortAscending) then m.sortAscending = true
|
||||
|
||||
m.top.showItemTitles = m.global.session.user.settings["itemgrid.gridTitles"]
|
||||
m.top.showItemTitles = userSettings["itemgrid.gridTitles"]
|
||||
|
||||
if LCase(m.top.parentItem.json.type) = "musicgenre"
|
||||
m.itemGrid.translation = "[96, 60]"
|
||||
|
@ -15,7 +15,8 @@ sub init()
|
||||
m.top.transcodeReasons = []
|
||||
m.bufferCheckTimer.duration = 30
|
||||
|
||||
if m.global.session.user.settings["ui.design.hideclock"] = true
|
||||
userSettings = m.global.session.user.settings
|
||||
if userSettings["ui.design.hideclock"]
|
||||
clockNode = findNodeBySubtype(m.top, "clock")
|
||||
if clockNode[0] <> invalid then clockNode[0].parent.removeChild(clockNode[0].node)
|
||||
end if
|
||||
@ -24,7 +25,7 @@ sub init()
|
||||
m.nextEpisodeButton = m.top.findNode("nextEpisode")
|
||||
m.nextEpisodeButton.text = tr("Next Episode")
|
||||
m.nextEpisodeButton.setFocus(false)
|
||||
m.nextupbuttonseconds = m.global.session.user.settings["playback.nextupbuttonseconds"].ToInt()
|
||||
m.nextupbuttonseconds = userSettings["playback.nextupbuttonseconds"].ToInt()
|
||||
|
||||
m.showNextEpisodeButtonAnimation = m.top.findNode("showNextEpisodeButton")
|
||||
m.hideNextEpisodeButtonAnimation = m.top.findNode("hideNextEpisodeButton")
|
||||
|
@ -19,10 +19,10 @@ sub init()
|
||||
|
||||
' Randomize the background colors
|
||||
backdropColor = "#00a4db" ' set default in case global var is invalid
|
||||
localGlobal = m.global
|
||||
myGlobal = m.global
|
||||
|
||||
if isValid(localGlobal) and isValid(localGlobal.constants) and isValid(localGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = localGlobal.constants.poster_bg_pallet
|
||||
if isValid(myGlobal) and isValid(myGlobal.constants) and isValid(myGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = myGlobal.constants.poster_bg_pallet
|
||||
backdropColor = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
end if
|
||||
|
||||
@ -67,8 +67,9 @@ sub itemContentChanged() as void
|
||||
m.poster = m.top.findNode("poster")
|
||||
itemData = m.top.itemContent
|
||||
m.title.text = itemData.title
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"] = false
|
||||
if not userSettings["ui.tvshows.disableUnwatchedEpisodeCount"]
|
||||
if isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
@ -96,7 +97,7 @@ sub itemContentChanged() as void
|
||||
|
||||
imageUrl = itemData.posterURL
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.blurunwatched"] = true
|
||||
if userSettings["ui.tvshows.blurunwatched"]
|
||||
if itemData.json.lookup("Type") = "Episode" and isValid(itemData.json.userdata)
|
||||
if not itemData.json.userdata.played
|
||||
imageUrl = imageUrl + "&blur=15"
|
||||
@ -118,7 +119,7 @@ sub focusChanged()
|
||||
m.staticTitle.visible = false
|
||||
m.title.visible = true
|
||||
' text to speech for accessibility
|
||||
if m.global.device.isAudioGuideEnabled = true
|
||||
if m.global.device.isAudioGuideEnabled
|
||||
txt2Speech = CreateObject("roTextToSpeech")
|
||||
txt2Speech.Flush()
|
||||
txt2Speech.Say(m.title.text)
|
||||
|
File diff suppressed because one or more lines are too long
@ -24,10 +24,10 @@ sub init()
|
||||
|
||||
' Randomize the background colors
|
||||
backdropColor = "#00a4db" ' set default in case global var is invalid
|
||||
localGlobal = m.global
|
||||
myGlobal = m.global
|
||||
|
||||
if isValid(localGlobal) and isValid(localGlobal.constants) and isValid(localGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = localGlobal.constants.poster_bg_pallet
|
||||
if isValid(myGlobal) and isValid(myGlobal.constants) and isValid(myGlobal.constants.poster_bg_pallet)
|
||||
posterBackgrounds = myGlobal.constants.poster_bg_pallet
|
||||
backdropColor = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
end if
|
||||
|
||||
@ -64,7 +64,7 @@ sub itemContentChanged()
|
||||
if isValid(m.unplayedCount) then m.unplayedCount.visible = false
|
||||
itemData = m.top.itemContent
|
||||
if itemData = invalid then return
|
||||
localGlobal = m.global
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
itemData.Title = itemData.name ' Temporarily required while we move from "HomeItem" to "JFContentItem"
|
||||
|
||||
@ -81,9 +81,9 @@ sub itemContentChanged()
|
||||
m.itemTextExtra.width = itemData.imageWidth
|
||||
m.itemTextExtra.visible = true
|
||||
m.itemTextExtra.text = ""
|
||||
|
||||
m.backdrop.width = itemData.imageWidth
|
||||
|
||||
|
||||
if isValid(itemData.iconUrl)
|
||||
m.itemIcon.uri = itemData.iconUrl
|
||||
end if
|
||||
@ -94,8 +94,8 @@ sub itemContentChanged()
|
||||
m.playedIndicator.visible = false
|
||||
|
||||
if LCase(itemData.type) = "series"
|
||||
if isValid(localGlobal) and isValid(localGlobal.session) and isValid(localGlobal.session.user) and isValid(localGlobal.session.user.settings)
|
||||
unwatchedEpisodeCountSetting = localGlobal.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"]
|
||||
if isValid(userSettings)
|
||||
unwatchedEpisodeCountSetting = userSettings["ui.tvshows.disableUnwatchedEpisodeCount"]
|
||||
if isValid(unwatchedEpisodeCountSetting) and not unwatchedEpisodeCountSetting
|
||||
if isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
@ -166,16 +166,16 @@ sub itemContentChanged()
|
||||
drawProgressBar(itemData)
|
||||
end if
|
||||
|
||||
if localGlobal.session.user.settings["ui.general.episodeimagesnextup"] = "webclient"
|
||||
tmpSetting = localGlobal.session.user.Configuration.useEpisodeImagesInNextUpAndResume
|
||||
if userSettings["ui.general.episodeimagesnextup"] = "webclient"
|
||||
tmpSetting = m.global.session.user.Configuration.useEpisodeImagesInNextUpAndResume
|
||||
if isValid(tmpSetting) and tmpSetting
|
||||
m.itemPoster.uri = itemData.thumbnailURL
|
||||
else
|
||||
m.itemPoster.uri = itemData.widePosterURL
|
||||
end if
|
||||
else if localGlobal.session.user.settings["ui.general.episodeimagesnextup"] = "show"
|
||||
else if userSettings["ui.general.episodeimagesnextup"] = "show"
|
||||
m.itemPoster.uri = itemData.widePosterURL
|
||||
else if localGlobal.session.user.settings["ui.general.episodeimagesnextup"] = "episode"
|
||||
else if userSettings["ui.general.episodeimagesnextup"] = "episode"
|
||||
m.itemPoster.uri = itemData.thumbnailURL
|
||||
end if
|
||||
|
||||
|
@ -78,10 +78,11 @@ sub processUserSections()
|
||||
m.processedRowCount = 0
|
||||
|
||||
sessionUser = m.global.session.user
|
||||
userSettings = sessionUser.settings
|
||||
|
||||
' calculate expected row count by processing homesections
|
||||
for i = 0 to 6
|
||||
userSection = sessionUser.settings["homesection" + i.toStr()]
|
||||
userSection = userSettings["homesection" + i.toStr()]
|
||||
sectionName = userSection ?? "none"
|
||||
sectionName = LCase(sectionName)
|
||||
|
||||
@ -101,7 +102,7 @@ sub processUserSections()
|
||||
' Add home sections in order based on user settings
|
||||
loadedSections = 0
|
||||
for i = 0 to 6
|
||||
userSection = sessionUser.settings["homesection" + i.toStr()]
|
||||
userSection = userSettings["homesection" + i.toStr()]
|
||||
sectionName = userSection ?? "none"
|
||||
sectionName = LCase(sectionName)
|
||||
|
||||
@ -151,10 +152,10 @@ function getOriginalSectionIndex(sectionName as string) as integer
|
||||
sectionIndex = 0
|
||||
indexLatestMediaSection = 0
|
||||
|
||||
sessionUser = m.global.session.user
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
for i = 0 to 6
|
||||
userSection = sessionUser.settings["homesection" + i.toStr()]
|
||||
userSection = userSettings["homesection" + i.toStr()]
|
||||
settingSectionName = userSection ?? "none"
|
||||
settingSectionName = LCase(settingSectionName)
|
||||
|
||||
|
@ -62,6 +62,7 @@ sub loadItems()
|
||||
|
||||
' Load Next Up
|
||||
else if m.top.itemsToLoad = "nextUp"
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
url = "Shows/NextUp"
|
||||
params = {}
|
||||
@ -70,12 +71,12 @@ sub loadItems()
|
||||
params["SortOrder"] = "Descending"
|
||||
params["ImageTypeLimit"] = 1
|
||||
params["UserId"] = m.global.session.user.id
|
||||
params["EnableRewatching"] = m.global.session.user.settings["ui.details.enablerewatchingnextup"]
|
||||
params["EnableRewatching"] = userSettings["ui.details.enablerewatchingnextup"]
|
||||
params["DisableFirstEpisode"] = false
|
||||
params["limit"] = 24
|
||||
params["EnableTotalRecordCount"] = false
|
||||
|
||||
maxDaysInNextUp = m.global.session.user.settings["ui.details.maxdaysnextup"].ToInt()
|
||||
maxDaysInNextUp = userSettings["ui.details.maxdaysnextup"].ToInt()
|
||||
if isValid(maxDaysInNextUp)
|
||||
if maxDaysInNextUp > 0
|
||||
dateToday = CreateObject("roDateTime")
|
||||
|
@ -60,9 +60,9 @@ sub onSelectAudioPressed()
|
||||
|
||||
audioData.data.push(audioStreamItem)
|
||||
end for
|
||||
|
||||
m.global.sceneManager.callFunc("radioDialog", tr("Select Audio"), audioData)
|
||||
m.global.sceneManager.observeField("returnData", "onSelectionMade")
|
||||
sceneManager = m.global.sceneManager
|
||||
sceneManager.callFunc("radioDialog", tr("Select Audio"), audioData)
|
||||
sceneManager.observeField("returnData", "onSelectionMade")
|
||||
end sub
|
||||
|
||||
' User requested subtitle selection popup
|
||||
@ -112,23 +112,25 @@ sub onSelectSubtitlePressed()
|
||||
"Type": "subtitleselection"
|
||||
})
|
||||
|
||||
m.global.sceneManager.callFunc("radioDialog", tr("Select Subtitles"), subtitleData)
|
||||
m.global.sceneManager.observeField("returnData", "onSelectionMade")
|
||||
sceneManager = m.global.sceneManager
|
||||
sceneManager.callFunc("radioDialog", tr("Select Subtitles"), subtitleData)
|
||||
sceneManager.observeField("returnData", "onSelectionMade")
|
||||
end sub
|
||||
|
||||
' User has selected something from the radioDialog popup
|
||||
sub onSelectionMade()
|
||||
m.global.sceneManager.unobserveField("returnData")
|
||||
sceneManager = m.global.sceneManager
|
||||
sceneManager.unobserveField("returnData")
|
||||
|
||||
if not isValid(m.global.sceneManager.returnData) then return
|
||||
if not isValid(m.global.sceneManager.returnData.type) then return
|
||||
if not isValid(sceneManager.returnData) then return
|
||||
if not isValid(sceneManager.returnData.type) then return
|
||||
|
||||
if LCase(m.global.sceneManager.returnData.type) = "subtitleselection"
|
||||
if LCase(sceneManager.returnData.type) = "subtitleselection"
|
||||
processSubtitleSelection()
|
||||
return
|
||||
end if
|
||||
|
||||
if LCase(m.global.sceneManager.returnData.type) = "audioselection"
|
||||
if LCase(sceneManager.returnData.type) = "audioselection"
|
||||
processAudioSelection()
|
||||
return
|
||||
end if
|
||||
@ -218,21 +220,24 @@ end sub
|
||||
' Playback state change event handlers
|
||||
sub onStateChange()
|
||||
if LCase(m.view.state) = "finished"
|
||||
sceneManager = m.global.sceneManager
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' Close any open dialogs
|
||||
if m.global.sceneManager.callFunc("isDialogOpen")
|
||||
m.global.sceneManager.callFunc("dismissDialog")
|
||||
if sceneManager.callFunc("isDialogOpen")
|
||||
sceneManager.callFunc("dismissDialog")
|
||||
end if
|
||||
|
||||
' If there is something next in the queue, play it
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
if queueManager.callFunc("getPosition") < queueManager.callFunc("getCount") - 1
|
||||
sceneManager.callFunc("clearPreviousScene")
|
||||
queueManager.callFunc("moveForward")
|
||||
queueManager.callFunc("playQueue")
|
||||
return
|
||||
end if
|
||||
|
||||
' Playback completed, return user to previous screen
|
||||
m.global.sceneManager.callFunc("popScene")
|
||||
sceneManager.callFunc("popScene")
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
end if
|
||||
end sub
|
||||
|
@ -99,6 +99,7 @@ sub itemContentChanged()
|
||||
' Updates video metadata
|
||||
item = m.top.itemContent
|
||||
if isValid(item) and isValid(item.json)
|
||||
userSettings = m.global.session.user.settings
|
||||
itemData = item.json
|
||||
m.top.id = itemData.id
|
||||
m.top.findNode("moviePoster").uri = m.top.itemContent.posterURL
|
||||
@ -122,7 +123,7 @@ sub itemContentChanged()
|
||||
m.infoGroup.removeChild(m.top.findNode("officialRating"))
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.movies.showRatings"]
|
||||
if userSettings["ui.movies.showRatings"]
|
||||
if isValid(itemData.communityRating)
|
||||
setFieldText("communityRating", int(itemData.communityRating * 10) / 10)
|
||||
else
|
||||
@ -147,7 +148,7 @@ sub itemContentChanged()
|
||||
|
||||
if type(itemData.RunTimeTicks) = "LongInteger"
|
||||
setFieldText("runtime", stri(getRuntime()) + " mins")
|
||||
if m.global.session.user.settings["ui.design.hideclock"] <> true
|
||||
if userSettings["ui.design.hideclock"] <> true
|
||||
setFieldText("ends-at", tr("Ends at %1").Replace("%1", getEndTime()))
|
||||
end if
|
||||
end if
|
||||
@ -175,7 +176,7 @@ sub itemContentChanged()
|
||||
m.top.findNode("details").removeChild(m.top.findNode("director"))
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.details.hidetagline"] = false
|
||||
if userSettings["ui.details.hidetagline"] = false
|
||||
if itemData.taglines.count() > 0
|
||||
setFieldText("tagline", itemData.taglines[0])
|
||||
end if
|
||||
|
@ -11,9 +11,14 @@ sub init()
|
||||
m.lastRecordedPositionTimestamp = 0
|
||||
m.scrubTimestamp = -1
|
||||
|
||||
m.playlistTypeCount = m.global.queueManager.callFunc("getQueueUniqueTypes").count()
|
||||
m.queueManager = m.global.queueManager
|
||||
m.playlistTypeCount = m.queueManager.callFunc("getQueueUniqueTypes").count()
|
||||
|
||||
m.audioPlayer = m.global.audioPlayer
|
||||
m.audioPlayer.observeField("state", "audioStateChanged")
|
||||
m.audioPlayer.observeField("position", "audioPositionChanged")
|
||||
m.audioPlayer.observeField("bufferingStatus", "bufferPositionChanged")
|
||||
|
||||
setupAudioNode()
|
||||
setupAnimationTasks()
|
||||
setupButtons()
|
||||
setupInfoNodes()
|
||||
@ -93,13 +98,6 @@ sub setupDataTasks()
|
||||
m.LoadScreenSaverTimeoutTask = CreateObject("roSGNode", "LoadScreenSaverTimeoutTask")
|
||||
end sub
|
||||
|
||||
' Creates audio node used to play song(s)
|
||||
sub setupAudioNode()
|
||||
m.global.audioPlayer.observeField("state", "audioStateChanged")
|
||||
m.global.audioPlayer.observeField("position", "audioPositionChanged")
|
||||
m.global.audioPlayer.observeField("bufferingStatus", "bufferPositionChanged")
|
||||
end sub
|
||||
|
||||
' Setup playback buttons, default to Play button selected
|
||||
sub setupButtons()
|
||||
m.buttons = m.top.findNode("buttons")
|
||||
@ -151,10 +149,10 @@ end sub
|
||||
sub bufferPositionChanged()
|
||||
if m.inScrubMode then return
|
||||
|
||||
if not isValid(m.global.audioPlayer.bufferingStatus)
|
||||
if not isValid(m.audioPlayer.bufferingStatus)
|
||||
bufferPositionBarWidth = m.seekBar.width
|
||||
else
|
||||
bufferPositionBarWidth = m.seekBar.width * m.global.audioPlayer.bufferingStatus.percentage
|
||||
bufferPositionBarWidth = m.seekBar.width * m.audioPlayer.bufferingStatus.percentage
|
||||
end if
|
||||
|
||||
' Ensure position bar is never wider than the seek bar
|
||||
@ -170,16 +168,16 @@ end sub
|
||||
sub audioPositionChanged()
|
||||
stopLoadingSpinner()
|
||||
|
||||
if m.global.audioPlayer.position = 0
|
||||
if m.audioPlayer.position = 0
|
||||
m.playPosition.width = 0
|
||||
end if
|
||||
|
||||
if not isValid(m.global.audioPlayer.position)
|
||||
if not isValid(m.audioPlayer.position)
|
||||
playPositionBarWidth = 0
|
||||
else if not isValid(m.songDuration)
|
||||
playPositionBarWidth = 0
|
||||
else
|
||||
songPercentComplete = m.global.audioPlayer.position / m.songDuration
|
||||
songPercentComplete = m.audioPlayer.position / m.songDuration
|
||||
playPositionBarWidth = m.seekBar.width * songPercentComplete
|
||||
end if
|
||||
|
||||
@ -191,7 +189,7 @@ sub audioPositionChanged()
|
||||
if not m.inScrubMode
|
||||
moveSeekbarThumb(playPositionBarWidth)
|
||||
' Change the seek position timestamp
|
||||
m.seekTimestamp.text = secondsToHuman(m.global.audioPlayer.position, false)
|
||||
m.seekTimestamp.text = secondsToHuman(m.audioPlayer.position, false)
|
||||
end if
|
||||
|
||||
' Use animation to make the display smooth
|
||||
@ -199,9 +197,9 @@ sub audioPositionChanged()
|
||||
m.playPositionAnimation.control = "start"
|
||||
|
||||
' Update displayed position timestamp
|
||||
if isValid(m.global.audioPlayer.position)
|
||||
m.lastRecordedPositionTimestamp = m.global.audioPlayer.position
|
||||
m.positionTimestamp.text = secondsToHuman(m.global.audioPlayer.position, false)
|
||||
if isValid(m.audioPlayer.position)
|
||||
m.lastRecordedPositionTimestamp = m.audioPlayer.position
|
||||
m.positionTimestamp.text = secondsToHuman(m.audioPlayer.position, false)
|
||||
else
|
||||
m.lastRecordedPositionTimestamp = 0
|
||||
m.positionTimestamp.text = "0:00"
|
||||
@ -249,25 +247,24 @@ sub endScreenSaver()
|
||||
end sub
|
||||
|
||||
sub audioStateChanged()
|
||||
|
||||
' Song Finished, attempt to move to next song
|
||||
if m.global.audioPlayer.state = "finished"
|
||||
if m.audioPlayer.state = "finished"
|
||||
' User has enabled single song loop, play current song again
|
||||
if m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = "one"
|
||||
m.scrubTimestamp = -1
|
||||
playAction()
|
||||
exitScrubMode()
|
||||
return
|
||||
end if
|
||||
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
if m.queueManager.callFunc("getPosition") < m.queueManager.callFunc("getCount") - 1
|
||||
m.top.state = "finished"
|
||||
else
|
||||
' We are at the end of the song queue
|
||||
|
||||
' User has enabled loop for entire song queue, move back to first song
|
||||
if m.global.audioPlayer.loopMode = "all"
|
||||
m.global.queueManager.callFunc("setPosition", -1)
|
||||
if m.audioPlayer.loopMode = "all"
|
||||
m.queueManager.callFunc("setPosition", -1)
|
||||
LoadNextSong()
|
||||
return
|
||||
end if
|
||||
@ -279,18 +276,19 @@ sub audioStateChanged()
|
||||
end sub
|
||||
|
||||
function playAction() as boolean
|
||||
if m.global.audioPlayer.state = "playing"
|
||||
m.global.audioPlayer.control = "pause"
|
||||
|
||||
if m.audioPlayer.state = "playing"
|
||||
m.audioPlayer.control = "pause"
|
||||
' Allow screen to go to real screensaver
|
||||
WriteAsciiFile("tmp:/scene.temp", "nowplaying-paused")
|
||||
MoveFile("tmp:/scene.temp", "tmp:/scene")
|
||||
else if m.global.audioPlayer.state = "paused"
|
||||
m.global.audioPlayer.control = "resume"
|
||||
else if m.audioPlayer.state = "paused"
|
||||
m.audioPlayer.control = "resume"
|
||||
' Write screen tracker for screensaver
|
||||
WriteAsciiFile("tmp:/scene.temp", "nowplaying")
|
||||
MoveFile("tmp:/scene.temp", "tmp:/scene")
|
||||
else if m.global.audioPlayer.state = "finished"
|
||||
m.global.audioPlayer.control = "play"
|
||||
else if m.audioPlayer.state = "finished"
|
||||
m.audioPlayer.control = "play"
|
||||
' Write screen tracker for screensaver
|
||||
WriteAsciiFile("tmp:/scene.temp", "nowplaying")
|
||||
MoveFile("tmp:/scene.temp", "tmp:/scene")
|
||||
@ -300,20 +298,19 @@ function playAction() as boolean
|
||||
end function
|
||||
|
||||
function previousClicked() as boolean
|
||||
currentQueuePosition = m.global.queueManager.callFunc("getPosition")
|
||||
|
||||
currentQueuePosition = m.queueManager.callFunc("getPosition")
|
||||
if currentQueuePosition = 0 then return false
|
||||
|
||||
if m.playlistTypeCount > 1
|
||||
previousItem = m.global.queueManager.callFunc("getItemByIndex", currentQueuePosition - 1)
|
||||
previousItemType = m.global.queueManager.callFunc("getItemType", previousItem)
|
||||
previousItem = m.queueManager.callFunc("getItemByIndex", currentQueuePosition - 1)
|
||||
previousItemType = m.queueManager.callFunc("getItemType", previousItem)
|
||||
|
||||
if previousItemType <> "audio"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
m.audioPlayer.control = "stop"
|
||||
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveBack")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
m.queueManager.callFunc("moveBack")
|
||||
m.queueManager.callFunc("playQueue")
|
||||
return true
|
||||
end if
|
||||
end if
|
||||
@ -323,34 +320,33 @@ function previousClicked() as boolean
|
||||
m.lastRecordedPositionTimestamp = 0
|
||||
m.positionTimestamp.text = "0:00"
|
||||
|
||||
if m.global.audioPlayer.state = "playing"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
if m.audioPlayer.state = "playing"
|
||||
m.audioPlayer.control = "stop"
|
||||
end if
|
||||
|
||||
' Reset loop mode due to manual user interaction
|
||||
if m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = "one"
|
||||
resetLoopModeToDefault()
|
||||
end if
|
||||
|
||||
m.global.queueManager.callFunc("moveBack")
|
||||
m.queueManager.callFunc("moveBack")
|
||||
pageContentChanged()
|
||||
|
||||
return true
|
||||
end function
|
||||
|
||||
sub resetLoopModeToDefault()
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.loopMode = ""
|
||||
setLoopButtonImage()
|
||||
end sub
|
||||
|
||||
function loopClicked() as boolean
|
||||
|
||||
if m.global.audioPlayer.loopMode = ""
|
||||
m.global.audioPlayer.loopMode = "all"
|
||||
else if m.global.audioPlayer.loopMode = "all"
|
||||
m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.loopMode = "all"
|
||||
else if m.audioPlayer.loopMode = "all"
|
||||
m.audioPlayer.loopMode = "one"
|
||||
else
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.loopMode = ""
|
||||
end if
|
||||
|
||||
setLoopButtonImage()
|
||||
@ -359,10 +355,10 @@ function loopClicked() as boolean
|
||||
end function
|
||||
|
||||
sub setLoopButtonImage()
|
||||
if m.global.audioPlayer.loopMode = "all"
|
||||
if m.audioPlayer.loopMode = "all"
|
||||
m.loopIndicator.opacity = "1"
|
||||
m.loopIndicator.uri = m.loopIndicator.uri.Replace("-off", "-on")
|
||||
else if m.global.audioPlayer.loopMode = "one"
|
||||
else if m.audioPlayer.loopMode = "one"
|
||||
m.loopIndicator.uri = m.loopIndicator.uri.Replace("-on", "1-on")
|
||||
else
|
||||
m.loopIndicator.uri = m.loopIndicator.uri.Replace("1-on", "-off")
|
||||
@ -370,19 +366,20 @@ sub setLoopButtonImage()
|
||||
end sub
|
||||
|
||||
function nextClicked() as boolean
|
||||
if m.playlistTypeCount > 1
|
||||
currentQueuePosition = m.global.queueManager.callFunc("getPosition")
|
||||
if currentQueuePosition < m.global.queueManager.callFunc("getCount") - 1
|
||||
|
||||
nextItem = m.global.queueManager.callFunc("getItemByIndex", currentQueuePosition + 1)
|
||||
nextItemType = m.global.queueManager.callFunc("getItemType", nextItem)
|
||||
if m.playlistTypeCount > 1
|
||||
currentQueuePosition = m.queueManager.callFunc("getPosition")
|
||||
if currentQueuePosition < m.queueManager.callFunc("getCount") - 1
|
||||
|
||||
nextItem = m.queueManager.callFunc("getItemByIndex", currentQueuePosition + 1)
|
||||
nextItemType = m.queueManager.callFunc("getItemType", nextItem)
|
||||
|
||||
if nextItemType <> "audio"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
m.audioPlayer.control = "stop"
|
||||
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
m.queueManager.callFunc("moveForward")
|
||||
m.queueManager.callFunc("playQueue")
|
||||
return true
|
||||
end if
|
||||
end if
|
||||
@ -394,11 +391,11 @@ function nextClicked() as boolean
|
||||
m.positionTimestamp.text = "0:00"
|
||||
|
||||
' Reset loop mode due to manual user interaction
|
||||
if m.global.audioPlayer.loopMode = "one"
|
||||
if m.audioPlayer.loopMode = "one"
|
||||
resetLoopModeToDefault()
|
||||
end if
|
||||
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
if m.queueManager.callFunc("getPosition") < m.queueManager.callFunc("getCount") - 1
|
||||
LoadNextSong()
|
||||
end if
|
||||
|
||||
@ -406,14 +403,14 @@ function nextClicked() as boolean
|
||||
end function
|
||||
|
||||
sub toggleShuffleEnabled()
|
||||
m.global.queueManager.callFunc("toggleShuffle")
|
||||
m.queueManager.callFunc("toggleShuffle")
|
||||
end sub
|
||||
|
||||
function findCurrentSongIndex(songList) as integer
|
||||
if not isValidAndNotEmpty(songList) then return 0
|
||||
|
||||
for i = 0 to songList.count() - 1
|
||||
if songList[i].id = m.global.queueManager.callFunc("getCurrentItem").id
|
||||
if songList[i].id = m.queueManager.callFunc("getCurrentItem").id
|
||||
return i
|
||||
end if
|
||||
end for
|
||||
@ -422,15 +419,14 @@ function findCurrentSongIndex(songList) as integer
|
||||
end function
|
||||
|
||||
function shuffleClicked() as boolean
|
||||
|
||||
currentSongIndex = findCurrentSongIndex(m.global.queueManager.callFunc("getUnshuffledQueue"))
|
||||
currentSongIndex = findCurrentSongIndex(m.queueManager.callFunc("getUnshuffledQueue"))
|
||||
|
||||
toggleShuffleEnabled()
|
||||
|
||||
if not m.global.queueManager.callFunc("getIsShuffled")
|
||||
if not m.queueManager.callFunc("getIsShuffled")
|
||||
m.shuffleIndicator.opacity = ".4"
|
||||
m.shuffleIndicator.uri = m.shuffleIndicator.uri.Replace("-on", "-off")
|
||||
m.global.queueManager.callFunc("setPosition", currentSongIndex)
|
||||
m.queueManager.callFunc("setPosition", currentSongIndex)
|
||||
setTrackNumberDisplay()
|
||||
return true
|
||||
end if
|
||||
@ -443,26 +439,26 @@ function shuffleClicked() as boolean
|
||||
end function
|
||||
|
||||
sub setShuffleIconState()
|
||||
if m.global.queueManager.callFunc("getIsShuffled")
|
||||
if m.queueManager.callFunc("getIsShuffled")
|
||||
m.shuffleIndicator.opacity = "1"
|
||||
m.shuffleIndicator.uri = m.shuffleIndicator.uri.Replace("-off", "-on")
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub setTrackNumberDisplay()
|
||||
setFieldTextValue("numberofsongs", "Track " + stri(m.global.queueManager.callFunc("getPosition") + 1) + "/" + stri(m.global.queueManager.callFunc("getCount")))
|
||||
setFieldTextValue("numberofsongs", "Track " + stri(m.queueManager.callFunc("getPosition") + 1) + "/" + stri(m.queueManager.callFunc("getCount")))
|
||||
end sub
|
||||
|
||||
sub LoadNextSong()
|
||||
if m.global.audioPlayer.state = "playing"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
if m.audioPlayer.state = "playing"
|
||||
m.audioPlayer.control = "stop"
|
||||
end if
|
||||
|
||||
exitScrubMode()
|
||||
|
||||
' Reset playPosition bar without animation
|
||||
m.playPosition.width = 0
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.queueManager.callFunc("moveForward")
|
||||
pageContentChanged()
|
||||
end sub
|
||||
|
||||
@ -471,7 +467,7 @@ sub pageContentChanged()
|
||||
|
||||
m.LoadAudioStreamTask.control = "STOP"
|
||||
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = m.queueManager.callFunc("getCurrentItem")
|
||||
|
||||
m.LoadAudioStreamTask.itemId = currentItem.id
|
||||
m.LoadAudioStreamTask.observeField("content", "onAudioStreamLoaded")
|
||||
@ -480,7 +476,7 @@ end sub
|
||||
|
||||
' If we have more and 1 song to play, fade in the next and previous controls
|
||||
sub loadButtons()
|
||||
if m.global.queueManager.callFunc("getCount") > 1
|
||||
if m.queueManager.callFunc("getCount") > 1
|
||||
m.shuffleIndicator.opacity = ".4"
|
||||
m.loopIndicator.opacity = ".4"
|
||||
m.displayButtonsAnimation.control = "start"
|
||||
@ -497,7 +493,7 @@ sub onAudioStreamLoaded()
|
||||
m.bufferPosition.width = 0
|
||||
|
||||
useMetaTask = false
|
||||
currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
currentItem = m.queueManager.callFunc("getCurrentItem")
|
||||
|
||||
if not isValid(currentItem.RunTimeTicks)
|
||||
useMetaTask = true
|
||||
@ -533,9 +529,9 @@ sub onAudioStreamLoaded()
|
||||
m.totalLengthTimestamp.text = ticksToHuman(currentItem.RunTimeTicks)
|
||||
end if
|
||||
|
||||
m.global.audioPlayer.content = data
|
||||
m.global.audioPlayer.control = "none"
|
||||
m.global.audioPlayer.control = "play"
|
||||
m.audioPlayer.content = data
|
||||
m.audioPlayer.control = "none"
|
||||
m.audioPlayer.control = "play"
|
||||
end if
|
||||
end sub
|
||||
|
||||
@ -741,7 +737,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if m.inScrubMode
|
||||
startLoadingSpinner()
|
||||
m.inScrubMode = false
|
||||
m.global.audioPlayer.seek = m.scrubTimestamp
|
||||
m.audioPlayer.seek = m.scrubTimestamp
|
||||
return true
|
||||
end if
|
||||
|
||||
@ -775,15 +771,15 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
end if
|
||||
|
||||
if key = "back"
|
||||
m.global.audioPlayer.control = "stop"
|
||||
m.global.audioPlayer.loopMode = ""
|
||||
m.audioPlayer.control = "stop"
|
||||
m.audioPlayer.loopMode = ""
|
||||
else if key = "rewind"
|
||||
return previousClicked()
|
||||
else if key = "fastforward"
|
||||
return nextClicked()
|
||||
else if key = "left"
|
||||
if m.buttons.hasFocus()
|
||||
if m.global.queueManager.callFunc("getCount") = 1 then return false
|
||||
if m.queueManager.callFunc("getCount") = 1 then return false
|
||||
|
||||
if m.top.selectedButtonIndex > 0
|
||||
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
|
||||
@ -793,7 +789,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
end if
|
||||
else if key = "right"
|
||||
if m.buttons.hasFocus()
|
||||
if m.global.queueManager.callFunc("getCount") = 1 then return false
|
||||
if m.queueManager.callFunc("getCount") = 1 then return false
|
||||
|
||||
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
|
||||
if m.top.selectedButtonIndex < m.buttonCount - 1 then m.top.selectedButtonIndex = m.top.selectedButtonIndex + 1
|
||||
|
@ -12,8 +12,9 @@ sub init()
|
||||
m.textBackground = m.top.findNode("background")
|
||||
m.statusTimer = m.top.findNode("statusTimer")
|
||||
m.statusTimer.observeField("fire", "statusUpdate")
|
||||
m.slideshow = m.global.session.user.settings["photos.slideshow"]
|
||||
m.random = m.global.session.user.settings["photos.random"]
|
||||
userSettings = m.global.session.user.settings
|
||||
m.slideshow = userSettings["photos.slideshow"]
|
||||
m.random = userSettings["photos.random"]
|
||||
|
||||
m.showStatusAnimation = m.top.findNode("showStatusAnimation")
|
||||
m.hideStatusAnimation = m.top.findNode("hideStatusAnimation")
|
||||
|
@ -93,26 +93,28 @@ sub settingFocused()
|
||||
m.integerSetting.visible = false
|
||||
m.radioSetting.visible = false
|
||||
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
if selectedSetting.type = invalid
|
||||
return
|
||||
else if selectedSetting.type = "bool"
|
||||
|
||||
m.boolSetting.visible = true
|
||||
|
||||
if m.global.session.user.settings[selectedSetting.settingName] = true
|
||||
if userSettings[selectedSetting.settingName] = true
|
||||
m.boolSetting.checkedItem = 1
|
||||
else
|
||||
m.boolSetting.checkedItem = 0
|
||||
end if
|
||||
else if selectedSetting.type = "integer"
|
||||
integerValue = m.global.session.user.settings[selectedSetting.settingName].ToStr()
|
||||
integerValue = userSettings[selectedSetting.settingName].ToStr()
|
||||
if isValid(integerValue)
|
||||
m.integerSetting.text = integerValue
|
||||
end if
|
||||
m.integerSetting.visible = true
|
||||
else if LCase(selectedSetting.type) = "radio"
|
||||
|
||||
selectedValue = m.global.session.user.settings[selectedSetting.settingName]
|
||||
selectedValue = userSettings[selectedSetting.settingName]
|
||||
|
||||
radioContent = CreateObject("roSGNode", "ContentNode")
|
||||
|
||||
@ -175,7 +177,6 @@ sub boolSettingChanged()
|
||||
set_setting(selectedSetting.settingName, "true")
|
||||
' setting specific triggers
|
||||
if selectedSetting.settingName = "global.rememberme"
|
||||
print "m.global.session.user.id=", m.global.session.user.id
|
||||
set_setting("active_user", m.global.session.user.id)
|
||||
end if
|
||||
else
|
||||
|
@ -23,13 +23,16 @@ end sub
|
||||
sub itemContentChanged()
|
||||
item = m.top.itemContent
|
||||
itemData = item.json
|
||||
userSettings = m.global.session.user.settings
|
||||
|
||||
' Set default video source if user hasn't selected one yet
|
||||
if item.selectedVideoStreamId = "" and isValid(itemData.MediaSources)
|
||||
item.selectedVideoStreamId = itemData.MediaSources[0].id
|
||||
end if
|
||||
|
||||
if isValid(itemData.indexNumber)
|
||||
if isValid(itemData.parentIndexNumber) and itemData.parentIndexNumber = 0
|
||||
indexNumber = `${tr("Special")} - `
|
||||
else if isValid(itemData.indexNumber)
|
||||
indexNumber = `${itemData.indexNumber}. `
|
||||
if isValid(itemData.indexNumberEnd)
|
||||
indexNumber = `${itemData.indexNumber}-${itemData.indexNumberEnd}. `
|
||||
@ -48,7 +51,7 @@ sub itemContentChanged()
|
||||
|
||||
imageUrl = item.posterURL
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.blurunwatched"] = true
|
||||
if userSettings["ui.tvshows.blurunwatched"] = true
|
||||
if itemData.lookup("Type") = "Episode"
|
||||
if not itemData.userdata.played
|
||||
imageUrl = imageUrl + "&blur=15"
|
||||
@ -66,12 +69,12 @@ sub itemContentChanged()
|
||||
m.top.findNode("runtime").text = stri(runTime).trim() + " mins"
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.design.hideclock"] <> true
|
||||
if userSettings["ui.design.hideclock"] <> true
|
||||
m.top.findNode("endtime").text = tr("Ends at %1").Replace("%1", getEndTime())
|
||||
end if
|
||||
end if
|
||||
|
||||
if m.global.session.user.settings["ui.tvshows.disableCommunityRating"] = false
|
||||
if userSettings["ui.tvshows.disableCommunityRating"] = false
|
||||
if isValid(itemData.communityRating)
|
||||
m.top.findNode("star").visible = true
|
||||
m.top.findNode("communityRating").text = str(int(itemData.communityRating * 10) / 10)
|
||||
|
@ -183,9 +183,11 @@ end function
|
||||
|
||||
sub onShuffleEpisodeDataLoaded()
|
||||
m.getShuffleEpisodesTask.unobserveField("data")
|
||||
|
||||
if isValid(m.getShuffleEpisodesTask.data)
|
||||
m.global.queueManager.callFunc("set", m.getShuffleEpisodesTask.data.items)
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
queueManager = m.global.queueManager
|
||||
queueManager.callFunc("set", m.getShuffleEpisodesTask.data.items)
|
||||
queueManager.callFunc("playQueue")
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
@ -37,7 +37,6 @@ sub init()
|
||||
m.optionControls.buttonFocused = m.optionControls.getChildCount() - 1
|
||||
|
||||
m.videoControls.getChild(m.defaultButtonIndex).focus = true
|
||||
m.deviceInfo = CreateObject("roDeviceInfo")
|
||||
end sub
|
||||
|
||||
' onProgressPercentageChanged: Handler for changes to m.top.progressPercentage param
|
||||
@ -213,7 +212,8 @@ sub inactiveCheck()
|
||||
return
|
||||
end if
|
||||
|
||||
if m.deviceInfo.timeSinceLastKeypress() >= m.top.inactiveTimeout
|
||||
deviceInfo = CreateObject("roDeviceInfo")
|
||||
if deviceInfo.timeSinceLastKeypress() >= m.top.inactiveTimeout
|
||||
m.top.action = "hide"
|
||||
end if
|
||||
end sub
|
||||
|
@ -9,6 +9,7 @@ sub init()
|
||||
m.log = log.Logger("VideoPlayerView")
|
||||
' Hide the overhang on init to prevent showing 2 clocks
|
||||
m.top.getScene().findNode("overhang").visible = false
|
||||
userSettings = m.global.session.user.settings
|
||||
m.currentItem = m.global.queueManager.callFunc("getCurrentItem")
|
||||
|
||||
m.top.id = m.currentItem.id
|
||||
@ -48,7 +49,7 @@ sub init()
|
||||
m.top.transcodeReasons = []
|
||||
m.bufferCheckTimer.duration = 30
|
||||
|
||||
if m.global.session.user.settings["ui.design.hideclock"] = true
|
||||
if userSettings["ui.design.hideclock"] = true
|
||||
clockNode = findNodeBySubtype(m.top, "clock")
|
||||
if clockNode[0] <> invalid then clockNode[0].parent.removeChild(clockNode[0].node)
|
||||
end if
|
||||
@ -57,7 +58,7 @@ sub init()
|
||||
m.nextEpisodeButton = m.top.findNode("nextEpisode")
|
||||
m.nextEpisodeButton.text = tr("Next Episode")
|
||||
m.nextEpisodeButton.setFocus(false)
|
||||
m.nextupbuttonseconds = m.global.session.user.settings["playback.nextupbuttonseconds"].ToInt()
|
||||
m.nextupbuttonseconds = userSettings["playback.nextupbuttonseconds"].ToInt()
|
||||
|
||||
m.showNextEpisodeButtonAnimation = m.top.findNode("showNextEpisodeButton")
|
||||
m.hideNextEpisodeButtonAnimation = m.top.findNode("hideNextEpisodeButton")
|
||||
@ -102,26 +103,30 @@ end sub
|
||||
' @param {string} action - skip action to take
|
||||
sub handleItemSkipAction(action as string)
|
||||
if action = "itemnext"
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' If there is something next in the queue, play it
|
||||
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
|
||||
if queueManager.callFunc("getPosition") < queueManager.callFunc("getCount") - 1
|
||||
m.top.control = "stop"
|
||||
session.video.Delete()
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveForward")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
queueManager.callFunc("moveForward")
|
||||
queueManager.callFunc("playQueue")
|
||||
end if
|
||||
|
||||
return
|
||||
end if
|
||||
|
||||
if action = "itemback"
|
||||
queueManager = m.global.queueManager
|
||||
|
||||
' If there is something previous in the queue, play it
|
||||
if m.global.queueManager.callFunc("getPosition") > 0
|
||||
if queueManager.callFunc("getPosition") > 0
|
||||
m.top.control = "stop"
|
||||
session.video.Delete()
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
m.global.queueManager.callFunc("moveBack")
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
queueManager.callFunc("moveBack")
|
||||
queueManager.callFunc("playQueue")
|
||||
end if
|
||||
|
||||
return
|
||||
@ -525,9 +530,9 @@ sub showNextEpisodeButton()
|
||||
if m.top.content.contenttype <> 4 then return ' only display when content is type "Episode"
|
||||
if m.nextupbuttonseconds = 0 then return ' is the button disabled?
|
||||
if m.nextEpisodeButton.opacity <> 0 then return
|
||||
userSession = m.global.session.user
|
||||
if userSession.settings["playback.playnextepisode"] = "disabled" then return
|
||||
if userSession.settings["playback.playnextepisode"] = "webclient" and not userSession.Configuration.EnableNextEpisodeAutoPlay then return
|
||||
userSettings = m.global.session.user.settings
|
||||
if userSettings["playback.playnextepisode"] = "disabled" then return
|
||||
if userSettings["playback.playnextepisode"] = "webclient" and not m.global.session.user.Configuration.EnableNextEpisodeAutoPlay then return
|
||||
|
||||
m.nextEpisodeButton.visible = true
|
||||
m.showNextEpisodeButtonAnimation.control = "start"
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -74,15 +74,18 @@
|
||||
end if
|
||||
end if
|
||||
|
||||
' has the current user ran this version before?
|
||||
usersLastRunVersion = m.global.session.user.settings.lastRunVersion
|
||||
if not isValid(usersLastRunVersion) or not versionChecker(m.global.session.user.settings.lastRunVersion, m.global.app.version)
|
||||
set_user_setting("LastRunVersion", m.global.app.version)
|
||||
' show what's new popup
|
||||
if m.global.session.user.settings["load.allowwhatsnew"]
|
||||
dialog = createObject("roSGNode", "WhatsNewDialog")
|
||||
m.scene.dialog = dialog
|
||||
m.scene.dialog.observeField("buttonSelected", m.port)
|
||||
' only show whats new popup and update lastRunVersion on prod
|
||||
if not m.global.app.isDev
|
||||
' has the current user ran this version before?
|
||||
usersLastRunVersion = m.global.session.user.settings.lastRunVersion
|
||||
if not isValid(usersLastRunVersion) or not versionChecker(usersLastRunVersion, m.global.app.version)
|
||||
set_user_setting("LastRunVersion", m.global.app.version)
|
||||
' show what's new popup
|
||||
if m.global.session.user.settings["load.allowwhatsnew"]
|
||||
dialog = createObject("roSGNode", "WhatsNewDialog")
|
||||
m.scene.dialog = dialog
|
||||
m.scene.dialog.observeField("buttonSelected", m.port)
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
|
@ -39,8 +39,10 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT
|
||||
params.EnableDirectPlay = false
|
||||
end if
|
||||
|
||||
if audioTrackIndex > -1
|
||||
selectedAudioStream = m.global.session.video.json.MediaStreams[audioTrackIndex]
|
||||
myGLobal = m.global
|
||||
|
||||
if audioTrackIndex > -1 and myGLobal.session.video.json.MediaStreams <> invalid
|
||||
selectedAudioStream = myGLobal.session.video.json.MediaStreams[audioTrackIndex]
|
||||
|
||||
if selectedAudioStream <> invalid
|
||||
params.AudioStreamIndex = audioTrackIndex
|
||||
@ -64,7 +66,6 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT
|
||||
end for
|
||||
end if
|
||||
end if
|
||||
|
||||
end if
|
||||
end if
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -99,11 +99,8 @@ sub SaveDeviceToGlobal()
|
||||
print "ERROR parsing deviceInfo.GetVideoMode()"
|
||||
end if
|
||||
videoWidth = heightToWidth[videoHeight]
|
||||
if videoHeight = "2160" and extraData = "b10"
|
||||
bitDepth = 10
|
||||
else if videoHeight = "4320"
|
||||
bitDepth = 12
|
||||
end if
|
||||
if extraData <> invalid and extraData = "b10" then bitDepth = 10
|
||||
if videoHeight = "4320" then bitDepth = 12
|
||||
|
||||
m.global.addFields({
|
||||
device: {
|
||||
|
@ -1314,6 +1314,14 @@
|
||||
<translation>Use Show Image</translation>
|
||||
<extracomment>User Setting - Setting option title</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play Next Episode Automatically</source>
|
||||
<translation>Play Next Episode Automatically</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>When finished playing a single episode, play the next one automatically.</source>
|
||||
<translation>When finished playing a single episode, play the next one automatically.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name></name>
|
||||
|
@ -1366,5 +1366,10 @@
|
||||
<translation>Both</translation>
|
||||
<extracomment>User Setting - Setting option title</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special</source>
|
||||
<translation>Special</translation>
|
||||
<extracomment>Special episode of a TV Show</extracomment>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
4
manifest
4
manifest
@ -2,8 +2,8 @@
|
||||
|
||||
title=Jellyfin
|
||||
major_version=2
|
||||
minor_version=1
|
||||
build_version=7
|
||||
minor_version=2
|
||||
build_version=0
|
||||
|
||||
### Main Menu Icons / Channel Poster Artwork
|
||||
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "jellyfin-roku",
|
||||
"version": "2.1.7",
|
||||
"version": "2.2.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "jellyfin-roku",
|
||||
"version": "2.1.7",
|
||||
"version": "2.2.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-2.0",
|
||||
"dependencies": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jellyfin-roku",
|
||||
"type": "module",
|
||||
"version": "2.1.7",
|
||||
"version": "2.2.0",
|
||||
"description": "Roku app for Jellyfin media server",
|
||||
"dependencies": {
|
||||
"@rokucommunity/bslib": "0.1.1",
|
||||
|
@ -72,15 +72,18 @@ sub Main (args as dynamic) as void
|
||||
end if
|
||||
end if
|
||||
|
||||
' has the current user ran this version before?
|
||||
usersLastRunVersion = m.global.session.user.settings.lastRunVersion
|
||||
if not isValid(usersLastRunVersion) or not versionChecker(m.global.session.user.settings.lastRunVersion, m.global.app.version)
|
||||
set_user_setting("LastRunVersion", m.global.app.version)
|
||||
' show what's new popup
|
||||
if m.global.session.user.settings["load.allowwhatsnew"]
|
||||
dialog = createObject("roSGNode", "WhatsNewDialog")
|
||||
m.scene.dialog = dialog
|
||||
m.scene.dialog.observeField("buttonSelected", m.port)
|
||||
' only show whats new popup and update lastRunVersion on prod
|
||||
if not m.global.app.isDev
|
||||
' has the current user ran this version before?
|
||||
usersLastRunVersion = m.global.session.user.settings.lastRunVersion
|
||||
if not isValid(usersLastRunVersion) or not versionChecker(usersLastRunVersion, m.global.app.version)
|
||||
set_user_setting("LastRunVersion", m.global.app.version)
|
||||
' show what's new popup
|
||||
if m.global.session.user.settings["load.allowwhatsnew"]
|
||||
dialog = createObject("roSGNode", "WhatsNewDialog")
|
||||
m.scene.dialog = dialog
|
||||
m.scene.dialog.observeField("buttonSelected", m.port)
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
|
@ -37,8 +37,10 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT
|
||||
params.EnableDirectPlay = false
|
||||
end if
|
||||
|
||||
if audioTrackIndex > -1
|
||||
selectedAudioStream = m.global.session.video.json.MediaStreams[audioTrackIndex]
|
||||
myGLobal = m.global
|
||||
|
||||
if audioTrackIndex > -1 and myGLobal.session.video.json.MediaStreams <> invalid
|
||||
selectedAudioStream = myGLobal.session.video.json.MediaStreams[audioTrackIndex]
|
||||
|
||||
if selectedAudioStream <> invalid
|
||||
params.AudioStreamIndex = audioTrackIndex
|
||||
@ -62,7 +64,6 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT
|
||||
end for
|
||||
end if
|
||||
end if
|
||||
|
||||
end if
|
||||
end if
|
||||
|
||||
|
@ -414,7 +414,9 @@ function getContainerProfiles() as object
|
||||
end function
|
||||
|
||||
function getCodecProfiles() as object
|
||||
globalUserSettings = m.global.session.user.settings
|
||||
myGlobal = m.global
|
||||
globalUserSettings = myGlobal.session.user.settings
|
||||
|
||||
codecProfiles = []
|
||||
profileSupport = {
|
||||
"h264": {},
|
||||
@ -555,26 +557,45 @@ function getCodecProfiles() as object
|
||||
hevcVideoRangeTypes = "SDR"
|
||||
vp9VideoRangeTypes = "SDR"
|
||||
av1VideoRangeTypes = "SDR"
|
||||
canPlayDovi = false
|
||||
|
||||
dp = di.GetDisplayProperties()
|
||||
if dp.Hdr10
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10"
|
||||
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10"
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10"
|
||||
end if
|
||||
if dp.Hdr10Plus
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10+"
|
||||
end if
|
||||
if dp.HLG
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG"
|
||||
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG"
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HLG"
|
||||
end if
|
||||
if dp.DolbyVision
|
||||
h264VideoRangeTypes = h264VideoRangeTypes + "|DOVI"
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI"
|
||||
'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI"
|
||||
if canPlay4k()
|
||||
dp = di.GetDisplayProperties()
|
||||
|
||||
if dp.DolbyVision
|
||||
canPlayDovi = true
|
||||
|
||||
h264VideoRangeTypes = h264VideoRangeTypes + "|DOVI|DOVIWithSDR"
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI|DOVIWithSDR"
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI|DOVIWithSDR"
|
||||
end if
|
||||
|
||||
if dp.Hdr10
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10"
|
||||
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10"
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10"
|
||||
|
||||
if canPlayDovi
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVIWithHDR10"
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|DOVIWithHDR10"
|
||||
end if
|
||||
end if
|
||||
|
||||
if dp.Hdr10Plus
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10+"
|
||||
end if
|
||||
|
||||
if dp.HLG
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG"
|
||||
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG"
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HLG"
|
||||
|
||||
if canPlayDovi
|
||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVIWithHLG"
|
||||
vp9VideoRangeTypes = vp9VideoRangeTypes + "|DOVIWithHLG"
|
||||
av1VideoRangeTypes = av1VideoRangeTypes + "|DOVIWithHLG"
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
' H264
|
||||
@ -605,12 +626,6 @@ function getCodecProfiles() as object
|
||||
"Value": "true",
|
||||
"IsRequired": false
|
||||
},
|
||||
{
|
||||
"Condition": "LessThanEqual",
|
||||
"Property": "VideoBitDepth",
|
||||
"Value": "8",
|
||||
"IsRequired": false
|
||||
},
|
||||
{
|
||||
"Condition": "EqualsAny",
|
||||
"Property": "VideoProfile",
|
||||
@ -1094,3 +1109,28 @@ function setPreferredCodec(codecString as string, preferredCodec as string) as s
|
||||
return newCodecString
|
||||
end if
|
||||
end function
|
||||
|
||||
' does the connected display support playing 4k video?
|
||||
function canPlay4k() as boolean
|
||||
deviceInfo = CreateObject("roDeviceInfo")
|
||||
hdmiStatus = CreateObject("roHdmiStatus")
|
||||
|
||||
' Check if the output mode is 2160p or higher
|
||||
maxVideoHeight = m.global.device.videoHeight
|
||||
if maxVideoHeight = invalid then return false
|
||||
if maxVideoHeight.ToInt() < 2160
|
||||
return false
|
||||
end if
|
||||
|
||||
' Check if HDCP 2.2 is enabled, skip check for TVs
|
||||
if deviceInfo.GetModelType() = "STB" and hdmiStatus.IsHdcpActive("2.2") <> true
|
||||
return false
|
||||
end if
|
||||
|
||||
' Check if the Roku player can decode 4K 60fps HEVC streams
|
||||
if deviceInfo.CanDecodeVideo({ Codec: "hevc", Profile: "main", Level: "5.1" }).result <> true
|
||||
return false
|
||||
end if
|
||||
|
||||
return true
|
||||
end function
|
||||
|
@ -97,11 +97,8 @@ sub SaveDeviceToGlobal()
|
||||
print "ERROR parsing deviceInfo.GetVideoMode()"
|
||||
end if
|
||||
videoWidth = heightToWidth[videoHeight]
|
||||
if videoHeight = "2160" and extraData = "b10"
|
||||
bitDepth = 10
|
||||
else if videoHeight = "4320"
|
||||
bitDepth = 12
|
||||
end if
|
||||
if extraData <> invalid and extraData = "b10" then bitDepth = 10
|
||||
if videoHeight = "4320" then bitDepth = 12
|
||||
|
||||
m.global.addFields({
|
||||
device: {
|
||||
|
Loading…
Reference in New Issue
Block a user