fix reconnect and add banner message when trying to reconnect5r
This commit is contained in:
parent
6bbd925dbc
commit
0f881b668c
5 changed files with 73 additions and 29 deletions
12
capybara.py
12
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())
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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(`
|
||||
<div class="card small-card center-text">
|
||||
<h2>Login</h2>
|
||||
<p>You need to enter the login code before you can start controlling your device.</p>
|
||||
<br>
|
||||
<div class="full-width">
|
||||
<input id="code-input" class="input full-width" placeholder="Code">
|
||||
<br>
|
||||
<button id="continue-button" class="button-default full-width">Continue</button>
|
||||
</div>
|
||||
<h2 id="banner-title"></h2>
|
||||
<p id="banner-text"></p>
|
||||
</div>
|
||||
`).children[0];
|
||||
|
||||
this.element.querySelector("#continue-button").addEventListener("click", () => {
|
||||
if (this.onPasswordSubmitted)
|
||||
this.onPasswordSubmitted(this.element.querySelector("#code-input").value);
|
||||
});
|
||||
|
||||
target.appendChild(this.element);
|
||||
}
|
||||
|
||||
unmount() {
|
||||
if (!this.element)
|
||||
return; // Already unmounted
|
||||
|
||||
this.element.parentElement.removeChild(this.element);
|
||||
this.element = null;
|
||||
}
|
||||
}
|
||||
|
||||
export default Banner;
|
||||
|
|
|
@ -7,6 +7,7 @@ class Connection {
|
|||
this.messageLog = Logger(["Connection", "Message"], ["log"]).log;
|
||||
this.url = url;
|
||||
this.isReady = false;
|
||||
this.reconnectTimeout = 0;
|
||||
}
|
||||
|
||||
formatAuthString(password) {
|
||||
|
@ -18,6 +19,7 @@ class Connection {
|
|||
this.ws.onerror = (e) => this.log("Error", e);
|
||||
this.ws.onopen = () => {
|
||||
this.log("Open");
|
||||
this.reconnectTimeout = 0;
|
||||
this.log("Sending authentication packet");
|
||||
this.ws.send(`0${this.formatAuthString(password)}`); // send auth packet
|
||||
};
|
||||
|
@ -35,9 +37,12 @@ class Connection {
|
|||
this.log("Closed due to bad auth - skipping reconnect");
|
||||
return;
|
||||
}
|
||||
this.log("Closed - attempting to reconnect in 4000ms");
|
||||
this.isReady = false;
|
||||
setTimeout(() => this.connect(), 4000);
|
||||
this.reconnectTimeout += 400;
|
||||
if (this.reconnectTimeout >= 30000)
|
||||
this.reconnectTimeout = 30000;
|
||||
this.log(`Closed - will reconnect in ${this.reconnectTimeout}ms`);
|
||||
setTimeout(() => this.connect(password), this.reconnectTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ body {
|
|||
color: var(--accent-bg-color);
|
||||
overflow-x: none;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.card {
|
||||
|
@ -105,7 +105,7 @@ body {
|
|||
}
|
||||
|
||||
.touchpad {
|
||||
height: clamp(5rem, 30rem, 55vh);
|
||||
height: clamp(5rem, 30rem, 50vh);
|
||||
width: 100%;
|
||||
background-color: var(--accent-bg-color);
|
||||
border-radius: var(--card-border-radius);
|
||||
|
@ -113,9 +113,15 @@ body {
|
|||
|
||||
/* for virtual keyboard */
|
||||
|
||||
.hg-theme-default {
|
||||
font-weight: var(--main-font-weight);
|
||||
font-family: var(--fonts-regular);
|
||||
}
|
||||
|
||||
.keyboard {
|
||||
padding: 8px;
|
||||
color: var(--body-bg-color);
|
||||
margin-top: 28px;
|
||||
margin-top: 24px;
|
||||
border-radius: var(--card-border-radius);
|
||||
background-color: var(--accent-bg-color);
|
||||
}
|
||||
|
@ -126,7 +132,6 @@ body {
|
|||
|
||||
.hg-button {
|
||||
margin: 2px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.hg-activeButton {
|
||||
|
|
Loading…
Reference in a new issue