Merge branch 'master' into jump-to-1st-item

This commit is contained in:
Jimi 2022-06-11 17:18:18 -06:00 committed by GitHub
commit d81f5dae6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 149 additions and 52 deletions

View File

@ -72,6 +72,11 @@ sub loadInitialItems()
m.sortField = get_user_setting("display.livetv.sortField") m.sortField = get_user_setting("display.livetv.sortField")
sortAscendingStr = get_user_setting("display.livetv.sortAscending") sortAscendingStr = get_user_setting("display.livetv.sortAscending")
m.filter = get_user_setting("display.livetv.filter") m.filter = get_user_setting("display.livetv.filter")
else if m.top.parentItem.collectionType = "music"
m.view = get_user_setting("display.music.view")
m.sortField = get_user_setting("display." + m.top.parentItem.Id + ".sortField")
sortAscendingStr = get_user_setting("display." + m.top.parentItem.Id + ".sortAscending")
m.filter = get_user_setting("display." + m.top.parentItem.Id + ".filter")
else else
m.view = invalid m.view = invalid
m.sortField = get_user_setting("display." + m.top.parentItem.Id + ".sortField") m.sortField = get_user_setting("display." + m.top.parentItem.Id + ".sortField")
@ -104,9 +109,20 @@ sub loadInitialItems()
else if m.top.parentItem.collectionType = "tvshows" else if m.top.parentItem.collectionType = "tvshows"
m.loadItemsTask.itemType = "Series" m.loadItemsTask.itemType = "Series"
else if m.top.parentItem.collectionType = "music" else if m.top.parentItem.collectionType = "music"
m.loadItemsTask.itemType = "MusicArtist,MusicAlbum" ' Default Settings
m.loadItemsTask.fallbackType = "MusicAlbum"
m.loadItemsTask.recursive = false m.loadItemsTask.recursive = false
m.loadItemsTask.itemType = "MusicArtist,MusicAlbum"
m.view = get_user_setting("display.music.view")
if m.view = "music-artist"
m.loadItemsTask.recursive = true
m.loadItemsTask.itemType = "MusicArtist"
else if m.view = "music-album"
m.loadItemsTask.itemType = "MusicAlbum"
m.loadItemsTask.recursive = true
end if
else if m.top.parentItem.collectionType = "livetv" else if m.top.parentItem.collectionType = "livetv"
m.loadItemsTask.itemType = "LiveTV" m.loadItemsTask.itemType = "LiveTV"
@ -217,7 +233,11 @@ sub SetUpOptions()
options.filter = [] options.filter = []
'Music 'Music
else if m.top.parentItem.collectionType = "music" else if m.top.parentItem.collectionType = "music"
options.views = [{ "Title": tr("Music"), "Name": "music" }] options.views = [
{ "Title": tr("Default"), "Name": "music-default" },
{ "Title": tr("Artists"), "Name": "music-artist" },
{ "Title": tr("Albums"), "Name": "music-album" },
]
options.sort = [ options.sort = [
{ "Title": tr("TITLE"), "Name": "SortName" }, { "Title": tr("TITLE"), "Name": "SortName" },
{ "Title": tr("DATE_ADDED"), "Name": "DateCreated" }, { "Title": tr("DATE_ADDED"), "Name": "DateCreated" },
@ -417,7 +437,6 @@ sub optionsClosed()
m.top.removeChild(m.tvGuide) m.top.removeChild(m.tvGuide)
end if end if
end if end if
end if end if
if m.top.parentItem.Type = "CollectionFolder" or m.top.parentItem.CollectionType = "CollectionFolder" if m.top.parentItem.Type = "CollectionFolder" or m.top.parentItem.CollectionType = "CollectionFolder"
@ -432,6 +451,21 @@ sub optionsClosed()
end if end if
reload = false reload = false
if m.top.parentItem.collectionType = "music"
if m.options.view <> m.view
if m.options.view = "music-artist"
m.view = "music-artist"
else if m.options.view = "music-album"
m.view = "music-album"
else
m.view = "music-default"
end if
set_user_setting("display.music.view", m.view)
reload = true
end if
end if
if m.options.sortField <> m.sortField or m.options.sortAscending <> m.sortAscending if m.options.sortField <> m.sortField or m.options.sortAscending <> m.sortAscending
m.sortField = m.options.sortField m.sortField = m.options.sortField
m.sortAscending = m.options.sortAscending m.sortAscending = m.options.sortAscending

View File

@ -59,17 +59,6 @@ sub loadItems()
if data.TotalRecordCount <> invalid then m.top.totalRecordCount = data.TotalRecordCount if data.TotalRecordCount <> invalid then m.top.totalRecordCount = data.TotalRecordCount
' When loading a collection, if no results are found, try searching by fallback type
if data.TotalRecordCount = 0
if m.top.FallbackType <> ""
' Ensure we didn't just search by the fallback type - prevent infinite loop
if m.top.ItemType <> m.top.FallbackType
m.top.ItemType = m.top.FallbackType
loadItems()
end if
end if
end if
for each item in data.Items for each item in data.Items
tmp = invalid tmp = invalid
if item.Type = "Movie" if item.Type = "Movie"

View File

@ -5,7 +5,6 @@
<field id="itemId" type="string" /> <field id="itemId" type="string" />
<field id="startIndex" type="integer" value="0" /> <field id="startIndex" type="integer" value="0" />
<field id="itemType" type="string" value="" /> <field id="itemType" type="string" value="" />
<field id="fallbackType" type="string" value="" />
<field id="limit" type="integer" value="60" /> <field id="limit" type="integer" value="60" />
<field id="metadata" type="assocarray" /> <field id="metadata" type="assocarray" />
<field id="sortField" type="string" value="SortName" /> <field id="sortField" type="string" value="SortName" />

View File

@ -3,6 +3,7 @@ sub init()
setupMainNode() setupMainNode()
m.playAlbum = m.top.findNode("playAlbum") m.playAlbum = m.top.findNode("playAlbum")
m.instantMix = m.top.findNode("instantMix")
m.albumCover = m.top.findNode("albumCover") m.albumCover = m.top.findNode("albumCover")
m.songList = m.top.findNode("songList") m.songList = m.top.findNode("songList")
m.infoGroup = m.top.FindNode("infoGroup") m.infoGroup = m.top.FindNode("infoGroup")
@ -12,7 +13,6 @@ sub init()
m.spinner.visible = true m.spinner.visible = true
m.dscr = m.top.findNode("overview") m.dscr = m.top.findNode("overview")
m.dscr.observeField("isTextEllipsized", "onEllipsisChanged")
createDialogPallete() createDialogPallete()
end sub end sub
@ -99,11 +99,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
if m.spinner.visible then return false if m.spinner.visible then return false
' Play Album is hidden, so there are no navigation needs here
if m.top.pageContent.json.ChildCount = 1
return false
end if
if key = "options" if key = "options"
if m.dscr.isTextEllipsized if m.dscr.isTextEllipsized
createFullDscrDlg() createFullDscrDlg()
@ -112,10 +107,24 @@ function onKeyEvent(key as string, press as boolean) as boolean
return false return false
end if end if
if key = "right" and m.playAlbum.hasFocus() if key = "right"
m.songList.setFocus(true) if m.playAlbum.hasFocus() or m.instantMix.hasFocus()
return true m.songList.setFocus(true)
return true
end if
else if key = "left" and m.songList.hasFocus() else if key = "left" and m.songList.hasFocus()
if m.playAlbum.visible
m.playAlbum.setFocus(true)
else if m.instantMix.visible
m.instantMix.setFocus(true)
else
return false
end if
return true
else if key = "down" and m.playAlbum.hasFocus()
m.instantMix.setFocus(true)
return true
else if key = "up" and m.instantMix.hasFocus()
m.playAlbum.setFocus(true) m.playAlbum.setFocus(true)
return true return true
end if end if
@ -123,19 +132,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
return false return false
end function end function
sub onEllipsisChanged()
if m.dscr.isTextEllipsized
dscrShowFocus()
end if
end sub
sub dscrShowFocus()
if m.dscr.isTextEllipsized
m.dscr.setFocus(true)
m.dscr.opacity = 1.0
end if
end sub
sub createFullDscrDlg() sub createFullDscrDlg()
dlg = CreateObject("roSGNode", "OverviewDialog") dlg = CreateObject("roSGNode", "OverviewDialog")
dlg.Title = tr("Press 'Back' to Close") dlg.Title = tr("Press 'Back' to Close")

View File

@ -10,6 +10,7 @@
<Label id="runtime" width="450" height="25" /> <Label id="runtime" width="450" height="25" />
<Label id="released" width="450" height="25" /> <Label id="released" width="450" height="25" />
<JFButton id="playAlbum" minChars="8" text="Play Album"></JFButton> <JFButton id="playAlbum" minChars="8" text="Play Album"></JFButton>
<JFButton id="instantMix" minChars="8" text="Instant Mix"></JFButton>
</LayoutGroup> </LayoutGroup>
<LayoutGroup id="infoGroup" layoutDirection="vert" itemSpacings="[15]"> <LayoutGroup id="infoGroup" layoutDirection="vert" itemSpacings="[15]">
<Label id="overview" wrap="true" height="310" width="1250" ellipsisText=" ... (Press * to read more)" /> <Label id="overview" wrap="true" height="310" width="1250" ellipsisText=" ... (Press * to read more)" />
@ -26,6 +27,7 @@
<field id="albumData" type="assocarray" alias="songList.MusicArtistAlbumData" /> <field id="albumData" type="assocarray" alias="songList.MusicArtistAlbumData" />
<field id="playSong" alias="songList.itemSelected" /> <field id="playSong" alias="songList.itemSelected" />
<field id="playAllSelected" alias="playAlbum.buttonSelected" /> <field id="playAllSelected" alias="playAlbum.buttonSelected" />
<field id="instantMixSelected" alias="instantMix.buttonSelected" />
</interface> </interface>
<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="MusicAlbumDetails.brs" /> <script type="text/brightscript" uri="MusicAlbumDetails.brs" />

View File

@ -12,18 +12,16 @@ sub init()
end sub end sub
sub updateSize() sub updateSize()
dimensions = m.top.getScene().currentDesignResolution m.top.translation = [450, 180]
border = 96 itemWidth = 1360
m.top.translation = [border, 75 + 115] itemHeight = 300
itemWidth = (dimensions["width"] - border * 2)
itemHeight = 400
m.top.visible = true m.top.visible = true
' Size of the individual rows ' Size of the individual rows
m.top.itemSize = [dimensions["width"] - border * 2, itemHeight] m.top.itemSize = [itemWidth, itemHeight]
' Spacing between Rows ' Spacing between Rows
m.top.itemSpacing = [0, 40] m.top.itemSpacing = [0, 40]

View File

@ -2,6 +2,11 @@ sub init()
m.top.optionsAvailable = false m.top.optionsAvailable = false
m.rows = m.top.findNode("picker") m.rows = m.top.findNode("picker")
m.poster = m.top.findNode("seasonPoster")
m.Random = m.top.findNode("Random")
m.tvEpisodeRow = m.top.findNode("tvEpisodeRow")
m.rows.observeField("doneLoading", "updateSeason") m.rows.observeField("doneLoading", "updateSeason")
end sub end sub
@ -10,12 +15,35 @@ sub setSeasonLoading()
end sub end sub
sub updateSeason() sub updateSeason()
imgParams = { "maxHeight": 450, "maxWidth": 300 }
m.poster.uri = ImageURL(m.top.seasonData.Id, "Primary", imgParams)
m.Random.visible = true
m.top.overhangTitle = m.top.seasonData.SeriesName + " - " + m.top.seasonData.name m.top.overhangTitle = m.top.seasonData.SeriesName + " - " + m.top.seasonData.name
end sub end sub
function onKeyEvent(key as string, press as boolean) as boolean function onKeyEvent(key as string, press as boolean) as boolean
handled = false handled = false
if key = "left" and not m.Random.hasFocus()
m.Random.setFocus(true)
return true
end if
if key = "right" and not m.tvEpisodeRow.hasFocus()
m.tvEpisodeRow.setFocus(true)
return true
end if
if key = "OK" or key = "play"
if m.Random.hasFocus()
randomEpisode = Rnd(m.rows.getChild(0).objects.items.count()) - 1
m.top.quickPlayNode = m.rows.getChild(0).objects.items[randomEpisode]
return true
end if
end if
focusedChild = m.top.focusedChild.focusedChild focusedChild = m.top.focusedChild.focusedChild
if focusedChild.content = invalid then return handled if focusedChild.content = invalid then return handled

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<component name="TVEpisodes" extends="JFGroup"> <component name="TVEpisodes" extends="JFGroup">
<children> <children>
<Poster id="seasonPoster" width="300" height="450" translation="[95,175]" />
<JFButton id="Random" text="Play Random" translation="[90, 640]" visible="false"></JFButton>
<TVEpisodeRowWithOptions id="picker" visible="true" /> <TVEpisodeRowWithOptions id="picker" visible="true" />
</children> </children>
<interface> <interface>
@ -10,4 +12,7 @@
<field id="objects" alias="picker.objects" /> <field id="objects" alias="picker.objects" />
</interface> </interface>
<script type="text/brightscript" uri="TVEpisodes.brs" /> <script type="text/brightscript" uri="TVEpisodes.brs" />
<script type="text/brightscript" uri="pkg:/source/api/Image.brs" />
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
</component> </component>

View File

@ -3,11 +3,11 @@
<children> <children>
<LayoutGroup id="toplevel" layoutDirection="vert" itemSpacings="[40]"> <LayoutGroup id="toplevel" layoutDirection="vert" itemSpacings="[40]">
<LayoutGroup id="main_group" layoutDirection="horiz" itemSpacings="[30]"> <LayoutGroup id="main_group" layoutDirection="horiz" itemSpacings="[30]">
<Poster id="poster" width="534" height="400" /> <Poster id="poster" width="350" height="300" />
<LayoutGroup id="text" layoutDirection="vert" itemSpacings="[15]"> <LayoutGroup id="text" layoutDirection="vert" itemSpacings="[15]">
<!-- Using poster of 1 length to get spacing. Not successful with adding translation to title --> <!-- Using poster of 1 length to get spacing. Not successful with adding translation to title -->
<Poster id="null" height="1" /> <Poster id="null" height="1" />
<ScrollingLabel id="title" font="font:LargeBoldSystemFont" maxWidth="1200" /> <ScrollingLabel id="title" font="font:MediumBoldSystemFont" maxWidth="950" />
<LayoutGroup layoutDirection="horiz" itemSpacings="[20]"> <LayoutGroup layoutDirection="horiz" itemSpacings="[20]">
<Label id="runtime" font="font:SmallestSystemFont" /> <Label id="runtime" font="font:SmallestSystemFont" />
<LayoutGroup layoutDirection="horiz" itemSpacings="[-5]"> <LayoutGroup layoutDirection="horiz" itemSpacings="[-5]">
@ -16,10 +16,10 @@
</LayoutGroup> </LayoutGroup>
<Label id="endtime" font="font:SmallestSystemFont" /> <Label id="endtime" font="font:SmallestSystemFont" />
</LayoutGroup> </LayoutGroup>
<Label id="overview" wrap="true" height="170" width="1200" maxLines="4" ellipsizeOnBoundary="true"/> <Label id="overview" font="font:SmallestSystemFont" wrap="true" height="130" width="950" maxLines="3" ellipsizeOnBoundary="true"/>
<LayoutGroup layoutDirection="horiz" itemSpacings="[15]"> <LayoutGroup layoutDirection="horiz" itemSpacings="[15]">
<Label id="video_codec" /> <Label id="video_codec" font="font:SmallestSystemFont" />
<ScrollingLabel id="audio_codec" /> <ScrollingLabel id="audio_codec" font="font:SmallestSystemFont" />
<label id="audio_codec_count" font="font:smallestSystemFont" vertAlign="top" color="#ceffff" /> <label id="audio_codec_count" font="font:smallestSystemFont" vertAlign="top" color="#ceffff" />
</LayoutGroup> </LayoutGroup>
</LayoutGroup> </LayoutGroup>

View File

@ -201,6 +201,13 @@ sub Main (args as dynamic) as void
m.spinner = screenContent.findNode("spinner") m.spinner = screenContent.findNode("spinner")
m.spinner.visible = true m.spinner.visible = true
group = CreateAudioPlayerGroup(screenContent.albumData.items) group = CreateAudioPlayerGroup(screenContent.albumData.items)
else if isNodeEvent(msg, "instantMixSelected")
' User has selected instant mix
' User has selected playlist of of audio they want us to play
screenContent = msg.getRoSGNode()
m.spinner = screenContent.findNode("spinner")
m.spinner.visible = true
group = CreateInstantMixGroup(screenContent.albumData.items)
else if isNodeEvent(msg, "episodeSelected") else if isNodeEvent(msg, "episodeSelected")
' If you select a TV Episode from ANYWHERE, follow this flow ' If you select a TV Episode from ANYWHERE, follow this flow
node = getMsgPicker(msg, "picker") node = getMsgPicker(msg, "picker")

View File

@ -380,6 +380,7 @@ function CreateMusicArtistDetailsGroup(musicartist)
group.albumData = MusicSongList(musicartist.id) group.albumData = MusicSongList(musicartist.id)
group.observeField("playSong", m.port) group.observeField("playSong", m.port)
group.observeField("playAllSelected", m.port) group.observeField("playAllSelected", m.port)
group.observeField("instantMixSelected", m.port)
else else
' User has albums under artists ' User has albums under artists
group = CreateObject("roSGNode", "MusicArtistDetails") group = CreateObject("roSGNode", "MusicArtistDetails")
@ -407,6 +408,9 @@ function CreateMusicAlbumDetailsGroup(album)
' Watch for user click on Play button on album ' Watch for user click on Play button on album
group.observeField("playAllSelected", m.port) group.observeField("playAllSelected", m.port)
' Watch for user click on Instant Mix button on album
group.observeField("instantMixSelected", m.port)
return group return group
end function end function
@ -481,6 +485,30 @@ function CreateAudioPlayerGroup(audiodata)
return group return group
end function end function
' Play Instant Mix
function CreateInstantMixGroup(audiodata)
songList = CreateInstantMix(audiodata[0].id)
group = CreateObject("roSGNode", "NowPlaying")
group.observeField("state", m.port)
songIDArray = CreateObject("roArray", 0, true)
' All we need is an array of Song IDs the user selected to play.
for each song in songList.items
songIDArray.push(song.id)
end for
songIDArray.shift()
group.pageContent = songIDArray
group.musicArtistAlbumData = songList.items
m.global.sceneManager.callFunc("pushScene", group)
return group
end function
function CreatePersonView(personData as object) as object function CreatePersonView(personData as object) as object
person = CreateObject("roSGNode", "PersonDetails") person = CreateObject("roSGNode", "PersonDetails")
m.global.SceneManager.callFunc("pushScene", person) m.global.SceneManager.callFunc("pushScene", person)

View File

@ -209,6 +209,17 @@ function AudioItem(id as string)
return getJson(resp) return getJson(resp)
end function end function
' Get Instant Mix based on item
function CreateInstantMix(id as string)
url = Substitute("/Items/{0}/InstantMix", id)
resp = APIRequest(url, {
"UserId": get_setting("active_user"),
"Limit": 201
})
return getJson(resp)
end function
function AudioStream(id as string) function AudioStream(id as string)
songData = AudioItem(id) songData = AudioItem(id)
@ -264,7 +275,7 @@ function TVEpisodes(show_id as string, season_id as string)
data = getJson(resp) data = getJson(resp)
results = [] results = []
for each item in data.Items for each item in data.Items
imgParams = { "AddPlayedIndicator": item.UserData.Played, "maxWidth": 712, "maxheight": 400 } imgParams = { "AddPlayedIndicator": item.UserData.Played, "maxWidth": 400, "maxheight": 250 }
if item.UserData.PlayedPercentage <> invalid if item.UserData.PlayedPercentage <> invalid
param = { "PercentPlayed": item.UserData.PlayedPercentage } param = { "PercentPlayed": item.UserData.PlayedPercentage }
imgParams.Append(param) imgParams.Append(param)
@ -272,7 +283,7 @@ function TVEpisodes(show_id as string, season_id as string)
tmp = CreateObject("roSGNode", "TVEpisodeData") tmp = CreateObject("roSGNode", "TVEpisodeData")
tmp.image = PosterImage(item.id, imgParams) tmp.image = PosterImage(item.id, imgParams)
if tmp.image <> invalid if tmp.image <> invalid
tmp.image.posterDisplayMode = "scaleToFit" tmp.image.posterDisplayMode = "scaleToZoom"
end if end if
tmp.json = item tmp.json = item
tmp.overview = ItemMetaData(item.id).overview tmp.overview = ItemMetaData(item.id).overview