Add Quick Connect.

This commit is contained in:
Jimi 2022-05-29 14:00:38 -06:00 committed by Cody Robibero
parent 3e11cd5ec8
commit 72f53da656
9 changed files with 215 additions and 8 deletions

View File

@ -9,25 +9,32 @@ function onKeyEvent(key as string, press as boolean) as boolean
list = m.top.findNode("configOptions")
checkbox = m.top.findNode("onOff")
button = m.top.findNode("submit")
submit = m.top.findNode("submit")
quickConnect = m.top.findNode("quickConnect")
if key = "back"
m.top.backPressed = true
else if key = "down" and checkbox.focusedChild = invalid and button.focusedChild = invalid
else if key = "down" and checkbox.focusedChild = invalid and submit.focusedChild = invalid
limit = list.content.getChildren(-1, 0).count() - 1
if limit = list.itemFocused
checkbox.setFocus(true)
return true
end if
else if key = "down" and button.focusedChild = invalid
button.setFocus(true)
else if key = "down" and submit.focusedChild = invalid
submit.setFocus(true)
return true
else if key = "up" and button.focusedChild <> invalid
else if key = "up" and submit.focusedChild <> invalid or quickConnect.focusedChild <> invalid
checkbox.setFocus(true)
return true
else if key = "up" and checkbox.focusedChild <> invalid
list.setFocus(true)
return true
else if key = "right" and submit.focusedChild <> invalid
quickConnect.setFocus(true)
return true
else if key = "left" and quickConnect.focusedChild <> invalid
submit.setFocus(true)
return true
end if
return false
end function

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="ConfigScene" extends="JFGroup">
<component name="LoginScene" extends="JFGroup">
<children>
<label text="Enter Configuration"
id="prompt"
@ -16,12 +16,21 @@
text="Submit"
showFocusFootprint="false"
translation="[150, 550]" />
<Button
id="quickConnect"
showFocusFootprint="false"
translation="[550, 550]"
/>
<label text=""
id="alert"
wrap="true"
width="1620"
font="font:MediumSystemFont"
translation="[150, 680]" />
<Timer
id="quickConnectTimer"
duration="3"
repeat="true" />
</children>
<script type="text/brightscript" uri="ConfigScene.brs"/>
<script type="text/brightscript" uri="LoginScene.brs"/>
</component>

View File

@ -0,0 +1,13 @@
sub init()
m.top.functionName = "monitorQuickConnect"
end sub
sub monitorQuickConnect()
authenticated = checkQuickConnect(m.top.secret)
if authenticated = true
m.top.authenticated = 1
else
m.top.authenticated = -1
end if
end sub

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="QuickConnect" extends="Task">
<interface>
<field id="secret" type="string" />
<field id="authenticated" type="integer" value="0"/>
</interface>
<script type="text/brightscript" uri="QuickConnect.brs" />
<script type="text/brightscript" uri="pkg:/source/api/userauth.brs" />
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
</component>

View File

@ -0,0 +1,68 @@
sub init()
m.quickConnectTimer = m.top.findNode("quickConnectTimer")
m.quickConnectTimer.observeField("fire", "quickConnectStatus")
m.quickConnectTimer.control = "start"
m.top.observeFieldScoped("buttonSelected", "onButtonSelected")
end sub
sub quickConnectStatus()
m.quickConnectTimer.control = "stop"
m.checkTask = CreateObject("roSGNode", "QuickConnect")
m.checkTask.secret = m.top.quickConnectJson.secret
m.checkTask.observeField("authenticated", "OnAuthenticated")
m.checkTask.control = "run"
end sub
sub OnAuthenticated()
m.checkTask.unobserveField("authenticated")
' Did we get the A-OK to authenticate?
authenticated = m.checkTask.authenticated
if authenticated < 0
' Still waiting, check again in 3 seconds...
authenticated = 0
m.checkTask.observeField("authenticated", "OnAuthenticated")
m.quickConnectTimer.control = "start"
else if authenticated > 0
' We've been given the go ahead, try to authenticate via Quick Connect...
authenticated = AuthenticateViaQuickConnect(m.top.quickConnectJson.secret)
if authenticated <> invalid and authenticated = true
m.user = AboutMe()
LoadUserPreferences()
LoadUserAbilities(m.user)
m.top.close = true
m.top.authenticated = true
else
dialog = createObject("roSGNode", "Dialog")
dialog.title = tr("Quick Connect")
dialog.buttons = [tr("OK")]
dialog.message = tr("There was an error authenticating via Quick Connect.")
m.scene.dialog = dialog
end if
end if
end sub
sub quickConnectClosed()
m.quickConnectTimer.control = "stop"
if m.checkTask <> invalid
m.checkTask.unobserveField("authenticated")
end if
m.top.close = true
end sub
sub onButtonSelected()
' only one button at the moment...
quickConnectClosed()
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
' Note that "OK" does not get sent here, hence onButtonSelected() above.
if key = "back"
quickConnectClosed()
return true
end if
return false
end function

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="QuickConnectDialog" extends="StandardMessageDialog">
<children>
<Timer id="quickConnectTimer" duration="3" repeat="false" />
</children>
<interface>
<field id="quickConnectJson" type="assocarray" />
<field id="authenticated" type="boolean" />
</interface>
<script type="text/brightscript" uri="QuickConnectDialog.brs" />
<script type="text/brightscript" uri="pkg:/source/api/userauth.brs" />
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
</component>

View File

@ -557,5 +557,21 @@
<translation>%1 of %2</translation>
<extracomment>Item position and count. %1 = current item. %2 = total number of items</extracomment>
</message>
<message>
<source>Quick Connect</source>
<translation>Quick Connect</translation>
</message>
<message>
<source>Here is your Quick Connect code:</source>
<translation>Here is your Quick Connect code:</translation>
</message>
<message>
<source>(Dialog will close automatically)</source>
<translation></translation>
</message>
<message>
<source>There was an error authenticating via Quick Connect.</source>
<translation>There was an error authenticating via Quick Connect.</translation>
</message>
</context>
</TS>

View File

@ -135,7 +135,7 @@ end function
function CreateSigninGroup(user = "")
' Get and Save Jellyfin user login credentials
group = CreateObject("roSGNode", "ConfigScene")
group = CreateObject("roSGNode", "LoginScene")
m.global.sceneManager.callFunc("pushScene", group)
port = CreateObject("roMessagePort")
@ -185,6 +185,10 @@ function CreateSigninGroup(user = "")
items.appendChild(saveCheckBox)
checkbox.content = items
checkbox.checkedState = [true]
' Add option for Quick Connect
quickConnect = group.findNode("quickConnect")
quickConnect.text = tr("Quick Connect")
quickConnect.observeField("buttonSelected", port)
items = [username_field, password_field]
config.configItems = items
@ -224,6 +228,23 @@ function CreateSigninGroup(user = "")
end if
print "Login attempt failed..."
group.findNode("alert").text = tr("Login attempt failed.")
else if node = "quickConnect"
json = initQuickConnect()
if json = invalid
group.findNode("alert").text = tr("Quick Connect not available.")
return "false"
end if
' Server user is talking to is at least 10.8 and has quick connect enabled...
m.quickConnectDialog = createObject("roSGNode", "QuickConnectDialog")
m.quickConnectDialog.quickConnectJson = json
m.quickConnectDialog.title = tr("Quick Connect")
m.quickConnectDialog.message = [tr("Here is your Quick Connect code: ") + json.Code, tr("(Dialog will close automatically)")]
m.quickConnectDialog.buttons = [tr("Cancel")]
m.quickConnectDialog.observeField("authenticated", port)
m.scene.dialog = m.quickConnectDialog
else if msg.getField() = "authenticated"
' Quick connect authentication was successful...
return "true"
end if
end if
end while

View File

@ -197,3 +197,49 @@ sub LoadUserAbilities(user)
set_user_setting("livetv.canrecord", "false")
end if
end sub
function initQuickConnect()
resp = APIRequest("QuickConnect/Initiate")
jsonResponse = getJson(resp)
if jsonResponse = invalid
return invalid
end if
if jsonResponse.Secret = invalid
return invalid
end if
return jsonResponse
end function
function checkQuickConnect(secret)
url = Substitute("QuickConnect/Connect?secret={0}", secret)
resp = APIRequest(url)
jsonResponse = getJson(resp)
if jsonResponse = invalid
return false
end if
if jsonResponse.Authenticated <> invalid and jsonResponse.Authenticated = true
return true
end if
return false
end function
function AuthenticateViaQuickConnect(secret)
params = {
secret: secret
}
req = APIRequest("Users/AuthenticateWithQuickConnect")
jsonResponse = postJson(req, FormatJson(params))
if jsonResponse <> invalid and jsonResponse.AccessToken <> invalid
userdata = CreateObject("roSGNode", "UserData")
userdata.json = jsonResponse
userdata.callFunc("setActive")
userdata.callFunc("saveToRegistry")
return true
end if
return false
end function