From 4c6d445c4abaa61ffe3c287a8ac46fb4d018f66f Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Thu, 16 Mar 2023 15:06:42 +0000 Subject: [PATCH 1/6] Unit list. --- client/public/stylesheets/layout.css | 8 +- client/public/stylesheets/olympus.css | 1 + client/public/stylesheets/unitdatatable.css | 27 +++++++ client/src/index.ts | 4 + client/src/units/unitdatatable.ts | 82 +++++++++++++++++++++ client/tsconfig.json | 2 +- client/views/index.ejs | 1 + client/views/unitdatatable.ejs | 7 ++ 8 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 client/public/stylesheets/unitdatatable.css create mode 100644 client/src/units/unitdatatable.ts create mode 100644 client/views/unitdatatable.ejs diff --git a/client/public/stylesheets/layout.css b/client/public/stylesheets/layout.css index 53a9863c..d12fd4ab 100644 --- a/client/public/stylesheets/layout.css +++ b/client/public/stylesheets/layout.css @@ -112,7 +112,7 @@ dl.ol-data-grid dd { } .ol-panel.ol-dialog { - padding:25px; + padding:20px; } .ol-dialog-close { @@ -138,6 +138,12 @@ dl.ol-data-grid dd { padding-top:15px; } +.ol-dialog.scrollable .ol-dialog-content { + overflow-y: auto; +} + + + .ol-checkbox label { align-items: center; cursor: pointer; diff --git a/client/public/stylesheets/olympus.css b/client/public/stylesheets/olympus.css index fb6e64c5..e6c3ed83 100644 --- a/client/public/stylesheets/olympus.css +++ b/client/public/stylesheets/olympus.css @@ -4,6 +4,7 @@ @import url("contextmenus.css"); @import url("mouseinfopanel.css"); @import url("units.css"); +@import url("unitdatatable.css"); @import url("unitcontrolpanel.css"); @import url("unitinfopanel.css"); diff --git a/client/public/stylesheets/unitdatatable.css b/client/public/stylesheets/unitdatatable.css new file mode 100644 index 00000000..93e9d737 --- /dev/null +++ b/client/public/stylesheets/unitdatatable.css @@ -0,0 +1,27 @@ +#unit-data-table { + display:flex; + flex-direction: column; + font-size:13px; + max-height: 150px; + width:fit-content; +} + +#unit-data-table > div { + display:flex; + flex-direction: row; + flex-wrap: nowrap; +} + +#unit-data-table > div > div { + text-overflow: ellipsis; + white-space: nowrap; + width:100px; +} + +#unit-data-table > div:first-of-type { + text-align: center; +} + +#unit-data-table > div > div:nth-of-type( 4 ) { + text-align: center; +} \ No newline at end of file diff --git a/client/src/index.ts b/client/src/index.ts index f74f7476..de36e338 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -10,6 +10,7 @@ import { ATC } from "./atc/ATC"; import { FeatureSwitches } from "./FeatureSwitches"; import { LogPanel } from "./panels/logpanel"; import { getAirbases, getBulllseye as getBulllseyes, getMission, getUnits, toggleDemoEnabled } from "./server/server"; +import { UnitDataTable } from "./units/unitdatatable"; var map: Map; @@ -29,6 +30,7 @@ var connected: boolean = false; var activeCoalition: string = "blue"; var sessionHash: string | null = null; +var unitDataTable = new UnitDataTable(); var featureSwitches; @@ -75,6 +77,7 @@ function setup() { startPeriodicUpdate(); } + function startPeriodicUpdate() { requestUpdate(); requestRefresh(); @@ -84,6 +87,7 @@ function requestUpdate() { /* Main update rate = 250ms is minimum time, equal to server update time. */ getUnits((data: UnitsData) => { getUnitsManager()?.update(data); + unitDataTable.refresh( data.units ); checkSessionHash(data.sessionHash); }, false); setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000); diff --git a/client/src/units/unitdatatable.ts b/client/src/units/unitdatatable.ts new file mode 100644 index 00000000..07fb8f01 --- /dev/null +++ b/client/src/units/unitdatatable.ts @@ -0,0 +1,82 @@ +export class UnitDataTable { + + #element; + #tableId = "unit-data-table"; + #hasUpdated = false; + + + constructor() { + + const table = document.getElementById( this.#tableId ); + + if ( table instanceof HTMLElement ) { + + this.#element = table; + + } else { + + return; + + } + + + } + + + getElement() { + return this.#element; + } + + + refresh( units:object ) { + + if ( this.#hasUpdated ) { + return; + } + + const unitsArray = Object.values( units ); + + + function addRow( parentEl:HTMLElement, columns:string[] ) { + + const rowDiv = document.createElement( "div" ); + + for ( const item of columns ) { + + const div = document.createElement( "div" ); + div.innerText = item; + rowDiv.appendChild( div ); + + } + + parentEl.appendChild( rowDiv ); + + } + + + const el = this.getElement(); + + if ( el ) { + + el.innerHTML = ""; + + addRow( el, [ "Callsign", "Name", "Category", "AI/Human" ] ) + + for ( const unit of unitsArray ) { + + const dataset = [ unit.baseData.unitName, unit.baseData.name, unit.baseData.category, ( unit.baseData.AI ) ? "AI" : "Human" ]; + + if ( this.getElement() ) { + + } + addRow( el, dataset ); + + } + + } + + + this.#hasUpdated = true; + + } +} \ No newline at end of file diff --git a/client/tsconfig.json b/client/tsconfig.json index 74c81cdf..d77f7eb3 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -9,7 +9,7 @@ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ diff --git a/client/views/index.ejs b/client/views/index.ejs index 3fbfbf5d..2a0a91ff 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -32,6 +32,7 @@ <%- include('navbar.ejs') %> <%- include('connectionstatuspanel.ejs') %> <%- include('dialogs.ejs') %> + <%- include('unitdatatable.ejs') %> <% /* %> <%- include('log.ejs') %> diff --git a/client/views/unitdatatable.ejs b/client/views/unitdatatable.ejs new file mode 100644 index 00000000..b71bca13 --- /dev/null +++ b/client/views/unitdatatable.ejs @@ -0,0 +1,7 @@ +
+ +
+ +
+ +
\ No newline at end of file From 2a8ab0f8cf6fe7f35bcf4c6f6040d75c3011888e Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Thu, 16 Mar 2023 16:01:49 +0000 Subject: [PATCH 2/6] Unit list v0.0.0.0.1 done. --- client/public/stylesheets/unitdatatable.css | 2 +- client/src/index.ts | 9 ++++- client/src/units/unitdatatable.ts | 37 ++++++++++++++++----- client/views/unitdatatable.ejs | 8 ++++- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/client/public/stylesheets/unitdatatable.css b/client/public/stylesheets/unitdatatable.css index 93e9d737..f666ab25 100644 --- a/client/public/stylesheets/unitdatatable.css +++ b/client/public/stylesheets/unitdatatable.css @@ -2,7 +2,7 @@ display:flex; flex-direction: column; font-size:13px; - max-height: 150px; + height: 250px; width:fit-content; } diff --git a/client/src/index.ts b/client/src/index.ts index f151acf2..9f9d19f4 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -141,13 +141,21 @@ function setupEvents() { /* Keyup events */ document.addEventListener("keyup", ev => { + switch (ev.code) { + case "KeyL": document.body.toggleAttribute("data-hide-labels"); break; + case "KeyD": toggleDemoEnabled(); + break; + + case "Quote": + unitDataTable.toggle(); } + }); /* @@ -158,7 +166,6 @@ function setupEvents() { unitName.setAttribute( "readonly", "true" ); // Do something with this: - console.log( unitName.value ); }); document.addEventListener( "editUnitName", ev => { diff --git a/client/src/units/unitdatatable.ts b/client/src/units/unitdatatable.ts index 07fb8f01..0e8bde65 100644 --- a/client/src/units/unitdatatable.ts +++ b/client/src/units/unitdatatable.ts @@ -2,7 +2,6 @@ export class UnitDataTable { #element; #tableId = "unit-data-table"; - #hasUpdated = false; constructor() { @@ -28,13 +27,27 @@ export class UnitDataTable { } + hide() { + this.getElement()?.closest( ".ol-dialog" )?.classList.add( "hide" ); + } + + refresh( units:object ) { - if ( this.#hasUpdated ) { - return; - } + const unitsArray = Object.values( units ).sort( ( a, b ) => { - const unitsArray = Object.values( units ); + const aVal = a.baseData.unitName.toLowerCase(); + const bVal = b.baseData.unitName.toLowerCase(); + + if ( aVal > bVal ) { + return 1; + } else if ( bVal > aVal ) { + return -1; + } else { + return 0; + } + + }); function addRow( parentEl:HTMLElement, columns:string[] ) { @@ -75,8 +88,16 @@ export class UnitDataTable { } - - this.#hasUpdated = true; - } + + + show() { + this.getElement()?.closest( ".ol-dialog" )?.classList.remove( "hide" ); + } + + + toggle() { + this.getElement()?.closest( ".ol-dialog" )?.classList.toggle( "hide" ); + } + } \ No newline at end of file diff --git a/client/views/unitdatatable.ejs b/client/views/unitdatatable.ejs index b71bca13..fb89a424 100644 --- a/client/views/unitdatatable.ejs +++ b/client/views/unitdatatable.ejs @@ -1,4 +1,10 @@ -
+
+ +
+ +
+

Unit list

+
From 764064fc0de1ed47229b9ceeb11248c56d9e965f Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Mon, 20 Mar 2023 11:57:01 +0000 Subject: [PATCH 3/6] Aligned getting and naming convention. --- client/src/index.ts | 6 +++++- client/src/units/unitdatatable.ts | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index 9f9d19f4..a16d03a5 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -87,7 +87,7 @@ function requestUpdate() { /* Main update rate = 250ms is minimum time, equal to server update time. */ getUnits((data: UnitsData) => { getUnitsManager()?.update(data); - unitDataTable.refresh( data.units ); + getUnitDataTable().update( data.units ) checkSessionHash(data.sessionHash); }, false); setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000); @@ -225,6 +225,10 @@ export function getMissionData() { return missionHandler; } +export function getUnitDataTable() { + return unitDataTable; +} + export function getUnitsManager() { return unitsManager; } diff --git a/client/src/units/unitdatatable.ts b/client/src/units/unitdatatable.ts index 0e8bde65..4149cebb 100644 --- a/client/src/units/unitdatatable.ts +++ b/client/src/units/unitdatatable.ts @@ -32,7 +32,17 @@ export class UnitDataTable { } - refresh( units:object ) { + show() { + this.getElement()?.closest( ".ol-dialog" )?.classList.remove( "hide" ); + } + + + toggle() { + this.getElement()?.closest( ".ol-dialog" )?.classList.toggle( "hide" ); + } + + + update( units:object ) { const unitsArray = Object.values( units ).sort( ( a, b ) => { @@ -90,14 +100,4 @@ export class UnitDataTable { } - - show() { - this.getElement()?.closest( ".ol-dialog" )?.classList.remove( "hide" ); - } - - - toggle() { - this.getElement()?.closest( ".ol-dialog" )?.classList.toggle( "hide" ); - } - } \ No newline at end of file From 314fd2a565b40ab310d1474e34e652053ddebb0c Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Mon, 20 Mar 2023 13:19:49 +0000 Subject: [PATCH 4/6] Changed heading for speed --- client/src/units/unit.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index 88f10943..db6b47f2 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -381,6 +381,10 @@ export class Unit extends Marker { var unitAltitudeDiv = element.querySelector(".unit-altitude"); if (unitAltitudeDiv != null) unitAltitudeDiv.innerHTML = String(Math.floor(this.getFlightData().altitude / 0.3048 / 1000)); + + var unitSpeedDiv = element.querySelector(".unit-speed"); + if (unitSpeedDiv != null) + unitSpeedDiv.innerHTML = String(Math.floor(this.getFlightData().speed * 1.94384 ) ); } var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); this.setZIndexOffset(1000 + Math.floor(this.getFlightData().altitude) - pos.y); @@ -487,8 +491,8 @@ export class Aircraft extends AirUnit {
${data.baseData.unitName}
-
+
`); } From 5033cccda0ed78943eb989c466f5e5820ac757e7 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Mon, 20 Mar 2023 14:20:42 +0000 Subject: [PATCH 5/6] Selected unit measurement now works. --- client/public/stylesheets/layout.css | 6 ++++- client/public/stylesheets/mouseinfopanel.css | 16 ++++++++++---- client/src/panels/mouseinfopanel.ts | 23 +++++++++++++++++--- client/views/mouseinfopanel.ejs | 6 +++-- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/client/public/stylesheets/layout.css b/client/public/stylesheets/layout.css index 53a9863c..b66681af 100644 --- a/client/public/stylesheets/layout.css +++ b/client/public/stylesheets/layout.css @@ -72,10 +72,14 @@ dl.ol-data-grid dd { margin-left: auto; } -.br-info[data-bearing][data-distance][data-distance-units]::after { +.br-info::after { content: attr( data-bearing ) '\00B0 / ' attr( data-distance ) attr( data-distance-units ); } +.br-info[data-message]::after { + content: attr( data-message ); +} + .coordinates::after { content: attr( data-dd ) "\00b0 " attr( data-mm ) "'" attr( data-ss ) "." attr( data-sss ) '"' attr( data-label ); } diff --git a/client/public/stylesheets/mouseinfopanel.css b/client/public/stylesheets/mouseinfopanel.css index c571e514..fe8030a3 100644 --- a/client/public/stylesheets/mouseinfopanel.css +++ b/client/public/stylesheets/mouseinfopanel.css @@ -25,7 +25,7 @@ #mouse-info-panel dt { height:20px; - width:40%; + width:30%; } #mouse-info-panel dt::after { @@ -44,12 +44,20 @@ width:16px; } -#mouse-info-panel dt#ref-measure-position::after { +#mouse-info-panel dt#ref-unit-position::after { background-image: url( "/images/icons/ruler.svg" ); background-position: 50% 50%; background-repeat: no-repeat; background-size:16px 16px; - content: " "; + content: ""; +} + +#mouse-info-panel dt#ref-measure-position::after { + background-image: url( "/images/pin.png" ); + background-position: 50% 50%; + background-repeat: no-repeat; + background-size:16px 16px; + content: ""; } @@ -79,5 +87,5 @@ } #mouse-info-panel dd { - width:60%; + width:70%; } \ No newline at end of file diff --git a/client/src/panels/mouseinfopanel.ts b/client/src/panels/mouseinfopanel.ts index cd76e7d9..ef7a9656 100644 --- a/client/src/panels/mouseinfopanel.ts +++ b/client/src/panels/mouseinfopanel.ts @@ -155,13 +155,30 @@ export class MouseInfoPanel extends Panel { #onUnitsSelection(units: Unit[]) { - if (units.length == 1) - this.getElement().querySelector(`#unit-position`)?.classList.toggle("hide", false); + const pos = this.getElement().querySelector(`#unit-position`); + + if ( units.length > 1 ) { + pos?.setAttribute( "data-message", "(multiple units)" ); + } else { + pos?.removeAttribute( "data-message" ); + } + } #onClearSelection() { this.#measureBox.classList.toggle("hide", true); - this.getElement().querySelector(`#unit-position`)?.classList.toggle("hide", true); + + const pos = this.getElement().querySelector(`#unit-position`); + + + if ( pos instanceof HTMLElement ) { + pos?.removeAttribute( "data-message" ); + + pos.dataset.bearing = "---"; + pos.dataset.distance = "---"; + pos.dataset.distanceUnits = "nm"; + + } } } diff --git a/client/views/mouseinfopanel.ejs b/client/views/mouseinfopanel.ejs index 935e1694..40d96ec7 100644 --- a/client/views/mouseinfopanel.ejs +++ b/client/views/mouseinfopanel.ejs @@ -4,14 +4,16 @@
+
+
-
+
-
+
From dd7d54603f992931c6f2993076fc7922a27430bc Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Mon, 20 Mar 2023 16:25:24 +0000 Subject: [PATCH 6/6] Mouse co-ordinates work; N/S and E/W are not negative. --- client/src/panels/mouseinfopanel.ts | 35 +++++++++++++++++++++++++++++ client/views/mouseinfopanel.ejs | 4 ++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/client/src/panels/mouseinfopanel.ts b/client/src/panels/mouseinfopanel.ts index ef7a9656..023ca085 100644 --- a/client/src/panels/mouseinfopanel.ts +++ b/client/src/panels/mouseinfopanel.ts @@ -72,6 +72,41 @@ export class MouseInfoPanel extends Panel { el.dataset.distanceUnits = "nm"; } } + + const refMouseLat = document.getElementById( "ref-mouse-position-latitude" ); + const mouseLat = document.getElementById( "mouse-position-latitude" ); + + if ( refMouseLat && mouseLat ) { + + let matches = String( mousePosition.lat ).match( /^\-?(\d+)\.(\d{2})(\d{2})(\d{2})/ ); + + if ( matches && matches.length ) { + mouseLat.dataset.dd = matches[1]; + mouseLat.dataset.mm = matches[2]; + mouseLat.dataset.ss = matches[3]; + mouseLat.dataset.sss = matches[4]; + } + + refMouseLat.dataset.label = ( mousePosition.lat < 0 ) ? "S" : "N"; + + } + + const refMouseLng = document.getElementById( "ref-mouse-position-longitude" ); + const mouseLng = document.getElementById( "mouse-position-longitude" ); + + if ( refMouseLng && mouseLng ) { + + let matches = String( mousePosition.lng ).match( /^\-?(\d+)\.(\d{2})(\d{2})(\d{2})/ ); + + if ( matches && matches.length ) { + mouseLng.dataset.dd = matches[1]; + mouseLng.dataset.mm = matches[2]; + mouseLng.dataset.ss = matches[3]; + mouseLng.dataset.sss = matches[4]; + } + + refMouseLng.dataset.label = ( mousePosition.lng < 0 ) ? "W" : "E"; + } } #onMapClick(e: any) diff --git a/client/views/mouseinfopanel.ejs b/client/views/mouseinfopanel.ejs index 40d96ec7..ecf62d24 100644 --- a/client/views/mouseinfopanel.ejs +++ b/client/views/mouseinfopanel.ejs @@ -20,9 +20,9 @@
-
+
-
+