2023-10-03 16:11:25 +00:00
|
|
|
import "pkg:/source/utils/misc.bs"
|
|
|
|
import "pkg:/source/utils/config.bs"
|
2023-05-03 21:21:04 +00:00
|
|
|
|
2019-05-03 12:48:59 +00:00
|
|
|
sub init()
|
2021-07-09 20:08:32 +00:00
|
|
|
m.top.optionsAvailable = false
|
|
|
|
main = m.top.findNode("toplevel")
|
|
|
|
main.translation = [96, 175]
|
2022-03-13 08:46:03 +00:00
|
|
|
m.extrasSlider = m.top.findNode("tvSeasonExtras")
|
2022-12-10 21:41:40 +00:00
|
|
|
m.unplayedCount = m.top.findNode("unplayedCount")
|
2022-12-10 21:19:14 +00:00
|
|
|
m.unplayedEpisodeCount = m.top.findNode("unplayedEpisodeCount")
|
2023-02-25 16:43:36 +00:00
|
|
|
m.getShuffleEpisodesTask = createObject("roSGNode", "getShuffleEpisodesTask")
|
|
|
|
m.Shuffle = m.top.findNode("Shuffle")
|
2022-03-13 08:46:03 +00:00
|
|
|
m.extrasSlider.visible = true
|
2023-09-16 21:18:03 +00:00
|
|
|
m.seasons = m.top.findNode("seasons")
|
2024-01-29 02:06:10 +00:00
|
|
|
m.overview = m.top.findNode("overview")
|
2024-03-09 13:46:52 +00:00
|
|
|
|
2024-03-11 22:52:16 +00:00
|
|
|
m.overview.ellipsisText = tr("... (Press * to read more)")
|
2019-05-03 12:48:59 +00:00
|
|
|
end sub
|
|
|
|
|
2019-12-07 02:49:37 +00:00
|
|
|
sub itemContentChanged()
|
2021-07-09 20:08:32 +00:00
|
|
|
' Updates video metadata
|
|
|
|
' TODO - make things use item rather than itemData
|
|
|
|
item = m.top.itemContent
|
|
|
|
itemData = item.json
|
|
|
|
|
2023-06-01 12:43:27 +00:00
|
|
|
if m.global.session.user.settings["ui.tvshows.disableUnwatchedEpisodeCount"] = false
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.UserData) and isValid(itemData.UserData.UnplayedItemCount)
|
2023-02-04 23:16:36 +00:00
|
|
|
if itemData.UserData.UnplayedItemCount > 0
|
|
|
|
m.unplayedCount.visible = true
|
|
|
|
m.unplayedEpisodeCount.text = itemData.UserData.UnplayedItemCount
|
|
|
|
end if
|
2022-12-10 22:41:22 +00:00
|
|
|
end if
|
2022-12-10 21:41:40 +00:00
|
|
|
end if
|
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
m.top.findNode("tvshowPoster").uri = m.top.itemContent.posterURL
|
|
|
|
|
|
|
|
' Handle all "As Is" fields
|
|
|
|
m.top.overhangTitle = itemData.name
|
2022-12-07 03:07:15 +00:00
|
|
|
|
|
|
|
'Check production year, if invalid remove label
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.productionYear)
|
2022-12-07 03:07:15 +00:00
|
|
|
setFieldText("releaseYear", itemData.productionYear)
|
|
|
|
else
|
|
|
|
m.top.findNode("main_group").removeChild(m.top.findNode("releaseYear"))
|
|
|
|
end if
|
|
|
|
|
|
|
|
'Check officialRating, if invalid remove label
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.officialRating)
|
2022-12-07 03:07:15 +00:00
|
|
|
setFieldText("officialRating", itemData.officialRating)
|
|
|
|
else
|
|
|
|
m.top.findNode("main_group").removeChild(m.top.findNode("officialRating"))
|
|
|
|
end if
|
|
|
|
|
|
|
|
'Check communityRating, if invalid remove label
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.communityRating)
|
2021-07-09 20:08:32 +00:00
|
|
|
m.top.findNode("star").visible = true
|
2022-08-27 15:31:15 +00:00
|
|
|
setFieldText("communityRating", int(itemData.communityRating * 10) / 10)
|
2021-07-09 20:08:32 +00:00
|
|
|
else
|
2022-12-07 03:07:15 +00:00
|
|
|
m.top.findNode("main_group").removeChild(m.top.findNode("communityRating"))
|
|
|
|
m.top.findNode("main_group").removeChild(m.top.findNode("star"))
|
2021-07-09 20:08:32 +00:00
|
|
|
m.top.findNode("star").visible = false
|
|
|
|
end if
|
2022-12-07 03:07:15 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
setFieldText("overview", itemData.overview)
|
|
|
|
|
2023-02-25 16:43:36 +00:00
|
|
|
m.Shuffle.visible = true
|
2021-07-09 20:08:32 +00:00
|
|
|
|
|
|
|
if type(itemData.RunTimeTicks) = "LongInteger"
|
|
|
|
setFieldText("runtime", stri(getRuntime()) + " mins")
|
|
|
|
end if
|
|
|
|
|
2022-12-07 03:07:15 +00:00
|
|
|
'History feild is set via the function getHistory()
|
2021-07-09 20:08:32 +00:00
|
|
|
setFieldText("history", getHistory())
|
|
|
|
|
2022-12-07 03:07:15 +00:00
|
|
|
'Check genres, if invalid remove label
|
2021-07-09 20:08:32 +00:00
|
|
|
if itemData.genres.count() > 0
|
|
|
|
setFieldText("genres", itemData.genres.join(", "))
|
2022-12-07 03:07:15 +00:00
|
|
|
else
|
|
|
|
m.top.findNode("main_group").removeChild(m.top.findNode("genres"))
|
2021-07-09 20:08:32 +00:00
|
|
|
end if
|
2022-12-07 03:07:15 +00:00
|
|
|
|
|
|
|
'We don't display Directors in the show page. Might want to remove this.
|
2021-07-09 20:08:32 +00:00
|
|
|
for each person in itemData.people
|
|
|
|
if person.type = "Director"
|
|
|
|
exit for
|
|
|
|
end if
|
|
|
|
end for
|
|
|
|
if itemData.taglines.count() > 0
|
|
|
|
setFieldText("tagline", itemData.taglines[0])
|
2022-12-07 03:07:15 +00:00
|
|
|
else
|
|
|
|
m.top.findNode("main_group").removeChild(m.top.findNode("tagline"))
|
2019-05-03 12:48:59 +00:00
|
|
|
end if
|
2019-12-07 02:49:37 +00:00
|
|
|
end sub
|
|
|
|
|
|
|
|
sub setFieldText(field, value)
|
2021-07-09 20:08:32 +00:00
|
|
|
node = m.top.findNode(field)
|
|
|
|
if node = invalid or value = invalid then return
|
|
|
|
|
|
|
|
' Handle non strings... Which _shouldn't_ happen, but hey
|
|
|
|
if type(value) = "roInt" or type(value) = "Integer"
|
|
|
|
value = str(value).trim()
|
|
|
|
else if type(value) = "roFloat" or type(value) = "Float"
|
|
|
|
value = str(value).trim()
|
|
|
|
else if type(value) <> "roString" and type(value) <> "String"
|
|
|
|
value = ""
|
|
|
|
end if
|
|
|
|
|
|
|
|
node.text = value
|
2019-12-07 02:49:37 +00:00
|
|
|
end sub
|
|
|
|
|
|
|
|
function getRuntime() as integer
|
2021-07-09 20:08:32 +00:00
|
|
|
itemData = m.top.itemContent.json
|
2019-12-07 02:49:37 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
' A tick is .1ms, so 1/10,000,000 for ticks to seconds,
|
|
|
|
' then 1/60 for seconds to minutess... 1/600,000,000
|
|
|
|
return round(itemData.RunTimeTicks / 600000000.0)
|
2019-12-07 02:49:37 +00:00
|
|
|
end function
|
|
|
|
|
|
|
|
function getEndTime() as string
|
2021-07-09 20:08:32 +00:00
|
|
|
itemData = m.top.itemContent.json
|
2019-12-07 02:49:37 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
date = CreateObject("roDateTime")
|
|
|
|
duration_s = int(itemData.RunTimeTicks / 10000000.0)
|
|
|
|
date.fromSeconds(date.asSeconds() + duration_s)
|
|
|
|
date.toLocalTime()
|
2019-12-07 02:49:37 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
return formatTime(date)
|
2019-12-07 02:49:37 +00:00
|
|
|
end function
|
|
|
|
|
|
|
|
function getHistory() as string
|
2021-07-09 20:08:32 +00:00
|
|
|
itemData = m.top.itemContent.json
|
|
|
|
' Aired Fridays at 9:30 PM on ABC (US)
|
|
|
|
|
|
|
|
airwords = invalid
|
|
|
|
studio = invalid
|
|
|
|
if itemData.status = "Ended"
|
|
|
|
verb = "Aired"
|
|
|
|
else
|
|
|
|
verb = "Airs"
|
|
|
|
end if
|
|
|
|
|
|
|
|
airdays = itemData.airdays
|
|
|
|
airtime = itemData.airtime
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(airtime) and airdays.count() = 1
|
2021-07-09 20:08:32 +00:00
|
|
|
airwords = airdays[0] + " at " + airtime
|
|
|
|
end if
|
|
|
|
|
|
|
|
if itemData.studios.count() > 0
|
|
|
|
studio = itemData.studios[0].name
|
|
|
|
end if
|
|
|
|
|
|
|
|
if studio = invalid and airwords = invalid
|
2022-12-07 03:07:15 +00:00
|
|
|
m.top.findNode("main_group").removeChild(m.top.findNode("history"))
|
2021-07-09 20:08:32 +00:00
|
|
|
return ""
|
|
|
|
end if
|
|
|
|
|
|
|
|
words = verb
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(airwords)
|
2021-07-09 20:08:32 +00:00
|
|
|
words = words + " " + airwords
|
|
|
|
end if
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(studio)
|
2021-07-09 20:08:32 +00:00
|
|
|
words = words + " on " + studio
|
|
|
|
end if
|
|
|
|
|
|
|
|
return words
|
2019-12-07 02:49:37 +00:00
|
|
|
end function
|
2019-05-03 12:48:59 +00:00
|
|
|
|
2019-12-07 02:49:37 +00:00
|
|
|
function round(f as float) as integer
|
2021-07-09 20:08:32 +00:00
|
|
|
' BrightScript only has a "floor" round
|
|
|
|
' This compares floor to floor + 1 to find which is closer
|
|
|
|
m = int(f)
|
|
|
|
n = m + 1
|
|
|
|
x = abs(f - m)
|
|
|
|
y = abs(f - n)
|
|
|
|
if y > x
|
|
|
|
return m
|
|
|
|
else
|
|
|
|
return n
|
|
|
|
end if
|
2019-12-07 02:49:37 +00:00
|
|
|
end function
|
2022-03-13 08:46:03 +00:00
|
|
|
|
2023-02-25 16:43:36 +00:00
|
|
|
sub onShuffleEpisodeDataLoaded()
|
|
|
|
m.getShuffleEpisodesTask.unobserveField("data")
|
|
|
|
m.global.queueManager.callFunc("set", m.getShuffleEpisodesTask.data.items)
|
|
|
|
m.global.queueManager.callFunc("playQueue")
|
|
|
|
end sub
|
|
|
|
|
2022-03-13 08:46:03 +00:00
|
|
|
function onKeyEvent(key as string, press as boolean) as boolean
|
2023-02-25 16:43:36 +00:00
|
|
|
if key = "OK" or key = "play"
|
|
|
|
if m.Shuffle.hasFocus()
|
|
|
|
m.getShuffleEpisodesTask.showID = m.top.itemContent.id
|
|
|
|
m.getShuffleEpisodesTask.observeField("data", "onShuffleEpisodeDataLoaded")
|
|
|
|
m.getShuffleEpisodesTask.control = "RUN"
|
|
|
|
return true
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
|
2022-04-26 01:02:50 +00:00
|
|
|
if not press then return false
|
|
|
|
|
2024-01-29 02:06:10 +00:00
|
|
|
if key = "options"
|
|
|
|
if m.overview.isTextEllipsized
|
|
|
|
if isAllValid([m.top.itemContent.json.name, m.top.itemContent.json.overview])
|
|
|
|
m.global.sceneManager.callFunc("standardDialog", m.top.itemContent.json.name, { data: ["<p>" + m.top.itemContent.json.overview + "</p>"] })
|
|
|
|
return true
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
return false
|
|
|
|
end if
|
|
|
|
|
2022-03-13 08:46:03 +00:00
|
|
|
topGrp = m.top.findNode("seasons")
|
|
|
|
bottomGrp = m.top.findNode("extrasGrid")
|
|
|
|
|
2024-01-29 02:06:10 +00:00
|
|
|
if key = "down" and m.overview.hasFocus()
|
2023-02-25 16:43:36 +00:00
|
|
|
m.Shuffle.setFocus(true)
|
|
|
|
return true
|
|
|
|
else if key = "down" and m.Shuffle.hasFocus()
|
2022-04-26 01:02:50 +00:00
|
|
|
topGrp.setFocus(true)
|
|
|
|
return true
|
|
|
|
else if key = "down" and topGrp.hasFocus()
|
2022-03-13 08:46:03 +00:00
|
|
|
bottomGrp.setFocus(true)
|
|
|
|
m.top.findNode("VertSlider").reverse = false
|
|
|
|
m.top.findNode("extrasFader").reverse = false
|
|
|
|
m.top.findNode("pplAnime").control = "start"
|
|
|
|
return true
|
2022-04-26 01:02:50 +00:00
|
|
|
else if key = "up" and bottomGrp.hasFocus()
|
2022-03-13 08:46:03 +00:00
|
|
|
if bottomGrp.itemFocused = 0
|
|
|
|
m.top.findNode("VertSlider").reverse = true
|
|
|
|
m.top.findNode("extrasFader").reverse = true
|
|
|
|
m.top.findNode("pplAnime").control = "start"
|
|
|
|
topGrp.setFocus(true)
|
|
|
|
return true
|
|
|
|
end if
|
2022-04-26 01:02:50 +00:00
|
|
|
else if key = "up" and topGrp.hasFocus()
|
2023-02-25 16:43:36 +00:00
|
|
|
m.Shuffle.setFocus(true)
|
|
|
|
return true
|
|
|
|
else if key = "up" and m.Shuffle.hasFocus()
|
2024-01-29 02:06:10 +00:00
|
|
|
m.overview.setFocus(true)
|
2022-04-26 01:02:50 +00:00
|
|
|
return true
|
2023-09-16 21:18:03 +00:00
|
|
|
else if key = "play" and m.seasons.hasFocus()
|
|
|
|
print "play was pressed from the seasons row"
|
|
|
|
if isValid(m.seasons.TVSeasonData) and isValid(m.seasons.TVSeasonData.Items)
|
|
|
|
itemFocused = m.seasons.rowItemFocused
|
|
|
|
m.top.quickPlayNode = m.seasons.TVSeasonData.Items[itemFocused[1]]
|
|
|
|
return true
|
|
|
|
end if
|
|
|
|
else if key = "play" and m.extrasSlider.isInFocusChain()
|
|
|
|
print "play was pressed from the extras grid"
|
|
|
|
extrasGrid = m.top.findNode("extrasGrid")
|
|
|
|
if extrasGrid.focusedItem <> invalid
|
|
|
|
m.top.quickPlayNode = extrasGrid.focusedItem
|
|
|
|
return true
|
|
|
|
end if
|
2022-03-13 08:46:03 +00:00
|
|
|
end if
|
2022-04-26 01:02:50 +00:00
|
|
|
|
2022-03-13 08:46:03 +00:00
|
|
|
return false
|
|
|
|
end function
|