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
|
|
|
|
2020-02-23 04:47:00 +00:00
|
|
|
sub init()
|
|
|
|
m.title = m.top.findNode("title")
|
2020-05-05 21:09:18 +00:00
|
|
|
m.title.text = tr("Loading...")
|
2022-04-26 01:02:50 +00:00
|
|
|
m.overview = m.top.findNode("overview")
|
2022-06-19 22:23:56 +00:00
|
|
|
m.poster = m.top.findNode("poster")
|
2022-12-20 02:21:09 +00:00
|
|
|
|
|
|
|
m.rating = m.top.findnode("rating")
|
|
|
|
m.infoBar = m.top.findnode("infoBar")
|
2022-12-28 20:13:03 +00:00
|
|
|
m.progressBackground = m.top.findNode("progressBackground")
|
|
|
|
m.progressBar = m.top.findnode("progressBar")
|
|
|
|
m.playedIndicator = m.top.findNode("playedIndicator")
|
2022-12-29 22:56:18 +00:00
|
|
|
m.checkmark = m.top.findNode("checkmark")
|
|
|
|
m.checkmark.font.size = 35
|
2023-05-26 23:04:20 +00:00
|
|
|
|
|
|
|
m.videoCodec = m.top.findNode("video_codec")
|
2020-02-23 04:47:00 +00:00
|
|
|
end sub
|
|
|
|
|
2021-06-26 10:18:09 +00:00
|
|
|
sub itemContentChanged()
|
2021-07-09 20:08:32 +00:00
|
|
|
item = m.top.itemContent
|
|
|
|
itemData = item.json
|
2023-05-20 23:33:42 +00:00
|
|
|
|
|
|
|
' 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
|
|
|
|
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.indexNumber)
|
2021-07-09 20:08:32 +00:00
|
|
|
indexNumber = itemData.indexNumber.toStr() + ". "
|
|
|
|
else
|
|
|
|
indexNumber = ""
|
|
|
|
end if
|
2022-04-26 01:02:50 +00:00
|
|
|
m.title.text = indexNumber + item.title
|
|
|
|
m.overview.text = item.overview
|
2020-02-23 04:47:00 +00:00
|
|
|
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.PremiereDate)
|
2022-11-09 19:44:12 +00:00
|
|
|
airDate = CreateObject("roDateTime")
|
|
|
|
airDate.FromISO8601String(itemData.PremiereDate)
|
|
|
|
m.top.findNode("aired").text = tr("Aired") + ": " + airDate.AsDateString("short-month-no-weekday")
|
|
|
|
end if
|
2022-11-09 03:29:38 +00:00
|
|
|
|
2022-06-19 22:23:56 +00:00
|
|
|
imageUrl = item.posterURL
|
|
|
|
|
2023-06-01 12:43:27 +00:00
|
|
|
if m.global.session.user.settings["ui.tvshows.blurunwatched"] = true
|
2022-06-19 22:23:56 +00:00
|
|
|
if itemData.lookup("Type") = "Episode"
|
|
|
|
if not itemData.userdata.played
|
|
|
|
imageUrl = imageUrl + "&blur=15"
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
|
|
|
|
m.poster.uri = imageUrl
|
|
|
|
|
2022-11-11 04:04:03 +00:00
|
|
|
if type(itemData.RunTimeTicks) = "roInt" or type(itemData.RunTimeTicks) = "LongInteger"
|
|
|
|
runTime = getRuntime()
|
|
|
|
if runTime < 2
|
|
|
|
m.top.findNode("runtime").text = "1 min"
|
|
|
|
else
|
|
|
|
m.top.findNode("runtime").text = stri(runTime).trim() + " mins"
|
|
|
|
end if
|
|
|
|
|
2023-06-01 12:43:27 +00:00
|
|
|
if m.global.session.user.settings["ui.design.hideclock"] <> true
|
2022-07-16 02:28:59 +00:00
|
|
|
m.top.findNode("endtime").text = tr("Ends at %1").Replace("%1", getEndTime())
|
|
|
|
end if
|
2021-07-09 20:08:32 +00:00
|
|
|
end if
|
2022-02-05 01:53:54 +00:00
|
|
|
|
2023-06-01 12:43:27 +00:00
|
|
|
if m.global.session.user.settings["ui.tvshows.disableCommunityRating"] = false
|
2023-01-01 14:24:07 +00:00
|
|
|
if isValid(itemData.communityRating)
|
|
|
|
m.top.findNode("star").visible = true
|
|
|
|
m.top.findNode("communityRating").text = str(int(itemData.communityRating * 10) / 10)
|
|
|
|
else
|
|
|
|
m.top.findNode("star").visible = false
|
|
|
|
end if
|
2021-07-09 20:08:32 +00:00
|
|
|
else
|
2023-01-02 13:14:39 +00:00
|
|
|
m.rating.visible = false
|
|
|
|
m.infoBar.itemSpacings = [20, -25, 20, 20]
|
2021-07-09 20:08:32 +00:00
|
|
|
end if
|
2022-02-05 01:53:54 +00:00
|
|
|
|
2022-12-28 20:13:03 +00:00
|
|
|
' Add checkmark in corner (if applicable)
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.UserData) and isValid(itemData.UserData.Played) and itemData.UserData.Played = true
|
2022-12-28 20:13:03 +00:00
|
|
|
m.playedIndicator.visible = true
|
|
|
|
end if
|
|
|
|
|
|
|
|
' Add progress bar on bottom (if applicable)
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(itemData.UserData) and isValid(itemData.UserData.PlayedPercentage) and itemData.UserData.PlayedPercentage > 0
|
2022-12-28 20:13:03 +00:00
|
|
|
m.progressBackground.width = m.poster.width
|
|
|
|
m.progressBackground.visible = true
|
2022-12-28 20:25:10 +00:00
|
|
|
progressWidthInPixels = int(m.progressBackground.width * itemData.UserData.PlayedPercentage / 100)
|
2022-12-28 20:13:03 +00:00
|
|
|
m.progressBar.width = progressWidthInPixels
|
|
|
|
m.progressBar.visible = true
|
|
|
|
end if
|
|
|
|
|
2023-05-21 12:25:58 +00:00
|
|
|
' Display current video_codec and check if there is more than one video to choose from...
|
2023-05-26 23:04:20 +00:00
|
|
|
m.videoCodec.visible = false
|
2023-05-20 23:33:42 +00:00
|
|
|
if isValid(itemData.MediaSources)
|
|
|
|
for i = 0 to itemData.MediaSources.Count() - 1
|
2023-07-12 22:39:54 +00:00
|
|
|
if item.selectedVideoStreamId = itemData.MediaSources[i].id and isValid(itemData.MediaSources[i].MediaStreams[0])
|
|
|
|
m.videoCodec.text = tr("Video") + ": " + itemData.MediaSources[i].MediaStreams[0].DisplayTitle
|
|
|
|
SetupAudioDisplay(itemData.MediaSources[i].MediaStreams, item.selectedAudioStreamIndex)
|
|
|
|
exit for
|
2023-05-20 23:33:42 +00:00
|
|
|
end if
|
|
|
|
end for
|
2023-05-26 23:04:20 +00:00
|
|
|
m.videoCodec.visible = true
|
2023-05-21 04:13:04 +00:00
|
|
|
DisplayVideoAvailable(itemData.MediaSources)
|
2023-05-20 23:33:42 +00:00
|
|
|
end if
|
2023-05-21 04:13:04 +00:00
|
|
|
end sub
|
2023-05-20 23:33:42 +00:00
|
|
|
|
2023-05-21 12:25:58 +00:00
|
|
|
' Display current audio_codec and check if there is more than one audio track to choose from...
|
|
|
|
sub SetupAudioDisplay(mediaStreams as object, selectedAudioStreamIndex as integer)
|
2023-05-21 04:13:04 +00:00
|
|
|
audioIdx = invalid
|
|
|
|
if isValid(mediaStreams)
|
|
|
|
for i = 0 to mediaStreams.Count() - 1
|
2023-05-26 23:04:20 +00:00
|
|
|
if LCase(mediaStreams[i].Type) = "audio" and audioIdx = invalid
|
2023-05-21 04:13:04 +00:00
|
|
|
if selectedAudioStreamIndex > 0 and selectedAudioStreamIndex < mediaStreams.Count()
|
|
|
|
audioIdx = selectedAudioStreamIndex
|
2022-04-24 03:49:42 +00:00
|
|
|
else
|
|
|
|
audioIdx = i
|
|
|
|
end if
|
2023-05-21 04:13:04 +00:00
|
|
|
m.top.findNode("audio_codec").text = tr("Audio") + ": " + mediaStreams[audioIdx].DisplayTitle
|
2022-02-05 01:53:54 +00:00
|
|
|
end if
|
2023-05-20 23:33:42 +00:00
|
|
|
if isValid(audioIdx) then exit for
|
2022-02-05 01:53:54 +00:00
|
|
|
end for
|
|
|
|
end if
|
2022-04-24 03:49:42 +00:00
|
|
|
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(audioIdx)
|
2022-04-29 13:20:34 +00:00
|
|
|
m.top.findNode("audio_codec").visible = true
|
2023-05-21 04:13:04 +00:00
|
|
|
DisplayAudioAvailable(mediaStreams)
|
2022-04-29 13:15:40 +00:00
|
|
|
else
|
2022-04-29 13:20:34 +00:00
|
|
|
m.top.findNode("audio_codec").visible = false
|
2022-04-29 13:15:40 +00:00
|
|
|
end if
|
2022-04-24 03:49:42 +00:00
|
|
|
end sub
|
|
|
|
|
2023-05-21 12:25:58 +00:00
|
|
|
' Adds "+N" (e.g. +1) if there is more than one video version to choose from
|
|
|
|
sub DisplayVideoAvailable(streams as object)
|
2023-05-20 23:33:42 +00:00
|
|
|
count = 0
|
|
|
|
for i = 0 to streams.Count() - 1
|
2023-05-26 23:04:20 +00:00
|
|
|
if LCase(streams[i].VideoType) = "videofile"
|
2023-05-20 23:33:42 +00:00
|
|
|
count++
|
|
|
|
end if
|
|
|
|
end for
|
|
|
|
|
|
|
|
if count > 1
|
|
|
|
m.top.findnode("video_codec_count").text = "+" + stri(count - 1).trim()
|
|
|
|
end if
|
|
|
|
end sub
|
|
|
|
|
2023-05-21 12:25:58 +00:00
|
|
|
' Adds "+N" (e.g. +1) if there is more than one audio track to choose from
|
|
|
|
sub DisplayAudioAvailable(streams as object)
|
2022-04-24 03:49:42 +00:00
|
|
|
count = 0
|
|
|
|
for i = 0 to streams.Count() - 1
|
|
|
|
if streams[i].Type = "Audio"
|
|
|
|
count++
|
|
|
|
end if
|
|
|
|
end for
|
|
|
|
|
|
|
|
if count > 1
|
|
|
|
m.top.findnode("audio_codec_count").text = "+" + stri(count - 1).trim()
|
|
|
|
end if
|
2021-06-26 10:18:09 +00:00
|
|
|
end sub
|
2020-02-23 04:47:00 +00:00
|
|
|
|
|
|
|
function getRuntime() as integer
|
2021-07-09 20:08:32 +00:00
|
|
|
itemData = m.top.itemContent.json
|
2020-02-23 04:47:00 +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 int(itemData.RunTimeTicks / 600000000.0)
|
2020-02-23 04:47:00 +00:00
|
|
|
end function
|
|
|
|
|
|
|
|
function getEndTime() as string
|
2021-07-09 20:08:32 +00:00
|
|
|
itemData = m.top.itemContent.json
|
|
|
|
date = CreateObject("roDateTime")
|
|
|
|
duration_s = int(itemData.RunTimeTicks / 10000000.0)
|
|
|
|
date.fromSeconds(date.asSeconds() + duration_s)
|
|
|
|
date.toLocalTime()
|
2020-02-23 04:47:00 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
return formatTime(date)
|
2020-02-23 04:47:00 +00:00
|
|
|
end function
|
2022-04-26 01:02:50 +00:00
|
|
|
|
|
|
|
sub focusChanged()
|
|
|
|
if m.top.itemHasFocus = true
|
|
|
|
' text to speech for accessibility
|
2023-03-27 16:50:44 +00:00
|
|
|
if m.global.device.isAudioGuideEnabled = true
|
2022-04-26 01:02:50 +00:00
|
|
|
txt2Speech = CreateObject("roTextToSpeech")
|
|
|
|
txt2Speech.Flush()
|
|
|
|
txt2Speech.Say(m.title.text)
|
|
|
|
txt2Speech.Say(m.overview.text)
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
end sub
|