jf-roku/source/ShowScenes.brs
2019-04-29 21:47:40 -04:00

741 lines
21 KiB
Plaintext

sub ShowServerSelect()
' Get and Save Jellyfin Server Information
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("ConfigScene")
screen.show()
themeScene(scene)
scene.findNode("prompt").text = "Connect to Server"
config = scene.findNode("configOptions")
server_field = CreateObject("roSGNode", "ConfigData")
server_field.label = "Server"
server_field.field = "server"
server_field.type = "string"
port_field = CreateObject("roSGNode", "ConfigData")
port_field.label = "Port"
port_field.field = "port"
port_field.type = "string"
items = [ server_field, port_field ]
config.configItems = items
button = scene.findNode("submit")
button.observeField("buttonSelected", port)
server_hostname = config.content.getChild(0)
server_port = config.content.getChild(1)
while(true)
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed()
return
else if type(msg) = "roSGNodeEvent"
node = msg.getNode()
if node = "submit"
set_setting("server", server_hostname.value)
set_setting("port", server_port.value)
if ServerInfo() = invalid then
' 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?"
SignOut()
else
return
endif
end if
end if
end while
end sub
sub ShowSignInSelect()
' Get and Save Jellyfin user login credentials
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("ConfigScene")
screen.show()
themeScene(scene)
scene.findNode("prompt").text = "Sign In"
config = scene.findNode("configOptions")
username_field = CreateObject("roSGNode", "ConfigData")
username_field.label = "Username"
username_field.field = "username"
username_field.type = "string"
password_field = CreateObject("roSGNode", "ConfigData")
password_field.label = "Password"
password_field.field = "password"
password_field.type = "password"
items = [ username_field, password_field ]
config.configItems = items
button = scene.findNode("submit")
button.observeField("buttonSelected", port)
config = scene.findNode("configOptions")
username = config.content.getChild(0)
password = config.content.getChild(1)
while(true)
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed()
return
else if type(msg) = "roSGNodeEvent"
node = msg.getNode()
if node = "submit"
' Validate credentials
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."
end if
end if
end while
end sub
sub ShowLibrarySelect()
' Main screen after logging in. Shows the user's libraries
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("Library")
screen.show()
themeScene(scene)
libs = LibraryList()
scene.libraries = libs
scene.observeField("librarySelected", port)
library = scene.findNode("LibrarySelect")
search = scene.findNode("search")
search.observeField("escape", port)
search.observeField("search_value", port)
sidepanel = scene.findNode("options")
new_options = []
options_buttons = [
{"title": "Change server", "id": "change_server"},
{"title": "Sign out", "id": "sign_out"},
{"title": "Add User", "id": "add_user"}
]
for each opt in options_buttons
o = CreateObject("roSGNode", "OptionsButton")
o.title = opt.title
o.id = opt.id
new_options.push(o)
o.observeField("escape", port)
end for
' And a profile button
user_node = CreateObject("roSGNode", "OptionsData")
user_node.id = "active_user"
user_node.title = "Profile"
user_node.base_title = "Profile"
user_options = []
for each user in AvailableUsers()
user_options.push({display: user.username + "@" + user.server, value: user.id})
end for
user_node.choices = user_options
user_node.value = get_setting("active_user")
new_options.push(user_node)
sidepanel.options = new_options
sidepanel.observeField("escape", port)
while(true)
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "escape") and msg.getNode() = "search"
library.setFocus(true)
else if nodeEventQ(msg, "escape") and msg.getNode() = "options"
if user_node.value <> get_setting("active_user")
PickUser(user_node.value)
setGlobal("user_change", true)
return
end if
library.setFocus(true)
else if nodeEventQ(msg, "escape") and msg.getNode() = "change_server"
unset_setting("server")
unset_setting("port")
SignOut()
return
else if nodeEventQ(msg, "escape") and msg.getNode() = "sign_out"
SignOut()
return
else if nodeEventQ(msg, "escape") and msg.getNode() = "add_user"
' We don't want to SignOut the current user
unset_setting("active_user")
unset_setting("server")
unset_setting("port")
return
else if nodeEventQ(msg, "search_value")
query = msg.getRoSGNode().search_value
if query <> invalid or query <> ""
ShowSearchOptions(query)
end if
search.search_value = ""
else if nodeEventQ(msg, "librarySelected")
target = getMsgRowTarget(msg, "LibrarySelect")
if target.type = "movies"
ShowMovieOptions(target)
else if target.type = "tvshows"
ShowTVShowOptions(target)
else if target.type = "boxsets"
ShowCollections(target)
else
scene.dialog = make_dialog("This library type is not yet implemented: " + target.type)
scene.dialog.observeField("buttonSelected", port)
end if
else if nodeEventQ(msg, "buttonSelected")
if msg.getNode() = "popup"
msg.getRoSGNode().close = true
end if
else
print msg
end if
end while
end sub
sub ShowMovieOptions(library)
' Movie list page
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("Movies")
screen.show()
overhang = scene.findNode("overhang")
overhang.title = library.name
themeScene(scene)
options = scene.findNode("MovieSelect")
options.library = library
page_num = 1
page_size = 30
sort_order = get_user_setting("movie_sort_order", "Ascending")
sort_field = get_user_setting("movie_sort_field", "SortName")
options_list = ItemList(library.id, {"limit": page_size,
"StartIndex": page_size * (page_num - 1),
"SortBy": sort_field,
"SortOrder": sort_order,
"IncludeItemTypes": "Movie"
})
options.movieData = options_list
options.observeField("itemSelected", port)
pager = scene.findNode("pager")
pager.currentPage = page_num
pager.maxPages = options_list.TotalRecordCount / page_size
if pager.maxPages = 0 then pager.maxPages = 1
pager.observeField("escape", port)
pager.observeField("pageSelected", port)
sidepanel = scene.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("escape", port)
while true
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "escape") and msg.getNode() = "pager"
options.setFocus(true)
else if nodeEventQ(msg, "escape") and msg.getNode() = "options"
options.setFocus(true)
else if nodeEventQ(msg, "pageSelected") and pager.pageSelected <> invalid
pager.pageSelected = invalid
page_num = int(val(msg.getData().id))
pager.currentPage = page_num
options_list = ItemList(library.id, {"limit": page_size,
"StartIndex": page_size * (page_num - 1),
"SortBy": sort_order,
"SortOrder": sort_field })
options.movieData = options_list
options.setFocus(true)
else if nodeEventQ(msg, "itemSelected")
target = getMsgRowTarget(msg)
ShowMovieDetails(target)
else
print msg
print msg.getField()
print msg.getData()
end if
end while
end sub
sub ShowMovieDetails(movie)
' Movie detail page
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("MovieItemDetailScene")
screen.show()
themeScene(scene)
movie = ItemMetaData(movie.id)
scene.itemContent = movie
buttons = scene.findNode("buttons")
for each b in buttons.getChildren(-1, 0)
b.observeField("buttonSelected", port)
end for
while true
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "buttonSelected")
if msg.getNode() = "play-button"
showVideoPlayer(movie.id)
else if msg.getNode() = "watched-button"
if movie.watched
UnmarkItemWatched(movie.id)
else
MarkItemWatched(movie.id)
end if
movie.watched = not movie.watched
else if msg.getNode() = "favorite-button"
if movie.favorite
UnmarkItemFavorite(movie.id)
else
MarkItemFavorite(movie.id)
end if
movie.favorite = not movie.favorite
end if
else
print msg
print type(msg)
end if
end while
end sub
sub ShowTVShowOptions(library)
' TV Show List Page
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("TVShows")
screen.show()
overhang = scene.findNode("overhang")
overhang.title = library.name
themeScene(scene)
options = scene.findNode("TVShowSelect")
options.library = library
page_num = 1
page_size = 30
sort_order = get_user_setting("series_sort_order", "Ascending")
sort_field = get_user_setting("series_sort_field", "SortName")
options_list = ItemList(library.id, {"limit": page_size,
"page": page_num,
"SortBy": sort_field,
"SortOrder": sort_order })
options.TVShowData = options_list
options.observeField("itemSelected", port)
pager = scene.findNode("pager")
pager.currentPage = page_num
pager.maxPages = options_list.TotalRecordCount / page_size
if pager.maxPages = 0 then pager.maxPages = 1
pager.observeField("escape", port)
pager.observeField("pageSelected", port)
sidepanel = scene.findNode("options")
panel_options = [
{"title": "Sort Field",
"base_title": "Sort Field",
"key": "series_sort_field",
"default": "SortName",
"values": [
{display: "Date Added", value: "DateCreated"},
{display: "Release Date", value: "PremiereDate"},
{display: "Name", value: "SortName"}
]},
{"title": "Sort Order",
"base_title": "Sort Order",
"key": "series_sort_order",
"default": "Ascending",
"values": [
{display: "Descending", value: "Descending"},
{display: "Ascending", value: "Ascending"}
]}
]
new_options = []
for each opt in panel_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("escape", port)
while true
msg = wait(0, port)
if nodeEventQ(msg, "escape") and msg.getNode() = "pager"
options.setFocus(true)
' TODO - rename
' Obnoxiously here, "options" getNode is the "options panel"
' and options.setFocus is the "options of tv shows"
else if nodeEventQ(msg, "escape") and msg.getNode() = "options"
options.setFocus(true)
else if nodeEventQ(msg, "pageSelected") and pager.pageSelected <> invalid
pager.pageSelected = invalid
page_num = int(val(msg.getData().id))
pager.currentPage = page_num
options_list = ItemList(library.id, {"limit": page_size,
"StartIndex": page_size * (page_num - 1),
"SortBy": sort_field,
"SortOrder": sort_order })
options.TVShowData = options_list
options.setFocus(true)
else if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "itemSelected")
target = getMsgRowTarget(msg)
ShowTVShowDetails(target)
end if
end while
end sub
sub ShowTVShowDetails(series)
' TV Show Detail Page
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("TVShowItemDetailScene")
screen.show()
themeScene(scene)
series = ItemMetaData(series.id)
scene.itemData = series
scene.findNode("description").findNode("buttons").setFocus(true)
scene.seasonData = TVSeasons(series.id)
scene.findNode("description").findNode("buttons").setFocus(true)
'buttons = scene.findNode("buttons")
'buttons.observeField("buttonSelected", port)
scene.findNode("seasons").observeField("rowItemSelected", port)
while true
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "buttonSelected")
' What button could we even be watching yet
else if nodeEventQ(msg, "rowItemSelected")
' Assume for now it's a season being selected
season_list = msg.getRoSGNode()
item = msg.getData()
season = season_list.content.getChild(item[0]).getChild(item[1])
ShowTVSeasonEpisodes(series, season)
else
print msg
print type(msg)
end if
end while
end sub
sub ShowTVSeasonEpisodes(series, season)
' TV Show Season Episdoe List
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("TVEpisodes")
screen.show()
themeScene(scene)
scene.showData = ItemMetaData(series.id)
scene.seasonData = TVSeasons(series.id)
scene.episodeData = TVEpisodes(series.id, season.id)
scene.findNode("TVEpisodeSelect").observeField("rowItemSelected", port)
while true
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "rowItemSelected")
episode_list = msg.getRoSGNode()
item = msg.getData()
episode = episode_list.content.getChild(item[0]).getChild(item[1])
ShowVideoPlayer(episode.id)
else
print msg
print type(msg)
end if
end while
end sub
sub ShowCollections(library)
' Load Movie Collection Items
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("Collections")
screen.show()
overhang = scene.findNode("overhang")
overhang.title = library.name
themeScene(scene)
options = scene.findNode("CollectionSelect")
options.library = library
page_num = 1
page_size = 30
sort_order = get_user_setting("collection_sort_order", "Ascending")
sort_field = get_user_setting("collection_sort_field", "SortName")
options_list = ItemList(library.id, {"limit": page_size,
"StartIndex": page_size * (page_num - 1),
"SortBy": sort_field,
"SortOrder": sort_order })
options.itemData = options_list
options.observeField("itemSelected", port)
pager = scene.findNode("pager")
pager.currentPage = page_num
pager.maxPages = options_list.TotalRecordCount / page_size
if pager.maxPages = 0 then pager.maxPages = 1
pager.observeField("escape", port)
pager.observeField("pageSelected", port)
sidepanel = scene.findNode("options")
panel_options = [
{"title": "Sort Field",
"base_title": "Sort Field",
"key": "movie_sort_field",
"default": "SortName",
"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 panel_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("escape", port)
while true
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "escape") and msg.getNode() = "pager"
options.setFocus(true)
else if nodeEventQ(msg, "escape") and msg.getNode() = "options"
options.setFocus(true)
else if nodeEventQ(msg, "pageSelected") and pager.pageSelected <> invalid
pager.pageSelected = invalid
page_num = int(val(msg.getData().id))
pager.currentPage = page_num
options_list = ItemList(library.id, {"limit": page_size,
"StartIndex": page_size * (page_num - 1),
"SortBy": sort_order,
"SortOrder": sort_field })
options.itemData = options_list
options.setFocus(true)
else if nodeEventQ(msg, "itemSelected")
target = getMsgRowTarget(msg)
ShowMovieOptions(target)
else
print msg
print msg.getField()
print msg.getData()
end if
end while
end sub
sub ShowSearchOptions(query)
' Search Results Page
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("SearchResults")
screen.show()
themeScene(scene)
options = scene.findNode("SearchSelect")
sort_order = get_user_setting("search_sort_order", "Ascending")
sort_field = get_user_setting("search_sort_field", "SortName")
results = SearchMedia(query)
options.itemData = results
options.query = query
options.observeField("itemSelected", port)
while true
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
return
else if nodeEventQ(msg, "itemSelected")
target = getMsgRowTarget(msg)
' TODO - swap this based on target.mediatype
' types: [ Episode, Movie, Audio, Person, Studio, MusicArtist ]
ShowMovieDetails(target)
else
print msg
print msg.getField()
print msg.getData()
end if
end while
end sub
sub showVideoPlayer(video_id)
' Video is Playing
port = CreateObject("roMessagePort")
screen = CreateObject("roSGScreen")
screen.setMessagePort(port)
scene = screen.CreateScene("Scene")
screen.show()
themeScene(scene)
video = VideoPlayer(video_id)
scene.appendChild(video)
video.setFocus(true)
video.observeField("state", port)
while true
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then
PlaystateStop(video_id)
return
' Video is already gone by this point
' TODO - add an event listener higher up that watches for closing
' so we can handle end of video a bit better
if video = invalid then return
progress = int( video.position / video.duration * 100)
if progress > 95 ' TODO - max resume percentage
MarkItemWatched(video_id)
end if
ticks = video.position * 10000000
PlaystateStop(video_id, {"PositionTicks": ticks})
return
else if nodeEventQ(msg, "state")
state = msg.getData()
if state = "stopped" or state = "finished"
print "Stopping Video!"
ticks = video.position * 10000000
PlaystateStop(video_id, {"PositionTicks": ticks})
screen.close()
else if state = "paused"
ticks = video.position * 10000000
PlaystateUpdate(video_id, {
"PositionTicks": ticks,
"IsPaused": true
})
else if state = "playing"
ticks = video.position * 10000000
PlaystateStart(video_id, {
"PositionTicks": ticks,
"IsPaused": false
})
end if
end if
end while
end sub