mirror of
https://github.com/jellyfin/jellyfin-roku.git
synced 2024-11-23 22:29:43 +00:00
Remove optional chaining operators from code (#1085)
* remove optional chaining operators + use isValid() + remove extra white space * address reviewer feedback
This commit is contained in:
parent
318668db5b
commit
25f03915ff
@ -22,7 +22,7 @@ sub init()
|
||||
'Parent is MarkupGrid and it's parent is the ItemGrid
|
||||
m.topParent = m.top.GetParent().GetParent()
|
||||
'Get the imageDisplayMode for these grid items
|
||||
if m.topParent.imageDisplayMode <> invalid
|
||||
if isValid(m.topParent.imageDisplayMode)
|
||||
m.itemPoster.loadDisplayMode = m.topParent.imageDisplayMode
|
||||
end if
|
||||
|
||||
@ -44,7 +44,7 @@ sub itemContentChanged()
|
||||
m.itemText.text = itemData.Title
|
||||
else if itemData.type = "Series"
|
||||
if get_user_setting("ui.tvshows.disableUnwatchedEpisodeCount", "false") = "false"
|
||||
if itemData?.json?.UserData?.UnplayedItemCount <> invalid
|
||||
if isValid(itemData.json) and isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
m.unplayedEpisodeCount.text = itemData.json.UserData.UnplayedItemCount
|
||||
@ -98,7 +98,7 @@ sub itemContentChanged()
|
||||
|
||||
m.posterText.height = 200
|
||||
m.posterText.width = 280
|
||||
else if itemData.json.type = "MusicAlbum"
|
||||
else if isValid(itemData.json.type) and itemData.json.type = "MusicAlbum"
|
||||
m.itemPoster.uri = itemData.PosterUrl
|
||||
m.itemText.text = itemData.Title
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<component name="GridItem" extends="Group">
|
||||
<children>
|
||||
<maskGroup id="posterMask" maskUri="pkg:/images/postermask.png" scaleRotateCenter="[145, 212.5]" scale="[0.85,0.85]">
|
||||
@ -20,4 +20,5 @@
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="GridItem.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
</component>
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
</component>
|
@ -4,7 +4,7 @@ sub init()
|
||||
m.top.limit = 60
|
||||
usersettingLimit = get_user_setting("itemgrid.Limit")
|
||||
|
||||
if usersettingLimit <> invalid
|
||||
if isValid(usersettingLimit)
|
||||
m.top.limit = usersettingLimit
|
||||
end if
|
||||
end sub
|
||||
@ -135,7 +135,7 @@ sub LoadItems_AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtit
|
||||
if m.playbackInfo.MediaSources[0].MediaStreams.Count() > 0 and meta.live = false
|
||||
tryDirectPlay = get_user_setting("playback.tryDirect.h264ProfileLevel") = "true" and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
|
||||
tryDirectPlay = tryDirectPlay or (get_user_setting("playback.tryDirect.hevcProfileLevel") = "true" and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "hevc")
|
||||
if tryDirectPlay and m.playbackInfo.MediaSources[0].TranscodingUrl <> invalid and forceTranscoding = false
|
||||
if tryDirectPlay and isValid(m.playbackInfo.MediaSources[0].TranscodingUrl) and forceTranscoding = false
|
||||
transcodingReasons = getTranscodeReasons(m.playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
if transcodingReasons.Count() = 1 and transcodingReasons[0] = "VideoLevelNotSupported"
|
||||
video.directPlaySupported = true
|
||||
@ -262,7 +262,7 @@ end function
|
||||
|
||||
function directPlaySupported(meta as object) as boolean
|
||||
devinfo = CreateObject("roDeviceInfo")
|
||||
if meta.json.MediaSources[0] <> invalid and meta.json.MediaSources[0].SupportsDirectPlay = false
|
||||
if isValid(meta.json.MediaSources[0]) and meta.json.MediaSources[0].SupportsDirectPlay = false
|
||||
return false
|
||||
end if
|
||||
|
||||
@ -271,10 +271,10 @@ function directPlaySupported(meta as object) as boolean
|
||||
end if
|
||||
|
||||
streamInfo = { Codec: meta.json.MediaStreams[0].codec }
|
||||
if meta.json.MediaStreams[0].Profile <> invalid and meta.json.MediaStreams[0].Profile.len() > 0
|
||||
if isValid(meta.json.MediaStreams[0].Profile) and meta.json.MediaStreams[0].Profile.len() > 0
|
||||
streamInfo.Profile = LCase(meta.json.MediaStreams[0].Profile)
|
||||
end if
|
||||
if meta.json.MediaSources[0].container <> invalid and meta.json.MediaSources[0].container.len() > 0
|
||||
if isValid(meta.json.MediaSources[0].container) and meta.json.MediaSources[0].container.len() > 0
|
||||
'CanDecodeVideo() requires the .container to be format: “mp4”, “hls”, “mkv”, “ism”, “dash”, “ts” if its to direct stream
|
||||
if meta.json.MediaSources[0].container = "mov"
|
||||
streamInfo.Container = "mp4"
|
||||
@ -333,12 +333,12 @@ sub autoPlayNextEpisode(videoID as string, showID as string)
|
||||
resp = APIRequest(url, urlParams)
|
||||
data = getJson(resp)
|
||||
|
||||
if data <> invalid and data.Items.Count() = 2
|
||||
if isValid(data) and data.Items.Count() = 2
|
||||
' setup new video node
|
||||
nextVideo = invalid
|
||||
' remove last videoplayer scene
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
if nextVideo <> invalid
|
||||
if isValid(nextVideo)
|
||||
m.global.sceneManager.callFunc("pushScene", nextVideo)
|
||||
else
|
||||
m.global.sceneManager.callFunc("popScene")
|
||||
@ -356,7 +356,7 @@ end sub
|
||||
' In the future, with a custom playback info view, we can return an associated array.
|
||||
function GetPlaybackInfo()
|
||||
sessions = api_API().sessions.get()
|
||||
if sessions <> invalid and sessions.Count() > 0
|
||||
if isValid(sessions) and sessions.Count() > 0
|
||||
return GetTranscodingStats(sessions[0])
|
||||
end if
|
||||
|
||||
@ -507,7 +507,7 @@ end function
|
||||
' returns the server-side track index for the appriate subtitle
|
||||
function defaultSubtitleTrackFromVid(video_id) as integer
|
||||
meta = ItemMetaData(video_id)
|
||||
if meta?.json?.mediaSources <> invalid
|
||||
if isValid(meta) and isValid(meta.json) and isValid(meta.json.mediaSources)
|
||||
subtitles = sortSubtitles(meta.id, meta.json.MediaSources[0].MediaStreams)
|
||||
default_text_subs = defaultSubtitleTrack(subtitles["all"], true) ' Find correct subtitle track (forced text)
|
||||
if default_text_subs <> -1
|
||||
@ -608,7 +608,7 @@ function sortSubtitles(id as string, MediaStreams)
|
||||
if stream.type = "Subtitle"
|
||||
|
||||
url = ""
|
||||
if stream.DeliveryUrl <> invalid
|
||||
if isValid(stream.DeliveryUrl)
|
||||
url = buildURL(stream.DeliveryUrl)
|
||||
end if
|
||||
|
||||
|
@ -18,9 +18,8 @@ sub init()
|
||||
end sub
|
||||
|
||||
sub updateSize()
|
||||
|
||||
image = invalid
|
||||
if m.top.itemContent <> invalid and m.top.itemContent.image <> invalid
|
||||
if isValid(m.top.itemContent) and isValid(m.top.itemContent.image)
|
||||
image = m.top.itemContent.image
|
||||
end if
|
||||
|
||||
@ -49,7 +48,6 @@ sub updateSize()
|
||||
|
||||
m.backdrop.width = m.poster.width
|
||||
m.backdrop.height = m.poster.height
|
||||
|
||||
end sub
|
||||
|
||||
sub itemContentChanged() as void
|
||||
@ -58,7 +56,7 @@ sub itemContentChanged() as void
|
||||
m.title.text = itemData.title
|
||||
|
||||
if get_user_setting("ui.tvshows.disableUnwatchedEpisodeCount", "false") = "false"
|
||||
if itemData?.json?.UserData?.UnplayedItemCount <> invalid
|
||||
if isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
m.unplayedEpisodeCount.text = itemData.json.UserData.UnplayedItemCount
|
||||
@ -66,12 +64,11 @@ sub itemContentChanged() as void
|
||||
end if
|
||||
end if
|
||||
|
||||
if itemData.json.lookup("Type") = "Episode" and itemData.json.IndexNumber <> invalid
|
||||
if itemData.json.lookup("Type") = "Episode" and isValid(itemData.json.IndexNumber)
|
||||
m.title.text = StrI(itemData.json.IndexNumber) + ". " + m.title.text
|
||||
|
||||
m.series.text = itemData.json.Series
|
||||
m.series.visible = true
|
||||
|
||||
else if itemData.json.lookup("Type") = "MusicAlbum"
|
||||
m.title.font = "font:SmallestSystemFont"
|
||||
m.staticTitle.font = "font:SmallestSystemFont"
|
||||
@ -83,8 +80,7 @@ sub itemContentChanged() as void
|
||||
imageUrl = itemData.posterURL
|
||||
|
||||
if get_user_setting("ui.tvshows.blurunwatched") = "true"
|
||||
|
||||
if itemData.json.lookup("Type") = "Episode" and itemData.json.userdata <> invalid
|
||||
if itemData.json.lookup("Type") = "Episode" and isValid(itemData.json.userdata)
|
||||
if not itemData.json.userdata.played
|
||||
imageUrl = imageUrl + "&blur=15"
|
||||
end if
|
||||
@ -99,25 +95,21 @@ end sub
|
||||
'
|
||||
' Enable title scrolling based on item Focus
|
||||
sub focusChanged()
|
||||
|
||||
if m.top.itemHasFocus = true
|
||||
m.title.repeatCount = -1
|
||||
m.series.repeatCount = -1
|
||||
m.staticTitle.visible = false
|
||||
m.title.visible = true
|
||||
|
||||
' text to speech for accessibility
|
||||
if m.deviceInfo.IsAudioGuideEnabled() = true
|
||||
txt2Speech = CreateObject("roTextToSpeech")
|
||||
txt2Speech.Flush()
|
||||
txt2Speech.Say(m.title.text)
|
||||
end if
|
||||
|
||||
else
|
||||
m.title.repeatCount = 0
|
||||
m.series.repeatCount = 0
|
||||
m.staticTitle.visible = true
|
||||
m.title.visible = false
|
||||
end if
|
||||
|
||||
end sub
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<component name="ListPoster" extends="Group">
|
||||
<children>
|
||||
<Rectangle id="backdrop" />
|
||||
@ -12,10 +12,11 @@
|
||||
<Label id="staticTitle" horizAlign="center" font="font:SmallSystemFont" wrap="false" />
|
||||
</children>
|
||||
<interface>
|
||||
<field id="itemContent" type="node" onChange="itemContentChanged"/>
|
||||
<field id="itemContent" type="node" onChange="itemContentChanged" />
|
||||
<field id="itemWidth" type="integer" />
|
||||
<field id="itemHasFocus" type="boolean" onChange="focusChanged" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="ListPoster.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
</component>
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
</component>
|
@ -33,13 +33,13 @@ sub itemContentChanged()
|
||||
|
||||
m.backdrop.width = itemData.imageWidth
|
||||
|
||||
if itemData.iconUrl <> invalid
|
||||
if isValid(itemData.iconUrl)
|
||||
m.itemIcon.uri = itemData.iconUrl
|
||||
end if
|
||||
|
||||
if LCase(itemData.type) = "series"
|
||||
if get_user_setting("ui.tvshows.disableUnwatchedEpisodeCount", "false") = "false"
|
||||
if itemData?.json?.UserData?.UnplayedItemCount <> invalid
|
||||
if isValid(itemData.json.UserData) and isValid(itemData.json.UserData.UnplayedItemCount)
|
||||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
m.unplayedEpisodeCount.text = itemData.json.UserData.UnplayedItemCount
|
||||
@ -84,7 +84,7 @@ sub itemContentChanged()
|
||||
end if
|
||||
|
||||
' Set Episode title if available
|
||||
if itemData.json.EpisodeTitle <> invalid
|
||||
if isValid(itemData.json.EpisodeTitle)
|
||||
m.itemTextExtra.text = itemData.json.EpisodeTitle
|
||||
end if
|
||||
|
||||
@ -106,10 +106,10 @@ sub itemContentChanged()
|
||||
|
||||
' Set Series and Episode Number for Extra Text
|
||||
extraPrefix = ""
|
||||
if itemData.json.ParentIndexNumber <> invalid
|
||||
if isValid(itemData.json.ParentIndexNumber)
|
||||
extraPrefix = "S" + StrI(itemData.json.ParentIndexNumber).trim()
|
||||
end if
|
||||
if itemData.json.IndexNumber <> invalid
|
||||
if isValid(itemData.json.IndexNumber)
|
||||
extraPrefix = extraPrefix + "E" + StrI(itemData.json.IndexNumber).trim()
|
||||
end if
|
||||
if extraPrefix.len() > 0
|
||||
@ -136,10 +136,10 @@ sub itemContentChanged()
|
||||
|
||||
' Set Release Year and Age Rating for Extra Text
|
||||
textExtra = ""
|
||||
if itemData.json.ProductionYear <> invalid
|
||||
if isValid(itemData.json.ProductionYear)
|
||||
textExtra = StrI(itemData.json.ProductionYear).trim()
|
||||
end if
|
||||
if itemData.json.OfficialRating <> invalid
|
||||
if isValid(itemData.json.OfficialRating)
|
||||
if textExtra <> ""
|
||||
textExtra = textExtra + " - " + itemData.json.OfficialRating
|
||||
else
|
||||
@ -181,14 +181,14 @@ sub itemContentChanged()
|
||||
end if
|
||||
|
||||
textExtra = ""
|
||||
if itemData.json.ProductionYear <> invalid
|
||||
if isValid(itemData.json.ProductionYear)
|
||||
textExtra = StrI(itemData.json.ProductionYear).trim()
|
||||
end if
|
||||
|
||||
' Set Years Run for Extra Text
|
||||
if itemData.json.Status = "Continuing"
|
||||
textExtra = textExtra + " - Present"
|
||||
else if itemData.json.Status = "Ended" and itemData.json.EndDate <> invalid
|
||||
else if itemData.json.Status = "Ended" and isValid(itemData.json.EndDate)
|
||||
textExtra = textExtra + " - " + LEFT(itemData.json.EndDate, 4)
|
||||
end if
|
||||
m.itemTextExtra.text = textExtra
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<component name="HomeItem" extends="Group">
|
||||
<children>
|
||||
<Rectangle id="backdrop" width="464" height="261" translation="[8,5]" />
|
||||
@ -26,4 +26,5 @@
|
||||
<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" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
</component>
|
@ -96,7 +96,7 @@ sub onLibrariesLoaded()
|
||||
m.LoadFavoritesTask.control = "RUN"
|
||||
|
||||
' validate library data
|
||||
if m.libraryData <> invalid and m.libraryData.count() > 0
|
||||
if isValid(m.libraryData) and m.libraryData.count() > 0
|
||||
userConfig = m.top.userConfig
|
||||
|
||||
' populate My Media row
|
||||
@ -163,7 +163,7 @@ sub updateFavoritesItems()
|
||||
rowIndex = getRowIndex("Favorites")
|
||||
|
||||
if itemData.count() < 1
|
||||
if rowIndex <> invalid
|
||||
if isValid(rowIndex)
|
||||
' remove the row
|
||||
deleteFromSizeArray(rowIndex)
|
||||
homeRows.removeChildIndex(rowIndex)
|
||||
@ -208,7 +208,7 @@ sub updateContinueItems()
|
||||
continueRowIndex = getRowIndex("Continue Watching")
|
||||
|
||||
if itemData.count() < 1
|
||||
if continueRowIndex <> invalid
|
||||
if isValid(continueRowIndex)
|
||||
' remove the row
|
||||
deleteFromSizeArray(continueRowIndex)
|
||||
homeRows.removeChildIndex(continueRowIndex)
|
||||
@ -219,7 +219,7 @@ sub updateContinueItems()
|
||||
row.title = tr("Continue Watching")
|
||||
itemSize = [464, 331]
|
||||
for each item in itemData
|
||||
if item.json?.UserData?.PlayedPercentage <> invalid
|
||||
if isValid(item.json) and isValid(item.json.UserData) and isValid(item.json.UserData.PlayedPercentage)
|
||||
item.PlayedPercentage = item.json.UserData.PlayedPercentage
|
||||
end if
|
||||
|
||||
@ -250,7 +250,7 @@ sub updateNextUpItems()
|
||||
nextUpRowIndex = getRowIndex("Next Up >")
|
||||
|
||||
if itemData.count() < 1
|
||||
if nextUpRowIndex <> invalid
|
||||
if isValid(nextUpRowIndex)
|
||||
' remove the row
|
||||
deleteFromSizeArray(nextUpRowIndex)
|
||||
homeRows.removeChildIndex(nextUpRowIndex)
|
||||
@ -269,7 +269,7 @@ sub updateNextUpItems()
|
||||
if nextUpRowIndex = invalid
|
||||
' insert new row under "Continue Watching"
|
||||
continueRowIndex = getRowIndex("Continue Watching")
|
||||
if continueRowIndex <> invalid
|
||||
if isValid(continueRowIndex)
|
||||
updateSizeArray(itemSize, continueRowIndex + 1)
|
||||
homeRows.insertChild(row, continueRowIndex + 1)
|
||||
else
|
||||
@ -305,7 +305,7 @@ sub updateLatestItems(msg)
|
||||
|
||||
if itemData.count() < 1
|
||||
' remove row
|
||||
if rowIndex <> invalid
|
||||
if isValid(rowIndex)
|
||||
deleteFromSizeArray(rowIndex)
|
||||
homeRows.removeChildIndex(rowIndex)
|
||||
end if
|
||||
@ -355,7 +355,7 @@ sub updateOnNowItems()
|
||||
onNowRowIndex = getRowIndex("On Now")
|
||||
|
||||
if itemData.count() < 1
|
||||
if onNowRowIndex <> invalid
|
||||
if isValid(onNowRowIndex)
|
||||
' remove the row
|
||||
deleteFromSizeArray(onNowRowIndex)
|
||||
homeRows.removeChildIndex(onNowRowIndex)
|
||||
@ -409,11 +409,11 @@ sub updateSizeArray(rowItemSize, rowIndex = invalid, action = "insert")
|
||||
newSizeArray.Push(rowItemSize)
|
||||
else if action = "insert"
|
||||
newSizeArray.Push(rowItemSize)
|
||||
if sizeArray[i] <> invalid
|
||||
if isValid(sizeArray[i])
|
||||
newSizeArray.Push(sizeArray[i])
|
||||
end if
|
||||
end if
|
||||
else if sizeArray[i] <> invalid
|
||||
else if isValid(sizeArray[i])
|
||||
newSizeArray.Push(sizeArray[i])
|
||||
end if
|
||||
end for
|
||||
@ -433,7 +433,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if press
|
||||
if key = "play"
|
||||
itemToPlay = m.top.content.getChild(m.top.rowItemFocused[0]).getChild(m.top.rowItemFocused[1])
|
||||
if itemToPlay <> invalid and (itemToPlay.type = "Movie" or itemToPlay.type = "Episode")
|
||||
if isValid(itemToPlay) and (itemToPlay.type = "Movie" or itemToPlay.type = "Episode")
|
||||
m.top.quickPlayNode = itemToPlay
|
||||
end if
|
||||
handled = true
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<component name="HomeRows" extends="RowList">
|
||||
<interface>
|
||||
<field id="selectedItem" type="node" alwaysNotify="true" />
|
||||
@ -7,5 +7,6 @@
|
||||
<function name="updateHomeRows" />
|
||||
<function name="loadLibraries" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="HomeRows.brs"/>
|
||||
</component>
|
||||
<script type="text/brightscript" uri="HomeRows.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
</component>
|
@ -4,7 +4,6 @@ sub init()
|
||||
m.position = 0
|
||||
end sub
|
||||
|
||||
'
|
||||
' Clear all content from play queue
|
||||
sub clear()
|
||||
m.queue = []
|
||||
@ -12,72 +11,52 @@ sub clear()
|
||||
setPosition(0)
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' Delete item from play queue at passed index
|
||||
sub deleteAtIndex(index)
|
||||
m.queue.Delete(index)
|
||||
m.queueTypes.Delete(index)
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' Return the number of items in the play queue
|
||||
function getCount()
|
||||
return m.queue.count()
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Return the item currently in focus from the play queue
|
||||
function getCurrentItem()
|
||||
return getItemByIndex(m.position)
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Return the item in the passed index from the play queue
|
||||
function getItemByIndex(index)
|
||||
return m.queue[index]
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Returns current playback position within the queue
|
||||
function getPosition()
|
||||
return m.position
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Move queue position back one
|
||||
sub moveBack()
|
||||
m.position--
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' Move queue position ahead one
|
||||
sub moveForward()
|
||||
m.position++
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' Return the current play queue
|
||||
function getQueue()
|
||||
return m.queue
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Return the types of items in current play queue
|
||||
function getQueueTypes()
|
||||
return m.queueTypes
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Return the unique types of items in current play queue
|
||||
function getQueueUniqueTypes()
|
||||
itemTypes = []
|
||||
@ -91,15 +70,11 @@ function getQueueUniqueTypes()
|
||||
return itemTypes
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Return item at end of play queue without removing
|
||||
function peek()
|
||||
return m.queue.peek()
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Play items in queue
|
||||
sub playQueue()
|
||||
nextItem = getCurrentItem()
|
||||
@ -116,37 +91,28 @@ sub playQueue()
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' Remove item at end of play queue
|
||||
sub pop()
|
||||
m.queue.pop()
|
||||
m.queueTypes.pop()
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' Push new items to the play queue
|
||||
sub push(newItem)
|
||||
m.queue.push(newItem)
|
||||
m.queueTypes.push(getItemType(newItem))
|
||||
end sub
|
||||
|
||||
'
|
||||
' Set the queue position
|
||||
sub setPosition(newPosition)
|
||||
m.position = newPosition
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' Return the fitst item in the play queue
|
||||
function top()
|
||||
return getItemByIndex(0)
|
||||
end function
|
||||
|
||||
|
||||
'
|
||||
' Replace play queue with passed array
|
||||
sub set(items)
|
||||
setPosition(0)
|
||||
@ -157,10 +123,9 @@ sub set(items)
|
||||
end sub
|
||||
|
||||
function getItemType(item) as string
|
||||
|
||||
if isValid(item?.json?.mediatype) and item.json.mediatype <> ""
|
||||
if isValid(item) and isValid(item.json) and isValid(item.json.mediatype) and item.json.mediatype <> ""
|
||||
return LCase(item.json.mediatype)
|
||||
else if isValid(item?.type) and item.type <> ""
|
||||
else if isValid(item) and isValid(item.type) and item.type <> ""
|
||||
return LCase(item.type)
|
||||
end if
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
'
|
||||
' View Creators
|
||||
' ----------------
|
||||
|
||||
' Play Audio
|
||||
sub CreateAudioPlayerView()
|
||||
m.view = CreateObject("roSGNode", "AudioPlayerView")
|
||||
@ -26,14 +22,12 @@ sub CreateVideoPlayerView()
|
||||
m.global.sceneManager.callFunc("pushScene", m.view)
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
' -----------------
|
||||
' Event Handlers
|
||||
' -----------------
|
||||
|
||||
' User requested subtitle selection popup
|
||||
sub onSelectSubtitlePressed()
|
||||
|
||||
' None is always first in the subtitle list
|
||||
subtitleData = {
|
||||
data: [{ "description": "None", "type": "subtitleselection" }]
|
||||
@ -80,9 +74,8 @@ end sub
|
||||
|
||||
' User requested playback info
|
||||
sub onSelectPlaybackInfoPressed()
|
||||
|
||||
' Check if we already have playback info and show it in a popup
|
||||
if isValid(m.playbackData?.playbackinfo)
|
||||
if isValid(m.playbackData) and isValid(m.playbackData.playbackinfo)
|
||||
m.global.sceneManager.callFunc("standardDialog", tr("Playback Info"), m.playbackData.playbackinfo)
|
||||
return
|
||||
end if
|
||||
@ -95,12 +88,11 @@ sub onPlaybackInfoLoaded()
|
||||
m.playbackData = m.getPlaybackInfoTask.data
|
||||
|
||||
' Check if we have playback info and show it in a popup
|
||||
if isValid(m.playbackData?.playbackinfo)
|
||||
if isValid(m.playbackData) and isValid(m.playbackData.playbackinfo)
|
||||
m.global.sceneManager.callFunc("standardDialog", tr("Playback Info"), m.playbackData.playbackinfo)
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
||||
' Playback state change event handlers
|
||||
sub onStateChange()
|
||||
if LCase(m.view.state) = "finished"
|
||||
|
@ -19,7 +19,7 @@ end sub
|
||||
|
||||
sub updateSeason()
|
||||
if get_user_setting("ui.tvshows.disableUnwatchedEpisodeCount", "false") = "false"
|
||||
if m.top.seasonData?.UserData?.UnplayedItemCount <> invalid
|
||||
if isValid(m.top.seasonData) and isValid(m.top.seasonData.UserData) and isValid(m.top.seasonData.UserData.UnplayedItemCount)
|
||||
if m.top.seasonData.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
m.unplayedEpisodeCount.text = m.top.seasonData.UserData.UnplayedItemCount
|
||||
@ -57,7 +57,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
return true
|
||||
end if
|
||||
|
||||
|
||||
if key = "OK" or key = "play"
|
||||
if m.Random.hasFocus()
|
||||
randomEpisode = Rnd(m.rows.getChild(0).objects.items.count()) - 1
|
||||
@ -81,7 +80,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
focusedChild = m.top.focusedChild.focusedChild
|
||||
if focusedChild.content = invalid then return handled
|
||||
|
||||
@ -94,7 +92,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if press and key = "play" or proceed = true
|
||||
m.top.lastFocus = focusedChild
|
||||
itemToPlay = focusedChild.content.getChild(focusedChild.rowItemFocused[0]).getChild(0)
|
||||
if itemToPlay <> invalid and itemToPlay.id <> ""
|
||||
if isValid(itemToPlay) and isValid(itemToPlay.id) and itemToPlay.id <> ""
|
||||
itemToPlay.type = "Episode"
|
||||
m.top.quickPlayNode = itemToPlay
|
||||
end if
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<component name="TVEpisodes" extends="JFGroup">
|
||||
<children>
|
||||
<Poster id="seasonPoster" width="300" height="450" translation="[95,175]">
|
||||
@ -20,4 +20,5 @@
|
||||
<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>
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
</component>
|
@ -18,7 +18,7 @@ end sub
|
||||
sub itemContentChanged()
|
||||
item = m.top.itemContent
|
||||
itemData = item.json
|
||||
if itemData.indexNumber <> invalid
|
||||
if isValid(itemData.indexNumber)
|
||||
indexNumber = itemData.indexNumber.toStr() + ". "
|
||||
else
|
||||
indexNumber = ""
|
||||
@ -26,7 +26,7 @@ sub itemContentChanged()
|
||||
m.title.text = indexNumber + item.title
|
||||
m.overview.text = item.overview
|
||||
|
||||
if itemData.PremiereDate <> invalid
|
||||
if isValid(itemData.PremiereDate)
|
||||
airDate = CreateObject("roDateTime")
|
||||
airDate.FromISO8601String(itemData.PremiereDate)
|
||||
m.top.findNode("aired").text = tr("Aired") + ": " + airDate.AsDateString("short-month-no-weekday")
|
||||
@ -70,12 +70,12 @@ sub itemContentChanged()
|
||||
end if
|
||||
|
||||
' Add checkmark in corner (if applicable)
|
||||
if isValid(itemData?.UserData?.Played) and itemData.UserData.Played = true
|
||||
if isValid(itemData.UserData) and isValid(itemData.UserData.Played) and itemData.UserData.Played = true
|
||||
m.playedIndicator.visible = true
|
||||
end if
|
||||
|
||||
' Add progress bar on bottom (if applicable)
|
||||
if isValid(itemData?.UserData?.PlayedPercentage) and itemData?.UserData?.PlayedPercentage > 0
|
||||
if isValid(itemData.UserData) and isValid(itemData.UserData.PlayedPercentage) and itemData.UserData.PlayedPercentage > 0
|
||||
m.progressBackground.width = m.poster.width
|
||||
m.progressBackground.visible = true
|
||||
progressWidthInPixels = int(m.progressBackground.width * itemData.UserData.PlayedPercentage / 100)
|
||||
@ -86,7 +86,7 @@ sub itemContentChanged()
|
||||
videoIdx = invalid
|
||||
audioIdx = invalid
|
||||
|
||||
if itemData.MediaStreams <> invalid
|
||||
if isValid(itemData.MediaStreams)
|
||||
for i = 0 to itemData.MediaStreams.Count() - 1
|
||||
if itemData.MediaStreams[i].Type = "Video" and videoIdx = invalid
|
||||
videoIdx = i
|
||||
@ -99,12 +99,12 @@ sub itemContentChanged()
|
||||
end if
|
||||
m.top.findNode("audio_codec").text = tr("Audio") + ": " + itemData.mediaStreams[audioIdx].DisplayTitle
|
||||
end if
|
||||
if videoIdx <> invalid and audioIdx <> invalid then exit for
|
||||
if isValid(videoIdx) and isValid(audioIdx) then exit for
|
||||
end for
|
||||
end if
|
||||
|
||||
m.top.findNode("video_codec").visible = videoIdx <> invalid
|
||||
if audioIdx <> invalid
|
||||
m.top.findNode("video_codec").visible = isValid(videoIdx)
|
||||
if isValid(audioIdx)
|
||||
m.top.findNode("audio_codec").visible = true
|
||||
DisplayAudioAvailable(itemData.mediaStreams)
|
||||
else
|
||||
@ -113,7 +113,6 @@ sub itemContentChanged()
|
||||
end sub
|
||||
|
||||
sub DisplayAudioAvailable(streams)
|
||||
|
||||
count = 0
|
||||
for i = 0 to streams.Count() - 1
|
||||
if streams[i].Type = "Audio"
|
||||
@ -124,7 +123,6 @@ sub DisplayAudioAvailable(streams)
|
||||
if count > 1
|
||||
m.top.findnode("audio_codec_count").text = "+" + stri(count - 1).trim()
|
||||
end if
|
||||
|
||||
end sub
|
||||
|
||||
function getRuntime() as integer
|
||||
|
@ -17,7 +17,7 @@ sub itemContentChanged()
|
||||
itemData = item.json
|
||||
|
||||
if get_user_setting("ui.tvshows.disableUnwatchedEpisodeCount", "false") = "false"
|
||||
if itemData?.UserData?.UnplayedItemCount <> invalid
|
||||
if isValid(itemData.UserData) and isValid(itemData.UserData.UnplayedItemCount)
|
||||
if itemData.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
m.unplayedEpisodeCount.text = itemData.UserData.UnplayedItemCount
|
||||
@ -31,21 +31,21 @@ sub itemContentChanged()
|
||||
m.top.overhangTitle = itemData.name
|
||||
|
||||
'Check production year, if invalid remove label
|
||||
if itemData.productionYear <> invalid
|
||||
if isValid(itemData.productionYear)
|
||||
setFieldText("releaseYear", itemData.productionYear)
|
||||
else
|
||||
m.top.findNode("main_group").removeChild(m.top.findNode("releaseYear"))
|
||||
end if
|
||||
|
||||
'Check officialRating, if invalid remove label
|
||||
if itemData.officialRating <> invalid
|
||||
if isValid(itemData.officialRating)
|
||||
setFieldText("officialRating", itemData.officialRating)
|
||||
else
|
||||
m.top.findNode("main_group").removeChild(m.top.findNode("officialRating"))
|
||||
end if
|
||||
|
||||
'Check communityRating, if invalid remove label
|
||||
if itemData.communityRating <> invalid
|
||||
if isValid(itemData.communityRating)
|
||||
m.top.findNode("star").visible = true
|
||||
setFieldText("communityRating", int(itemData.communityRating * 10) / 10)
|
||||
else
|
||||
@ -134,7 +134,7 @@ function getHistory() as string
|
||||
|
||||
airdays = itemData.airdays
|
||||
airtime = itemData.airtime
|
||||
if airtime <> invalid and airdays.count() = 1
|
||||
if isValid(airtime) and airdays.count() = 1
|
||||
airwords = airdays[0] + " at " + airtime
|
||||
end if
|
||||
|
||||
@ -148,10 +148,10 @@ function getHistory() as string
|
||||
end if
|
||||
|
||||
words = verb
|
||||
if airwords <> invalid
|
||||
if isValid(airwords)
|
||||
words = words + " " + airwords
|
||||
end if
|
||||
if studio <> invalid
|
||||
if isValid(studio)
|
||||
words = words + " on " + studio
|
||||
end if
|
||||
|
||||
|
@ -31,10 +31,10 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
||||
|
||||
' Special handling for "Programs" or "Vidoes" launched from "On Now" or elsewhere on the home screen...
|
||||
' basically anything that is a Live Channel.
|
||||
if isValid(meta?.json?.ChannelId)
|
||||
if meta.json.EpisodeTitle <> invalid
|
||||
if isValid(meta.json) and isValid(meta.json.ChannelId)
|
||||
if isValid(meta.json.EpisodeTitle)
|
||||
meta.title = meta.json.EpisodeTitle
|
||||
else if meta.json.Name <> invalid
|
||||
else if isValid(meta.json.Name)
|
||||
meta.title = meta.json.Name
|
||||
end if
|
||||
meta.showID = meta.json.id
|
||||
@ -243,11 +243,9 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
||||
video.content.SubtitleTracks = subtitles["text"]
|
||||
|
||||
' 'TODO: allow user selection of subtitle track before playback initiated, for now set to no subtitles
|
||||
|
||||
video.directPlaySupported = m.playbackInfo.MediaSources[0].SupportsDirectPlay
|
||||
fully_external = false
|
||||
|
||||
|
||||
' For h264/hevc video, Roku spec states that it supports specfic encoding levels
|
||||
' The device can decode content with a Higher Encoding level but may play it back with certain
|
||||
' artifacts. If the user preference is set, and the only reason the server says we need to
|
||||
@ -256,7 +254,7 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
||||
if m.playbackInfo.MediaSources[0].MediaStreams.Count() > 0 and meta.live = false
|
||||
tryDirectPlay = get_user_setting("playback.tryDirect.h264ProfileLevel") = "true" and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
|
||||
tryDirectPlay = tryDirectPlay or (get_user_setting("playback.tryDirect.hevcProfileLevel") = "true" and m.playbackInfo.MediaSources[0].MediaStreams[0].codec = "hevc")
|
||||
if tryDirectPlay and m.playbackInfo.MediaSources[0].TranscodingUrl <> invalid and forceTranscoding = false
|
||||
if tryDirectPlay and isValid(m.playbackInfo.MediaSources[0].TranscodingUrl) and forceTranscoding = false
|
||||
transcodingReasons = getTranscodeReasons(m.playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
if transcodingReasons.Count() = 1 and transcodingReasons[0] = "VideoLevelNotSupported"
|
||||
video.directPlaySupported = true
|
||||
@ -324,7 +322,6 @@ end sub
|
||||
function PlayIntroVideo(video_id, audio_stream_idx) as boolean
|
||||
' Intro videos only play if user has cinema mode setting enabled
|
||||
if get_user_setting("playback.cinemamode") = "true"
|
||||
|
||||
' Check if server has intro videos setup and available
|
||||
introVideos = GetIntroVideos(video_id)
|
||||
|
||||
@ -362,7 +359,6 @@ end function
|
||||
' Extract array of Transcode Reasons from the content URL
|
||||
' @returns Array of Strings
|
||||
function getTranscodeReasons(url as string) as object
|
||||
|
||||
regex = CreateObject("roRegex", "&TranscodeReasons=([^&]*)", "")
|
||||
match = regex.Match(url)
|
||||
|
||||
@ -384,19 +380,18 @@ end function
|
||||
|
||||
function directPlaySupported(meta as object) as boolean
|
||||
devinfo = CreateObject("roDeviceInfo")
|
||||
if meta.json.MediaSources[0] <> invalid and meta.json.MediaSources[0].SupportsDirectPlay = false
|
||||
if isValid(meta.json.MediaSources[0]) and meta.json.MediaSources[0].SupportsDirectPlay = false
|
||||
return false
|
||||
end if
|
||||
|
||||
if meta.json.MediaStreams[0] = invalid
|
||||
if not isValid(meta.json.MediaSources[0])
|
||||
return false
|
||||
end if
|
||||
|
||||
streamInfo = { Codec: meta.json.MediaStreams[0].codec }
|
||||
if meta.json.MediaStreams[0].Profile <> invalid and meta.json.MediaStreams[0].Profile.len() > 0
|
||||
if isValid(meta.json.MediaStreams[0].Profile) and meta.json.MediaStreams[0].Profile.len() > 0
|
||||
streamInfo.Profile = LCase(meta.json.MediaStreams[0].Profile)
|
||||
end if
|
||||
if meta.json.MediaSources[0].container <> invalid and meta.json.MediaSources[0].container.len() > 0
|
||||
if isValid(meta.json.MediaSources[0].container) and meta.json.MediaSources[0].container.len() > 0
|
||||
'CanDecodeVideo() requires the .container to be format: “mp4”, “hls”, “mkv”, “ism”, “dash”, “ts” if its to direct stream
|
||||
if meta.json.MediaSources[0].container = "mov"
|
||||
streamInfo.Container = "mp4"
|
||||
@ -406,8 +401,7 @@ function directPlaySupported(meta as object) as boolean
|
||||
end if
|
||||
|
||||
decodeResult = devinfo.CanDecodeVideo(streamInfo)
|
||||
return decodeResult <> invalid and decodeResult.result
|
||||
|
||||
return isValid(decodeResult) and decodeResult.result
|
||||
end function
|
||||
|
||||
function getContainerType(meta as object) as string
|
||||
@ -455,12 +449,12 @@ sub autoPlayNextEpisode(videoID as string, showID as string)
|
||||
resp = APIRequest(url, urlParams)
|
||||
data = getJson(resp)
|
||||
|
||||
if data <> invalid and data.Items.Count() = 2
|
||||
if isValid(data) and data.Items.Count() = 2
|
||||
' setup new video node
|
||||
nextVideo = CreateVideoPlayerGroup(data.Items[1].Id, invalid, 1, false, false)
|
||||
' remove last videoplayer scene
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
if nextVideo <> invalid
|
||||
if isValid(nextVideo)
|
||||
m.global.sceneManager.callFunc("pushScene", nextVideo)
|
||||
else
|
||||
m.global.sceneManager.callFunc("popScene")
|
||||
@ -478,7 +472,7 @@ end sub
|
||||
' In the future, with a custom playback info view, we can return an associated array.
|
||||
function GetPlaybackInfo()
|
||||
sessions = api_API().sessions.get()
|
||||
if sessions <> invalid and sessions.Count() > 0
|
||||
if isValid(sessions) and sessions.Count() > 0
|
||||
return GetTranscodingStats(sessions[0])
|
||||
end if
|
||||
|
||||
|
@ -38,7 +38,6 @@ function searchMedia(query as string)
|
||||
' This appears to be done differently on the web now
|
||||
' For each potential type, a separate query is done:
|
||||
' varying item types, and artists, and people
|
||||
|
||||
if query <> ""
|
||||
resp = APIRequest(Substitute("Search/Hints", get_setting("active_user")), {
|
||||
"searchTerm": query,
|
||||
@ -55,7 +54,6 @@ function searchMedia(query as string)
|
||||
"limit": 100
|
||||
})
|
||||
|
||||
|
||||
data = getJson(resp)
|
||||
results = []
|
||||
for each item in data.SearchHints
|
||||
@ -79,7 +77,7 @@ function ItemMetaData(id as string)
|
||||
|
||||
imgParams = {}
|
||||
if data.type <> "Audio"
|
||||
if data?.UserData?.PlayedPercentage <> invalid
|
||||
if data.UserData <> invalid and data.UserData.PlayedPercentage <> invalid
|
||||
param = { "PercentPlayed": data.UserData.PlayedPercentage }
|
||||
imgParams.Append(param)
|
||||
end if
|
||||
|
@ -21,7 +21,7 @@ end function
|
||||
' returns the server-side track index for the appriate subtitle
|
||||
function defaultSubtitleTrackFromVid(video_id) as integer
|
||||
meta = ItemMetaData(video_id)
|
||||
if meta?.json?.mediaSources <> invalid
|
||||
if isValid(meta) and isValid(meta.json) and isValid(meta.json.mediaSources)
|
||||
subtitles = sortSubtitles(meta.id, meta.json.MediaSources[0].MediaStreams)
|
||||
default_text_subs = defaultSubtitleTrack(subtitles["all"], true) ' Find correct subtitle track (forced text)
|
||||
if default_text_subs <> -1
|
||||
@ -130,7 +130,7 @@ function selectSubtitleTrackDialog(tracks, currentTrack = -1)
|
||||
default = ""
|
||||
if item.IsForced then forced = " [Forced]"
|
||||
if item.IsDefault then default = " - Default"
|
||||
if item.Track.Language <> invalid
|
||||
if isValid(item.Track.Language)
|
||||
language = iso6392.lookup(item.Track.Language)
|
||||
if language = invalid then language = item.Track.Language
|
||||
else
|
||||
@ -157,7 +157,7 @@ sub changeSubtitleDuringPlayback(newid)
|
||||
currentSubtitles = video.Subtitles[video.SelectedSubtitle]
|
||||
newSubtitles = video.Subtitles[newid]
|
||||
|
||||
if newSubtitles.IsEncoded or (currentSubtitles <> invalid and currentSubtitles.IsEncoded)
|
||||
if newSubtitles.IsEncoded or (isValid(currentSubtitles) and currentSubtitles.IsEncoded)
|
||||
' With encoded subtitles we need to stop/start playback
|
||||
video.control = "stop"
|
||||
AddVideoContent(video, video.mediaSourceId, video.audioIndex, newSubtitles.Index, video.position * 10000000)
|
||||
@ -195,7 +195,7 @@ function sortSubtitles(id as string, MediaStreams)
|
||||
if stream.type = "Subtitle"
|
||||
|
||||
url = ""
|
||||
if stream.DeliveryUrl <> invalid
|
||||
if isValid(stream.DeliveryUrl)
|
||||
url = buildURL(stream.DeliveryUrl)
|
||||
end if
|
||||
|
||||
|
@ -91,19 +91,23 @@ function get_dialog_result(dialog, port)
|
||||
end function
|
||||
|
||||
function lastFocusedChild(obj as object) as object
|
||||
if LCase(obj.focusedChild.focusedChild.subType()) = "tvepisodes"
|
||||
if isValid(obj?.focusedChild?.focusedChild?.lastFocus)
|
||||
return obj.focusedChild.focusedChild.lastFocus
|
||||
if isValid(obj)
|
||||
if isValid(obj.focusedChild) and isValid(obj.focusedChild.focusedChild) and LCase(obj.focusedChild.focusedChild.subType()) = "tvepisodes"
|
||||
if isValid(obj.focusedChild.focusedChild.lastFocus)
|
||||
return obj.focusedChild.focusedChild.lastFocus
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
child = obj
|
||||
for i = 0 to obj.getChildCount()
|
||||
if obj.focusedChild <> invalid
|
||||
child = child.focusedChild
|
||||
end if
|
||||
end for
|
||||
return child
|
||||
child = obj
|
||||
for i = 0 to obj.getChildCount()
|
||||
if isValid(obj.focusedChild)
|
||||
child = child.focusedChild
|
||||
end if
|
||||
end for
|
||||
return child
|
||||
else
|
||||
return invalid
|
||||
end if
|
||||
end function
|
||||
|
||||
function show_dialog(message as string, options = [], defaultSelection = 0) as integer
|
||||
@ -348,7 +352,7 @@ sub stopLoadingSpinner()
|
||||
if isValid(m.spinner)
|
||||
m.spinner.visible = false
|
||||
end if
|
||||
if isValid(m.scene?.dialog)
|
||||
if isValid(m.scene) and isValid(m.scene.dialog)
|
||||
m.scene.dialog.close = true
|
||||
end if
|
||||
end sub
|
||||
|
Loading…
Reference in New Issue
Block a user