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;