components_config_SetServerScreen.bs

import "pkg:/source/roku_modules/log/LogMixin.brs"
import "pkg:/source/utils/config.bs"

sub init()
    m.log = log.Logger("SetServerScreen")
    m.top.setFocus(true)

    m.serverPicker = m.top.findNode("serverPicker")
    m.serverUrlTextbox = m.top.findNode("serverUrlTextbox")
    m.serverUrlContainer = m.top.findNode("serverUrlContainer")
    m.serverUrlOutline = m.top.findNode("serverUrlOutline")
    m.submit = m.top.findNode("submit")

    m.top.observeField("serverUrl", "clearErrorMessage")

    ScanForServers()
end sub

function onKeyEvent(key as string, press as boolean) as boolean
    m.log.debug("SetServerScreen onKeyEvent", key, press)

    if not press then return true
    handled = true

    if key = "OK" and m.serverPicker.hasFocus()
        m.top.serverUrl = m.serverPicker.content.getChild(m.serverPicker.itemFocused).baseUrl
        m.submit.setFocus(true)
        'if the user pressed the down key and we are already at the last child of server picker, then change focus to the url textbox
    else if key = "down" and m.serverPicker.hasFocus() and m.serverPicker.content.getChildCount() > 0 and m.serverPicker.itemFocused = m.serverPicker.content.getChildCount() - 1
        m.serverUrlContainer.setFocus(true)

        'user navigating up to the server picker from the input box (it's only focusable if it has items)
    else if key = "up" and m.serverUrlContainer.hasFocus() and m.servers.Count() > 0
        m.serverPicker.setFocus(true)
    else if key = "up" and m.serverUrlContainer.hasFocus() and m.servers.Count() = 0
        ScanForServers()
    else if key = "back" and m.serverUrlContainer.hasFocus() and m.servers.Count() > 0
        m.serverPicker.setFocus(true)
    else if key = "OK" and m.serverUrlContainer.hasFocus()
        ShowKeyboard()
    else if key = "back" and m.submit.hasFocus() and m.servers.Count() > 0
        m.serverPicker.setFocus(true)
    else if key = "back" and m.submit.hasFocus() and m.servers.Count() = 0
        m.serverUrlContainer.setFocus(true)
    else if key = "back" and m.serverUrlContainer.hasFocus() and m.servers.Count() = 0
        ScanForServers()
    else if key = "back" and m.serverPicker.hasFocus() and m.servers.Count() > 0
        ScanForServers()
        ' On "back" with or without available local servers, will rescan for servers
    else if key = "up" and m.submit.hasFocus()
        m.serverUrlContainer.setFocus(true)
        'focus the submit button from serverUrl
    else if key = "down" and m.serverUrlContainer.hasFocus()
        m.submit.setFocus(true)
    else if key = "options"
        if m.serverPicker.itemFocused >= 0 and m.serverPicker.itemFocused < m.serverPicker.content.getChildCount()
            serverName = m.serverPicker.content.getChild(m.serverPicker.itemFocused).name
            if m.servers.Count() > 0 and Instr(1, serverName, "Saved") > 0
                'Can only delete previously saved servers, not locally discovered ones
                'So if we are on a "Saved" item, let the options dialog be shown (handled elsewhere)
                handled = false
            end if
        end if
    else
        handled = false
    end if
    'show/hide input box outline
    m.serverUrlOutline.visible = m.serverUrlContainer.isInFocusChain()

    return handled
end function

sub ScanForServers()
    m.ssdpScanner = CreateObject("roSGNode", "ServerDiscoveryTask")
    'run the task
    m.ssdpScanner.observeField("content", "ScanForServersComplete")
    m.ssdpScanner.control = "RUN"
    startLoadingSpinner(false)
end sub

sub ScanForServersComplete(event)
    m.servers = event.getData()

    items = CreateObject("roSGNode", "ContentNode")
    for each server in m.servers
        server.subtype = "ContentNode"
        'add new fields for every server property onto the ContentNode (rather than making a dedicated component just to hold data...)
        items.update([server], true)
    end for

    'load any previously logged in to servers as well (if they aren't already discovered on the local network)
    saved = get_setting("saved_servers")
    if saved <> invalid
        savedServers = ParseJson(saved)
        for each server in savedServers.serverList
            alreadyListed = false
            for each listed in m.servers
                if LCase(listed.baseUrl) = server.baseUrl 'saved server data is always lowercase
                    alreadyListed = true
                    exit for
                end if
            end for
            if alreadyListed = false
                items.update([server], true)
                m.servers.push(server)
            end if
        end for
    end if

    m.serverPicker.content = items
    stopLoadingSpinner()

    'if we have at least one server, focus on the server picker
    if m.servers.Count() > 0
        m.serverPicker.setFocus(true)
        'no servers found...focus on the input textbox
    else
        m.serverUrlContainer.setFocus(true)
        'show/hide input box outline
        m.serverUrlOutline.visible = true
    end if

end sub

sub ShowKeyboard()
    dialog = createObject("roSGNode", "StandardKeyboardDialog")
    dialog.title = tr("Enter the server name or ip address")
    dialog.buttons = [tr("OK"), tr("Cancel")]
    dialog.text = m.serverUrlTextbox.text
    greenPalette = createObject("roSGNode", "RSGPalette")
    greenPalette.colors = { DialogBackgroundColor: "#2A2B2A" }
    dialog.palette = greenPalette

    m.top.getscene().dialog = dialog
    m.dialog = dialog

    dialog.observeField("buttonSelected", "onDialogButton")
end sub

function onDialogButton()
    d = m.dialog
    button_text = d.buttons[d.buttonSelected]

    if button_text = tr("OK")
        m.serverUrlTextbox.text = d.text
        m.dialog.close = true
        return true
    else if button_text = tr("Cancel")
        m.dialog.close = true
        return true
    else
        return false
    end if
end function

sub clearErrorMessage()
    m.top.errorMessage = ""
end sub

' JFScreen hook called when the screen is displayed by the screen manager
sub OnScreenShown()
    scene = m.top.getScene()
    overhang = scene.findNode("overhang")
    if isValid(overhang)
        overhang.isLogoVisible = true
        overhang.currentUser = ""
        overhang.title = ""
    end if
end sub