So much reorganizing

This commit is contained in:
Nick Bisby 2019-10-13 14:33:14 -05:00
parent e1839b66cd
commit 0ec2872093
21 changed files with 200 additions and 115 deletions

View File

@ -87,9 +87,6 @@ function onKeyEvent(key as string, press as boolean) as boolean
if key = "down" and (m.top.itemFocused + 1) = m.top.content.getChildCount()
m.top.escapeButton = "down"
return true
else if key = "options"
m.top.escapeButton = "options"
return true
end if
return false

View File

@ -4,10 +4,5 @@ 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
end if
return false
end function

View File

@ -0,0 +1,11 @@
sub init()
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if key = "OK"
m.top.close = true
return true
end if
return false
end function

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="JFMessageDialog" extends="Dialog">
<script type="text/brightscript" uri="JFMessageDialog.brs" />
</component>

16
components/JFScene.brs Normal file
View File

@ -0,0 +1,16 @@
sub init()
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 = "options"
m.top.optionsPressed = true
return true
end if
return false
end function

8
components/JFScene.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="JFScene" extends="Scene">
<interface>
<field id="backPressed" type="boolean" alwaysNotify="true" />
<field id="optionsPressed" type="boolean" alwaysNotify="true" />
</interface>
<script type="text/brightscript" uri="JFScene.brs" />
</component>

View File

@ -1,13 +1,2 @@
sub init()
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
end if
return false
end function

View File

@ -23,6 +23,7 @@ function setData()
end function
function onItemSelected()
print "HI"
i = m.top.itemSelected
itemField = m.top.content.getchild(i)
@ -59,7 +60,7 @@ sub show_dialog(configField)
dialog.text = configField.value
end if
m.top.getparent().dialog = dialog
m.top.getscene().dialog = dialog
m.dialog = dialog
dialog.observeField("buttonSelected", "onDialogButton")

View File

@ -1,6 +1,4 @@
sub init()
m.top.backgroundColor = "#000b35ff"
m.top.backgroundURI = ""
m.tracker=m.top.createChild("TrackerTask")
m.top.setFocus(true)
end sub
@ -8,6 +6,7 @@ end sub
function onKeyEvent(key as String, press as Boolean) as Boolean
' Returns true if user navigates to a new focusable element
if not press then return false
list = m.top.findNode("configOptions")
button = m.top.findNode("submit")
if key = "down" and button.focusedChild = invalid

View File

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="ConfigScene" extends="Scene">
<component name="ConfigScene" extends="JFGroup">
<children>
<Overhang
id="overhang"
title="Configure"
/>
<label text="Enter Configuration"
id="prompt"
font="font:LargeBoldSystemFont"

View File

@ -2,5 +2,4 @@ sub init()
end sub
sub press()
m.top.escape = true
end sub

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="OptionsButton" extends="ContentNode">
<interface>
<field id="escape" type="boolean" alwaysNotify="true" />
<function name="press" />
<field id="optionSelected" type="boolean" alwaysNotify="true" />
</interface>
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
<script type="text/brightscript" uri="options-button.brs" />

View File

@ -3,7 +3,6 @@
<children>
<LibraryRow id="LibrarySelect" />
<Rectangle id="footerBackdrop" height="200" />
<SearchBox id="search" />
<OptionsSlider id="options" />
</children>

View File

@ -134,14 +134,3 @@ function round(f as float) as integer
return n
end if
end function
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
end if
return false
end function

View File

@ -1,14 +1,3 @@
sub init()
m.top.overhangTitle = "Movies"
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
end if
return false
end function
end sub

View File

@ -2,6 +2,7 @@
<component name="Movies" extends="JFGroup">
<children>
<ItemGrid id="picker" visible="true" itemsPerRow="10" />
<OptionsSlider id="options" />
</children>
<interface>
<field id="movieSelected" alias="picker.itemSelected" />

View File

@ -11,13 +11,6 @@ sub init()
list = m.top.findNode("panelList")
panel.list = list
bd = m.top.findNode("backdrop")
bd.color = "#101010DD"
bd.translation = [0, 0]
dimensions = m.top.getScene().currentDesignResolution
bd.width = 575
bd.height = dimensions.height
end sub
sub setFields()
@ -35,12 +28,12 @@ function onKeyEvent(key as string, press as boolean) as boolean
if key = "options" or key = "back"
m.top.visible = false
m.top.escape = true
m.top.closeSidePanel = true
return true
else if key = "OK"
list = m.top.findNode("panelList")
data = list.content.getChild(list.itemFocused)
data.callFunc("press")
data.optionSelected = true
return true
end if

View File

@ -2,7 +2,11 @@
<component name="OptionsSlider" extends="PanelSet">
<children>
<ListPanel id="panel">
<Rectangle id="backdrop" />
<Rectangle id="backdrop"
translation="[0, 0]"
color="#101010DD"
width="575"
height="1080" />
<LabelList id="panelList">
<ContentNode id="fieldList" role="content" />
</LabelList>
@ -11,7 +15,7 @@
<interface>
<field id="buttons" type="nodearray" onChange="setFields" />
<field id="options" type="nodearray" onChange="setFields" />
<field id="escape" type="boolean" alwaysNotify="true" />
<field id="closeSidePanel" type="boolean" alwaysNotify="true" />
</interface>
<script type="text/brightscript" uri="panel.brs" />
</component>

View File

@ -7,7 +7,7 @@ sub Main()
m.screen = CreateObject("roSGScreen")
m.port = CreateObject("roMessagePort")
m.screen.setMessagePort(m.port)
m.scene = m.screen.CreateScene("Scene")
m.scene = m.screen.CreateScene("JFScene")
m.screen.show()
m.overhang = CreateObject("roSGNode", "JFOverhang")
@ -20,10 +20,17 @@ sub Main()
' Confirm the configured server and user work
group = CreateLibraryScene()
group = CreateLibraryGroup()
m.overhang.title = group.overhangTitle
m.scene.appendChild(group)
m.scene.observeField("backPressed", m.port)
m.scene.observeField("optionsPressed", m.port)
' This is the core logic loop. Mostly for transitioning between scenes
' This now only references m. fields so could be placed anywhere, in theory
' "group" is always "whats on the screen"
' m.scene's children is the "previous view" stack
while(true)
msg = wait(0, m.port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
@ -46,6 +53,17 @@ sub Main()
group.setFocus(true)
end if
group.visible = true
else if isNodeEvent(msg, "optionsPressed")
group.lastFocus = group.focusedChild
panel = group.findNode("options")
panel.visible = true
panel.findNode("panelList").setFocus(true)
else if isNodeEvent(msg, "closeSidePanel")
if group.lastFocus <> invalid
group.lastFocus.setFocus(true)
else
group.setFocus(true)
end if
else if isNodeEvent(msg, "librarySelected")
' If you select a library from ANYWHERE, follow this flow
node = getMsgPicker(msg, "LibrarySelect")
@ -54,11 +72,12 @@ sub Main()
group.setFocus(false)
group.visible = false
group = CreateMovieScene(node)
group = CreateMovieListGroup(node)
m.overhang.title = group.overhangTitle
m.scene.appendChild(group)
else
print node.type
' TODO - switch on more node types
message_dialog("This library type is not yet implemented: " + node.type)
end if
else if isNodeEvent(msg, "movieSelected")
' If you select a movie from ANYWHERE, follow this flow
@ -68,25 +87,46 @@ sub Main()
group.setFocus(false)
group.visible = false
group = CreateMovieDetails(node)
group = CreateMovieDetailsGroup(node)
m.scene.appendChild(group)
m.overhang.title = group.overhangTitle
else if isNodeEvent(msg, "buttonSelected")
' If a button is selected, we have some determining to do
btn = getButton(msg)
if btn.id = "play-button"
' TODO - Do a better job of picking the focusedChild
' TODO - Do a better job of picking the last focus
group.lastFocus = group.focusedChild
group.setFocus(false)
group.visible = false
video_id = group.id
group = CreateVideoPlayer(video_id)
group = CreateVideoPlayerGroup(video_id)
m.scene.appendChild(group)
group.setFocus(true)
group.control = "play"
m.overhang.visible = false
end if
else if isNodeEvent(msg, "optionSelected")
button = msg.getRoSGNode()
if button.id = "goto_search"
print "Search goes here"
else if button.id = "change_server"
unset_setting("server")
unset_setting("port")
SignOut()
wipe_groups()
goto app_start
else if button.id = "sign_out"
SignOut()
wipe_groups()
goto app_start
else if button.id = "add_user"
unset_setting("active_user")
unset_setting("server")
unset_setting("port")
wipe_groups()
goto app_start
end if
else
print type(msg)
print msg
@ -100,12 +140,12 @@ sub LoginFlow()
start_login:
if get_setting("server") = invalid or ServerInfo() = invalid then
print "Get server details"
ShowServerSelect()
CreateServerGroup()
end if
if get_setting("active_user") = invalid then
print "Get user login"
ShowSigninSelect()
CreateSigninGroup()
end if
m.user = AboutMe()
@ -114,6 +154,8 @@ sub LoginFlow()
unset_setting("active_user")
goto start_login
end if
wipe_groups()
end sub
sub RunScreenSaver()
@ -135,4 +177,11 @@ sub RunScreenSaver()
end if
end while
end sub
sub wipe_groups()
' The 1 remaining child should be the overhang
while(m.scene.getChildCount() > 1)
m.scene.removeChildIndex(1)
end while
end sub

View File

@ -1,15 +1,12 @@
sub ShowServerSelect()
sub CreateServerGroup()
' Get and Save Jellyfin Server Information
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("ConfigScene")
screen.show()
group = CreateObject("roSGNode", "ConfigScene")
m.scene.appendChild(group)
themeScene(scene)
scene.findNode("prompt").text = "Connect to Server"
group.findNode("prompt").text = "Connect to Server"
config = scene.findNode("configOptions")
config = group.findNode("configOptions")
server_field = CreateObject("roSGNode", "ConfigData")
server_field.label = "Server"
server_field.field = "server"
@ -27,14 +24,14 @@ sub ShowServerSelect()
items = [ server_field, port_field ]
config.configItems = items
button = scene.findNode("submit")
button.observeField("buttonSelected", port)
button = group.findNode("submit")
button.observeField("buttonSelected", m.port)
server_hostname = config.content.getChild(0)
server_port = config.content.getChild(1)
while(true)
msg = wait(0, port)
msg = wait(0, m.port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed()
return
else if type(msg) = "roSGNodeEvent"
@ -46,28 +43,28 @@ sub ShowServerSelect()
' Maybe don't unset setting, but offer as a prompt
' Server not found, is it online? New values / Retry
print "Server not found, is it online? New values / Retry"
scene.findNode("alert").text = "Server not found, is it online?"
group.findNode("alert").text = "Server not found, is it online?"
SignOut()
else
group.visible = false
return
endif
end if
end if
end while
' Just hide it when done, in case we need to come back
group.visible = false
end sub
sub ShowSignInSelect()
sub CreateSigninGroup()
' Get and Save Jellyfin user login credentials
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("ConfigScene")
screen.show()
group = CreateObject("roSGNode", "ConfigScene")
m.scene.appendChild(group)
themeScene(scene)
scene.findNode("prompt").text = "Sign In"
group.findNode("prompt").text = "Sign In"
config = scene.findNode("configOptions")
config = group.findNode("configOptions")
username_field = CreateObject("roSGNode", "ConfigData")
username_field.label = "Username"
username_field.field = "username"
@ -79,17 +76,18 @@ sub ShowSignInSelect()
items = [ username_field, password_field ]
config.configItems = items
button = scene.findNode("submit")
button.observeField("buttonSelected", port)
button = group.findNode("submit")
button.observeField("buttonSelected", m.port)
config = scene.findNode("configOptions")
config = group.findNode("configOptions")
username = config.content.getChild(0)
password = config.content.getChild(1)
while(true)
msg = wait(0, port)
msg = wait(0, m.port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed()
group.visible = false
return
else if type(msg) = "roSGNodeEvent"
node = msg.getNode()
@ -98,13 +96,16 @@ sub ShowSignInSelect()
get_token(username.value, password.value)
if get_setting("active_user") <> invalid then return
print "Login attempt failed..."
scene.findNode("alert").text = "Login attempt failed."
group.findNode("alert").text = "Login attempt failed."
end if
end if
end while
' Just hide it when done, in case we need to come back
group.visible = false
end sub
function CreateLibraryScene()
function CreateLibraryGroup()
' Main screen after logging in. Shows the user's libraries
group = CreateObject("roSGNode", "Library")
@ -112,15 +113,14 @@ function CreateLibraryScene()
group.libraries = libs
group.observeField("librarySelected", m.port)
group.observeField("backPressed", m.port)
library = group.findNode("LibrarySelect")
search = group.findNode("search")
sidepanel = group.findNode("options")
sidepanel.observeField("closeSidePanel", m.port)
new_options = []
options_buttons = [
{"title": "Search", "id": "goto_search"},
{"title": "Change server", "id": "change_server"},
{"title": "Sign out", "id": "sign_out"},
{"title": "Add User", "id": "add_user"}
@ -129,6 +129,7 @@ function CreateLibraryScene()
o = CreateObject("roSGNode", "OptionsButton")
o.title = opt.title
o.id = opt.id
o.observeField("optionSelected", m.port)
new_options.push(o)
end for
@ -150,16 +151,49 @@ function CreateLibraryScene()
return group
end function
function CreateMovieScene(library)
function CreateMovieListGroup(library)
group = CreateObject("roSGNode", "Movies")
group.observeField("backPressed", m.port)
group.observeField("movieSelected", m.port)
sidepanel = group.findNode("options")
movie_options = [
{"title": "Sort Field",
"base_title": "Sort Field",
"key": "movie_sort_field",
"default": "DateCreated",
"values": [
{display: "Date Added", value: "DateCreated"},
{display: "Release Date", value: "PremiereDate"},
{display: "Name", value: "SortName"}
]},
{"title": "Sort Order",
"base_title": "Sort Order",
"key": "movie_sort_order",
"default": "Ascending",
"values": [
{display: "Descending", value: "Descending"},
{display: "Ascending", value: "Ascending"}
]}
]
new_options = []
for each opt in movie_options
o = CreateObject("roSGNode", "OptionsData")
o.title = opt.title
o.choices = opt.values
o.base_title = opt.base_title
o.config_key = opt.key
o.value = get_user_setting(opt.key, opt.default)
new_options.append([o])
end for
sidepanel.options = new_options
sidepanel.observeField("closeSidePanel", m.port)
page_num = 1
page_size = 20
sort_order = "Ascending"
sort_field = "SortName"
sort_order = get_user_setting("movie_sort_order", "Ascending")
sort_field = get_user_setting("movie_sort_field", "SortName")
item_list = ItemList(library.id, {"limit": page_size,
"StartIndex": page_size * (page_num - 1),
@ -172,10 +206,9 @@ function CreateMovieScene(library)
return group
end function
function CreateMovieDetails(movie)
function CreateMovieDetailsGroup(movie)
group = CreateObject("roSGNode", "MovieDetails")
group.observeField("backPressed", m.port)
movie = ItemMetaData(movie.id)
group.itemContent = movie
@ -509,7 +542,14 @@ sub ShowSearchOptions(query)
end while
end sub
function CreateVideoPlayer(video_id)
function CreateSidePanel(buttons, options)
group = CreateObject("roSGNode", "OptionsSlider")
group.buttons = buttons
group.options = options
end function
function CreateVideoPlayerGroup(video_id)
' Video is Playing
video = VideoPlayer(video_id)

View File

@ -35,12 +35,19 @@ function leftPad(base as string, fill as string, length as integer) as string
return base
end function
function make_dialog(message="" as string)
function message_dialog(message="" as string)
' Takes a string and returns an object for dialog popup
dialog = createObject("roSGNode", "Dialog")
dialog = createObject("roSGNode", "JFMessageDialog")
dialog.id = "popup"
dialog.buttons = ["OK"]
dialog.message = message
return dialog
m.scene.dialog = dialog
m.scene.dialog.observeField("buttonSelected", handle_dialog)
m.scene.dialog.setFocus(true)
end function
function handle_dialog(msg)
print("THERE")
m.scene.dialog.close = true
end function