mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Committing so I don't lose work.
This commit is contained in:
77
client/src/FeatureSwitches.ts
Normal file
77
client/src/FeatureSwitches.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
export interface FeatureSwitchInterface {
|
||||
"enabled": boolean,
|
||||
"label": string,
|
||||
"name": string,
|
||||
"options"?: object,
|
||||
"removeArtifactsIfDisabled"?: boolean
|
||||
}
|
||||
|
||||
|
||||
class FeatureSwitch {
|
||||
enabled;
|
||||
label;
|
||||
name;
|
||||
removeArtifactsIfDisabled = true;
|
||||
|
||||
constructor( config:FeatureSwitchInterface ) {
|
||||
|
||||
this.enabled = config.enabled;
|
||||
this.label = config.label;
|
||||
this.name = config.name;
|
||||
|
||||
}
|
||||
|
||||
|
||||
isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class FeatureSwitches {
|
||||
|
||||
#featureSwitches:FeatureSwitch[] = [
|
||||
|
||||
new FeatureSwitch({
|
||||
"enabled": false,
|
||||
"label": "AIC",
|
||||
"name": "aic"
|
||||
}),
|
||||
|
||||
new FeatureSwitch({
|
||||
"enabled": false,
|
||||
"label": "ATC",
|
||||
"name": "atc",
|
||||
"options": {
|
||||
"key": "value"
|
||||
}
|
||||
})
|
||||
|
||||
];
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
this.#removeArtifacts();
|
||||
|
||||
}
|
||||
|
||||
|
||||
getSwitch( switchName:string ) {
|
||||
|
||||
return this.#featureSwitches.find( featureSwitch => featureSwitch.name === switchName );
|
||||
|
||||
}
|
||||
|
||||
|
||||
#removeArtifacts() {
|
||||
|
||||
for ( const featureSwitch of this.#featureSwitches ) {
|
||||
if ( !featureSwitch.isEnabled() && featureSwitch.removeArtifactsIfDisabled !== false ) {
|
||||
document.querySelectorAll( "[data-feature-switch='" + featureSwitch.name + "']" ).forEach( el => el.remove() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
35
client/src/ToggleableFeature.ts
Normal file
35
client/src/ToggleableFeature.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
export abstract class ToggleableFeature {
|
||||
|
||||
#status:boolean = false;
|
||||
|
||||
|
||||
constructor( defaultStatus:boolean ) {
|
||||
|
||||
this.#status = defaultStatus;
|
||||
|
||||
this.onStatusUpdate();
|
||||
|
||||
}
|
||||
|
||||
|
||||
getStatus() : boolean {
|
||||
return this.#status;
|
||||
}
|
||||
|
||||
|
||||
protected onStatusUpdate() {}
|
||||
|
||||
|
||||
toggleStatus( force?:boolean ) : void {
|
||||
|
||||
if ( force ) {
|
||||
this.#status = force;
|
||||
} else {
|
||||
this.#status = !this.#status;
|
||||
}
|
||||
|
||||
this.onStatusUpdate();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
import { ToggleableFeature } from "../ToggleableFeature";
|
||||
import { AICFormation_Azimuth } from "./AICFormation/Azimuth";
|
||||
import { AICFormation_Range } from "./AICFormation/Range";
|
||||
import { AICFormation_Single } from "./AICFormation/Single";
|
||||
import { AICFormationDescriptorSection } from "./AICFormationDescriptorSection";
|
||||
|
||||
|
||||
export class AIC {
|
||||
|
||||
#status:boolean = true;
|
||||
export class AIC extends ToggleableFeature {
|
||||
|
||||
#formations = [
|
||||
|
||||
@@ -18,8 +17,10 @@ export class AIC {
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
super( false );
|
||||
|
||||
this.#onStatusUpdate();
|
||||
this.onStatusUpdate();
|
||||
|
||||
// This feels kind of dirty
|
||||
let $aicFormationList = document.getElementById( "aic-formation-list" );
|
||||
@@ -80,30 +81,10 @@ export class AIC {
|
||||
}
|
||||
|
||||
|
||||
getStatus() {
|
||||
return this.#status;
|
||||
}
|
||||
|
||||
|
||||
#onStatusUpdate() {
|
||||
|
||||
const status:boolean = this.getStatus();
|
||||
onStatusUpdate() {
|
||||
|
||||
// Update the DOM
|
||||
document.body.classList.toggle( "aic-enabled", status );
|
||||
|
||||
}
|
||||
|
||||
|
||||
toggleStatus(force?:boolean) {
|
||||
|
||||
if ( force ) {
|
||||
this.#status = force;
|
||||
} else {
|
||||
this.#status = !this.#status;
|
||||
}
|
||||
|
||||
this.#onStatusUpdate();
|
||||
document.body.classList.toggle( "aic-enabled", this.getStatus() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
87
client/src/atc/ATC.ts
Normal file
87
client/src/atc/ATC.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { ToggleableFeature } from "../ToggleableFeature";
|
||||
import Sortable from 'sortablejs';
|
||||
import { ATCFLightList } from "./FlightList";
|
||||
|
||||
export class ATC extends ToggleableFeature {
|
||||
|
||||
constructor() {
|
||||
|
||||
super( true );
|
||||
|
||||
//this.#generateFlightList();
|
||||
|
||||
let $list = document.getElementById( "atc-strip-board-arrivals" );
|
||||
|
||||
if ( $list instanceof HTMLElement ) {
|
||||
Sortable.create( $list, {
|
||||
"handle": ".handle"
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#generateFlightList() {
|
||||
|
||||
const flightList = new ATCFLightList();
|
||||
const flights:any = flightList.getFlights( true );
|
||||
|
||||
const $tbody = document.getElementById( "atc-flight-list-table-body" );
|
||||
|
||||
if ( $tbody instanceof HTMLElement ) {
|
||||
|
||||
if ( flights.length > 0 ) {
|
||||
|
||||
let flight:any = {};
|
||||
|
||||
let $button, i;
|
||||
|
||||
for ( [ i, flight ] of flights.entries() ) {
|
||||
|
||||
const $row = document.createElement( "tr" );
|
||||
$row.dataset.status = flight.status
|
||||
|
||||
let $td = document.createElement( "td" );
|
||||
$td.innerText = flight.name;
|
||||
$row.appendChild( $td );
|
||||
|
||||
$td = document.createElement( "td" );
|
||||
$td.innerText = flight.takeOffTime;
|
||||
$row.appendChild( $td );
|
||||
|
||||
$td = document.createElement( "td" );
|
||||
$td.innerText = "00:0" + ( 5 + i );
|
||||
$row.appendChild( $td );
|
||||
|
||||
$td = document.createElement( "td" );
|
||||
$td.innerText = flight.status;
|
||||
$row.appendChild( $td );
|
||||
|
||||
|
||||
$td = document.createElement( "td" );
|
||||
$button = document.createElement( "button" );
|
||||
$button.innerText = "...";
|
||||
|
||||
$td.appendChild( $button );
|
||||
|
||||
$row.appendChild( $td );
|
||||
|
||||
|
||||
$tbody.appendChild( $row );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected onStatusUpdate(): void {
|
||||
|
||||
document.body.classList.toggle( "atc-enabled", this.getStatus() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
export interface ATCAPIInterface {
|
||||
get: CallableFunction
|
||||
}
|
||||
|
||||
export abstract class ATCAPI {
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
7
client/src/atc/ATCMockAPI.ts
Normal file
7
client/src/atc/ATCMockAPI.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export abstract class ATCMockAPI {
|
||||
|
||||
constructor() {}
|
||||
|
||||
generateMockData() {}
|
||||
|
||||
}
|
||||
40
client/src/atc/ATCMockAPI/Flights.ts
Normal file
40
client/src/atc/ATCMockAPI/Flights.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { ATCMockAPI } from "../ATCMockAPI";
|
||||
|
||||
export class ATCMockAPI_Flights extends ATCMockAPI {
|
||||
|
||||
|
||||
generateMockData() {
|
||||
|
||||
let data = [];
|
||||
const statuses = [ "unknown", "checkedIn", "readyToTaxi" ]
|
||||
|
||||
for ( const [ i, flightName ] of [ "Shark", "Whale", "Dolphin" ].entries() ) {
|
||||
|
||||
data.push({
|
||||
"name": flightName,
|
||||
"status": statuses[ i ],
|
||||
"takeOffTime": "18:0" + i
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
localStorage.setItem( "flightList", JSON.stringify( data ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
get( generateMockDataIfEmpty?:boolean ) : object {
|
||||
|
||||
generateMockDataIfEmpty = generateMockDataIfEmpty || false;
|
||||
|
||||
let data = localStorage.getItem( "flightList" ) || "[]";
|
||||
|
||||
if ( data === "[]" && generateMockDataIfEmpty ) {
|
||||
this.generateMockData();
|
||||
}
|
||||
|
||||
return JSON.parse( data );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
18
client/src/atc/FlightList.ts
Normal file
18
client/src/atc/FlightList.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { ATCMockAPI_Flights } from "./ATCMockAPI/Flights";
|
||||
|
||||
export class ATCFLightList {
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
getFlights( generateMockDataIfEmpty?:boolean ) {
|
||||
let api = new ATCMockAPI_Flights();
|
||||
return api.get( generateMockDataIfEmpty );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,6 +14,8 @@ import { Slider } from "./controls/slider";
|
||||
import { AIC } from "./aic/AIC";
|
||||
|
||||
import { VisibilityControlPanel } from "./panels/visibilitycontrolpanel";
|
||||
import { ATC } from "./atc/ATC";
|
||||
import { FeatureSwitches } from "./FeatureSwitches";
|
||||
|
||||
/* TODO: should this be a class? */
|
||||
var map: Map;
|
||||
@@ -41,13 +43,22 @@ var aic: AIC;
|
||||
var aicToggleButton: Button;
|
||||
var aicHelpButton: Button;
|
||||
|
||||
|
||||
var atc: ATC;
|
||||
var atcToggleButton: Button;
|
||||
|
||||
var altitudeSlider: Slider;
|
||||
var airspeedSlider: Slider;
|
||||
|
||||
var connected: boolean;
|
||||
var activeCoalition: string;
|
||||
|
||||
var featureSwitches;
|
||||
|
||||
function setup() {
|
||||
|
||||
featureSwitches = new FeatureSwitches();
|
||||
|
||||
/* Initialize */
|
||||
map = new Map('map-container');
|
||||
unitsManager = new UnitsManager();
|
||||
@@ -63,9 +74,6 @@ function setup() {
|
||||
mouseInfoPanel = new MouseInfoPanel("mouse-info-panel");
|
||||
visibilityControlPanel = new VisibilityControlPanel("visibility-control-panel");
|
||||
|
||||
scenarioDropdown = new Dropdown("scenario-dropdown", ["Caucasus", "Syria", "Marianas", "Nevada", "South Atlantic", "The channel"], () => { });
|
||||
mapSourceDropdown = new Dropdown("map-source-dropdown", map.getLayers(), (option: string) => map.setLayer(option));
|
||||
|
||||
missionData = new MissionData();
|
||||
|
||||
/* Unit control buttons */
|
||||
@@ -79,15 +87,20 @@ function setup() {
|
||||
airspeedSlider = new Slider("airspeed-slider", 0, 100, "kts", (value: number) => getUnitsManager().selectedUnitsSetSpeed(value / 1.94384));
|
||||
|
||||
/* AIC */
|
||||
aic = new AIC();
|
||||
|
||||
aicToggleButton = new Button( "toggle-aic-button", ["images/buttons/radar.svg"], () => {
|
||||
aic.toggleStatus();
|
||||
});
|
||||
let aicFeatureSwitch = featureSwitches.getSwitch( "aic" );
|
||||
|
||||
aicHelpButton = new Button( "aic-help-button", [ "images/buttons/question-mark.svg" ], () => {
|
||||
aic.toggleHelp();
|
||||
});
|
||||
if ( aicFeatureSwitch?.isEnabled() ) {
|
||||
aic = new AIC();
|
||||
|
||||
aicToggleButton = new Button( "toggle-aic-button", ["images/buttons/radar.svg"], () => {
|
||||
aic.toggleStatus();
|
||||
});
|
||||
|
||||
aicHelpButton = new Button( "aic-help-button", [ "images/buttons/question-mark.svg" ], () => {
|
||||
aic.toggleHelp();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* Generic clicks */
|
||||
@@ -104,6 +117,22 @@ function setup() {
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*** ATC ***/
|
||||
|
||||
let atcFeatureSwitch = featureSwitches.getSwitch( "atc" );
|
||||
|
||||
if ( atcFeatureSwitch?.isEnabled() ) {
|
||||
|
||||
atc = new ATC();
|
||||
|
||||
atcToggleButton = new Button( "atc-toggle-button", [ "images/buttons/atc.svg" ], () => {
|
||||
atc.toggleStatus();
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Default values */
|
||||
activeCoalition = "blue";
|
||||
connected = false;
|
||||
|
||||
Reference in New Issue
Block a user