diff --git a/capybara.py b/capybara.py index 97805c4..421c9fc 100755 --- a/capybara.py +++ b/capybara.py @@ -2,7 +2,7 @@ import sys from asyncio import wait_for, TimeoutError from base64 import b64encode from sanic import Sanic -from sanic.response import file, redirect +from sanic.response import file, redirect, empty from InputController import InputController from MessageParser import MessageParser @@ -10,7 +10,7 @@ from MessageParser import MessageParser app = Sanic( "capybara", - load_env="CAPYBARA_" + env_prefix="CAPYBARA_" ) input_controller = InputController() control_message_parser = MessageParser() @@ -40,13 +40,15 @@ async def gateway(req, ws): return code, args = control_message_parser.parse(auth_payload) - if (not code or + if ( + not code or code != "0" or - args["auth_string"] != app.ctx.EXPECTED_AUTH_STRING): # 0 is the code for the initial auth packet + args["auth_string"] != app.ctx.EXPECTED_AUTH_STRING + ): # 0 is the code for the initial auth packet await ws.close(code=4001, reason="Invalid auth packet") return - await ws.send("1") # send a single `1` to let the client know the server is input packets + await ws.send("1") # send a single `1` to let the client know the server is accepting input packets while True: input_controller.process_message(await ws.recv()) diff --git a/frontend/src/App.js b/frontend/src/App.js index 49473a4..85d193c 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,3 +1,4 @@ +import Banner from "./Banner"; import Connection from "./Connection"; import KeyboardController from "./Keyboard"; import { getAuth, setAuth } from "./LocalConfiguration"; @@ -18,6 +19,8 @@ class App { this.unmountApp(); if (code === 4001) { // 4001 - code for bad auth this.transitionTo("login"); + } else { + this.transitionTo("reconnectingBanner"); } }); this.connection.onHandshakeCompleted = () => { @@ -28,24 +31,45 @@ class App { transitionTo(type) { switch (type) { case "login": + this.unmountBannerComponent(); this.unmountApp(); this.mountLoginComponent(); break; case "app": + this.unmountBannerComponent(); this.unmountLoginComponent(); this.mountApp(); break; + case "reconnectingBanner": + this.unmountApp(); + this.unmountLoginComponent(); + this.mountBannerComponent("Connecting...", "Looks like you've lost connection. We're trying to reconnect you."); + break; default: throw new Error(`transitionTo type ${type} is invalid`); } } + mountBannerComponent(title, text) { + if (!this.bannerComponent) + this.bannerComponent = new Banner(); + + this.bannerComponent.mountOn(this.mountElement); + this.bannerComponent.updateTitle(title); + this.bannerComponent.updateText(text); + } + + unmountBannerComponent() { + if (this.bannerComponent) + this.bannerComponent.unmount(); + } + mountLoginComponent() { if (!this.loginPromptComponent) this.loginPromptComponent = new LoginPrompt(this.connection); this.loginPromptComponent.mountOn(this.mountElement); - this.loginPromptComponent.onPasswordSubmitted = p => { + this.loginPromptComponent.onPasswordSubmitted = (p) => { setAuth(p); this.connection.connect(p); }; diff --git a/frontend/src/Banner.js b/frontend/src/Banner.js index 7395654..d9f1f6d 100644 --- a/frontend/src/Banner.js +++ b/frontend/src/Banner.js @@ -1,10 +1,19 @@ class Banner { constructor() { - this.text = null; + this.element = null; + + this.title = ""; + this.text = ""; } - updateText(text) { - this.text = text; + updateText(newText) { + this.text = newText; + this.element.querySelector("#banner-text").innerText = this.text; + } + + updateTitle(newTitle) { + this.title = newTitle; + this.element.querySelector("#banner-title").innerText = this.title; } mountOn(target) { @@ -13,22 +22,21 @@ class Banner { this.element = document.createRange().createContextualFragment(`
You need to enter the login code before you can start controlling your device.
-