Skip to content

Commit 06ccb11

Browse files
committed
Update code docs
1 parent 06d0332 commit 06ccb11

9 files changed

Lines changed: 134 additions & 14 deletions

docs/components_GetShuffleItemsTask.bs.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@
3838
})
3939
if isValid(moviesData) and isValid(moviesData.Items) then items.append(moviesData.Items)
4040
if isValid(episodesData) and isValid(episodesData.Items) then items.append(episodesData.Items)
41+
else if input.type = "BoxSet"
42+
data = GetApi().GetItemsByQuery({
43+
"ParentId": input.id,
44+
"SortBy": "Random",
45+
"Limit": 200,
46+
"EnableTotalRecordCount": false
47+
})
48+
if isValid(data) and isValid(data.Items) then items = data.Items
4149
end if
4250

4351
m.top.shuffleItems = items

docs/components_ItemDetails.bs.html

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@
428428
populateInfoGroupMusicVideo(item, userSettings)
429429
else if item.type = "Person"
430430
populateInfoGroupPerson(item)
431+
else if item.type = "BoxSet"
432+
populateInfoGroupBoxSet(item, userSettings)
431433
else
432434
' Movie, Video, Recording
433435
populateInfoGroupMovie(item, userSettings)
@@ -671,6 +673,50 @@
671673
end if
672674
end sub
673675

676+
' populateInfoGroupBoxSet: Info rows for BoxSet (movie collection)
677+
' Row 1: Year · Official Rating · Community Rating · N Movies
678+
' Row 2: Genres · Studio
679+
sub populateInfoGroupBoxSet(item as object, userSettings as object)
680+
if item.productionYear > 0
681+
yearNode = createInfoLabel("releaseYear")
682+
yearNode.text = stri(item.productionYear).trim()
683+
displayInfoNode(yearNode)
684+
end if
685+
686+
if isValidAndNotEmpty(item.officialRating)
687+
ratingNode = createInfoLabel("officialRating")
688+
ratingNode.text = item.officialRating
689+
displayInfoNode(ratingNode)
690+
end if
691+
692+
if userSettings.uiMoviesShowRatings and item.communityRating > 0
693+
communityRatingNode = CreateObject("roSGNode", "CommunityRating")
694+
communityRatingNode.id = "communityRating"
695+
communityRatingNode.rating = item.communityRating
696+
displayInfoNode(communityRatingNode)
697+
end if
698+
699+
if item.childCount > 0
700+
movieCountNode = createInfoLabel("movieCount")
701+
movieLabel = tr("Movie")
702+
if item.childCount <> 1 then movieLabel = tr("Movies")
703+
movieCountNode.text = stri(item.childCount).trim() + " " + movieLabel
704+
displayInfoNode(movieCountNode)
705+
end if
706+
707+
if item.genres.count() > 0
708+
genreNode = createInfoLabel("genre")
709+
genreNode.text = item.genres.join(" / ")
710+
displayDirectorGenreNode(genreNode)
711+
end if
712+
713+
if item.studios.count() > 0
714+
studioNode = createInfoLabel("studio")
715+
studioNode.text = item.studios[0]
716+
displayDirectorGenreNode(studioNode)
717+
end if
718+
end sub
719+
674720
' populateInfoGroupSeason: Info rows for Season
675721
' Row 1: Year · Official Rating (series) · Avg episode runtime (series) · Ends At
676722
' Row 2: Series name · Episode count · Studio
@@ -866,9 +912,9 @@
866912

867913
' Media tracks and stream options are only relevant for playable types
868914
' Use reparenting instead of visible=false — invisible nodes still take up LayoutGroup space
869-
setTracksInLayout(item.type <> "Series" and item.type <> "Season" and item.type <> "Person")
915+
setTracksInLayout(item.type <> "Series" and item.type <> "Season" and item.type <> "Person" and item.type <> "BoxSet")
870916

871-
if item.type <> "Series" and item.type <> "Season" and item.type <> "Person"
917+
if item.type <> "Series" and item.type <> "Season" and item.type <> "Person" and item.type <> "BoxSet"
872918
if m.top.selectedVideoStreamId = "" and isValidAndNotEmpty(item.mediaSourceId)
873919
m.top.selectedVideoStreamId = item.mediaSourceId
874920
end if
@@ -1188,7 +1234,7 @@
11881234
if isValidAndNotEmpty(logoImageTag)
11891235
imgParams = { maxHeight: 212, maxWidth: 500, quality: 90, tag: logoImageTag }
11901236
m.itemLogo.uri = ImageURL(logoItemId, "Logo", imgParams)
1191-
else if item.type = "Movie" or item.type = "Series"
1237+
else if item.type = "Movie" or item.type = "Series" or item.type = "BoxSet"
11921238
' No logo: fall back to primary (poster) image — fetch at full quality; display height is
11931239
' capped by LOGO_MAX_DISPLAY_HEIGHT in onLogoLoadStatusChanged to avoid overlapping info rows.
11941240
if isValidAndNotEmpty(item.primaryImageTag)
@@ -1512,7 +1558,7 @@
15121558
playButton = CreateObject("roSGNode", "IconButton")
15131559
playButton.id = "playButton"
15141560
playButton.icon = "pkg:/images/icons/play.png"
1515-
if itemType = "Series" or itemType = "Season"
1561+
if itemType = "Series" or itemType = "Season" or itemType = "BoxSet"
15161562
playButton.text = tr("Play All")
15171563
else
15181564
playButton.text = tr("Play")
@@ -1529,8 +1575,8 @@
15291575
m.buttonGrp.appendChild(watchedButton)
15301576
end if
15311577

1532-
' Shuffle button — Series and Season only (Person shuffle is async via onPersonHasMediaChanged)
1533-
if itemType = "Series" or itemType = "Season"
1578+
' Shuffle button — Series, Season, and BoxSet (Person shuffle is async via onPersonHasMediaChanged)
1579+
if itemType = "Series" or itemType = "Season" or itemType = "BoxSet"
15341580
m.shuffleButton = CreateObject("roSGNode", "IconButton")
15351581
m.shuffleButton.id = "shuffleButton"
15361582
m.shuffleButton.icon = "pkg:/images/icons/shuffle.png"

docs/components_extras_ExtrasRowList.bs.html

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
m.LoadAdditionalPartsTask.itemsToLoad = "additionalparts"
2121
m.LoadSeasonsTask = CreateObject("roSGNode", "LoadItemsTask")
2222
m.LoadSeasonsTask.itemsToLoad = "seasons"
23+
m.LoadBoxSetItemsTask = CreateObject("roSGNode", "LoadItemsTask")
24+
m.LoadBoxSetItemsTask.itemsToLoad = "boxsetitems"
2325
m.LoadMoviesTask = CreateObject("roSGNode", "LoadItemsTask")
2426
m.LoadMoviesTask.itemsToLoad = "personMovies"
2527
m.LoadShowsTask = CreateObject("roSGNode", "LoadItemsTask")
@@ -47,6 +49,7 @@
4749
m.rowCast = invalid
4850
m.rowLikeThis = invalid
4951
m.rowSpecialFeatures = invalid
52+
m.rowBoxSetItems = invalid
5053
m.rowMovies = invalid
5154
m.rowTvShows = invalid
5255
m.rowSeries = invalid
@@ -88,6 +91,8 @@
8891
m.LoadShowsTask.unobserveField("content")
8992
m.LoadSeriesTask.control = "STOP"
9093
m.LoadSeriesTask.unobserveField("content")
94+
m.LoadBoxSetItemsTask.control = "STOP"
95+
m.LoadBoxSetItemsTask.unobserveField("content")
9196
end sub
9297

9398
' loadParts: Start the extras loading chain appropriate for the item type.
@@ -96,7 +101,8 @@
96101
' Movie / Video / Recording → AdditionalParts → People → LikeThis → SpecialFeatures
97102
' MusicVideo / Episode → People → LikeThis
98103
' Series → Seasons → People → LikeThis
99-
' Season → Episodes ("Season X") → People → LikeThis'
104+
' Season → Episodes ("Season X") → People → LikeThis
105+
' BoxSet → BoxSetItems ("Movies") → People → LikeThis
100106
' m.top.type must be set before calling this function (done by ShowScenes.bs).
101107
sub loadParts(data as object)
102108
cancelInFlightChain()
@@ -132,6 +138,11 @@
132138
m.LoadPeopleTask.observeField("content", "onPeopleLoaded")
133139
m.LoadPeopleTask.peopleList = m.people
134140
m.LoadPeopleTask.control = "RUN"
141+
else if itemType = "BoxSet"
142+
m.top.rowItemSize = [rowSlotSize.PORTRAIT]
143+
m.LoadBoxSetItemsTask.itemId = m.top.parentId
144+
m.LoadBoxSetItemsTask.observeField("content", "onBoxSetItemsLoaded")
145+
m.LoadBoxSetItemsTask.control = "RUN"
135146
else
136147
' Movie, Video, Recording: full chain starting with AdditionalParts
137148
m.LoadAdditionalPartsTask.observeField("content", "onAdditionalPartsLoaded")
@@ -240,6 +251,25 @@
240251
m.LoadPeopleTask.control = "RUN"
241252
end sub
242253

254+
' onBoxSetItemsLoaded: Build "Movies" row then chain to People → LikeThis (BoxSet only)
255+
sub onBoxSetItemsLoaded()
256+
content = m.LoadBoxSetItemsTask.content
257+
m.LoadBoxSetItemsTask.unobserveField("content")
258+
m.LoadBoxSetItemsTask.content = []
259+
260+
if isValid(content) and content.count() > 0
261+
m.rowBoxSetItems = populateRow(m.rowBoxSetItems, tr("Movies"), content, rowSlotSize.ROW_HEIGHT_PORTRAIT)
262+
else if isValid(m.rowBoxSetItems)
263+
m.top.content.removeChild(m.rowBoxSetItems)
264+
m.rowBoxSetItems = invalid
265+
end if
266+
267+
' Continue chain: People → LikeThis
268+
m.LoadPeopleTask.observeField("content", "onPeopleLoaded")
269+
m.LoadPeopleTask.peopleList = m.people
270+
m.LoadPeopleTask.control = "RUN"
271+
end sub
272+
243273
sub onAdditionalPartsLoaded()
244274
parts = m.LoadAdditionalPartsTask.content
245275
m.LoadAdditionalPartsTask.unobserveField("content")
@@ -311,8 +341,8 @@
311341
m.rowLikeThis = invalid
312342
end if
313343

314-
' SpecialFeatures only for Movie / Video / Recording — not MusicVideo, Episode, Series, or Season
315-
if itemType <> "MusicVideo" and itemType <> "Episode" and itemType <> "Series" and itemType <> "Season"
344+
' SpecialFeatures only for Movie / Video / Recording — not MusicVideo, Episode, Series, Season, or BoxSet
345+
if itemType <> "MusicVideo" and itemType <> "Episode" and itemType <> "Series" and itemType <> "Season" and itemType <> "BoxSet"
316346
m.SpecialFeaturesTask.observeField("content", "onSpecialFeaturesLoaded")
317347
m.SpecialFeaturesTask.itemId = m.top.parentId
318348
m.SpecialFeaturesTask.control = "RUN"

docs/components_home_LoadItemsTask.bs.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@
263263
results.push(AudioStream(m.top.itemId))
264264
else if m.top.itemsToLoad = "backdropImage"
265265
results.push(BackdropImage(m.top.itemId))
266+
else if m.top.itemsToLoad = "boxsetitems"
267+
data = GetApi().GetItemsByQuery({
268+
"ParentId": m.top.itemId,
269+
"SortBy": "SortName",
270+
"SortOrder": "Ascending",
271+
"Fields": "PrimaryImageAspectRatio,Overview",
272+
"EnableTotalRecordCount": false
273+
})
274+
if isValid(data) and isValid(data.Items)
275+
for each item in data.Items
276+
node = m.transformer.transformBaseItem(item)
277+
if isValid(node) then results.push(node)
278+
end for
279+
end if
266280
end if
267281

268282
m.top.content = results

docs/data/search.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/module-ExtrasRowList.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/module-ItemDetails.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/source_Main.bs.html

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,13 @@
199199
group.observeField("selectedItem", m.port)
200200
group.observeField("quickPlayNode", m.port)
201201
m.global.sceneManager.callFunc("pushScene", group)
202-
else if selectedItemType = "UserView" or selectedItemType = "Folder" or selectedItemType = "Channel" or selectedItemType = "BoxSet"
202+
else if selectedItemType = "UserView" or selectedItemType = "Folder" or selectedItemType = "Channel"
203203
group = CreateLibraryView(selectedItem)
204204
group.observeField("selectedItem", m.port)
205205
group.observeField("quickPlayNode", m.port)
206206
m.global.sceneManager.callFunc("pushScene", group)
207+
else if selectedItemType = "BoxSet"
208+
group = CreateItemDetailsGroup(selectedItem)
207209
else if selectedItemType = "Episode" or LCase(selectedItemType) = "recording"
208210
group = CreateItemDetailsGroup(selectedItem)
209211
else if selectedItemType = "Series"
@@ -437,6 +439,8 @@
437439
m.global.queueManager.callFunc("playQueue")
438440
else if node.type = "Person"
439441
group = CreateItemDetailsGroup(node)
442+
else if node.type = "BoxSet"
443+
group = CreateItemDetailsGroup(node)
440444
else if node.type = "TvChannel"
441445
m.global.queueManager.callFunc("clear")
442446
m.global.queueManager.callFunc("push", nodeHelpers.createQueueItem(node))
@@ -520,6 +524,22 @@
520524
else
521525
stopLoadingSpinner()
522526
end if
527+
else if group.subtype() = "ItemDetails" and group.itemContent.type = "BoxSet"
528+
' BoxSet "Play All": queue all movies in collection in alphabetical order
529+
item = group.itemContent
530+
boxsetData = GetApi().GetItemsByQuery({
531+
"ParentId": item.id,
532+
"SortBy": "SortName",
533+
"SortOrder": "Ascending",
534+
"EnableTotalRecordCount": false
535+
})
536+
if isValid(boxsetData) and isValid(boxsetData.Items) and boxsetData.Items.count() > 0
537+
m.global.queueManager.callFunc("clear")
538+
m.global.queueManager.callFunc("set", boxsetData.Items)
539+
m.global.queueManager.callFunc("playQueue")
540+
else
541+
stopLoadingSpinner()
542+
end if
523543
else
524544
queueItem = nodeHelpers.createQueueItem(group.itemContent)
525545
if not isValid(queueItem) then return

docs/source_data_JellyfinDataTransformer.bs.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,10 @@
651651
count = apiData.ChildCount ?? 0
652652
if count = 1
653653
return "1 item"
654+
else if count > 1
655+
return str(count).trim() + " items"
654656
end if
655-
return str(count).trim() + " items"
657+
return ""
656658

657659
else if itemType = "Program" or itemType = "Recording"
658660
episodeTitle = apiData.EpisodeTitle ?? ""

0 commit comments

Comments
 (0)