mirror of
https://github.com/jellyfin/jellyfin-roku.git
synced 2024-11-23 06:09:41 +00:00
Add appears on artist section
This commit is contained in:
parent
80b14e310b
commit
5f4fb2239f
@ -69,17 +69,11 @@ end sub
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if not press then return false
|
||||
|
||||
if key = "OK" and m.top.hasFocus()
|
||||
' Simply toggle the selected field to trigger the next event
|
||||
m.top.selected = not m.top.selected
|
||||
return true
|
||||
end if
|
||||
|
||||
if key = "right" and m.top.hasFocus()
|
||||
if key = "right" and m.top.focus
|
||||
m.top.escape = "right"
|
||||
end if
|
||||
|
||||
if key = "left" and m.top.hasFocus()
|
||||
if key = "left" and m.top.focus
|
||||
m.top.escape = "left"
|
||||
end if
|
||||
|
||||
|
@ -163,25 +163,16 @@ sub loadInitialItems()
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
else if getCollectionType() = "music"
|
||||
' Default Settings
|
||||
m.loadItemsTask.recursive = true
|
||||
m.itemGrid.itemSize = "[290, 290]"
|
||||
|
||||
if m.voiceBox.text <> ""
|
||||
m.loadItemsTask.recursive = true
|
||||
else
|
||||
m.loadItemsTask.recursive = false
|
||||
m.itemGrid.itemSize = "[290, 290]"
|
||||
end if
|
||||
|
||||
m.loadItemsTask.itemType = "MusicArtist,MusicAlbum"
|
||||
m.loadItemsTask.itemType = "MusicArtist"
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
|
||||
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"
|
||||
if m.view = "music-album"
|
||||
m.loadItemsTask.itemType = "MusicAlbum"
|
||||
m.loadItemsTask.recursive = true
|
||||
end if
|
||||
else if m.top.parentItem.collectionType = "livetv"
|
||||
m.loadItemsTask.itemType = "TvChannel"
|
||||
|
@ -77,6 +77,12 @@ sub loadItems()
|
||||
else if m.top.view = "Genres"
|
||||
url = "Genres"
|
||||
params.append({ UserId: get_setting("active_user") })
|
||||
else if m.top.ItemType = "MusicArtist"
|
||||
url = "Artists"
|
||||
params.append({
|
||||
UserId: get_setting("active_user")
|
||||
})
|
||||
params.IncludeItemTypes = ""
|
||||
else
|
||||
url = Substitute("Users/{0}/Items/", get_setting("active_user"))
|
||||
end if
|
||||
@ -110,7 +116,9 @@ sub loadItems()
|
||||
tmp = CreateObject("roSGNode", "FolderData")
|
||||
else if item.Type = "Studio"
|
||||
tmp = CreateObject("roSGNode", "FolderData")
|
||||
else if item.Type = "MusicArtist" or item.Type = "MusicAlbum"
|
||||
else if item.Type = "MusicAlbum"
|
||||
tmp = CreateObject("roSGNode", "MusicAlbumData")
|
||||
else if item.Type = "MusicArtist"
|
||||
tmp = CreateObject("roSGNode", "MusicArtistData")
|
||||
else if item.Type = "Audio"
|
||||
tmp = CreateObject("roSGNode", "MusicSongData")
|
||||
|
@ -1,13 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="MusicAlbumData" extends="ContentNode">
|
||||
<component name="MusicAlbumData" extends="JFContentItem">
|
||||
<interface>
|
||||
<field id="id" type="string" />
|
||||
<field id="title" type="string" />
|
||||
<field id="image" type="node" onChange="setPoster" />
|
||||
<field id="posterURL" type="string" />
|
||||
<field id="overview" type="string" />
|
||||
<field id="type" type="string" value="Episode" />
|
||||
<field id="json" type="assocarray" onChange="setFields" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="MusicAlbumData.brs" />
|
||||
</component>
|
||||
|
@ -1,15 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="MusicSongData" extends="ContentNode">
|
||||
<component name="MusicSongData" extends="JFContentItem">
|
||||
<interface>
|
||||
<field id="id" type="string" />
|
||||
<field id="title" type="string" />
|
||||
<field id="trackNumber" type="integer" />
|
||||
<field id="image" type="node" onChange="setPoster" />
|
||||
<field id="posterURL" type="string" />
|
||||
<field id="overview" type="string" />
|
||||
<field id="type" type="string" value="Song" />
|
||||
<field id="json" type="assocarray" onChange="setFields" />
|
||||
<field id="favorite" type="boolean" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="MusicSongData.brs" />
|
||||
</component>
|
||||
|
@ -15,10 +15,15 @@ function getData()
|
||||
|
||||
for each album in albumData.items
|
||||
gridAlbum = CreateObject("roSGNode", "ContentNode")
|
||||
|
||||
if not isValid(album.posterURL) or album.posterURL = ""
|
||||
album.posterURL = "pkg:/images/icons/album.png"
|
||||
end if
|
||||
|
||||
gridAlbum.shortdescriptionline1 = album.title
|
||||
gridAlbum.HDGRIDPOSTERURL = album.posterURL
|
||||
gridAlbum.hdposterurl = album.posterURL
|
||||
gridAlbum.SDGRIDPOSTERURL = album.SDGRIDPOSTERURL
|
||||
gridAlbum.SDGRIDPOSTERURL = album.posterURL
|
||||
gridAlbum.sdposterurl = album.posterURL
|
||||
|
||||
data.appendChild(gridAlbum)
|
||||
@ -47,6 +52,15 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
m.top.escape = key
|
||||
return true
|
||||
end if
|
||||
else if key = "down"
|
||||
totalCount = m.top.MusicArtistAlbumData.items.count()
|
||||
totalRows = div_ceiling(totalCount, 5)
|
||||
currentRow = div_ceiling(m.top.itemFocused + 1, 5)
|
||||
|
||||
if currentRow = totalRows
|
||||
m.top.escape = key
|
||||
return true
|
||||
end if
|
||||
end if
|
||||
|
||||
return false
|
||||
|
@ -5,4 +5,5 @@
|
||||
<field id="escape" type="string" alwaysNotify="true" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="AlbumGrid.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
</component>
|
||||
|
@ -8,8 +8,16 @@ sub init()
|
||||
m.albumHeader = m.top.findNode("albumHeader")
|
||||
m.albumHeader.text = tr("Albums")
|
||||
|
||||
m.appearsOnHeader = m.top.findNode("appearsOnHeader")
|
||||
m.appearsOnHeader.text = tr("AppearsOn")
|
||||
|
||||
m.appearsOn = m.top.findNode("appearsOn")
|
||||
m.appearsOn.observeField("escape", "onAppearsOnEscape")
|
||||
m.appearsOn.observeField("MusicArtistAlbumData", "onAppearsOnData")
|
||||
|
||||
m.albums = m.top.findNode("albums")
|
||||
m.albums.observeField("escape", "onAlbumsEscape")
|
||||
m.albums.observeField("MusicArtistAlbumData", "onAlbumsData")
|
||||
|
||||
m.pageLoadAnimation = m.top.findNode("pageLoad")
|
||||
m.pageLoadAnimation.control = "start"
|
||||
@ -33,15 +41,47 @@ sub init()
|
||||
createDialogPallete()
|
||||
end sub
|
||||
|
||||
sub onAlbumsData()
|
||||
' We have no album data
|
||||
if m.albums.MusicArtistAlbumData.TotalRecordCount = 0
|
||||
m.sectionScroller.removeChild(m.top.findNode("albumsSlide"))
|
||||
m.sectionNavigation.removeChild(m.top.findNode("albumsLink"))
|
||||
m.top.findNode("appearsOnSlide").callFunc("scrollUpToOnDeck")
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub onAppearsOnData()
|
||||
' We have no appears on data
|
||||
if m.appearsOn.MusicArtistAlbumData.TotalRecordCount = 0
|
||||
m.sectionScroller.removeChild(m.top.findNode("appearsOnSlide"))
|
||||
m.sectionNavigation.removeChild(m.top.findNode("appearsOnLink"))
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub onSectionScrollerChange()
|
||||
m.overhang.isVisible = (m.sectionScroller.displayedIndex = 0)
|
||||
end sub
|
||||
|
||||
sub OnScreenShown()
|
||||
m.sectionScroller.focus = true
|
||||
|
||||
if m.sectionScroller.displayedIndex = 0
|
||||
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
|
||||
m.top.selectedButtonIndex = 0
|
||||
m.buttonGrp.setFocus(true)
|
||||
else
|
||||
m.overhang.opacity = "0"
|
||||
m.overhang.isVisible = false
|
||||
m.overhang.opacity = "1"
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub OnScreenHidden()
|
||||
if not m.overhang.isVisible
|
||||
m.overhang.disableMoveAnimation = true
|
||||
m.overhang.isVisible = true
|
||||
m.overhang.disableMoveAnimation = false
|
||||
m.overhang.opacity = "1"
|
||||
end if
|
||||
end sub
|
||||
|
||||
@ -50,6 +90,18 @@ sub onAlbumsEscape()
|
||||
m.sectionNavigation.selected = m.sectionScroller.displayedIndex - 1
|
||||
else if m.albums.escape = "left"
|
||||
m.sectionNavigation.setFocus(true)
|
||||
else if m.albums.escape = "down"
|
||||
if m.sectionScroller.displayedIndex + 1 < m.sectionNavigation.getChildCount()
|
||||
m.sectionNavigation.selected = m.sectionScroller.displayedIndex + 1
|
||||
end if
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub onAppearsOnEscape()
|
||||
if m.appearsOn.escape = "up"
|
||||
m.sectionNavigation.selected = m.sectionScroller.displayedIndex - 1
|
||||
else if m.appearsOn.escape = "left"
|
||||
m.sectionNavigation.setFocus(true)
|
||||
end if
|
||||
end sub
|
||||
|
||||
@ -95,7 +147,6 @@ sub pageContentChanged()
|
||||
' Populate scene data
|
||||
setScreenTitle(item.json)
|
||||
setPosterImage(item.posterURL)
|
||||
setOnScreenTextValues(item.json)
|
||||
end sub
|
||||
|
||||
sub setScreenTitle(json)
|
||||
@ -129,10 +180,12 @@ sub setBackdropImage(data)
|
||||
end if
|
||||
end sub
|
||||
|
||||
' Populate on screen text variables
|
||||
sub setOnScreenTextValues(json)
|
||||
if isValid(json)
|
||||
setFieldTextValue("overview", json.overview)
|
||||
' Event fired when page data is loaded
|
||||
sub artistOverviewChanged()
|
||||
overviewContent = m.top.artistOverview
|
||||
|
||||
if isValid(overviewContent)
|
||||
setFieldTextValue("overview", overviewContent)
|
||||
end if
|
||||
end sub
|
||||
|
||||
@ -194,19 +247,17 @@ sub createDialogPallete()
|
||||
}
|
||||
end sub
|
||||
|
||||
sub OnScreenShown()
|
||||
m.sectionScroller.focus = true
|
||||
|
||||
if m.sectionScroller.displayedIndex = 0
|
||||
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
|
||||
m.top.selectedButtonIndex = 0
|
||||
m.buttonGrp.setFocus(true)
|
||||
end if
|
||||
end sub
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
|
||||
if m.buttonGrp.isInFocusChain()
|
||||
if key = "OK"
|
||||
if press
|
||||
selectedButton = m.buttonGrp.getChild(m.top.selectedButtonIndex)
|
||||
selectedButton.selected = not selectedButton.selected
|
||||
return true
|
||||
end if
|
||||
end if
|
||||
|
||||
if key = "left"
|
||||
if m.top.selectedButtonIndex > 0
|
||||
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
|
||||
@ -241,11 +292,13 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
end if
|
||||
|
||||
if key = "down"
|
||||
selectedButton = m.buttonGrp.getChild(m.top.selectedButtonIndex)
|
||||
selectedButton.focus = false
|
||||
if m.sectionNavigation.getChildCount() > 1
|
||||
selectedButton = m.buttonGrp.getChild(m.top.selectedButtonIndex)
|
||||
selectedButton.focus = false
|
||||
|
||||
m.top.selectedButtonIndex = 0
|
||||
m.sectionNavigation.selected = m.sectionScroller.displayedIndex + 1
|
||||
m.top.selectedButtonIndex = 0
|
||||
m.sectionNavigation.selected = m.sectionScroller.displayedIndex + 1
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
|
@ -19,20 +19,27 @@
|
||||
</LayoutGroup>
|
||||
</Section>
|
||||
|
||||
<Section id="slide-2" translation="[0, 1050]" defaultFocusID="albums">
|
||||
<Section id="albumsSlide" translation="[0, 950]" defaultFocusID="albums">
|
||||
<Rectangle id='albumRect' translation="[0, 0]" width="1920" height="1080" color="#000000" opacity=".75" />
|
||||
<Label id="albumHeader" translation="[120, 50]" font="font:LargeSystemFont" />
|
||||
<AlbumGrid id="albums" translation="[120, 150]" vertFocusAnimationStyle="fixedFocus" basePosterSize="[300, 300]" numColumns="5" numRows="99" caption1NumLines="1" itemSpacing="[50, 50]" />
|
||||
</Section>
|
||||
|
||||
<Section id="appearsOnSlide" translation="[0, 1100]" defaultFocusID="appearsOn">
|
||||
<Rectangle id='appearsOnRect' translation="[0, 0]" width="1920" height="1080" color="#000000" opacity=".75" />
|
||||
<Label id="appearsOnHeader" translation="[120, 50]" font="font:LargeSystemFont" />
|
||||
<AlbumGrid id="appearsOn" translation="[120, 150]" vertFocusAnimationStyle="fixedFocus" basePosterSize="[300, 300]" numColumns="5" numRows="99" caption1NumLines="1" itemSpacing="[50, 50]" />
|
||||
</Section>
|
||||
|
||||
</SectionScroller>
|
||||
|
||||
<bgv_ButtonGroupVert id="sectionNavigation" translation="[-100, 175]" itemSpacings="[10]">
|
||||
<sob_SlideOutButton background="#070707" focusBackground="#00a4dc" highlightBackground="#555555" padding="20" icon="pkg:/images/icons/details.png" text="Details" height="50" width="60" />
|
||||
<sob_SlideOutButton background="#070707" focusBackground="#00a4dc" highlightBackground="#555555" padding="20" icon="pkg:/images/icons/cd.png" text="Albums" height="50" width="60" />
|
||||
<sob_SlideOutButton id="albumsLink" background="#070707" focusBackground="#00a4dc" highlightBackground="#555555" padding="20" icon="pkg:/images/icons/cd.png" text="Albums" height="50" width="60" />
|
||||
<sob_SlideOutButton id="appearsOnLink" background="#070707" focusBackground="#00a4dc" highlightBackground="#555555" padding="20" icon="pkg:/images/icons/cassette.png" text="Appears On" height="50" width="60" />
|
||||
</bgv_ButtonGroupVert>
|
||||
|
||||
<Animation id="pageLoad" duration=".5" repeat="false">
|
||||
<Vector2DFieldInterpolator key="[0.0, .5]" keyValue="[[0, 1050], [0, 750]]" fieldToInterp="slide-2.translation" />
|
||||
<Animation id="pageLoad" duration="1" repeat="false">
|
||||
<Vector2DFieldInterpolator key="[0.5, 1.0]" keyValue="[[-100, 175], [40, 175]]" fieldToInterp="sectionNavigation.translation" />
|
||||
</Animation>
|
||||
|
||||
@ -40,7 +47,10 @@
|
||||
<interface>
|
||||
<field id="pageContent" type="node" onChange="pageContentChanged" />
|
||||
<field id="musicArtistAlbumData" type="assocarray" alias="albums.MusicArtistAlbumData" />
|
||||
<field id="musicArtistAppearsOnData" type="assocarray" alias="appearsOn.MusicArtistAlbumData" />
|
||||
<field id="artistOverview" type="string" onChange="artistOverviewChanged" />
|
||||
<field id="musicAlbumSelected" alias="albums.itemSelected" />
|
||||
<field id="appearsOnSelected" alias="appearsOn.itemSelected" />
|
||||
<field id="playArtistSelected" alias="play.selected" />
|
||||
<field id="instantMixSelected" alias="instantMix.selected" />
|
||||
<field id="selectedButtonIndex" type="integer" value="-1" />
|
||||
|
@ -15,6 +15,16 @@ sub init()
|
||||
m.scrollOffBottomPosition = m.top.findNode("scrollOffBottomPosition")
|
||||
m.scrollOffBottomOpacity = m.top.findNode("scrollOffBottomOpacity")
|
||||
|
||||
m.scrollUpToOnDeckAnimation = m.top.findNode("scrollUpToOnDeckAnimation")
|
||||
m.scrollUpToOnDeckPosition = m.top.findNode("scrollUpToOnDeckPosition")
|
||||
|
||||
m.scrollDownToOnDeckAnimation = m.top.findNode("scrollDownToOnDeckAnimation")
|
||||
m.scrollDownToOnDeckPosition = m.top.findNode("scrollDownToOnDeckPosition")
|
||||
|
||||
m.scrollOffOnDeckAnimation = m.top.findNode("scrollOffOnDeckAnimation")
|
||||
m.scrollOffOnDeckPosition = m.top.findNode("scrollOffOnDeckPosition")
|
||||
|
||||
m.top.observeField("translation", "onTranslationChange")
|
||||
m.top.observeField("id", "onIDChange")
|
||||
m.top.observeField("focusedChild", "onFocusChange")
|
||||
end sub
|
||||
@ -31,6 +41,18 @@ sub onIDChange()
|
||||
|
||||
m.scrollOffBottomPosition.fieldToInterp = m.top.id + ".translation"
|
||||
m.scrollOffBottomOpacity.fieldToInterp = m.top.id + ".opacity"
|
||||
|
||||
m.scrollUpToOnDeckPosition.fieldToInterp = m.top.id + ".translation"
|
||||
|
||||
m.scrollDownToOnDeckPosition.fieldToInterp = m.top.id + ".translation"
|
||||
|
||||
m.scrollOffOnDeckPosition.fieldToInterp = m.top.id + ".translation"
|
||||
end sub
|
||||
|
||||
sub onTranslationChange()
|
||||
m.startingPosition = m.top.translation
|
||||
m.scrollOffBottomPosition.keyValue = "[[0, 0], [" + str(m.startingPosition[0]) + ", " + str(m.startingPosition[1]) + "]]"
|
||||
m.top.unobserveField("translation")
|
||||
end sub
|
||||
|
||||
sub showFromTop()
|
||||
@ -49,6 +71,18 @@ sub scrollOffTop()
|
||||
m.scrollOffTopAnimation.control = "start"
|
||||
end sub
|
||||
|
||||
sub scrollUpToOnDeck()
|
||||
m.scrollUpToOnDeckAnimation.control = "start"
|
||||
end sub
|
||||
|
||||
sub scrollDownToOnDeck()
|
||||
m.scrollDownToOnDeckAnimation.control = "start"
|
||||
end sub
|
||||
|
||||
sub scrollOffOnDeck()
|
||||
m.scrollOffOnDeckAnimation.control = "start"
|
||||
end sub
|
||||
|
||||
sub onFocusChange()
|
||||
defaultFocusElement = m.top.findNode(m.top.defaultFocusID)
|
||||
|
||||
|
@ -3,19 +3,28 @@
|
||||
<children>
|
||||
<Animation id="showFromBottomAnimation" duration="0.5" repeat="false">
|
||||
<Vector2DFieldInterpolator id="showFromBottomPosition" key="[0.0, 1.0]" keyValue="[[0, 750], [0, 0]]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="showFromBottomOpacity" key="[0.0, 1.0]" keyValue="[0.75, 0.95]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="showFromBottomOpacity" key="[0.0, 1.0]" keyValue="[0.55, 0.95]" fieldToInterp="" />
|
||||
</Animation>
|
||||
<Animation id="showFromTopAnimation" duration="0.5" repeat="false">
|
||||
<Vector2DFieldInterpolator id="showFromTopPosition" key="[0.0, 1.0]" keyValue="[[0, -1080], [0, 0]]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="showFromTopOpacity" key="[0.0, 1.0]" keyValue="[0.75, 0.95]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="showFromTopOpacity" key="[0.0, 1.0]" keyValue="[0.55, 0.95]" fieldToInterp="" />
|
||||
</Animation>
|
||||
<Animation id="scrollOffBottomAnimation" duration="0.5" repeat="false">
|
||||
<Vector2DFieldInterpolator id="scrollOffBottomPosition" key="[0.0, 1.0]" keyValue="[[0, 0], [0, 750]]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="scrollOffBottomOpacity" key="[0.0, 1.0]" keyValue="[0.95, 0.75]" fieldToInterp="" />
|
||||
<Vector2DFieldInterpolator id="scrollOffBottomPosition" key="[0.0, 1.0]" keyValue="[]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="scrollOffBottomOpacity" key="[0.0, 1.0]" keyValue="[0.95, 0.55]" fieldToInterp="" />
|
||||
</Animation>
|
||||
<Animation id="scrollOffTopAnimation" duration="0.5" repeat="false">
|
||||
<Vector2DFieldInterpolator id="scrollOffTopPosition" key="[0.0, 1.0]" keyValue="[[0, 0], [0, -1080]]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="scrollOffTopOpacity" key="[0.0, 1.0]" keyValue="[0.95, 0.75]" fieldToInterp="" />
|
||||
<FloatFieldInterpolator id="scrollOffTopOpacity" key="[0.0, 1.0]" keyValue="[0.95, 0.55]" fieldToInterp="" />
|
||||
</Animation>
|
||||
<Animation id="scrollUpToOnDeckAnimation" duration="0.5" repeat="false">
|
||||
<Vector2DFieldInterpolator id="scrollUpToOnDeckPosition" key="[0.0, 1.0]" keyValue="[[0, 1100], [0, 950]]" fieldToInterp="" />
|
||||
</Animation>
|
||||
<Animation id="scrollDownToOnDeckAnimation" duration="0.5" repeat="false">
|
||||
<Vector2DFieldInterpolator id="scrollDownToOnDeckPosition" key="[0.0, 1.0]" keyValue="[[0, 0], [0, 950]]" fieldToInterp="" />
|
||||
</Animation>
|
||||
<Animation id="scrollOffOnDeckAnimation" duration="0.5" repeat="false">
|
||||
<Vector2DFieldInterpolator id="scrollOffOnDeckPosition" key="[0.0, 1.0]" keyValue="[[0, 950], [0, 1080]]" fieldToInterp="" />
|
||||
</Animation>
|
||||
</children>
|
||||
<interface>
|
||||
@ -24,6 +33,9 @@
|
||||
<function name="showFromBottom" />
|
||||
<function name="scrollOffTop" />
|
||||
<function name="scrollOffBottom" />
|
||||
<function name="scrollUpToOnDeck" />
|
||||
<function name="scrollDownToOnDeck" />
|
||||
<function name="scrollOffOnDeck" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
<script type="text/brightscript" uri="section.brs" />
|
||||
|
@ -24,13 +24,34 @@ sub displayedIndexChanged()
|
||||
displayedSection = m.top.getChild(m.top.displayedIndex)
|
||||
displayedSection.setFocus(true)
|
||||
|
||||
onDeckSection = invalid
|
||||
previouslyOnDeckSection = invalid
|
||||
|
||||
if m.top.displayedIndex + 1 <= (m.top.getChildCount() - 1)
|
||||
onDeckSection = m.top.getChild(m.top.displayedIndex + 1)
|
||||
end if
|
||||
|
||||
if m.top.displayedIndex + 2 <= (m.top.getChildCount() - 1)
|
||||
previouslyOnDeckSection = m.top.getChild(m.top.displayedIndex + 2)
|
||||
end if
|
||||
|
||||
' Move sections either up or down depending on what index we're moving to
|
||||
if m.top.displayedIndex > m.previouslyDisplayedSection
|
||||
m.top.getChild(m.previouslyDisplayedSection).callFunc("scrollOffTop")
|
||||
for i = m.previouslyDisplayedSection to m.top.displayedIndex - 1
|
||||
m.top.getChild(i).callFunc("scrollOffTop")
|
||||
end for
|
||||
|
||||
displayedSection.callFunc("showFromBottom")
|
||||
if isValid(onDeckSection)
|
||||
onDeckSection.callFunc("scrollUpToOnDeck")
|
||||
end if
|
||||
else if m.top.displayedIndex < m.previouslyDisplayedSection
|
||||
m.top.getChild(m.previouslyDisplayedSection).callFunc("scrollOffBottom")
|
||||
m.top.getChild(m.top.displayedIndex + 1).callFunc("scrollDownToOnDeck")
|
||||
displayedSection.callFunc("showFromTop")
|
||||
|
||||
if isValid(previouslyOnDeckSection)
|
||||
previouslyOnDeckSection.callFunc("scrollOffOnDeck")
|
||||
end if
|
||||
end if
|
||||
|
||||
m.previouslyDisplayedSection = m.top.displayedIndex
|
||||
|
BIN
images/icons/album.png
Normal file
BIN
images/icons/album.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
BIN
images/icons/cassette.png
Normal file
BIN
images/icons/cassette.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
@ -188,6 +188,12 @@ sub Main (args as dynamic) as void
|
||||
albums = msg.getRoSGNode()
|
||||
node = albums.musicArtistAlbumData.items[ptr]
|
||||
group = CreateAlbumView(node)
|
||||
else if isNodeEvent(msg, "appearsOnSelected")
|
||||
' If you select a Music Album from ANYWHERE, follow this flow
|
||||
ptr = msg.getData()
|
||||
albums = msg.getRoSGNode()
|
||||
node = albums.musicArtistAppearsOnData.items[ptr]
|
||||
group = CreateAlbumView(node)
|
||||
else if isNodeEvent(msg, "playSong")
|
||||
' User has selected audio they want us to play
|
||||
selectedIndex = msg.getData()
|
||||
|
@ -377,9 +377,9 @@ end function
|
||||
' Shows details on selected artist. Bio, image, and list of available albums
|
||||
function CreateArtistView(musicartist)
|
||||
musicData = MusicAlbumList(musicartist.id)
|
||||
appearsOnData = AppearsOnList(musicartist.id)
|
||||
|
||||
' User only has songs under artists
|
||||
if musicData = invalid or musicData.Items.Count() = 0
|
||||
if (musicData = invalid or musicData.Items.Count() = 0) and (appearsOnData = invalid or appearsOnData.Items.Count() = 0)
|
||||
' Just songs under artists...
|
||||
group = CreateObject("roSGNode", "AlbumView")
|
||||
group.pageContent = ItemMetaData(musicartist.id)
|
||||
@ -392,9 +392,13 @@ function CreateArtistView(musicartist)
|
||||
group = CreateObject("roSGNode", "ArtistView")
|
||||
group.pageContent = ItemMetaData(musicartist.id)
|
||||
group.musicArtistAlbumData = musicData
|
||||
group.musicArtistAppearsOnData = appearsOnData
|
||||
group.artistOverview = ArtistOverview(musicartist.name)
|
||||
|
||||
group.observeField("musicAlbumSelected", m.port)
|
||||
group.observeField("playArtistSelected", m.port)
|
||||
group.observeField("instantMixSelected", m.port)
|
||||
group.observeField("appearsOnSelected", m.port)
|
||||
end if
|
||||
|
||||
m.global.sceneManager.callFunc("pushScene", group)
|
||||
@ -531,8 +535,6 @@ function CreateArtistMixGroup(artistID)
|
||||
songIDArray.push(song.id)
|
||||
end for
|
||||
|
||||
songIDArray.shift()
|
||||
|
||||
group.pageContent = songIDArray
|
||||
group.musicArtistAlbumData = songList.items
|
||||
|
||||
|
@ -78,7 +78,7 @@ function ItemMetaData(id as string)
|
||||
if data = invalid then return invalid
|
||||
imgParams = {}
|
||||
if data.type <> "Audio"
|
||||
if data.UserData.PlayedPercentage <> invalid
|
||||
if data?.UserData?.PlayedPercentage <> invalid
|
||||
param = { "PercentPlayed": data.UserData.PlayedPercentage }
|
||||
imgParams.Append(param)
|
||||
end if
|
||||
@ -163,21 +163,55 @@ function ItemMetaData(id as string)
|
||||
end if
|
||||
end function
|
||||
|
||||
' Music Artist Data
|
||||
function ArtistOverview(name as string)
|
||||
req = createObject("roUrlTransfer")
|
||||
url = Substitute("Artists/{0}", req.escape(name))
|
||||
resp = APIRequest(url)
|
||||
data = getJson(resp)
|
||||
if data = invalid then return invalid
|
||||
return data.overview
|
||||
end function
|
||||
|
||||
' Get list of albums belonging to an artist
|
||||
function MusicAlbumList(id as string)
|
||||
url = Substitute("Users/{0}/Items", get_setting("active_user"), id)
|
||||
url = Substitute("Users/{0}/Items", get_setting("active_user"))
|
||||
resp = APIRequest(url, {
|
||||
"UserId": get_setting("active_user"),
|
||||
"parentId": id,
|
||||
"AlbumArtistIds": id,
|
||||
"includeitemtypes": "MusicAlbum",
|
||||
"sortBy": "SortName"
|
||||
"sortBy": "SortName",
|
||||
"Recursive": true
|
||||
})
|
||||
|
||||
data = getJson(resp)
|
||||
results = []
|
||||
for each item in data.Items
|
||||
tmp = CreateObject("roSGNode", "MusicAlbumData")
|
||||
tmp.image = PosterImage(item.id, { "maxHeight": "500", "maxWidth": "500" })
|
||||
tmp.image = PosterImage(item.id)
|
||||
tmp.json = item
|
||||
results.push(tmp)
|
||||
end for
|
||||
data.Items = results
|
||||
return data
|
||||
end function
|
||||
|
||||
' Get list of albums an artist appears on
|
||||
function AppearsOnList(id as string)
|
||||
url = Substitute("Users/{0}/Items", get_setting("active_user"))
|
||||
resp = APIRequest(url, {
|
||||
"ContributingArtistIds": id,
|
||||
"ExcludeItemIds": id,
|
||||
"includeitemtypes": "MusicAlbum",
|
||||
"sortBy": "PremiereDate,ProductionYear,SortName",
|
||||
"SortOrder": "Descending",
|
||||
"Recursive": true
|
||||
})
|
||||
|
||||
data = getJson(resp)
|
||||
results = []
|
||||
for each item in data.Items
|
||||
tmp = CreateObject("roSGNode", "MusicAlbumData")
|
||||
tmp.image = PosterImage(item.id)
|
||||
tmp.json = item
|
||||
results.push(tmp)
|
||||
end for
|
||||
@ -232,15 +266,18 @@ end function
|
||||
|
||||
' Get Instant Mix based on item
|
||||
function CreateArtistMix(id as string)
|
||||
url = Substitute("Users/{0}/Items", get_setting("active_user"), id)
|
||||
url = Substitute("Users/{0}/Items", get_setting("active_user"))
|
||||
resp = APIRequest(url, {
|
||||
"UserId": get_setting("active_user"),
|
||||
"parentId": id,
|
||||
"Filters": "IsNotFolder",
|
||||
"Recursive": true,
|
||||
"SortBy": "SortName",
|
||||
"ArtistIds": id,
|
||||
"Recursive": "true",
|
||||
"MediaTypes": "Audio",
|
||||
"Limit": 300
|
||||
"Filters": "IsNotFolder",
|
||||
"SortBy": "SortName",
|
||||
"Limit": 300,
|
||||
"Fields": "Chapters",
|
||||
"ExcludeLocationTypes": "Virtual",
|
||||
"EnableTotalRecordCount": false,
|
||||
"CollapseBoxSetItems": false
|
||||
})
|
||||
|
||||
return getJson(resp)
|
||||
|
Loading…
Reference in New Issue
Block a user