From 14147168f97e29fdf56b82272aa1995ee70f5005 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Sun, 26 Mar 2023 20:00:23 +0100 Subject: [PATCH] ATC stuff. --- client/routes/api/atc.js | 5 ++- client/src/atc/atc.ts | 46 +++++++++++++++-------- client/src/atc/atcboard.ts | 67 +++++++++++++++++++++++++++++++++- client/src/atc/board/flight.ts | 66 +++++++++++++++++++++++++++++++-- client/views/atc.ejs | 2 +- 5 files changed, 164 insertions(+), 22 deletions(-) diff --git a/client/routes/api/atc.js b/client/routes/api/atc.js index 616d1361..fa6efabf 100644 --- a/client/routes/api/atc.js +++ b/client/routes/api/atc.js @@ -26,8 +26,9 @@ function uuidv4() { function Flight( name ) { - this.id = uuidv4(); - this.name = name; + this.id = uuidv4(); + this.name = name; + this.status = "unknown"; } Flight.prototype.getData = function() { diff --git a/client/src/atc/atc.ts b/client/src/atc/atc.ts index 8a668975..d3010987 100644 --- a/client/src/atc/atc.ts +++ b/client/src/atc/atc.ts @@ -2,14 +2,16 @@ import { ATCBoard } from "./atcboard"; import { ATCBoardFlight } from "./board/flight"; export interface FlightInterface { - id : string; - name : string; + id : string; + name : string; + status : "unknown"; } class ATCDataHandler { #atc:ATC; + #flights:{[key:string]: FlightInterface} = {}; #updateInterval:number|undefined = undefined; #updateIntervalDelay:number = 1000; @@ -21,6 +23,12 @@ class ATCDataHandler { } + + getFlights() { + return this.#flights; + } + + startUpdates() { this.#updateInterval = setInterval( () => { @@ -34,13 +42,21 @@ class ATCDataHandler { }) .then( response => response.json() ) .then( data => { - this.#atc.setFlights( data ); + this.setFlights( data ); }); }, this.#updateIntervalDelay ); } + + setFlights( flights:{[key:string]: any} ) { + + this.#flights = flights; + + } + + stopUpdates() { clearInterval( this.#updateInterval ); @@ -54,9 +70,8 @@ class ATCDataHandler { export class ATC { - #boards:[] = []; + #boards:ATCBoard[] = []; #dataHandler:ATCDataHandler; - #flights:{[key:string]: FlightInterface} = {}; constructor() { @@ -69,30 +84,31 @@ export class ATC { addBoard( board:T ) { + + board.startUpdates(); + + this.#boards.push( board ); } + getDataHandler() { + return this.#dataHandler; + } + + lookForBoards() { - document.querySelectorAll( "ol-atc-board" ).forEach( board => { + document.querySelectorAll( ".ol-atc-board" ).forEach( board => { if ( board instanceof HTMLElement ) { - this.addBoard( new ATCBoardFlight( board ) ); + this.addBoard( new ATCBoardFlight( this, board ) ); } }); } - - setFlights( flights:{[key:string]: any} ) { - - this.#flights = flights; - - } - - startUpdates() { this.#dataHandler.startUpdates(); diff --git a/client/src/atc/atcboard.ts b/client/src/atc/atcboard.ts index 32010b3e..780cfed6 100644 --- a/client/src/atc/atcboard.ts +++ b/client/src/atc/atcboard.ts @@ -1,15 +1,80 @@ +import { ATC } from "./atc"; + +export interface ATCTemplateInterface { + "template": string +} + export abstract class ATCBoard { + #atc:ATC; + #templates: {[key:string]: string} = {}; + + // Elements #boardElement:HTMLElement; + #stripBoardElement:HTMLElement; + + // Update timing + #updateInterval:number|undefined = undefined; + #updateIntervalDelay:number = 1000; - constructor( boardElement:HTMLElement ) { + constructor( atc:ATC, boardElement:HTMLElement ) { + + this.#atc = atc; this.#boardElement = boardElement; + this.#stripBoardElement = this.getBoardElement().querySelector( ".atc-strip-board" ); } + + getATC() { + return this.#atc; + } + + getBoardElement() { return this.#boardElement; } + + + getStripBoardElement() { + return this.#stripBoardElement; + } + + + getTemplate( key:string ) { + + return this.#templates[ key ] || false; + + } + + + protected update() { + console.warn( "No custom update method defined." ); + } + + + setTemplates( templates:{[key:string]: string} ) { + this.#templates = templates; + } + + + startUpdates() { + + this.#updateInterval = setInterval( () => { + + this.update(); + + }, this.#updateIntervalDelay ); + + } + + + stopUpdates() { + + clearInterval( this.#updateInterval ); + + } + } \ No newline at end of file diff --git a/client/src/atc/board/flight.ts b/client/src/atc/board/flight.ts index 6935dfe7..8bd4b1ba 100644 --- a/client/src/atc/board/flight.ts +++ b/client/src/atc/board/flight.ts @@ -1,11 +1,71 @@ +import { getMissionData } from "../.."; +import { ATC } from "../atc"; import { ATCBoard } from "../atcboard"; export class ATCBoardFlight extends ATCBoard { - constructor( element:HTMLElement ) { + constructor( atc:ATC, element:HTMLElement ) { - super( element ); + super( atc, element ); + + console.log( getMissionData() ); + + document.addEventListener( "deleteFlightStrip", ( ev:CustomEventInit ) => { + + if ( ev.detail.id ) { + + fetch( '/api/atc/flight/' + ev.detail.id, { + method: 'DELETE', + headers: { + 'Accept': '*/*', + 'Content-Type': 'application/json' + } + }); + + } + + }); } - + + + update() { + + const flights = Object.values( this.getATC().getDataHandler().getFlights() ); + const stripBoard = this.getStripBoardElement(); + + + for( const strip of stripBoard.children ) { + strip.toggleAttribute( "data-updating", true ); + } + + + flights.forEach( flight => { + + let strip = stripBoard.querySelector( `[data-flight-id="${flight.id}"]`); + + if ( !strip ) { + + const template = `
+
${flight.name}
+
${flight.status}
+ +
`; + + stripBoard.insertAdjacentHTML( "beforeend", template ); + + strip = stripBoard.lastElementChild; + + } + + strip.toggleAttribute( "data-updating", false ); + + }); + + stripBoard.querySelectorAll( `[data-updating]` ).forEach( strip => { + strip.remove(); + }); + + } + } \ No newline at end of file diff --git a/client/views/atc.ejs b/client/views/atc.ejs index 0117cc0e..66c36e5f 100644 --- a/client/views/atc.ejs +++ b/client/views/atc.ejs @@ -1,5 +1,5 @@
-
+
\ No newline at end of file