Merge branch 'master' into autoplay-playback-info

This commit is contained in:
Anthony Lavado 2021-03-20 00:36:53 -04:00 committed by GitHub
commit b6df996503
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 224 additions and 304 deletions

View File

@ -1,96 +0,0 @@
sub init()
m.top.itemComponentName = "ListPoster"
m.top.content = setData()
m.top.rowFocusAnimationStyle = "floatingFocus"
m.top.showRowLabel = [false]
m.top.setFocus(true)
end sub
sub updateSize()
m.top.numRows = 1
if m.top.itemsPerRow = invalid or m.top.itemsPerRow = 0 then
m.top.itemsPerRow = 6
end if
dimensions = m.top.getScene().currentDesignResolution
topBorder = 75
border = 96
topSpace = topBorder + 105
m.top.translation = [96, topSpace]
textHeight = 100
itemWidth = (dimensions["width"] - border*2) / m.top.itemsPerRow -20
itemHeight = itemWidth * 1.5 + textHeight
if itemHeight*m.top.rowsPerPage > (dimensions["height"] - topBorder - 115) then
ratio = (itemHeight*m.top.rowsPerPage) / (981 - topSpace - 15)
itemHeight = itemHeight / ratio
itemWidth = itemWidth / ratio
end if
m.top.visible = true
' Size of the individual rows
m.top.itemSize = [dimensions["width"] - border*2, itemHeight]
' Spacing between Rows
m.top.itemSpacing = [ 0, 10]
' Size of items in the row
m.top.rowItemSize = [ itemWidth, itemHeight ]
' Spacing between items in the row
itemSpace = (dimensions["width"] - border*2 - itemWidth*m.top.itemsPerRow) / (m.top.itemsPerRow-1)
m.top.rowItemSpacing = [ itemSpace-1, 0 ]
end sub
function setupRows()
updateSize()
objects = m.top.objects
itemsPerRow = m.top.itemsPerRow
n = objects.items.count()
' This tests to make sure we are at an integer number of rows
if int(n/itemsPerRow) = n/itemsPerRow then
m.top.numRows = n/itemsPerRow
' Otherwise we need an extra (not full) row for the leftovers
else
m.top.numRows = n/itemsPerRow + 1
end if
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
objects = m.top.objects
itemsPerRow = m.top.itemsPerRow
for rowNum = 1 to m.top.numRows
row = data.CreateChild("ContentNode")
for i = 1 to itemsPerRow
index = (rowNum - 1) * itemsPerRow + i
if index > objects.items.count() then
exit for
end if
row.appendChild(objects.items[index-1])
end for
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,10 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="ItemGrid" extends="RowList">
<interface>
<field id="itemsPerRow" type="int" />
<field id="rowsPerPage" type="int" value="2" />
<field id="objects" type="assocarray" onChange="setupRows" />
<field id="escapeButton" type="string" alwaysNotify="true" />
</interface>
<script type="text/brightscript" uri="ItemGrid.brs" />
</component>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<component name="ItemGrid2" extends="JFGroup"> <component name="ItemGrid" extends="JFGroup">
<children> <children>
<poster id="backdrop" <poster id="backdrop"
loadDisplayMode="scaleToFill" loadDisplayMode="scaleToFill"
@ -39,5 +39,5 @@
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" /> <script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" /> <script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
<script type="text/brightscript" uri="pkg:/source/utils/deviceCapabilities.brs" /> <script type="text/brightscript" uri="pkg:/source/utils/deviceCapabilities.brs" />
<script type="text/brightscript" uri="ItemGrid2.brs" /> <script type="text/brightscript" uri="ItemGrid.brs" />
</component> </component>

View File

@ -1,14 +0,0 @@
sub init()
m.top.overhangTitle = "Collections"
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if key = "down"
m.top.lastFocus = m.top.focusedChild
m.top.findNode("paginator").setFocus(true)
end if
return false
end function

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="Collections" extends="JFGroup">
<children>
<ItemGrid id="picker" visible="true" itemsPerRow="6" />
<OptionsSlider id="options" />
<Rectangle translation="[0,981]" width="1920" height="100" color="#101010" />
</children>
<interface>
<field id="collectionSelected" alias="picker.itemSelected" />
<field id="objects" alias="picker.objects" />
<field id="pageNumber" type="integer" />
</interface>
<script type="text/brightscript" uri="Collections.brs" />
</component>

View File

@ -1,14 +0,0 @@
sub init()
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if key = "down"
m.top.lastFocus = m.top.focusedChild
m.top.findNode("paginator").setFocus(true)
end if
return false
end function

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="TVShows" extends="JFGroup">
<children>
<ItemGrid id="picker" visible="true" itemsPerRow="6" />
<OptionsSlider id="options" />
<Rectangle translation="[0,981]" width="1920" height="100" color="#101010" />
</children>
<interface>
<field id="seriesSelected" alias="picker.itemSelected" />
<field id="objects" alias="picker.objects" />
<field id="pageNumber" type="integer" />
</interface>
<script type="text/brightscript" uri="TVShows.brs" />
</component>

View File

@ -301,4 +301,16 @@
<extracomment>Menu option for showing Live TV Guide / Schedule</extracomment> <extracomment>Menu option for showing Live TV Guide / Schedule</extracomment>
</message> </message>
</context> </context>
<context>
<name></name>
<message>
<comment>Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)</comment>
<source>NO_ITEMS</source>
<translation>This %1 contains no items</translation>
</message>
<message>
<source>Add User</source>
<translation>Add User</translation>
</message>
</context>
</TS> </TS>

View File

@ -269,5 +269,202 @@
<translation>Si è verificato un errore durante la riproduzione di questo elemento.</translation> <translation>Si è verificato un errore durante la riproduzione di questo elemento.</translation>
<extracomment>Dialog detail when error occurs during playback</extracomment> <extracomment>Dialog detail when error occurs during playback</extracomment>
</message> </message>
<message>
<source>TV Guide</source>
<translation>Guida TV</translation>
<extracomment>Menu option for showing Live TV Guide / Schedule</extracomment>
</message>
<message>
<source>Channels</source>
<translation>Canali</translation>
<extracomment>Menu option for showing Live TV Channel List</extracomment>
</message>
<message>
<source>Repeat</source>
<translation>Ripeti</translation>
<extracomment>If TV Shows has previously been broadcasted</extracomment>
</message>
<message>
<source>Live</source>
<translation>Dal vivo</translation>
<extracomment>If TV Show is being broadcast live (not pre-recorded)</extracomment>
</message>
<message>
<source>Ends at</source>
<translation>Terminato</translation>
<extracomment>(Past Tense) For defining a day and time when a program ended (e.g. Ended Wednesday, 08:00) </extracomment>
</message>
<message>
<source>Ended at</source>
<translation>Terminato alle</translation>
<extracomment>(Past Tense) For defining time when a program will ended (e.g. Ended at 08:00) </extracomment>
</message>
<message>
<source>Starts</source>
<translation>Inizierà</translation>
<extracomment>(Future Tense) For defining a day and time when a program will start (e.g. Starts Wednesday, 08:00) </extracomment>
</message>
<message>
<source>Starts at</source>
<translation>Inizierà alle</translation>
<extracomment>(Future Tense) For defining time when a program will start today (e.g. Starts at 08:00) </extracomment>
</message>
<message>
<source>Started</source>
<translation>Iniziato</translation>
<extracomment>(Past Tense) For defining a day and time when a program started (e.g. Started Wednesday, 08:00) </extracomment>
</message>
<message>
<source>Started at</source>
<translation>Iniziato alle</translation>
<extracomment>(Past Tense) For defining time when a program started today (e.g. Started at 08:00) </extracomment>
</message>
<message>
<source>Saturday</source>
<translation>Sabato</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<source>Friday</source>
<translation>Venerdì</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<source>Thursday</source>
<translation>Giovedì</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<source>Wednesday</source>
<translation>Mercoledì</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<source>Tuesday</source>
<translation>Martedì</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<source>Monday</source>
<translation>Lunedì</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<source>Sunday</source>
<translation>Domenica</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<source>tomorrow</source>
<translation>domani</translation>
<extracomment>Next day</extracomment>
</message>
<message>
<source>yesterday</source>
<translation>ieri</translation>
<extracomment>Previous day</extracomment>
</message>
<message>
<source>today</source>
<translation>oggi</translation>
<extracomment>Current day</extracomment>
</message>
<message>
<comment>Title of Tab for options to filter library content</comment>
<source>TAB_FILTER</source>
<translation>Filtra</translation>
</message>
<message>
<comment>Title of Tab for options to sort library content</comment>
<source>TAB_SORT</source>
<translation>Ordina</translation>
</message>
<message>
<comment>Title of Tab for switching &quot;views&quot; when looking at a library</comment>
<source>TAB_VIEW</source>
<translation>Vista</translation>
</message>
<message>
<source>RUNTIME</source>
<translation>Tempo trascorso</translation>
</message>
<message>
<source>RELEASE_DATE</source>
<translation>Data di rilascio</translation>
</message>
<message>
<source>PLAY_COUNT</source>
<translation>Numero di riproduzioni</translation>
</message>
<message>
<source>OFFICIAL_RATING</source>
<translation>Valutazione parentale</translation>
</message>
<message>
<source>DATE_PLAYED</source>
<translation>Data di riproduzione</translation>
</message>
<message>
<source>DATE_ADDED</source>
<translation>Data di aggiunta</translation>
</message>
<message>
<source>CRITIC_RATING</source>
<translation>Valutazione critica</translation>
</message>
<message>
<source>IMDB_RATING</source>
<translation>Valutazione IMDb</translation>
</message>
<message>
<comment>Name or Title field of media item</comment>
<source>TITLE</source>
<translation>Nome</translation>
</message>
<message>
<comment>Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)</comment>
<source>NO_ITEMS</source>
<translation>Questo %1 non contiene elementi</translation>
</message>
<message>
<source>Unable to load Channel Data from the server</source>
<translation>Impossibile ottenere dati del canale dal server</translation>
</message>
<message>
<source>Error loading Channel Data</source>
<translation>Errore nel caricamento dei dati del canale</translation>
</message>
<message>
<source>Loading Channel Data</source>
<translation>Caricamento dati del canale</translation>
</message>
<message>
<source>An error was encountered while playing this item.</source>
<translation>C&apos;è stato un errore nella riproduzione di questo elemento.</translation>
<extracomment>Dialog detail when error occurs during playback</extracomment>
</message>
<message>
<source>There was an error retrieving the data for this item from the server.</source>
<translation>C&apos;è stato un errore nell&apos;ottenimento di informazioni dal sever per questo elemento.</translation>
<extracomment>Dialog detail when unable to load Content from Server</extracomment>
</message>
<message>
<source>Error During Playback</source>
<translation>Errore durante la riproduzione</translation>
<extracomment>Dialog title when error occurs during playback</extracomment>
</message>
<message>
<source>Error Retrieving Content</source>
<translation>Errore nell&apos;ottenimento del contenuto</translation>
<extracomment>Dialog title when unable to load Content from Server</extracomment>
</message>
<message>
<source>Sign Out</source>
<translation>Esci</translation>
</message>
<message>
<source>Change Server</source>
<translation>Cambia Server</translation>
</message>
</context> </context>
</TS> </TS>

View File

@ -61,6 +61,11 @@ sub Main()
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
print "CLOSING SCREEN" print "CLOSING SCREEN"
return return
else if isNodeEvent(msg, "buttonSelected")
' Dialog Button Selected - If not handled more locally, just close the dialog
dialog = msg.getRoSGNode()
dialog.unobserveField("buttonSelected")
dialog.close = true
else if isNodeEvent(msg, "backPressed") else if isNodeEvent(msg, "backPressed")
n = m.scene.getChildCount() - 1 n = m.scene.getChildCount() - 1
if msg.getRoSGNode().focusedChild <> invalid and msg.getRoSGNode().focusedChild.isSubtype("JFVideo") if msg.getRoSGNode().focusedChild <> invalid and msg.getRoSGNode().focusedChild.isSubtype("JFVideo")
@ -103,49 +108,12 @@ sub Main()
else if isNodeEvent(msg, "selectedItem") else if isNodeEvent(msg, "selectedItem")
' If you select a library from ANYWHERE, follow this flow ' If you select a library from ANYWHERE, follow this flow
selectedItem = msg.getData() selectedItem = msg.getData()
if (selectedItem.type = "CollectionFolder" OR selectedItem.type = "UserView" OR selectedItem.type = "Folder") AND ( selectedItem.collectionType = "movies" or selectedItem.collectionType = "CollectionFolder") if selectedItem.type = "CollectionFolder" OR selectedItem.type = "UserView" OR selectedItem.type = "Folder"
group.lastFocus = group.focusedChild group.lastFocus = group.focusedChild
group.setFocus(false) group.setFocus(false)
group.visible = false group.visible = false
m.overhang.title = selectedItem.title m.overhang.title = selectedItem.title
group = CreateMovieListGroup(selectedItem) group = CreateItemGrid(selectedItem)
group.overhangTitle = selectedItem.title
m.scene.appendChild(group)
else if (selectedItem.type = "CollectionFolder" OR selectedItem.type = "UserView") AND selectedItem.collectionType = "tvshows"
group.lastFocus = group.focusedChild
group.setFocus(false)
group.visible = false
m.overhang.title = selectedItem.title
group = CreateSeriesListGroup(selectedItem)
group.overhangTitle = selectedItem.title
m.scene.appendChild(group)
else if (selectedItem.type = "CollectionFolder" OR selectedItem.type = "UserView") AND selectedItem.collectionType = "boxsets" OR selectedItem.type = "Boxset"
group.lastFocus = group.focusedChild
group.setFocus(false)
group.visible = false
m.overhang.title = selectedItem.title
group = CreateCollectionsList(selectedItem)
group.overhangTitle = selectedItem.title
m.scene.appendChild(group)
else if ((selectedItem.type = "CollectionFolder" OR selectedItem.type = "UserView") AND selectedItem.collectionType = "livetv") OR selectedItem.type = "Channel"
group.lastFocus = group.focusedChild
group.setFocus(false)
group.visible = false
m.overhang.title = selectedItem.title
group = CreateChannelList(selectedItem)
group.overhangTitle = selectedItem.title
m.scene.appendChild(group)
else if selectedItem.type = "Boxset" or selectedItem.collectionType = "folders" then
group.lastFocus = group.focusedChild
group.setFocus(false)
group.visible = false
m.overhang.title = selectedItem.title
group = CreateCollectionDetailList(selectedItem.Id)
group.overhangTitle = selectedItem.title group.overhangTitle = selectedItem.title
m.scene.appendChild(group) m.scene.appendChild(group)
else if selectedItem.type = "Folder" else if selectedItem.type = "Folder"
@ -154,7 +122,7 @@ sub Main()
group.visible = false group.visible = false
m.overhang.title = selectedItem.title m.overhang.title = selectedItem.title
group = CreateCollectionsList(selectedItem) group = CreateItemGrid(selectedItem)
group.overhangTitle = selectedItem.title group.overhangTitle = selectedItem.title
m.scene.appendChild(group) m.scene.appendChild(group)
else if selectedItem.type = "Episode" then else if selectedItem.type = "Episode" then
@ -225,14 +193,11 @@ sub Main()
dialog.message = tr("Unable to load Channel Data from the server") dialog.message = tr("Unable to load Channel Data from the server")
dialog.buttons = [tr("OK")] dialog.buttons = [tr("OK")]
m.scene.dialog = dialog m.scene.dialog = dialog
m.scene.dialog.observeField("buttonSelected", m.port)
end if end if
else else
' TODO - switch on more node types ' TODO - switch on more node types
if selectedItem.type = "CollectionFolder" OR selectedItem.type = "UserView" then message_dialog("This type is not yet supported: " + selectedItem.type + ".")
message_dialog("This library type is not yet implemented: " + selectedItem.collectionType + ".")
else
message_dialog("This library type is not yet implemented: " + selectedItem.type + ".")
end if
selectedItem = invalid selectedItem = invalid
end if end if
else if isNodeEvent(msg, "movieSelected") else if isNodeEvent(msg, "movieSelected")

View File

@ -211,50 +211,6 @@ function CreateHomeGroup()
return group return group
end function end function
function CreateMovieListGroup(libraryItem)
group = CreateObject("roSGNode", "ItemGrid2")
group.parentItem = libraryItem
group.observeField("selectedItem", m.port)
group.observeField("quickPlayNode", m.port)
sidepanel = group.findNode("options")
movie_options = [
{"title": "Sort Field",
"base_title": "Sort Field",
"key": "movie_sort_field",
"default": "DateCreated",
"values": [
{display: tr("Date Added"), value: "DateCreated"},
{display: tr("Release Date"), value: "PremiereDate"},
{display: tr("Name"), value: "SortName"}
]},
{"title": "Sort Order",
"base_title": "Sort Order",
"key": "movie_sort_order",
"default": "Ascending",
"values": [
{display: tr("Descending"), value: "Descending"},
{display: tr("Ascending"), value: "Ascending"}
]}
]
new_options = []
for each opt in movie_options
o = CreateObject("roSGNode", "OptionsData")
o.title = tr(opt.title)
o.choices = opt.values
o.base_title = tr(opt.base_title)
o.config_key = opt.key
o.value = get_user_setting(opt.key, opt.default)
new_options.append([o])
end for
sidepanel.options = new_options
sidepanel.observeField("closeSidePanel", m.port)
return group
end function
function CreateMovieDetailsGroup(movie) function CreateMovieDetailsGroup(movie)
group = CreateObject("roSGNode", "MovieDetails") group = CreateObject("roSGNode", "MovieDetails")
@ -269,18 +225,6 @@ function CreateMovieDetailsGroup(movie)
return group return group
end function end function
function CreateSeriesListGroup(libraryItem)
group = CreateObject("roSGNode", "ItemGrid2")
group.parentItem = libraryItem
group.observeField("selectedItem", m.port)
sidepanel = group.findNode("options")
return group
end function
function CreateSeriesDetailsGroup(series) function CreateSeriesDetailsGroup(series)
group = CreateObject("roSGNode", "TVShowDetails") group = CreateObject("roSGNode", "TVShowDetails")
@ -304,46 +248,10 @@ function CreateSeasonDetailsGroup(series, season)
return group return group
end function end function
function CreateCollectionsList(libraryItem) function CreateItemGrid(libraryItem)
group = CreateObject("roSGNode", "ItemGrid")
group = CreateObject("roSGNode", "ItemGrid2")
group.parentItem = libraryItem group.parentItem = libraryItem
group.observeField("selectedItem", m.port) group.observeField("selectedItem", m.port)
group.observeField("quickPlayNode", m.port)
sidepanel = group.findNode("options")
return group
end function
function CreateCollectionDetailList(collectionId)
sort_order = get_user_setting("movie_sort_order", "Ascending")
sort_field = get_user_setting("movie_sort_field", "SortName")
item_list = ItemList(collectionId, {
"SortBy": sort_field,
"SortOrder": sort_order
})
group = CreateObject("roSGNode", "CollectionDetail")
group.collectionId = collectionId
group.objects = item_list
group.observeField("selectedItem", m.port)
return group
end function
function CreateChannelList(libraryItem)
group = CreateObject("roSGNode", "ItemGrid2")
group.parentItem = libraryItem
group.observeField("selectedItem", m.port)
sidepanel = group.findNode("options")
return group return group
end function end function

View File

@ -198,7 +198,7 @@ function sortSubtitles(id as string, MediaStreams)
'Documentation lists that srt, ttml, and dfxp can be sideloaded but only srt was working in my testing, 'Documentation lists that srt, ttml, and dfxp can be sideloaded but only srt was working in my testing,
'forcing srt for all text subtitles 'forcing srt for all text subtitles
url = Substitute("{0}/Videos/{1}/{2}/Subtitles/{3}/0/", get_url(), dashedid, id, stream.index.tostr()) url = Substitute("{0}/Videos/{1}/{2}/Subtitles/{3}/0/", get_url(), dashedid, id, stream.index.tostr())
url = url + Substitute("Stream.js?api_key={0}&format=srt", get_setting("active_user")) url = url + Substitute("Stream.srt?api_key={0}", get_setting("active_user"))
stream = { stream = {
"Track": { "Language" : stream.language, "Description": stream.displaytitle , "TrackName": url }, "Track": { "Language" : stream.language, "Description": stream.displaytitle , "TrackName": url },
"IsTextSubtitleStream": stream.IsTextSubtitleStream, "IsTextSubtitleStream": stream.IsTextSubtitleStream,