Skip to content

Commit

Permalink
Update API docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jellyfin-bot committed Jul 12, 2024
1 parent 5ad10e3 commit f8f469e
Show file tree
Hide file tree
Showing 13 changed files with 182 additions and 15 deletions.
17 changes: 8 additions & 9 deletions docs/api/components_WhatsNewDialog.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

m.top.id = "OKDialog"
m.top.height = 900
m.top.title = m.global.app.version + " - " + tr("What's New?")
m.top.title = tr("Welcome to version") + " " + m.global.app.version
m.top.buttons = [tr("OK")]

dialogStyles = {
Expand All @@ -16,21 +16,20 @@
"fontUri": "font:SystemFontFile",
"color": "#EFEFEFFF"
},
"author": {
"url": {
"fontSize": 27,
"fontUri": "font:SystemFontFile",
"color": "#00a4dcFF"
}
}

whatsNewList = ParseJSON(ReadAsciiFile("pkg:/source/static/whatsNew/" + m.global.app.version.ToStr().trim() + ".json"))

for each item in whatsNewList
textLine = m.content.CreateChild("StdDlgMultiStyleTextItem")
textLine.drawingStyles = dialogStyles
textLine.text = "• " + item.description + " <author>" + item.author + "</author>"
end for
' empty line for spacing
textLine = m.content.CreateChild("StdDlgMultiStyleTextItem")
textLine.text = ""

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>"
end sub

sub setPalette()
Expand Down
39 changes: 37 additions & 2 deletions docs/api/components_home_HomeRows.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,25 @@
' create a "Latest In" row for each library
for each lib in m.filteredLatest
if lib.collectionType <> "boxsets" and lib.collectionType <> "livetv" and lib.json.CollectionType <> "Program"
sectionName = `${tr("Latest in")} ${lib.name} >`

imagesize = homeRowItemSizes.WIDE_POSTER

if isValid(lib.json.CollectionType)
if LCase(lib.json.CollectionType) = "movies"
imagesize = homeRowItemSizes.MOVIE_POSTER
else if LCase(lib.json.CollectionType) = "music"
imagesize = homeRowItemSizes.MUSIC_ALBUM
end if
end if

if not sectionExists(sectionName)
nextUpRow = m.top.content.CreateChild("HomeRow")
nextUpRow.title = sectionName
nextUpRow.imageWidth = imagesize[0]
nextUpRow.cursorSize = imagesize
end if

loadLatest = createObject("roSGNode", "LoadItemsTask")
loadLatest.itemsToLoad = "latest"
loadLatest.itemId = lib.id
Expand Down Expand Up @@ -377,13 +396,31 @@
' createLiveTVRow: Creates a row displaying the live tv now on section
'
sub createLiveTVRow()
sectionName = tr("On Now")

if not sectionExists(sectionName)
nextUpRow = m.top.content.CreateChild("HomeRow")
nextUpRow.title = sectionName
nextUpRow.imageWidth = homeRowItemSizes.WIDE_POSTER[0]
nextUpRow.cursorSize = homeRowItemSizes.WIDE_POSTER
end if

m.LoadOnNowTask.observeField("content", "updateOnNowItems")
m.LoadOnNowTask.control = "RUN"
end sub

' createContinueWatchingRow: Creates a row displaying items the user can continue watching
'
sub createContinueWatchingRow()
sectionName = tr("Continue Watching")

if not sectionExists(sectionName)
nextUpRow = m.top.content.CreateChild("HomeRow")
nextUpRow.title = sectionName
nextUpRow.imageWidth = homeRowItemSizes.WIDE_POSTER[0]
nextUpRow.cursorSize = homeRowItemSizes.WIDE_POSTER
end if

' Load the Continue Watching Data
m.LoadContinueWatchingTask.observeField("content", "updateContinueWatchingItems")
m.LoadContinueWatchingTask.control = "RUN"
Expand Down Expand Up @@ -480,8 +517,6 @@
return
end if

sectionName = tr("Continue Watching")

' remake row using the new data
row = CreateObject("roSGNode", "HomeRow")
row.title = sectionName
Expand Down
1 change: 1 addition & 0 deletions docs/api/components_manager_QueueManager.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@

' Set starting point for top item in the queue
sub setTopStartingPoint(positionTicks)
if getCount() = 0 then return
m.queue[0].startingPoint = positionTicks
end sub

Expand Down
42 changes: 42 additions & 0 deletions docs/api/components_movies_MovieDetails.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,58 @@
m.buttonGrp.setFocus(true)
m.top.lastFocus = m.buttonGrp

m.isFirstRun = true
m.top.observeField("itemContent", "itemContentChanged")

' Animation used to swap out posters on reloads
m.moviePosterSwapAnimation = m.top.findNode("moviePosterSwapAnimation")
m.moviePosterSwapAnimation.observeField("state", "onMoviePosterSwapAnimationStateChange")

m.top.observeField("newPosterImageURI", "onNewPosterImageURIChange")

m.moviePoster = m.top.findNode("moviePoster")
m.moviePosterSwap = m.top.findNode("moviePosterSwap")
m.moviePosterSwap.observeField("loadStatus", "onPosterLoadStatusChanged")
end sub

' onNewPosterImageURIChange: Handler for newPosterImageURI param change
'
sub onNewPosterImageURIChange()
m.moviePosterSwap.uri = m.top.newPosterImageURI
end sub

' onPosterLoadStatusChanged: Handler for changes to m.moviePosterSwap.loadStatus
'
sub onPosterLoadStatusChanged()
if LCase(m.moviePosterSwap.loadStatus) <> "ready" then return
m.moviePosterSwapAnimation.control = "start"
end sub

' onMoviePosterSwapAnimationStateChange: Handler for changes to m.moviePosterSwapAnimation.state
'
sub onMoviePosterSwapAnimationStateChange()
if LCase(m.moviePosterSwapAnimation.state) <> "stopped" then return
m.moviePoster.uri = m.moviePosterSwap.uri
m.moviePoster.opacity = 1
m.moviePosterSwap.opacity = 0
m.moviePosterSwap.uri = ""
end sub

' OnScreenShown: Callback function when view is presented on screen
'
sub OnScreenShown()
' set focus to button group
if m.extrasGrp.opacity = 1
m.top.lastFocus.setFocus(true)
else
m.buttonGrp.setFocus(true)
end if

if m.isFirstRun
m.isFirstRun = false
else
m.top.refreshMovieDetailsData = not m.top.refreshMovieDetailsData
end if
end sub

sub trailerAvailableChanged()
Expand Down
16 changes: 16 additions & 0 deletions docs/api/components_tvshows_TVEpisodes.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
m.unplayedEpisodeCount = m.top.findNode("unplayedEpisodeCount")

m.rows.observeField("doneLoading", "updateSeason")

m.isFirstRun = true
end sub

sub setSeasonLoading()
Expand All @@ -38,6 +40,8 @@
if m.top.seasonData.UserData.UnplayedItemCount > 0
m.unplayedCount.visible = true
m.unplayedEpisodeCount.text = m.top.seasonData.UserData.UnplayedItemCount
else
m.unplayedCount.visible = false
end if
end if
end if
Expand Down Expand Up @@ -68,6 +72,18 @@
return invalid
end function

' OnScreenShown: Callback function when view is presented on screen
'
sub OnScreenShown()
if m.isFirstRun
m.isFirstRun = false
return
end if

m.tvEpisodeRow.setFocus(true)
m.top.refreshSeasonDetailsData = not m.top.refreshSeasonDetailsData
end sub

' Handle navigation input from the remote and act on it
function onKeyEvent(key as string, press as boolean) as boolean
if key = "left" and m.tvEpisodeRow.hasFocus()
Expand Down
5 changes: 5 additions & 0 deletions docs/api/components_tvshows_TVListDetails.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
' Add checkmark in corner (if applicable)
if isValid(itemData.UserData) and isValid(itemData.UserData.Played) and itemData.UserData.Played = true
m.playedIndicator.visible = true
else
m.playedIndicator.visible = false
end if

' Add progress bar on bottom (if applicable)
Expand All @@ -95,6 +97,9 @@
progressWidthInPixels = int(m.progressBackground.width * itemData.UserData.PlayedPercentage / 100)
m.progressBar.width = progressWidthInPixels
m.progressBar.visible = true
else
m.progressBackground.visible = false
m.progressBar.visible = false
end if

' Display current video_codec and check if there is more than one video to choose from...
Expand Down
2 changes: 1 addition & 1 deletion docs/api/data/search.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/api/module-MovieDetails.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/api/module-TVEpisodes.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/api/module-misc.html

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions docs/api/source_Main.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,42 @@
end if
elapsed = timeSpan.TotalMilliseconds() / 1000
print "Quick Play finished loading in " + elapsed.toStr() + " seconds."
else if isNodeEvent(msg, "refreshSeasonDetailsData")
startLoadingSpinner()

currentEpisode = m.global.queueManager.callFunc("getCurrentItem")
currentScene = m.global.sceneManager.callFunc("getActiveScene")

' Find the object in the scene's data and update its json data
for i = 0 to currentScene.objects.Items.count() - 1
if LCase(currentScene.objects.Items[i].id) = LCase(currentEpisode.id)
currentScene.objects.Items[i].json = api.users.GetItem(m.global.session.user.id, currentEpisode.id)
m.global.queueManager.callFunc("setTopStartingPoint", currentScene.objects.Items[i].json.UserData.PlaybackPositionTicks)
exit for
end if
end for

seasonMetaData = ItemMetaData(currentScene.seasonData.id)
currentScene.seasonData = seasonMetaData.json
currentScene.episodeObjects = currentScene.objects
currentScene.callFunc("updateSeason")
stopLoadingSpinner()
else if isNodeEvent(msg, "refreshMovieDetailsData")
startLoadingSpinner()

currentScene = m.global.sceneManager.callFunc("getActiveScene")

' Refresh movie detail data
currentScene.itemContent.json = api.users.GetItem(m.global.session.user.id, currentScene.itemContent.id)
movieMetaData = ItemMetaData(currentScene.itemContent.id)

' Redraw movie poster
currentScene.newPosterImageURI = movieMetaData.posterURL

' Set updated starting point for the queue item
m.global.queueManager.callFunc("setTopStartingPoint", currentScene.itemContent.json.UserData.PlaybackPositionTicks)

stopLoadingSpinner()
else if isNodeEvent(msg, "selectedItem")
' If you select a library from ANYWHERE, follow this flow
selectedItem = msg.getData()
Expand Down
3 changes: 3 additions & 0 deletions docs/api/source_ShowScenes.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@
' start building MovieDetails view
group = CreateObject("roSGNode", "MovieDetails")
group.observeField("quickPlayNode", m.port)
group.observeField("refreshMovieDetailsData", m.port)
group.overhangTitle = movie.title
group.optionsAvailable = false
group.trailerAvailable = false
Expand Down Expand Up @@ -783,6 +784,8 @@
group.episodeObjects = group.objects
group.extrasObjects = TVSeasonExtras(season.id)

group.observeField("refreshSeasonDetailsData", m.port)

' watch for button presses
group.observeField("selectedItem", m.port)
group.observeField("quickPlayNode", m.port)
Expand Down
30 changes: 30 additions & 0 deletions docs/api/source_utils_misc.bs.html
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,36 @@
return true
end function

' isChainValid: Returns whether or not all the properties in the passed property chain are valid.
' Stops evaluating at first found false value
'
' @param {dynamic} root - high-level object to test property chain against
' @param {string} propertyPath - chain of properties under root object to test
' @return {boolean} indicating if all properties in chain are valid
function isChainValid(root as dynamic, propertyPath as string) as boolean
rootPath = root
properties = propertyPath.Split(".")

if not isValid(rootPath) then return false

' Root path is valid, and no properties were passed. Return state of root
if properties.count() = 0 then return true
if properties[0] = "" then return true

if not isValid(rootPath.lookup(properties[0])) then return false

rootPath = rootPath.lookup(properties[0])

properties.shift()

if properties.count() <> 0
nextPath = properties.join(".")
return isChainValid(rootPath, nextPath)
end if

return true
end function

' Returns whether or not passed value is valid and not empty
' Accepts a string, or any countable type (arrays and lists)
function isValidAndNotEmpty(input as dynamic) as boolean
Expand Down

0 comments on commit f8f469e

Please sign in to comment.