Improved interface for TV episodes

This commit is contained in:
thomabx 2020-02-22 20:47:00 -08:00
parent 76fc41c23b
commit fb757570c3
9 changed files with 153 additions and 69 deletions

View File

@ -0,0 +1,54 @@
sub init()
m.title = m.top.findNode("title")
m.title.text = "Loading..."
end sub
function itemContentChanged() as void
item = m.top.itemContent
itemData = item.json
m.top.findNode("title").text = item.title
m.top.findNode("poster").uri = item.posterURL
m.top.findNode("overview").text = item.overview
if type(itemData.RunTimeTicks) = "LongInteger"
m.top.findNode("runtime").text = stri(getRuntime()) + " mins"
m.top.findNode("endtime").text = "Ends at " + getEndTime()
end if
if itemData.communityRating <> invalid then
m.top.findNode("communityRating").text = str(int(itemData.communityRating*10)/10)
end if
end function
function getRuntime() as integer
itemData = m.top.itemContent.json
' 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)
end function
function getEndTime() as string
itemData = m.top.itemContent.json
date = CreateObject("roDateTime")
duration_s = int(itemData.RunTimeTicks / 10000000.0)
date.fromSeconds(date.asSeconds() + duration_s)
date.toLocalTime()
hours = date.getHours()
meridian = "AM"
if hours = 0
hours = 12
meridian = "AM"
else if hours = 12
hours = 12
meridian = "PM"
else if hours > 12
hours = hours - 12
meridian = "PM"
end if
minutes = stri(date.getMinutes()).trim()
if val(minutes) > 10
minutes= "0" + minutes
end if
return Substitute("{0}:{1} {2}", stri(hours).trim(), stri(date.getMinutes()).trim(), meridian)
end function

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="TVListDetails" extends="Group">
<children>
<LayoutGroup id="toplevel" layoutDirection="vert" itemSpacings="[40]">
<LayoutGroup id="main_group" layoutDirection="horiz" itemSpacings="[30]">
<Poster id="poster" width="534" height="300" />
<LayoutGroup id="text" layoutDirection="vert" itemSpacings="[15]">
<!-- Using poster of 1 length to get spacing. Not successful with adding translation to title -->
<Poster id="null" height="1" />
<ScrollingLabel id="title" font="font:LargeBoldSystemFont" maxWidth="1200" />
<LayoutGroup layoutDirection="horiz" itemSpacings="[20]">
<Label id="runtime" font="font:SmallestSystemFont" />
<Label id="communityRating" font="font:SmallestSystemFont" />
<Label id="endtime" font="font:SmallestSystemFont" />
</LayoutGroup>
<Label id="overview" wrap="true" height="170" width="1200" maxLines="4" ellipsizeOnBoundary="true"/>
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
</children>
<interface>
<field id="itemContent" type="node" onChange="itemContentChanged"/>
</interface>
<script type="text/brightscript" uri="details-list.brs" />
</component>

View File

@ -1,7 +0,0 @@
sub init()
m.top.overhangTitle = "Season"
end sub
sub setSeason()
m.top.overhangTitle = m.top.seasonData.name
end sub

View File

@ -0,0 +1,7 @@
sub init()
m.top.overhangTitle = "Season"
end sub
sub setSeason()
m.top.overhangTitle = m.top.seasonData.SeriesName + " - " + m.top.seasonData.name
end sub

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="TVEpisodes" extends="JFGroup">
<children>
<ItemGrid id="picker" visible="true" itemsPerRow="10" />
<TVEpisodeRow id="picker" visible="true" />
</children>
<interface>
<field id="episodeSelected" alias="picker.itemSelected" />
<field id="seasonData" type="node" onChange="setSeason" />
<field id="seasonData" type="associativearray" onChange="setSeason" />
<field id="objects" alias="picker.objects" />
</interface>
<script type="text/brightscript" uri="episode.brs" />
<script type="text/brightscript" uri="episodes.brs" />
</component>

View File

@ -1,67 +1,66 @@
sub init()
m.top.itemComponentName = "ListPoster"
m.top.itemComponentName = "TVListDetails"
m.top.content = setData()
m.top.rowFocusAnimationStyle = "floatingFocus"
m.top.rowFocusAnimationStyle = "floatingFocus"
updateSize()
m.top.setFocus(true)
m.top.showRowLabel = [false]
updateSize()
m.top.setFocus(true)
end sub
sub updateSize()
m.top.numRows = 1
m.top.rowSize = 3
m.top.numRows = 1
m.top.itemsPerRow = 1
dimensions = m.top.getScene().currentDesignResolution
dimensions = m.top.getScene().currentDesignResolution
border = 75
m.top.translation = [border, border + 115]
border = 75
m.top.translation = [border, border + 115]
textHeight = 80
itemWidth = (dimensions["width"] - border*2) / m.top.rowSize
itemHeight = itemWidth * dimensions["height"]/ dimensions["width"] + textHeight
textHeight = 80
itemWidth = (dimensions["width"] - border*2)
itemHeight = 300
m.top.visible = true
m.top.visible = true
m.top.itemSize = [dimensions["width"] - border*2, itemHeight]
m.top.itemSpacing = [ 0, 10 ]
' Size of the individual rows
m.top.itemSize = [dimensions["width"] - border*2, itemHeight]
' Spacing between Rows
m.top.itemSpacing = [ 0, 40]
m.top.rowItemSize = [ itemWidth, itemHeight ]
m.top.rowItemSpacing = [ 0, 0 ]
episodeData = m.top.TVEpisodeData
if episodeData = invalid then return
rowsize = m.top.rowSize
n = episodeData.items.count()
' Test for no remainder
if int(n/rowsize) = n/rowsize then
m.top.numRows = n/rowsize
else
m.top.numRows = n/rowsize + 1
end if
' Size of items in the row
m.top.rowItemSize = [ itemWidth, itemHeight ]
' Spacing between items in the row
m.top.rowItemSpacing = [ 20, 0 ]
end sub
function getData()
if m.top.TVEpisodeData = invalid then
data = CreateObject("roSGNode", "ContentNode")
return data
end if
updateSize()
episodeData = m.top.TVEpisodeData
rowsize = m.top.rowSize
data = CreateObject("roSGNode", "ContentNode")
row = data.CreateChild("ContentNode")
row.title = "Episodes"
for each item in episodeData.items
row.appendChild(item)
end for
m.top.content = data
return data
function setupRows()
updateSize()
objects = m.top.objects
m.top.numRows = objects.items.count()
m.top.content = setData()
end function
function setData()
data = CreateObject("roSGNode", "ContentNode")
if m.top.objects = invalid then
' Return an empty node just to return something; we'll update once we have data
return data
end if
for each item in m.top.objects.items
row = data.CreateChild("ContentNode")
row.appendChild(item)
end for
return data
end function
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
return false
end function

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="TVEpisodeRow" extends="RowList">
<interface>
<field id="rowSize" type="int" />
<field id="TVEpisodeData" type="associativearray" onChange="getData" />
<field id="itemsPerRow" type="int" />
<field id="objects" type="associativearray" onChange="setupRows" />
<field id="escapeButton" type="string" alwaysNotify="true" />
</interface>
<script type="text/brightscript" uri="rowlist-episode.brs" />
</component>

View File

@ -198,7 +198,6 @@ end function
function CreateMovieDetailsGroup(movie)
group = CreateObject("roSGNode", "MovieDetails")
movie = ItemMetaData(movie.id)
group.itemContent = movie
@ -243,7 +242,7 @@ end function
function CreateSeasonDetailsGroup(series, season)
group = CreateObject("roSGNode", "TVEpisodes")
group.seasonData = TVSeasons(series.id)
group.seasonData = ItemMetaData(season.id)
group.objects = TVEpisodes(series.id, season.id)
group.observeField("episodeSelected", m.port)

View File

@ -131,7 +131,7 @@ function ItemList(library_id = invalid as string, params = {})
tmp.json = item
results.push(tmp)
else
print item.type
print "Items.brs::ItemList received unhandled type: " item.type
' Otherwise we just stick with the JSON
results.push(item)
end if
@ -165,8 +165,13 @@ function ItemMetaData(id as string)
tmp.image = PosterImage(data.id)
tmp.json = item
return tmp
else if data.type = "Season"
tmp = CreateObject("roSGNode", "TVSeasonData")
tmp.image = PosterImage(data.id)
tmp.json = data
return tmp
else
print data.type
print "Items.brs::ItemMetaData processed unhandled type: " data.type
' Return json if we don't know what it is
return data
end if
@ -202,13 +207,14 @@ function TVEpisodes(show_id as string, season_id as string)
data = getJson(resp)
results = []
for each item in data.Items
imgParams = { "AddPlayedIndicator": item.UserData.Played }
imgParams = { "AddPlayedIndicator": item.UserData.Played, "maxWidth": 712, "maxheight": 400 }
tmp = CreateObject("roSGNode", "TVEpisodeData")
tmp.image = PosterImage(item.id, imgParams)
if tmp.image <> invalid
tmp.image.posterDisplayMode = "scaleToFit"
end if
tmp.json = item
tmp.overview = ItemMetaData(item.id).overview
results.push(tmp)
end for
data.Items = results