capybara/frontend/App.js
2022-08-26 22:09:08 +03:00

109 lines
3.3 KiB
JavaScript

import Banner from "./Banner.js";
import connection, { ConnectionEvent } from "./connection.js";
import KeyboardController from "./Keyboard.js";
import { setItem } from "./storage.js";
import LoginPrompt from "./LoginPrompt.js";
import TouchpadController from "./Touchpad.js";
class App {
constructor() {
this.connection = connection;
this.touchpad = new TouchpadController(this.connection);
this.keyboard = new KeyboardController(this.connection);
this.bannerComponent = new Banner();
this.loginPromptComponent = new LoginPrompt(this.connection);
this.connectionHandlers = [];
}
mountOn(mount, keepMountChildren=false) {
this.mountElement = mount;
if (!keepMountChildren) {
while (mount.firstChild) {
mount.removeChild(mount.lastChild);
}
}
this.connectionHandlers.push([ConnectionEvent.Closed, this.connection.subscribe(ConnectionEvent.Closed, (code) => {
this.unmountApp();
if (code === 4001) { // 4001 - code for bad auth
this.transitionTo("login");
} else {
this.transitionTo("reconnectingBanner");
}
})]);
this.connectionHandlers.push([ConnectionEvent.Ready, this.connection.subscribe(ConnectionEvent.Ready, () => {
this.transitionTo("app");
})]);
}
unmount() {
if (this.mountElement) {
this.unmountApp();
this.unmountBannerComponent();
this.unmountLoginComponent();
}
this.connectionHandlers.forEach(([ event, handler ]) => {
this.connection.unsubscribe(event, handler);
});
}
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) {
this.bannerComponent.mountOn(this.mountElement);
this.bannerComponent.updateTitle(title);
this.bannerComponent.updateText(text);
}
unmountBannerComponent() {
this.bannerComponent.unmount();
}
mountLoginComponent() {
this.loginPromptComponent.mountOn(this.mountElement);
this.loginPromptComponent.onPasswordSubmitted = (p) => {
setItem("auth:token", p);
this.connection.connect();
};
}
unmountLoginComponent() {
if (this.loginPromptComponent)
this.loginPromptComponent.unmount();
}
mountApp() {
this.touchpad.mountOn(this.mountElement);
this.keyboard.mountOn(this.mountElement);
}
unmountApp() {
this.touchpad.unmount();
this.keyboard.unmount();
}
}
export default App;