components_data_SceneManager.bs
import "pkg:/source/roku_modules/log/LogMixin.brs"
import "pkg:/source/utils/dialogs.bs"
import "pkg:/source/utils/misc.bs"
sub init()
m.log = new log.Logger("SceneManager")
m.scene = m.top.getScene()
m.overhang = m.scene.findNode("overhang")
end sub
' SceneManager is purely a shared SERVICE node — backdrop, theme, the overhang user/clock
' passthroughs below, and the one dialog QUERY (isDialogOpen) that needs to answer for both
' presentation channels at once. It no longer SHOWS dialogs: every dialog in the app goes
' through source/utils/dialogs.bs and answers on its own node. The router host (JRScene) owns
' navigation and its own overhang controller; there is no scene stack (pushScene / popScene /
' getActiveScene etc.).
' Signal that home screen should be reloaded (used after theme color changes)
' Main.bs observes reloadHomeRequested field and handles the actual reload
sub reloadHome()
m.top.reloadHomeRequested = true
end sub
' Update username in overhang
sub updateUser()
' Passthrough to overhang
if isValid(m.overhang) then m.overhang.currentUser = m.top.currentUser
end sub
' Reset time
sub resetTime()
' Passthrough to overhang
m.overhang.callFunc("resetTime")
end sub
' Set the background image
' @param {string} uri - The image URI to display
' @param {boolean} isAnimated - Whether to animate the transition
' @param {boolean} forceBackdrop - Force show backdrop regardless of user setting (used for login splashscreen)
sub setBackgroundImage(uri as string, isAnimated = true as boolean, forceBackdrop = false as boolean)
m.log.info("SceneManager.setBackgroundImage called", uri, isAnimated, forceBackdrop)
' Passthrough to scene via callFunc
if isValid(m.scene)
m.scene.callFunc("setBackgroundImage", uri, isAnimated, forceBackdrop)
else
m.log.error("SceneManager.setBackgroundImage: m.scene is invalid!")
end if
end sub
' Is ANY dialog currently on screen? Callers use this to hold off on something
' that would interfere — the OSD's inactivity auto-hide, the player's
' end-of-playback teardown.
'
' There are TWO channels and this must answer for both. It used to check only
' Roku's modal channel, so it began silently returning false for every dialog in
' the app when the JRDialog family moved to scene-appended overlays. The OSD read
' that false and hid itself out from under an open dialog, taking focus with it
' — the dialog stayed on screen but deaf, and Back fell through to the player.
function isDialogOpen() as boolean
if isValid(m.scene.dialog) then return true
return isOverlayDialogOpen()
end function
' Refresh theme colors on JRScene and overhang.
' Called after theme color settings change (settings exit, login, logout).
' Uses refreshThemeOnTree() to walk the overhang's node tree and update all
' themed elements (labels, buttons, icons) in place — no component recreation
' or per-component refresh functions needed.
sub refreshThemeColors()
m.scene.backgroundColor = m.global.constants.colorBackgroundPrimary
if isValid(m.overhang)
refreshThemeOnTree(m.overhang)
end if
end sub