Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix photo regression, add photo support to home screen, and add quickplay photo support #1494

Merged
merged 10 commits into from
Nov 15, 2023
16 changes: 10 additions & 6 deletions components/ItemGrid/ItemGrid.bs
Original file line number Diff line number Diff line change
Expand Up @@ -801,21 +801,25 @@ function onKeyEvent(key as string, press as boolean) as boolean
m.loadItemsTask.control = "stop"
return true
end if
else if key = "play"
else if key = "OK"
markupGrid = m.top.findNode("itemGrid")
itemToPlay = getItemFocused()

if itemToPlay <> invalid
m.top.quickPlayNode = itemToPlay
return true
else if itemToPlay <> invalid and itemToPlay.type = "Photo"
if itemToPlay <> invalid and itemToPlay.type = "Photo"
' Spawn photo player task
photoPlayer = CreateObject("roSgNode", "PhotoDetails")
photoPlayer.items = markupGrid
photoPlayer.itemsNode = markupGrid
photoPlayer.itemIndex = markupGrid.itemFocused
m.global.sceneManager.callfunc("pushScene", photoPlayer)
return true
end if
else if key = "play"
itemToPlay = getItemFocused()

if itemToPlay <> invalid
m.top.quickPlayNode = itemToPlay
return true
end if
else if key = "left" and topGrp.isinFocusChain()
m.top.alphaActive = true
topGrp.setFocus(false)
Expand Down
28 changes: 27 additions & 1 deletion components/data/HomeData.bs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ sub setData()
m.top.widePosterUrl = ImageURL(datum.Id, "Backdrop", imgParams)
end if

else if datum.type = "Movie" or datum.type = "Video"
else if datum.type = "Movie"
m.top.isWatched = datum.UserData.Played

imgParams = {}
Expand All @@ -96,6 +96,20 @@ sub setData()
imgParams["Tag"] = datum.BackdropImageTags[0]
m.top.thumbnailUrl = ImageURL(datum.id, "Backdrop", imgParams)
end if
else if datum.type = "Video"
m.top.isWatched = datum.UserData.Played

imgParams = {
"maxHeight": 261,
"maxWidth": 464
}

if datum.ImageTags <> invalid and datum.ImageTags.Primary <> invalid
imgParams.Append({ "Tag": datum.ImageTags.Primary })
end if

m.top.posterURL = ImageURL(datum.id, "Primary", imgParams)
m.top.thumbnailUrl = m.top.posterURL
else if datum.type = "MusicAlbum"
params = { "Tag": datum.ImageTags.Primary, "maxHeight": 261, "maxWidth": 261 }
m.top.thumbnailURL = ImageURL(datum.id, "Primary", params)
Expand All @@ -106,5 +120,17 @@ sub setData()
m.top.thumbnailURL = ImageURL(datum.id, "Primary", params)
m.top.widePosterUrl = m.top.thumbnailURL
m.top.iconUrl = "pkg:/images/media_type_icons/live_tv_white.png"
else if datum.type = "Photo"
params = { "Tag": datum.ImageTags.Primary, "maxHeight": 261, "maxWidth": 464 }

m.top.thumbnailURL = ImageURL(datum.id, "Primary", params)
m.top.widePosterUrl = m.top.thumbnailURL
m.top.posterUrl = m.top.thumbnailURL
else if datum.type = "PhotoAlbum"
params = { "Tag": datum.ImageTags.Primary, "maxHeight": 261, "maxWidth": 464 }

m.top.thumbnailURL = ImageURL(datum.id, "Primary", params)
m.top.widePosterUrl = m.top.thumbnailURL
m.top.posterUrl = m.top.thumbnailURL
end if
end sub
4 changes: 3 additions & 1 deletion components/home/Home.bs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ sub OnScreenShown()
m.top.setFocus(true)
end if

refresh()
if not m.isFirstRun
refresh()
end if

' post the device profile the first time this screen is loaded
if m.isFirstRun
Expand Down
34 changes: 34 additions & 0 deletions components/home/HomeItem.bs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ sub itemContentChanged()
m.itemText.maxWidth = itemData.imageWidth
m.itemTextExtra.width = itemData.imageWidth
m.itemTextExtra.visible = true
m.itemTextExtra.text = ""

m.backdrop.width = itemData.imageWidth

Expand Down Expand Up @@ -179,6 +180,7 @@ sub itemContentChanged()
else
m.itemPoster.uri = itemData.thumbnailURL
end if

return
end if

Expand Down Expand Up @@ -261,6 +263,38 @@ sub itemContentChanged()
return
end if

if itemData.type = "Photo"
m.itemText.text = itemData.name
m.itemPoster.uri = ImageURL(itemData.id)

' subtext
if isValidAndNotEmpty(itemData.json)
if isValid(itemData.json.ProductionYear)
m.itemTextExtra.text = itemData.json.ProductionYear.ToStr().trim()
end if
if isValidAndNotEmpty(itemData.json.Album)
if m.itemTextExtra.text = ""
m.itemTextExtra.text = tr("Album") + ": " + itemData.json.Album.trim()
else
m.itemTextExtra.text = m.itemTextExtra.text + " - " + tr("Album") + ": " + itemData.json.Album.trim()
end if
end if
end if
return
end if

if itemData.type = "PhotoAlbum"
m.itemText.text = itemData.name
m.itemPoster.uri = ImageURL(itemData.id)

' subtext
if isValid(itemData.json.ChildCount)
m.itemTextExtra.text = itemData.json.ChildCount.ToStr().trim() + " items"
end if

return
end if

m.log.warn("Unhandled Home Item Type", itemData.type)
end sub

Expand Down
7 changes: 0 additions & 7 deletions components/home/HomeRows.bs
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,6 @@ end sub

' Update home row data
sub updateHomeRows()
if m.global.playstateTask.state = "run"
m.global.playstateTask.observeField("state", "updateHomeRows")
return
end if

m.global.playstateTask.unobserveField("state")

' If resume section exists, reload row's data
if m.homeSectionIndexes.doesExist("resume")
m.LoadContinueWatchingTask.observeField("content", "updateContinueWatchingItems")
Expand Down
20 changes: 14 additions & 6 deletions components/photos/LoadPhotoTask.bs
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import "pkg:/source/api/Image.bs"
import "pkg:/source/utils/config.bs"
import "pkg:/source/api/baserequest.bs"
import "pkg:/source/utils/misc.bs"

sub init()
m.top.functionName = "loadItems"
end sub

sub loadItems()
item = m.top.itemContent
if item <> invalid
params = {
maxHeight: 1080,
maxWidth: 1920
}
params = {
maxHeight: 1080,
maxWidth: 1920
}

if isValid(m.top.itemNodeContent)
item = m.top.itemNodeContent
m.top.results = ImageURL(item.Id, "Primary", params)
else if isValid(m.top.itemArrayContent)
item = m.top.itemArrayContent
m.top.results = ImageURL(item.Id, "Primary", params)
else
m.top.results = invalid
end if



end sub
3 changes: 2 additions & 1 deletion components/photos/LoadPhotoTask.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

<component name="LoadPhotoTask" extends="Task">
<interface>
<field id="itemContent" type="node" />
<field id="itemNodeContent" type="node" />
<field id="itemArrayContent" type="assocarray" />
<field id="results" type="string" />
</interface>
</component>
62 changes: 56 additions & 6 deletions components/photos/PhotoDetails.bs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,19 @@ end sub
sub itemContentChanged()
if isValidToContinue(m.top.itemIndex)
m.LoadLibrariesTask = createObject("roSGNode", "LoadPhotoTask")
itemContent = m.top.items.content.getChild(m.top.itemIndex)
m.LoadLibrariesTask.itemContent = itemContent
if isValid(m.top.itemsNode)
if isValid(m.top.itemsNode.content)
m.LoadLibrariesTask.itemNodeContent = m.top.itemsNode.content.getChild(m.top.itemIndex)
else if isValidAndNotEmpty(m.top.itemsNode.id)
m.LoadLibrariesTask.itemNodeContent = m.top.itemsNode
end if
else if isValid(m.top.itemsArray)
itemContent = m.top.itemsArray[m.top.itemIndex]
m.LoadLibrariesTask.itemArrayContent = itemContent
else
return
end if

m.LoadLibrariesTask.observeField("results", "onPhotoLoaded")
m.LoadLibrariesTask.control = "RUN"
end if
Expand Down Expand Up @@ -53,8 +64,22 @@ sub nextSlide()
m.slideshowTimer.control = "start"
end if
else if m.random = true
index = rnd(m.top.items.content.getChildCount() - 1)
if isValidToContinue(index)
index = invalid

if isValid(m.top.itemsNode)
if isValidAndNotEmpty(m.top.itemsNode.content)
index = rnd(m.top.itemsNode.content.getChildCount() - 1)
else
' we're dealing with a single photo
return
end if
else if isValid(m.top.itemsArray)
if m.top.itemsArray.count() > 0
index = rnd(m.top.itemsArray.count() - 1)
end if
end if

if isValid(index) and isValidToContinue(index)
m.top.itemIndex = index
m.slideshowTimer.control = "start"
end if
Expand All @@ -66,6 +91,23 @@ sub statusUpdate()
m.hideStatusAnimation.control = "start"
end sub

' JFScreen hook.
' Used to ensure tasks are stopped
sub OnScreenHidden()
m.slideshowTimer.control = "stop"
m.statusTimer.control = "stop"
end sub

' isSlideshow component field has changed
sub isSlideshowChanged()
m.slideshow = m.top.isSlideshow
end sub

' isRandom component field has changed
sub isRandomChanged()
m.random = m.top.isRandom
end sub

function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false

Expand Down Expand Up @@ -116,8 +158,16 @@ function onKeyEvent(key as string, press as boolean) as boolean
end function

function isValidToContinue(index as integer)
if isValid(m.top.items) and isValid(m.top.items.content)
if index >= 0 and index < m.top.items.content.getChildCount()
if isValid(m.top.itemsNode)
if isValidAndNotEmpty(m.top.itemsNode.content)
if index >= 0 and index < m.top.itemsNode.content.getChildCount()
return true
end if
else if isValidAndNotEmpty(m.top.itemsNode) and index = 0
return true
end if
else if isValidAndNotEmpty(m.top.itemsArray)
if index >= 0 and index < m.top.itemsArray.count()
return true
end if
end if
Expand Down
7 changes: 5 additions & 2 deletions components/photos/PhotoDetails.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<component name="PhotoDetails" extends="JFGroup">
<component name="PhotoDetails" extends="JFScreen">
<children>
<Poster id="photo" width="1920" height="1080" loadDisplayMode="scaleToFit" />
<Rectangle id="background" color="0x101010EE" height="120" width="500" Translation="[700, -150]" opacity="0">
Expand All @@ -19,7 +19,10 @@

</children>
<interface>
<field id="items" type="node" />
<field id="itemsNode" type="node" />
<field id="itemsArray" type="roArray" />
<field id="isSlideshow" type="bool" onChange="isSlideshowChanged" />
<field id="isRandom" type="bool" onChange="isRandomChanged" />
<field id="itemIndex" type="integer" value="-1" onChange="itemContentChanged" />
</interface>
</component>
30 changes: 29 additions & 1 deletion source/Main.bs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ sub Main (args as dynamic) as void
quickplay.tvChannel(itemNode)
else if itemType = "program"
quickplay.program(itemNode)
else if itemType = "photo"
quickplay.photo(itemNode)
else if itemType = "photoalbum"
quickplay.photoAlbum(itemNode)
end if

m.global.queueManager.callFunc("playQueue")
Expand Down Expand Up @@ -293,7 +297,31 @@ sub Main (args as dynamic) as void
end if

else if selectedItemType = "Photo"
' Nothing to do here, handled in ItemGrid
' only handle selection if it's from the home screen
if selectedItem.isSubType("HomeData")
print "a photo was selected from the home screen"
print "selectedItem=", selectedItem

quickplay.photo(selectedItem)
end if
else if selectedItemType = "PhotoAlbum"
print "a photo album was selected"
print "selectedItem=", selectedItem

' grab all photos inside photo album
photoAlbumData = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": selectedItem.id,
"includeItemTypes": "Photo",
"Recursive": true
})
print "photoAlbumData=", photoAlbumData

if isValid(photoAlbumData) and isValidAndNotEmpty(photoAlbumData.items)
photoPlayer = CreateObject("roSgNode", "PhotoDetails")
photoPlayer.itemsArray = photoAlbumData.items
photoPlayer.itemIndex = 0
m.global.sceneManager.callfunc("pushScene", photoPlayer)
end if
else if selectedItemType = "MusicArtist"
group = CreateArtistView(selectedItem.json)
if not isValid(group)
Expand Down
3 changes: 3 additions & 0 deletions source/utils/misc.bs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ function isValidAndNotEmpty(input as dynamic) as boolean
if inputType = "string" or inputType = "rostring"
trimmedInput = input.trim()
return trimmedInput <> ""
else if inputType = "rosgnode"
inputId = input.id
return inputId <> invalid
else if countableTypes.doesExist(inputType)
return input.count() > 0
else
Expand Down
Loading