Merge pull request #1515 from cewert/add-more-loading-spinners

Convert app to use one spinner attached to JFScene + resize spinner
This commit is contained in:
1hitsong 2023-11-29 20:21:53 -05:00 committed by GitHub
commit 39448b7ceb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 172 additions and 131 deletions

View File

@ -64,9 +64,6 @@ sub init()
'set inital counts for overhang before content is loaded.
m.loadItemsTask.totalRecordCount = 0
m.spinner = m.top.findNode("spinner")
m.spinner.visible = true
m.Alpha = m.top.findNode("AlphaMenu")
m.AlphaSelected = m.top.findNode("AlphaSelected")
@ -92,7 +89,7 @@ end sub
'Load initial set of Data
sub loadInitialItems()
m.loadItemsTask.control = "stop"
m.spinner.visible = true
startLoadingSpinner()
if m.top.parentItem.json.Type = "CollectionFolder" 'or m.top.parentItem.json.Type = "Folder"
m.top.HomeLibraryItem = m.top.parentItem.Id
@ -238,7 +235,7 @@ sub loadInitialItems()
end if
m.loadItemsTask.observeField("content", "ItemDataLoaded")
m.spinner.visible = true
startLoadingSpinner(false)
m.loadItemsTask.control = "RUN"
SetUpOptions()
end sub
@ -450,6 +447,7 @@ end sub
'
'Handle loaded data, and add to Grid
sub ItemDataLoaded(msg)
stopLoadingSpinner()
m.top.alphaActive = false
itemData = msg.GetData()
m.loadItemsTask.unobserveField("content")
@ -475,7 +473,7 @@ sub ItemDataLoaded(msg)
m.genreList.setFocus(true)
m.loading = false
m.spinner.visible = false
stopLoadingSpinner()
return
end if
@ -498,7 +496,7 @@ sub ItemDataLoaded(msg)
m.itemGrid.setFocus(true)
m.genreList.setFocus(false)
m.spinner.visible = false
stopLoadingSpinner()
end sub
'
@ -571,7 +569,7 @@ end sub
'
'Load next set of items
sub loadMoreData()
m.spinner.visible = true
startLoadingSpinner(false)
if m.Loading = true then return
m.Loading = true
m.loadItemsTask.startIndex = m.loadedItems
@ -594,7 +592,7 @@ sub onItemalphaSelected()
m.loadItemsTask.searchTerm = ""
m.VoiceBox.text = ""
m.loadItemsTask.nameStartsWith = m.alpha.itemAlphaSelected
m.spinner.visible = true
startLoadingSpinner(false)
loadInitialItems()
end if
end sub
@ -609,7 +607,7 @@ sub onvoiceFilter()
m.loadItemsTask.NameStartsWith = " "
m.loadItemsTask.searchTerm = m.voiceBox.text
m.loadItemsTask.recursive = true
m.spinner.visible = true
startLoadingSpinner(false)
loadInitialItems()
end if
end sub
@ -845,7 +843,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
end if
if key = "replay"
m.spinner.visible = true
m.loadItemsTask.searchTerm = ""
m.loadItemsTask.nameStartsWith = ""
m.voiceBox.text = ""

View File

@ -22,7 +22,6 @@
<Button id="micButton" maxWidth="20" translation="[20, 120]" iconUri="pkg:/images/icons/mic_icon.png" />
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1910" horizAlign="center" vertAlign="center" height="64" visible="false" />
<ItemGridOptions id="options" visible="false" />
<Spinner id="spinner" translation="[900, 450]" />
<Animation id="backroundSwapAnimation" duration="1" repeat="false" easeFunction="linear">
<FloatFieldInterpolator id="fadeinLoading" key="[0.0, 1.0]" keyValue="[ 0.00, 0.25 ]" fieldToInterp="backdropTransition.opacity" />
<FloatFieldInterpolator id="fadeoutLoaded" key="[0.0, 1.0]" keyValue="[ 0.25, 0.00 ]" fieldToInterp="backdrop.opacity" />

View File

@ -17,7 +17,6 @@ sub setupNodes()
m.selectedMovieOfficialRating = m.top.findNode("selectedMovieOfficialRating")
m.movieLogo = m.top.findNode("movieLogo")
m.swapAnimation = m.top.findNode("backroundSwapAnimation")
m.spinner = m.top.findNode("spinner")
m.Alpha = m.top.findNode("AlphaMenu")
m.AlphaSelected = m.top.findNode("AlphaSelected")
m.micButton = m.top.findNode("micButton")
@ -83,8 +82,6 @@ sub init()
'set inital counts for overhang before content is loaded.
m.loadItemsTask.totalRecordCount = 0
m.spinner.visible = true
'Get reset folder setting
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
@ -117,7 +114,7 @@ end sub
'Load initial set of Data
sub loadInitialItems()
m.loadItemsTask.control = "stop"
m.spinner.visible = true
startLoadingSpinner(false)
if m.top.parentItem.json.Type = "CollectionFolder"
m.top.HomeLibraryItem = m.top.parentItem.Id
@ -219,7 +216,6 @@ sub loadInitialItems()
end if
m.loadItemsTask.observeField("content", "ItemDataLoaded")
m.spinner.visible = true
m.loadItemsTask.control = "RUN"
m.getFiltersTask.observeField("filters", "FilterDataLoaded")
@ -436,7 +432,7 @@ sub ItemDataLoaded(msg)
m.genreList.setFocus(true)
m.loading = false
m.spinner.visible = false
stopLoadingSpinner()
' Return focus to options menu if it was opened while library was loading
if m.options.visible
m.options.setFocus(true)
@ -486,7 +482,7 @@ sub ItemDataLoaded(msg)
m.emptyText.visible = true
end if
m.spinner.visible = false
stopLoadingSpinner()
' Return focus to options menu if it was opened while library was loading
if m.options.visible
m.options.setFocus(true)
@ -691,7 +687,7 @@ end sub
'
'Load next set of items
sub loadMoreData()
m.spinner.visible = true
startLoadingSpinner(false)
if m.Loading = true then return
m.Loading = true
m.loadItemsTask.startIndex = m.loadedItems
@ -736,7 +732,6 @@ sub onItemalphaSelected()
m.loadItemsTask.searchTerm = ""
m.VoiceBox.text = ""
m.loadItemsTask.nameStartsWith = m.alpha.itemAlphaSelected
m.spinner.visible = true
loadInitialItems()
end if
end sub
@ -751,7 +746,6 @@ sub onvoiceFilter()
m.loadItemsTask.NameStartsWith = " "
m.loadItemsTask.searchTerm = m.voiceBox.text
m.loadItemsTask.recursive = true
m.spinner.visible = true
loadInitialItems()
end if
end sub
@ -924,7 +918,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
end if
if key = "replay"
m.spinner.visible = true
m.loadItemsTask.searchTerm = ""
m.loadItemsTask.nameStartsWith = ""
m.voiceBox.text = ""

View File

@ -39,7 +39,6 @@
<Button id="micButton" maxWidth="20" translation="[20, 120]" iconUri="pkg:/images/icons/mic_icon.png" />
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1910" horizAlign="center" vertAlign="center" height="64" visible="false" />
<ItemGridOptions id="options" visible="false" />
<Spinner id="spinner" translation="[900, 450]" />
<Animation id="backroundSwapAnimation" duration="1" repeat="false" easeFunction="linear">
<FloatFieldInterpolator id="fadeinLoading" key="[0.0, 1.0]" keyValue="[ 0.00, 1.00 ]" fieldToInterp="backdropTransition.opacity" />
<FloatFieldInterpolator id="fadeoutLoaded" key="[0.0, 1.0]" keyValue="[ 1.00, 0.00 ]" fieldToInterp="backdrop.opacity" />

View File

@ -17,7 +17,6 @@ sub setupNodes()
m.selectedArtistGenres = m.top.findNode("selectedArtistGenres")
m.artistLogo = m.top.findNode("artistLogo")
m.swapAnimation = m.top.findNode("backroundSwapAnimation")
m.spinner = m.top.findNode("spinner")
m.Alpha = m.top.findNode("AlphaMenu")
m.AlphaSelected = m.top.findNode("AlphaSelected")
m.micButton = m.top.findNode("micButton")
@ -77,8 +76,6 @@ sub init()
'set inital counts for overhang before content is loaded.
m.loadItemsTask.totalRecordCount = 0
m.spinner.visible = true
'Get reset folder setting
m.resetGrid = m.global.session.user.settings["itemgrid.reset"]
@ -111,7 +108,7 @@ end sub
'Load initial set of Data
sub loadInitialItems()
m.loadItemsTask.control = "stop"
m.spinner.visible = true
startLoadingSpinner()
if LCase(m.top.parentItem.json.Type) = "collectionfolder"
m.top.HomeLibraryItem = m.top.parentItem.Id
@ -204,7 +201,6 @@ sub loadInitialItems()
end if
m.loadItemsTask.observeField("content", "ItemDataLoaded")
m.spinner.visible = true
m.loadItemsTask.control = "RUN"
SetUpOptions()
end sub
@ -326,6 +322,7 @@ end sub
'
'Handle loaded data, and add to Grid
sub ItemDataLoaded(msg)
stopLoadingSpinner()
m.top.alphaActive = false
itemData = msg.GetData()
m.loadItemsTask.unobserveField("content")
@ -351,7 +348,6 @@ sub ItemDataLoaded(msg)
m.loadedRows = m.loadedItems / m.genreList.numColumns
m.loading = false
m.spinner.visible = false
return
end if
@ -374,8 +370,6 @@ sub ItemDataLoaded(msg)
m.emptyText.text = tr("NO_ITEMS").Replace("%1", m.top.parentItem.Type)
m.emptyText.visible = true
end if
m.spinner.visible = false
end sub
'
@ -556,7 +550,7 @@ end sub
'
'Load next set of items
sub loadMoreData()
m.spinner.visible = true
startLoadingSpinner(false)
if m.Loading = true then return
m.Loading = true
m.loadItemsTask.startIndex = m.loadedItems
@ -612,7 +606,6 @@ sub onItemalphaSelected()
m.loadItemsTask.searchTerm = ""
m.VoiceBox.text = ""
m.loadItemsTask.nameStartsWith = m.alpha.itemAlphaSelected
m.spinner.visible = true
loadInitialItems()
end if
end sub
@ -627,7 +620,6 @@ sub onvoiceFilter()
m.loadItemsTask.NameStartsWith = " "
m.loadItemsTask.searchTerm = m.voiceBox.text
m.loadItemsTask.recursive = true
m.spinner.visible = true
loadInitialItems()
end if
end sub
@ -787,7 +779,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
end if
if key = "replay"
m.spinner.visible = true
m.loadItemsTask.searchTerm = ""
m.loadItemsTask.nameStartsWith = ""
m.voiceBox.text = ""

View File

@ -24,7 +24,6 @@
<Button id="micButton" maxWidth="20" translation="[20, 120]" iconUri="pkg:/images/icons/mic_icon.png" />
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1910" horizAlign="center" vertAlign="center" height="64" visible="false" />
<ItemGridOptions id="options" visible="false" />
<Spinner id="spinner" translation="[900, 450]" />
<Animation id="backroundSwapAnimation" duration="1" repeat="false" easeFunction="linear">
<FloatFieldInterpolator id="fadeinLoading" key="[0.0, 1.0]" keyValue="[ 0.00, 1.00 ]" fieldToInterp="backdropTransition.opacity" />
<FloatFieldInterpolator id="fadeoutLoaded" key="[0.0, 1.0]" keyValue="[ 1.00, 0.00 ]" fieldToInterp="backdrop.opacity" />

View File

@ -3,6 +3,27 @@ import "pkg:/source/utils/misc.bs"
sub init()
m.top.backgroundColor = "#262626" '"#101010"
m.top.backgroundURI = ""
m.spinner = m.top.findNode("spinner")
end sub
' Triggered when the isLoading boolean component field is changed
sub isLoadingChanged()
m.spinner.visible = m.top.isLoading
end sub
' Triggered when the disableRemote boolean component field is changed
sub disableRemoteChanged()
if m.top.disableRemote
dialog = createObject("roSGNode", "ProgressDialog")
dialog.id = "invisibiledialog"
dialog.visible = false
dialog.opacity = 0
m.top.dialog = dialog
else
if isValid(m.top.dialog)
m.top.dialog.close = true
end if
end if
end sub
function onKeyEvent(key as string, press as boolean) as boolean

View File

@ -3,8 +3,11 @@
<children>
<Group id="content" />
<JFOverhang id="overhang" />
<Spinner id="spinner" translation="[897, 477]" visible="false" />
</children>
<interface>
<field id="disableRemote" type="boolean" value="false" onchange="disableRemoteChanged" />
<field id="isLoading" type="boolean" value="false" onchange="isLoadingChanged" />
<field id="exit" type="boolean" alwaysNotify="true" />
</interface>
</component>

View File

@ -2,5 +2,5 @@ sub init()
m.top.poster.uri = "pkg:/images/spinner.png"
m.top.control = "start"
m.top.clockwise = true
m.top.spinInterval = 3
m.top.spinInterval = 1
end sub

View File

@ -5,7 +5,6 @@ sub init()
m.log = log.Logger("SetServerScreen")
m.top.setFocus(true)
m.spinner = m.top.findNode("spinner")
m.serverPicker = m.top.findNode("serverPicker")
m.serverUrlTextbox = m.top.findNode("serverUrlTextbox")
m.serverUrlContainer = m.top.findNode("serverUrlContainer")
@ -76,7 +75,7 @@ sub ScanForServers()
'run the task
m.ssdpScanner.observeField("content", "ScanForServersComplete")
m.ssdpScanner.control = "RUN"
m.spinner.visible = true
startLoadingSpinner(false)
end sub
sub ScanForServersComplete(event)
@ -109,7 +108,7 @@ sub ScanForServersComplete(event)
end if
m.serverPicker.content = items
m.spinner.visible = false
stopLoadingSpinner()
'if we have at least one server, focus on the server picker
if m.servers.Count() > 0

View File

@ -15,7 +15,6 @@
</LayoutGroup>
<!--background for server picker-->
<Rectangle color="0x00000020" width="1620" height="400">
<Spinner id="spinner" translation="[717, 136]" />
<MarkupList id="serverPicker" translation="[50, 20]" itemComponentName="JFServer" itemSpacing="[0, 10]" itemSize="[1520, 100]" numRows="3" vertFocusAnimationStyle="floatingFocus" />
</Rectangle>

View File

@ -1,3 +1,5 @@
import "pkg:/source/utils/misc.bs"
sub init()
m.EPGLaunchCompleteSignaled = false
m.scheduleGrid = m.top.findNode("scheduleGrid")
@ -26,8 +28,6 @@ sub init()
m.top.lastFocus = m.scheduleGrid
m.channelIndex = {}
m.spinner = m.top.findNode("spinner")
end sub
sub channelFilterSet()
@ -48,14 +48,14 @@ sub channelsearchTermSet()
if LCase(m.top.searchTerm) = LCase(tr("all")) or m.LoadChannelsTask.searchTerm = LCase(tr("all"))
m.top.searchTerm = " "
m.LoadChannelsTask.searchTerm = " "
m.spinner.visible = true
startLoadingSpinner()
m.LoadChannelsTask.control = "RUN"
'filter if the searterm is not invalid
else if m.top.searchTerm <> invalid and LCase(m.LoadChannelsTask.searchTerm) <> LCase(m.top.searchTerm)
if m.LoadChannelsTask.state = "run" then m.LoadChannelsTask.control = "stop"
m.LoadChannelsTask.searchTerm = m.top.searchTerm
m.spinner.visible = true
startLoadingSpinner()
m.LoadChannelsTask.control = "RUN"
end if
@ -125,7 +125,7 @@ sub onScheduleLoaded()
m.scheduleGrid.showLoadingDataFeedback = false
m.scheduleGrid.setFocus(true)
m.LoadScheduleTask.schedule = []
m.spinner.visible = false
stopLoadingSpinner()
end sub
sub onProgramFocused()

View File

@ -12,7 +12,6 @@
programTitleFocusedColor="#ffffff" iconFocusedColor="#ff0000"
showPastTimeScreen="true" pastTimeScreenBlendColor="#555555"
/>
<Spinner id="spinner" translation="[900, 450]" />
<Animation id="gridMoveAnimation" duration="1" repeat="false" easeFunction="outQuad">
<Vector2DFieldInterpolator id="gridMoveAnimationPosition" key="[0.0, 0.5]" fieldToInterp="scheduleGrid.translation" />
</Animation>

View File

@ -1,8 +1,11 @@
import "pkg:/source/utils/misc.bs"
sub init()
m.top.optionsAvailable = false
end sub
sub itemContentChanged()
stopLoadingSpinner()
m.top.findNode("UserRow").ItemContent = m.top.itemContent
redraw()
end sub

View File

@ -21,8 +21,6 @@ sub init()
m.buttonGrp.setFocus(true)
m.top.lastFocus = m.buttonGrp
m.spinner = m.top.findNode("spinner")
m.top.observeField("itemContent", "itemContentChanged")
end sub
@ -150,7 +148,7 @@ sub itemContentChanged()
SetUpVideoOptions(itemData.mediaSources)
SetUpAudioOptions(itemData.mediaStreams)
m.buttonGrp.visible = true
m.spinner.visible = false
stopLoadingSpinner()
end sub

View File

@ -40,7 +40,6 @@
</LayoutGroup>
</LayoutGroup>
<MovieOptions id="movieOptions" visible="false" />
<Spinner id="spinner" translation="[900, 450]" visible="true" />
<!-- "Cast and Crew" row -->
<extrasSlider id="movieExtras" />

View File

@ -12,8 +12,6 @@ sub init()
m.songListRect = m.top.FindNode("songListRect")
m.songList.observeField("doneLoading", "onDoneLoading")
m.spinner = m.top.findNode("spinner")
m.spinner.visible = true
m.dscr = m.top.findNode("overview")
createDialogPallete()
@ -99,8 +97,6 @@ end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if m.spinner.visible then return false
if key = "options"
if m.dscr.isTextEllipsized
createFullDscrDlg()
@ -169,9 +165,5 @@ end sub
sub onDoneLoading()
m.songList.unobservefield("doneLoading")
m.spinner.visible = false
end sub
sub OnScreenHidden()
m.spinner.visible = false
stopLoadingSpinner()
end sub

View File

@ -20,7 +20,6 @@
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
<Spinner id="spinner" translation="[920, 540]" visible="false" />
</children>
<interface>
<field id="pageContent" type="node" onChange="pageContentChanged" />

View File

@ -76,6 +76,7 @@ sub OnScreenShown()
m.overhang.isVisible = false
m.overhang.opacity = "1"
end if
stopLoadingSpinner()
end sub
sub OnScreenHidden()

View File

@ -447,6 +447,7 @@ sub loadButtons()
end sub
sub onAudioStreamLoaded()
stopLoadingSpinner()
data = m.LoadAudioStreamTask.content[0]
m.LoadAudioStreamTask.unobserveField("content")
if data <> invalid and data.count() > 0

View File

@ -11,8 +11,6 @@ sub init()
m.songListRect = m.top.FindNode("songListRect")
m.songList.observeField("doneLoading", "onDoneLoading")
m.spinner = m.top.findNode("spinner")
m.spinner.visible = true
m.dscr = m.top.findNode("overview")
createDialogPallete()
@ -98,8 +96,6 @@ end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if m.spinner.visible then return false
if key = "options"
if m.dscr.isTextEllipsized
createFullDscrDlg()
@ -160,9 +156,5 @@ end sub
sub onDoneLoading()
m.songList.unobservefield("doneLoading")
m.spinner.visible = false
end sub
sub OnScreenHidden()
m.spinner.visible = false
stopLoadingSpinner()
end sub

View File

@ -19,7 +19,6 @@
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
<Spinner id="spinner" translation="[920, 540]" visible="false" />
</children>
<interface>
<field id="pageContent" type="node" onChange="pageContentChanged" />

View File

@ -41,6 +41,7 @@ sub itemContentChanged()
end sub
sub onPhotoLoaded()
stopLoadingSpinner()
if m.LoadLibrariesTask.results <> invalid
photo = m.top.findNode("photo")
photo.uri = m.LoadLibrariesTask.results

View File

@ -6,7 +6,6 @@ import "pkg:/source/utils/deviceCapabilities.bs"
sub init()
m.top.optionsAvailable = false
m.searchSpinner = m.top.findnode("searchSpinner")
m.searchSelect = m.top.findnode("searchSelect")
m.searchTask = CreateObject("roSGNode", "SearchTask")
@ -20,12 +19,12 @@ sub searchMedias()
query = m.top.searchAlpha
'if user deletes the search string hide the spinner
if query.len() = 0
m.searchSpinner.visible = false
stopLoadingSpinner()
end if
'if search task is running and user selectes another letter stop the search and load the next letter
m.searchTask.control = "stop"
if query <> invalid and query <> ""
m.searchSpinner.visible = true
startLoadingSpinner(false)
end if
m.searchTask.observeField("results", "loadResults")
m.searchTask.query = query
@ -37,7 +36,7 @@ end sub
sub loadResults()
m.searchTask.unobserveField("results")
m.searchSpinner.visible = false
stopLoadingSpinner()
m.searchSelect.itemdata = m.searchTask.results
m.searchSelect.query = m.top.SearchAlpha
m.searchHelpText.visible = false

View File

@ -10,7 +10,6 @@
<SearchRow id="searchSelect" visible="true" focusable="true" />
</LayoutGroup>
<OptionsSlider id="options" />
<Spinner id="searchSpinner" visible="false" translation="[1050, 500]" />
</children>
<interface>
<field id="query" type="string" alwaysNotify="true" />

View File

@ -297,6 +297,8 @@ sub onVideoContentLoaded()
videoContent = m.LoadMetaDataTask.content
m.LoadMetaDataTask.content = []
stopLoadingSpinner()
' If we have nothing to play, return to previous screen
if not isValid(videoContent)
showPlaybackErrorDialog(tr("There was an error retrieving the data for this item from the server."))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -48,12 +48,11 @@ sub Main (args as dynamic) as void
' remove login scenes from the stack
sceneManager.callFunc("clearScenes")
stopLoadingSpinner()
' load home page
sceneManager.currentUser = m.global.session.user.name
group = CreateHomeGroup()
group.callFunc("loadLibraries")
stopLoadingSpinner()
sceneManager.callFunc("pushScene", group)
m.scene.observeField("exit", m.port)
@ -129,8 +128,6 @@ sub Main (args as dynamic) as void
' measure processing time
timeSpan = CreateObject("roTimespan")
startMediaLoadingSpinner()
group = sceneManager.callFunc("getActiveScene")
reportingNode = msg.getRoSGNode()
itemNode = invalid
@ -162,6 +159,7 @@ sub Main (args as dynamic) as void
' can't play the item without knowing what type it is
if isValid(itemType)
startLoadingSpinner()
m.global.queueManager.callFunc("clear") ' empty queue/playlist
m.global.queueManager.callFunc("resetShuffle") ' turn shuffle off
@ -206,20 +204,18 @@ sub Main (args as dynamic) as void
else if itemType = "photoalbum"
quickplay.photoAlbum(itemNode)
end if
m.global.queueManager.callFunc("playQueue")
end if
end if
stopLoadingSpinner()
elapsed = timeSpan.TotalMilliseconds() / 1000
print "Quick Play finished loading in " + elapsed.toStr() + " seconds."
else if isNodeEvent(msg, "selectedItem")
' If you select a library from ANYWHERE, follow this flow
selectedItem = msg.getData()
if isValid(selectedItem)
startLoadingSpinner()
selectedItemType = selectedItem.type
if selectedItemType = "CollectionFolder"
if selectedItem.collectionType = "movies"
group = CreateMovieLibraryView(selectedItem)
@ -251,7 +247,6 @@ sub Main (args as dynamic) as void
end if
selectedItem.selectedAudioStreamIndex = audio_stream_idx
' Display playback options dialog
if selectedItem.json.userdata.PlaybackPositionTicks > 0
m.global.queueManager.callFunc("hold", selectedItem)
@ -273,7 +268,6 @@ sub Main (args as dynamic) as void
CreatePersonView(selectedItem)
else if selectedItemType = "TvChannel" or selectedItemType = "Video" or selectedItemType = "Program"
' User selected a Live TV channel / program
' Show Channel Loading spinner
dialog = createObject("roSGNode", "ProgressDialog")
dialog.title = tr("Loading Channel Data")
@ -325,6 +319,7 @@ sub Main (args as dynamic) as void
else if selectedItemType = "MusicArtist"
group = CreateArtistView(selectedItem.json)
if not isValid(group)
stopLoadingSpinner()
message_dialog(tr("Unable to find any albums or songs belonging to this artist"))
end if
else if selectedItemType = "MusicAlbum"
@ -340,19 +335,23 @@ sub Main (args as dynamic) as void
m.global.queueManager.callFunc("playQueue")
else
' TODO - switch on more node types
stopLoadingSpinner()
message_dialog("This type is not yet supported: " + selectedItemType + ".")
end if
end if
else if isNodeEvent(msg, "movieSelected")
' If you select a movie from ANYWHERE, follow this flow
startLoadingSpinner()
node = getMsgPicker(msg, "picker")
group = CreateMovieDetailsGroup(node)
else if isNodeEvent(msg, "seriesSelected")
' If you select a TV Series from ANYWHERE, follow this flow
startLoadingSpinner()
node = getMsgPicker(msg, "picker")
group = CreateSeriesDetailsGroup(node.id)
else if isNodeEvent(msg, "seasonSelected")
' If you select a TV Season from ANYWHERE, follow this flow
startLoadingSpinner()
ptr = msg.getData()
' ptr is for [row, col] of selected item... but we only have 1 row
series = msg.getRoSGNode()
@ -362,18 +361,27 @@ sub Main (args as dynamic) as void
end if
else if isNodeEvent(msg, "musicAlbumSelected")
' If you select a Music Album from ANYWHERE, follow this flow
startLoadingSpinner()
ptr = msg.getData()
albums = msg.getRoSGNode()
node = albums.musicArtistAlbumData.items[ptr]
group = CreateAlbumView(node)
if not isValid(group)
stopLoadingSpinner()
end if
else if isNodeEvent(msg, "appearsOnSelected")
' If you select a Music Album from ANYWHERE, follow this flow
startLoadingSpinner()
ptr = msg.getData()
albums = msg.getRoSGNode()
node = albums.musicArtistAppearsOnData.items[ptr]
group = CreateAlbumView(node)
if not isValid(group)
stopLoadingSpinner()
end if
else if isNodeEvent(msg, "playSong")
' User has selected audio they want us to play
startLoadingSpinner()
selectedIndex = msg.getData()
screenContent = msg.getRoSGNode()
@ -383,6 +391,7 @@ sub Main (args as dynamic) as void
m.global.queueManager.callFunc("playQueue")
else if isNodeEvent(msg, "playItem")
' User has selected audio they want us to play
startLoadingSpinner()
selectedIndex = msg.getData()
screenContent = msg.getRoSGNode()
@ -393,8 +402,7 @@ sub Main (args as dynamic) as void
else if isNodeEvent(msg, "playAllSelected")
' User has selected playlist of of audio they want us to play
screenContent = msg.getRoSGNode()
m.spinner = screenContent.findNode("spinner")
m.spinner.visible = true
startLoadingSpinner()
m.global.queueManager.callFunc("clear")
m.global.queueManager.callFunc("resetShuffle")
@ -402,6 +410,7 @@ sub Main (args as dynamic) as void
m.global.queueManager.callFunc("playQueue")
else if isNodeEvent(msg, "playArtistSelected")
' User has selected playlist of of audio they want us to play
startLoadingSpinner()
screenContent = msg.getRoSGNode()
m.global.queueManager.callFunc("clear")
@ -413,10 +422,7 @@ sub Main (args as dynamic) as void
' 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")
if isValid(m.spinner)
m.spinner.visible = true
end if
startLoadingSpinner()
viewHandled = false
@ -458,6 +464,7 @@ sub Main (args as dynamic) as void
options.query = query
else if isNodeEvent(msg, "itemSelected")
' Search item selected
startLoadingSpinner()
node = getMsgPicker(msg)
' TODO - swap this based on target.mediatype
' types: [ Series (Show), Episode, Movie, Audio, Person, Studio, MusicArtist ]
@ -493,6 +500,7 @@ sub Main (args as dynamic) as void
m.global.queueManager.callFunc("playQueue")
else
' TODO - switch on more node types
stopLoadingSpinner()
message_dialog("This type is not yet supported: " + node.type + ".")
end if
else if isNodeEvent(msg, "buttonSelected")
@ -501,7 +509,7 @@ sub Main (args as dynamic) as void
group = sceneManager.callFunc("getActiveScene")
if isValid(btn) and btn.id = "play-button"
' User chose Play button from movie detail view
startLoadingSpinner()
' Check if a specific Audio Stream was selected
audio_stream_idx = 0
if isValid(group) and isValid(group.selectedAudioStreamIndex)
@ -534,6 +542,7 @@ sub Main (args as dynamic) as void
else if btn <> invalid and btn.id = "trailer-button"
' User chose to play a trailer from the movie detail view
startLoadingSpinner()
dialog = createObject("roSGNode", "ProgressDialog")
dialog.title = tr("Loading trailer")
m.scene.dialog = dialog
@ -545,6 +554,8 @@ sub Main (args as dynamic) as void
m.global.queueManager.callFunc("set", trailerData)
m.global.queueManager.callFunc("playQueue")
dialog.close = true
else
stopLoadingSpinner()
end if
if isValid(group) and isValid(group.lastFocus)
@ -732,6 +743,7 @@ sub Main (args as dynamic) as void
end if
else if isNodeEvent(msg, "dataReturned")
popupNode = msg.getRoSGNode()
stopLoadingSpinner()
if isValid(popupNode) and isValid(popupNode.returnData)
selectedItem = m.global.queueManager.callFunc("getHold")
m.global.queueManager.callFunc("clearHold")
@ -739,6 +751,7 @@ sub Main (args as dynamic) as void
if isValid(selectedItem) and selectedItem.count() > 0 and isValid(selectedItem[0])
if popupNode.returnData.indexselected = 0
'Resume video from resume point
startLoadingSpinner()
startingPoint = 0
if isValid(selectedItem[0].json) and isValid(selectedItem[0].json.UserData) and isValid(selectedItem[0].json.UserData.PlaybackPositionTicks)
@ -753,6 +766,7 @@ sub Main (args as dynamic) as void
m.global.queueManager.callFunc("playQueue")
else if popupNode.returnData.indexselected = 1
'Start Over from beginning selected, set position to 0
startLoadingSpinner()
selectedItem[0].startingPoint = 0
m.global.queueManager.callFunc("clear")
m.global.queueManager.callFunc("push", selectedItem[0])

View File

@ -16,12 +16,9 @@ function LoginFlow()
invalidServer = true
if not startOver
' Show Connecting to Server spinner
dialog = createObject("roSGNode", "ProgressDialog")
dialog.title = tr("Connecting to Server")
m.scene.dialog = dialog
m.scene.isLoading = true
invalidServer = ServerInfo().Error
dialog.close = true
m.scene.isLoading = false
end if
m.serverSelection = "Saved"
@ -92,7 +89,7 @@ function LoginFlow()
unset_setting("server")
goto start_login
else if userSelected <> ""
startMediaLoadingSpinner()
startLoadingSpinner()
print "A public user was selected with username=" + userSelected
session.user.Update("name", userSelected)
regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "")
@ -302,10 +299,7 @@ function CreateServerGroup()
else if type(msg) = "roSGNodeEvent"
node = msg.getNode()
if node = "submit"
' Show Connecting to Server spinner
dialog = createObject("roSGNode", "ProgressDialog")
dialog.title = tr("Connecting to Server")
m.scene.dialog = dialog
m.scene.isLoading = true
serverUrl = inferServerUrl(screen.serverUrl)
@ -321,7 +315,7 @@ function CreateServerGroup()
end if
set_setting("server", serverUrl)
end if
dialog.close = true
m.scene.isLoading = false
if isConnected = false or serverInfoResult = invalid
' Maybe don't unset setting, but offer as a prompt
@ -481,7 +475,7 @@ function CreateSigninGroup(user = "")
else if type(msg) = "roSGNodeEvent"
node = msg.getNode()
if node = "submit"
startMediaLoadingSpinner()
startLoadingSpinner()
' Validate credentials
activeUser = get_token(username.value, password.value)
if isValid(activeUser)
@ -813,17 +807,19 @@ function CreateSeasonDetailsGroupByID(seriesID as string, seasonID as string) as
group = CreateObject("roSGNode", "TVEpisodes")
group.optionsAvailable = false
' push scene asap (to prevent extra button presses when retriving series/movie info)
m.global.sceneManager.callFunc("pushScene", group)
group.seasonData = seasonMetaData.json
group.objects = TVEpisodes(seriesID, seasonID)
group.episodeObjects = group.objects
group.extrasObjects = TVSeasonExtras(seasonID)
' watch for button presses
group.observeField("episodeSelected", m.port)
group.observeField("quickPlayNode", m.port)
' finished building SeasonDetails view
' don't wait for the extras button
stopLoadingSpinner()
m.global.sceneManager.callFunc("pushScene", group)
' check for specials/extras for this season
group.extrasObjects = TVSeasonExtras(seasonID)
' finished building SeasonDetails view
return group
end function
@ -877,7 +873,7 @@ function CreateVideoPlayerGroup(video_id as string, mediaSourceId = invalid as d
' validate video_id
if not isValid(video_id) or video_id = "" then return invalid
startMediaLoadingSpinner()
startLoadingSpinner()
' Video is Playing
video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), forceTranscoding, showIntro, allowResumeDialog)
@ -936,6 +932,6 @@ sub playbackOptionDialog(time as longinteger, meta as object)
resumeData.push(tr("Go to episode"))
end if
end if
stopLoadingSpinner()
m.global.sceneManager.callFunc("optionDialog", tr("Playback Options"), [], resumeData)
end sub

View File

@ -59,7 +59,7 @@ sub AddVideoContent(video as object, mediaSourceId as dynamic, audio_stream_idx
if playbackPosition > 0
stopLoadingSpinner()
dialogResult = startPlayBackOver(playbackPosition)
startMediaLoadingSpinner()
startLoadingSpinner()
'Dialog returns -1 when back pressed, 0 for resume, and 1 for start over
if dialogResult = -1
'User pressed back, return invalid and don't load video

View File

@ -451,27 +451,30 @@ function toString(input) as string
return str(input)
end function
sub startLoadingSpinner()
m.spinner = createObject("roSGNode", "Spinner")
m.spinner.translation = "[900, 450]"
m.spinner.visible = true
m.scene.appendChild(m.spinner)
end sub
'
' startLoadingSpinner: Start a loading spinner and attach it to the main JFScene.
' Displays an invisible ProgressDialog node by default to disable keypresses while loading.
'
' @param {boolean} [disableRemote=true]
sub startLoadingSpinner(disableRemote = true as boolean)
if not isValid(m.scene)
m.scene = m.top.getScene()
end if
sub startMediaLoadingSpinner()
dialog = createObject("roSGNode", "ProgressDialog")
dialog.id = "invisibiledialog"
dialog.visible = false
m.scene.dialog = dialog
startLoadingSpinner()
if not m.scene.isLoading
m.scene.disableRemote = disableRemote
m.scene.isLoading = true
end if
end sub
sub stopLoadingSpinner()
if isValid(m.spinner)
m.spinner.visible = false
if not isValid(m.scene)
m.scene = m.top.getScene()
end if
if isValid(m.scene) and isValid(m.scene.dialog)
m.scene.dialog.close = true
if m.scene.isLoading
m.scene.disableRemote = false
m.scene.isLoading = false
end if
end sub

View File

@ -84,6 +84,8 @@ namespace quickplay
photoPlayer.itemsArray = photoAlbumData.items
photoPlayer.itemIndex = 0
m.global.sceneManager.callfunc("pushScene", photoPlayer)
else
stopLoadingSpinner()
end if
end sub
@ -103,6 +105,8 @@ namespace quickplay
})
if isValid(albumSongs) and isValidAndNotEmpty(albumSongs.items)
quickplay.pushToQueue(albumSongs.items)
else
stopLoadingSpinner()
end if
end sub
@ -126,6 +130,8 @@ namespace quickplay
if isValid(artistSongs) and isValidAndNotEmpty(artistSongs.items)
quickplay.pushToQueue(artistSongs.items, true)
else
stopLoadingSpinner()
end if
end sub
@ -142,6 +148,8 @@ namespace quickplay
})
if isValid(data) and isValidAndNotEmpty(data.Items)
quickplay.pushToQueue(data.items)
else
stopLoadingSpinner()
end if
end sub
@ -197,6 +205,8 @@ namespace quickplay
if isValid(data) and isValidAndNotEmpty(data.Items)
' add all episodes found to a playlist
quickplay.pushToQueue(data.Items)
else
stopLoadingSpinner()
end if
end if
end if
@ -240,6 +250,8 @@ namespace quickplay
end for
if m.global.queueManager.callFunc("getCount") > 1
m.global.queueManager.callFunc("toggleShuffle")
else
stopLoadingSpinner()
end if
end if
end sub
@ -305,6 +317,8 @@ namespace quickplay
end if
end if
end if
else
stopLoadingSpinner()
end if
end sub
@ -345,6 +359,8 @@ namespace quickplay
if m.global.queueManager.callFunc("getCount") > 1
m.global.queueManager.callFunc("toggleShuffle")
else
stopLoadingSpinner()
end if
end sub
@ -352,8 +368,8 @@ namespace quickplay
sub tvChannel(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
stopLoadingSpinner()
group = CreateVideoPlayerGroup(itemNode.id)
stopLoadingSpinner()
m.global.sceneManager.callFunc("pushScene", group)
end sub
@ -361,8 +377,8 @@ namespace quickplay
sub program(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.json) or not isValid(itemNode.json.ChannelId) then return
stopLoadingSpinner()
group = CreateVideoPlayerGroup(itemNode.json.ChannelId)
stopLoadingSpinner()
m.global.sceneManager.callFunc("pushScene", group)
end sub
@ -383,6 +399,8 @@ namespace quickplay
if m.global.queueManager.callFunc("getCount") > 1
m.global.queueManager.callFunc("toggleShuffle")
end if
else
stopLoadingSpinner()
end if
end sub
@ -451,6 +469,8 @@ namespace quickplay
quickplay.pushToQueue(folderData.items, true)
end if
end if
else
stopLoadingSpinner()
end if
end sub
@ -484,6 +504,8 @@ namespace quickplay
end if
end for
quickplay.pushToQueue(movieList)
else
stopLoadingSpinner()
end if
else if collectionType = "music"
' get audio files from under this collection
@ -501,6 +523,8 @@ namespace quickplay
print "songsData=", songsData
if isValid(songsData) and isValidAndNotEmpty(songsData.items)
quickplay.pushToQueue(songsData.Items, true)
else
stopLoadingSpinner()
end if
else if collectionType = "boxsets"
' get list of all boxsets inside
@ -529,6 +553,8 @@ namespace quickplay
if isValid(boxsetData) and isValidAndNotEmpty(boxsetData.items)
' add all boxset items to queue
quickplay.pushToQueue(boxsetData.Items)
else
stopLoadingSpinner()
end if
end if
else if collectionType = "tvshows" or collectionType = "collectionfolder"
@ -545,7 +571,15 @@ namespace quickplay
print "tvshowsData=", tvshowsData
if isValid(tvshowsData) and isValidAndNotEmpty(tvshowsData.items)
quickplay.multipleSeries(tvshowsData.items)
' the type of media returned from api may change.
if LCase(tvshowsData.items[0].Type) = "series"
quickplay.multipleSeries(tvshowsData.items)
else
' if first item is not a series, then assume they are all videos and/or episodes
quickplay.pushToQueue(tvshowsData.items)
end if
else
stopLoadingSpinner()
end if
else if collectionType = "musicvideos"
' get randomized list of videos inside
@ -562,6 +596,8 @@ namespace quickplay
print "data=", data
if isValid(data) and isValidAndNotEmpty(data.items)
quickplay.pushToQueue(data.Items)
else
stopLoadingSpinner()
end if
else if collectionType = "homevideos"
' Photo library - items can be type video, photo, or photoAlbum
@ -582,8 +618,11 @@ namespace quickplay
photoPlayer.itemsArray = folderData.items
photoPlayer.itemIndex = 0
m.global.sceneManager.callfunc("pushScene", photoPlayer)
else
stopLoadingSpinner()
end if
else
stopLoadingSpinner()
print "Quick Play WARNING: Unknown collection type"
end if
end sub
@ -621,6 +660,8 @@ namespace quickplay
' validate api results
if isValid(playlistItems) and isValidAndNotEmpty(playlistItems.items)
quickplay.pushToQueue(playlistItems.items, true)
else
stopLoadingSpinner()
end if
end if
else if collectionType = "livetv"
@ -643,8 +684,11 @@ namespace quickplay
print "myChannel=", myChannel
' play channel
quickplay.tvChannel(myChannel)
else
stopLoadingSpinner()
end if
else
stopLoadingSpinner()
print "Quick Play CollectionFolder WARNING: Unknown collection type"
end if
end sub