components_login_UserSelect.bs
import "pkg:/source/api/baserequest.bs"
import "pkg:/source/roku_modules/log/LogMixin.brs"
import "pkg:/source/utils/misc.bs"
sub init()
m.log = log.Logger("UserSelect")
m.log.verbose("Initializing UserSelect component")
m.top.optionsAvailable = false
m.buttons = m.top.findNode("buttons")
m.buttons.callFunc("center")
' Create branding config task (reusable instance)
m.brandingTask = createObject("roSGNode", "BrandingConfigTask")
m.log.debug("Created BrandingConfigTask")
end sub
sub itemContentChanged()
stopLoadingSpinner()
m.top.findNode("UserRow").ItemContent = m.top.itemContent
redraw()
end sub
sub redraw()
userCount = m.top.itemContent.Count()
topBorder = 360
leftBorder = 130
itemWidth = 300
itemSpacing = 40
if userCount < 5
leftBorder = (1920 - ((userCount * itemWidth) + ((userCount - 1) * itemSpacing))) / 2
end if
' break()
m.top.findNode("UserRow").translation = [leftBorder, topBorder]
end sub
' JRScreen hook called when the screen is displayed by the screen manager
sub OnScreenShown()
m.log.info("UserSelect screen shown")
scene = m.top.getScene()
overhang = scene.findNode("overhang")
if isValid(overhang)
overhang.isLogoVisible = true
overhang.currentUser = ""
m.log.debug("Configured overhang for UserSelect")
end if
' Load splashscreen (handles race condition)
loadSplashscreen()
end sub
' JRScreen hook called when the screen is hidden by the screen manager
sub OnScreenHidden()
m.log.info("UserSelect screen hidden - clearing backdrop")
' Stop task to prevent wasted resources
m.brandingTask.control = "STOP"
' Cleanup observers and reset task
m.global.server.unobserveFieldScoped("splashscreenEnabled")
m.brandingTask.unobserveFieldScoped("responseCode")
m.brandingTask.callFunc("empty")
' Clear backdrop using forceBackdrop to ensure it clears even before login
m.global.sceneManager.callFunc("setBackgroundImage", "", true, true)
end sub
' Load splashscreen if enabled on server
' Always fetches fresh branding config from server
sub loadSplashscreen()
m.log.info("Loading splashscreen - fetching branding config from server")
' Clear backdrop while waiting (forceBackdrop ensures it works before login)
m.global.sceneManager.callFunc("setBackgroundImage", "", false, true)
' Check if value is already cached (from previous session)
serverNode = m.global.server
if isValid(serverNode.splashscreenEnabled)
' Already cached, apply immediately for instant display
m.log.debug("Splashscreen setting already cached, applying immediately")
applySplashscreen(serverNode.splashscreenEnabled)
else
m.log.debug("Splashscreen setting not cached")
end if
' Always observe and refresh in case cached value is stale
serverNode.observeFieldScoped("splashscreenEnabled", "onSplashscreenEnabledLoaded")
m.brandingTask.observeFieldScoped("responseCode", "onBrandingConfigComplete")
m.brandingTask.control = "RUN"
end sub
' Called when branding config task completes
sub onBrandingConfigComplete()
responseCode = m.brandingTask.responseCode
m.log.debug("Branding config fetch completed", "responseCode:", responseCode)
if responseCode = 200
m.log.info("Branding config cached successfully", "splashscreenEnabled:", m.global.server.splashscreenEnabled)
else
failureReason = m.brandingTask.failureReason
m.log.warn("Branding config fetch failed", "reason:", failureReason)
end if
' Cleanup task
m.brandingTask.unobserveFieldScoped("responseCode")
m.brandingTask.callFunc("empty")
end sub
' Called when branding config finishes loading (if we had to wait)
sub onSplashscreenEnabledLoaded()
serverNode = m.global.server
splashEnabled = serverNode.splashscreenEnabled
m.log.debug("Branding config loaded (async)", "splashscreenEnabled:", splashEnabled)
' Unobserve (only fire once)
serverNode.unobserveFieldScoped("splashscreenEnabled")
' Check validity again (defensive)
if isValid(splashEnabled)
applySplashscreen(splashEnabled)
else
m.log.warn("Branding config still invalid after loading - using default")
' Clear backdrop using forceBackdrop to ensure it works before login
m.global.sceneManager.callFunc("setBackgroundImage", "", true, true)
end if
end sub
' Apply splash background based on enabled flag
' Uses forceBackdrop parameter to show splashscreen before user login
sub applySplashscreen(serverSplashEnabled as boolean)
' Get global splash screen setting (reads from registry or settings.json default)
' This works before user login since global settings are device-wide
globalSetting = getGlobalSplashScreenSetting()
' Resolve splash screen setting (JellyRock global override or server setting)
splashEnabled = resolveSplashScreen(globalSetting, serverSplashEnabled)
m.log.debug("Applying splashscreen", "globalSetting:", globalSetting, "serverSetting:", serverSplashEnabled, "resolvedValue:", splashEnabled)
if splashEnabled = true
' Build splash URL with correct parameters
splashUrl = buildURL("/Branding/Splashscreen", { "format": "jpg", "tag": "splash" })
' buildURL returns invalid when server URL is not configured
if not isValid(splashUrl)
m.log.warn("Cannot load splashscreen - server URL not configured")
m.global.sceneManager.callFunc("setBackgroundImage", "", true, true)
return
end if
m.log.info("Splashscreen enabled - loading", splashUrl)
' Set backdrop with animation, forceBackdrop=true bypasses user setting check
m.global.sceneManager.callFunc("setBackgroundImage", splashUrl, true, true)
else
m.log.info("Splashscreen disabled - using default background")
m.global.sceneManager.callFunc("setBackgroundImage", "", true, true)
end if
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if key = "back"
m.top.backPressed = true
return true
else if key = "up"
if m.top.focusedChild.isSubType("JRButtonGroup")
m.top.findNode("UserRow").setFocus(true)
return true
end if
else if key = "down"
if m.top.focusedChild.isSubType("UserRow")
m.buttons.callFunc("focus")
return true
end if
end if
return false
end function