mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Added airbase info and spawn menu
This commit is contained in:
parent
fd15406f5d
commit
ebfa7916c6
@ -7,12 +7,14 @@ export const EventsContext = createContext({
|
||||
setMeasureMenuVisible: (e: boolean) => {},
|
||||
setDrawingMenuVisible: (e: boolean) => {},
|
||||
setOptionsMenuVisible: (e: boolean) => {},
|
||||
setAirbaseMenuVisible: (e: boolean) => {},
|
||||
toggleMainMenuVisible: () => {},
|
||||
toggleSpawnMenuVisible: () => {},
|
||||
toggleUnitControlMenuVisible: () => {},
|
||||
toggleMeasureMenuVisible: () => {},
|
||||
toggleDrawingMenuVisible: () => {},
|
||||
toggleOptionsMenuVisible: () => {},
|
||||
toggleAirbaseMenuVisible: () => {},
|
||||
});
|
||||
|
||||
export const EventsProvider = EventsContext.Provider;
|
||||
|
||||
@ -12,7 +12,6 @@ export class Airbase extends CustomMarker {
|
||||
runways: [],
|
||||
};
|
||||
#coalition: string = "";
|
||||
#hasChartDataBeenSet: boolean = false;
|
||||
#properties: string[] = [];
|
||||
#parkings: string[] = [];
|
||||
|
||||
@ -22,10 +21,6 @@ export class Airbase extends CustomMarker {
|
||||
this.#name = options.name;
|
||||
}
|
||||
|
||||
chartDataHasBeenSet() {
|
||||
return this.#hasChartDataBeenSet;
|
||||
}
|
||||
|
||||
createIcon() {
|
||||
var icon = new DivIcon({
|
||||
className: "leaflet-airbase-marker",
|
||||
@ -43,10 +38,10 @@ export class Airbase extends CustomMarker {
|
||||
el.appendChild(img);
|
||||
this.getElement()?.appendChild(el);
|
||||
el.addEventListener("mouseover", (ev) => {
|
||||
document.dispatchEvent(new CustomEvent("airbaseMouseover", { detail: this }));
|
||||
document.dispatchEvent(new CustomEvent("airbasemouseover", { detail: this }));
|
||||
});
|
||||
el.addEventListener("mouseout", (ev) => {
|
||||
document.dispatchEvent(new CustomEvent("airbaseMouseout", { detail: this }));
|
||||
document.dispatchEvent(new CustomEvent("airbasemouseout", { detail: this }));
|
||||
});
|
||||
el.dataset.coalition = this.#coalition;
|
||||
}
|
||||
@ -73,7 +68,6 @@ export class Airbase extends CustomMarker {
|
||||
}
|
||||
|
||||
setChartData(chartData: AirbaseChartData) {
|
||||
this.#hasChartDataBeenSet = true;
|
||||
this.#chartData = chartData;
|
||||
}
|
||||
|
||||
|
||||
@ -87,7 +87,7 @@ export class MissionManager {
|
||||
position: new LatLng(airbase.latitude, airbase.longitude),
|
||||
name: airbase.callsign,
|
||||
}).addTo(getApp().getMap());
|
||||
this.#airbases[airbase.callsign].on("contextmenu", (e) => this.#onAirbaseClick(e));
|
||||
this.#airbases[airbase.callsign].on("click", (e) => this.#onAirbaseClick(e));
|
||||
this.#loadAirbaseChartData(airbase.callsign);
|
||||
}
|
||||
|
||||
@ -316,7 +316,9 @@ export class MissionManager {
|
||||
if (requestRefresh) getApp().getServerManager().refreshAll();
|
||||
}
|
||||
|
||||
#onAirbaseClick(e: any) {}
|
||||
#onAirbaseClick(ev: any) {
|
||||
document.dispatchEvent(new CustomEvent("airbaseclick", { detail: ev.target }));
|
||||
}
|
||||
|
||||
#loadAirbaseChartData(callsign: string) {
|
||||
if (!this.#theatre) {
|
||||
@ -324,7 +326,7 @@ export class MissionManager {
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", `api/airbases/${this.#theatre.toLowerCase()}/${callsign}`, true);
|
||||
xhr.open("GET", window.location.href.split("?")[0].replace("vite/", "") + `api/airbases/${this.#theatre.toLowerCase()}/${callsign}`, true);
|
||||
xhr.responseType = "json";
|
||||
xhr.onload = () => {
|
||||
var status = xhr.status;
|
||||
|
||||
@ -142,8 +142,6 @@ export class ServerManager {
|
||||
|
||||
setAddress(address: string) {
|
||||
this.#REST_ADDRESS = `${address.replace("vite/", "").replace("vite", "")}olympus`;
|
||||
// TODO: TEMPORARY FOR DEBUGGING
|
||||
// this.#REST_ADDRESS = `https://refugees.dcsolympus.com/olympus`;
|
||||
|
||||
console.log(`Setting REST address to ${this.#REST_ADDRESS}`);
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ export const StateContext = createContext({
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: false,
|
||||
optionsMenuVisible: false,
|
||||
airbaseMenuVisible: false,
|
||||
mapHiddenTypes: MAP_HIDDEN_TYPES_DEFAULTS,
|
||||
mapOptions: MAP_OPTIONS_DEFAULTS,
|
||||
mapSources: [] as string[],
|
||||
|
||||
@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faArrowCircleDown } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
export function OlAccordion(props: { title: string; children?: JSX.Element | JSX.Element[]; showArrows?: boolean }) {
|
||||
export function OlAccordion(props: { title: string; children?: JSX.Element | JSX.Element[]; showArrows?: boolean; className?: string }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [scrolledUp, setScrolledUp] = useState(true);
|
||||
const [scrolledDown, setScrolledDown] = useState(false);
|
||||
@ -31,6 +31,7 @@ export function OlAccordion(props: { title: string; children?: JSX.Element | JSX
|
||||
type="button"
|
||||
onClick={() => setOpen(!open)}
|
||||
className={`
|
||||
${props.className ?? ""}
|
||||
flex w-full items-center justify-between gap-3 border-gray-200 py-2
|
||||
text-gray-700
|
||||
dark:border-gray-700 dark:text-white
|
||||
|
||||
141
frontend/react/src/ui/panels/airbasemenu.tsx
Normal file
141
frontend/react/src/ui/panels/airbasemenu.tsx
Normal file
@ -0,0 +1,141 @@
|
||||
import React, { useState } from "react";
|
||||
import { Menu } from "./components/menu";
|
||||
import { OlCheckbox } from "../components/olcheckbox";
|
||||
import { OlRangeSlider } from "../components/olrangeslider";
|
||||
import { OlNumberInput } from "../components/olnumberinput";
|
||||
import { Coalition, MapOptions } from "../../types/types";
|
||||
import { getApp } from "../../olympusapp";
|
||||
import { Airbase } from "../../mission/airbase";
|
||||
import { FaArrowLeft, FaCompass } from "react-icons/fa6";
|
||||
import { getUnitsByLabel } from "../../other/utils";
|
||||
import { UnitBlueprint } from "../../interfaces";
|
||||
import { IDLE } from "../../constants/constants";
|
||||
import { OlSearchBar } from "../components/olsearchbar";
|
||||
import { OlAccordion } from "../components/olaccordion";
|
||||
import { OlUnitEntryList } from "../components/olunitlistentry";
|
||||
import { olButtonsVisibilityAircraft, olButtonsVisibilityHelicopter } from "../components/olicons";
|
||||
import { UnitSpawnMenu } from "./unitspawnmenu";
|
||||
|
||||
export function AirbaseMenu(props: { open: boolean; onClose: () => void; airbase: Airbase | null; children?: JSX.Element | JSX.Element[] }) {
|
||||
const [blueprint, setBlueprint] = useState(null as null | UnitBlueprint);
|
||||
const [filterString, setFilterString] = useState("");
|
||||
|
||||
const [filteredAircraft, filteredHelicopters, filteredAirDefense, filteredGroundUnits, filteredNavyUnits] = getUnitsByLabel(filterString);
|
||||
|
||||
return (
|
||||
<Menu title={props.airbase?.getName() ?? "No airbase selected"} open={props.open} onClose={props.onClose} showBackButton={false} canBeHidden={true}>
|
||||
<div
|
||||
className={`
|
||||
flex flex-col gap-2 font-normal text-gray-800
|
||||
dark:text-white
|
||||
`}
|
||||
>
|
||||
<div
|
||||
data-coalition={props.airbase?.getCoalition()}
|
||||
className={`
|
||||
flex flex-col content-center justify-between gap-2 border-l-4
|
||||
bg-olympus-200/30 py-3 pl-4 pr-5
|
||||
data-[coalition='blue']:border-blue-500
|
||||
data-[coalition='neutral']:border-gray-500
|
||||
data-[coalition='red']:border-red-500
|
||||
`}
|
||||
>
|
||||
<div className="flex w-full justify-between">
|
||||
<span className="text-gray-400">ICAO name</span>
|
||||
<span>{props.airbase?.getChartData().ICAO !== "" ? props.airbase?.getChartData().ICAO : "N/A"}</span>
|
||||
</div>
|
||||
<div className="flex w-full justify-between">
|
||||
<span className="text-gray-400">TACAN</span>
|
||||
<span>{props.airbase?.getChartData().TACAN !== "" ? props.airbase?.getChartData().TACAN : "None"}</span>
|
||||
</div>
|
||||
<div className="flex w-full justify-between">
|
||||
<span className="text-gray-400">Elevation</span>
|
||||
<span>{props.airbase?.getChartData().elevation !== "" ? props.airbase?.getChartData().elevation : "N/A"}ft</span>
|
||||
</div>
|
||||
|
||||
<OlAccordion title={`Runways`} className="!p-0 !text-gray-400">
|
||||
<div className="flex flex-col gap-2">
|
||||
{props.airbase?.getChartData().runways.map((runway) => {
|
||||
return (
|
||||
<>
|
||||
{Object.keys(runway.headings[0]).map((runwayName) => {
|
||||
return (
|
||||
<div className="flex w-full justify-between">
|
||||
<span>
|
||||
{" "}
|
||||
<span className="text-gray-400">RWY</span> {runwayName}
|
||||
</span>
|
||||
<span
|
||||
className={`
|
||||
flex gap-1 rounded-full bg-olympus-200/30 px-2
|
||||
py-1
|
||||
`}
|
||||
>
|
||||
<FaCompass className={`my-auto text-gray-400`} /> {runway.headings[0][runwayName].magHeading}°{" "}
|
||||
<span className={`text-gray-400`}>ILS</span>{" "}
|
||||
{runway.headings[0][runwayName].ILS !== "" ? runway.headings[0][runwayName].ILS + "MHz" : "None"}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</OlAccordion>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 flex gap-2 px-5 text-white bold">
|
||||
{blueprint && (
|
||||
<FaArrowLeft
|
||||
className={`
|
||||
my-auto h-8 w-8 cursor-pointer rounded-md p-2
|
||||
dark:text-gray-500 dark:hover:bg-gray-700 dark:hover:text-white
|
||||
`}
|
||||
onClick={() => setBlueprint(null)}
|
||||
/>
|
||||
)}
|
||||
<span className="my-auto">Spawn units at airbase</span>
|
||||
</div>
|
||||
<>
|
||||
{blueprint === null && (
|
||||
<div className="p-5">
|
||||
<OlSearchBar onChange={(value) => setFilterString(value)} text={filterString} />
|
||||
<OlAccordion title={`Aircraft`}>
|
||||
<div
|
||||
className={`
|
||||
flex max-h-80 flex-col gap-1 overflow-y-scroll no-scrollbar
|
||||
`}
|
||||
>
|
||||
{Object.entries(filteredAircraft).map((entry) => {
|
||||
return <OlUnitEntryList key={entry[0]} icon={olButtonsVisibilityAircraft} blueprint={entry[1]} onClick={() => setBlueprint(entry[1])} />;
|
||||
})}
|
||||
</div>
|
||||
</OlAccordion>
|
||||
<OlAccordion title={`Helicopters`}>
|
||||
<div
|
||||
className={`
|
||||
flex max-h-80 flex-col gap-1 overflow-y-scroll no-scrollbar
|
||||
`}
|
||||
>
|
||||
{Object.entries(filteredHelicopters).map((entry) => {
|
||||
return <OlUnitEntryList key={entry[0]} icon={olButtonsVisibilityHelicopter} blueprint={entry[1]} onClick={() => setBlueprint(entry[1])} />;
|
||||
})}
|
||||
</div>
|
||||
</OlAccordion>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!(blueprint === null) && (
|
||||
<UnitSpawnMenu
|
||||
blueprint={blueprint}
|
||||
spawnAtLocation={false}
|
||||
airbase={props.airbase}
|
||||
coalition={(props.airbase?.getCoalition() ?? "blue") as Coalition}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import { OlStateButton } from "../components/olstatebutton";
|
||||
import { faGamepad, faRuler, faPencil, faEllipsisV, faCog, faQuestionCircle, faPlusSquare, faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faGamepad, faRuler, faPencil, faEllipsisV, faCog, faQuestionCircle, faPlusSquare, faMagnifyingGlass, faPlaneDeparture } from "@fortawesome/free-solid-svg-icons";
|
||||
import { EventsConsumer } from "../../eventscontext";
|
||||
import { StateConsumer } from "../../statecontext";
|
||||
import { IDLE } from "../../constants/constants";
|
||||
@ -52,6 +52,12 @@ export function SideBar() {
|
||||
icon={faPencil}
|
||||
tooltip="Hide/show drawing menu"
|
||||
></OlStateButton>
|
||||
<OlStateButton
|
||||
onClick={events.toggleAirbaseMenuVisible}
|
||||
checked={appState.airbaseMenuVisible}
|
||||
icon={faPlaneDeparture}
|
||||
tooltip="Hide/show airbase menu"
|
||||
></OlStateButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-16 flex-wrap content-end justify-center p-4">
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Menu } from "./components/menu";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||
import { OlSearchBar } from "../components/olsearchbar";
|
||||
import { OlAccordion } from "../components/olaccordion";
|
||||
import { getApp } from "../../olympusapp";
|
||||
@ -18,8 +16,6 @@ import {
|
||||
import { IDLE, SPAWN_UNIT } from "../../constants/constants";
|
||||
import { getUnitsByLabel } from "../../other/utils";
|
||||
|
||||
library.add(faPlus);
|
||||
|
||||
export function SpawnMenu(props: { open: boolean; onClose: () => void; children?: JSX.Element | JSX.Element[] }) {
|
||||
const [blueprint, setBlueprint] = useState(null as null | UnitBlueprint);
|
||||
const [filterString, setFilterString] = useState("");
|
||||
@ -107,7 +103,7 @@ export function SpawnMenu(props: { open: boolean; onClose: () => void; children?
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!(blueprint === null) && <UnitSpawnMenu blueprint={blueprint} />}
|
||||
{!(blueprint === null) && <UnitSpawnMenu blueprint={blueprint} spawnAtLocation={true} />}
|
||||
</>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
@ -11,8 +11,9 @@ import { getApp } from "../../olympusapp";
|
||||
import { IDLE, SPAWN_UNIT } from "../../constants/constants";
|
||||
import { ftToM, getUnitCategoryByBlueprint } from "../../other/utils";
|
||||
import { LatLng } from "leaflet";
|
||||
import { Airbase } from "../../mission/airbase";
|
||||
|
||||
export function UnitSpawnMenu(props: { blueprint: UnitBlueprint }) {
|
||||
export function UnitSpawnMenu(props: { blueprint: UnitBlueprint; spawnAtLocation: boolean; airbase?: Airbase | null; coalition?: Coalition }) {
|
||||
/* Compute the min and max values depending on the unit type */
|
||||
const minNumber = 1;
|
||||
const maxNumber = 4;
|
||||
@ -30,31 +31,60 @@ export function UnitSpawnMenu(props: { blueprint: UnitBlueprint }) {
|
||||
|
||||
/* When the menu is opened show the unit preview on the map as a cursor */
|
||||
useEffect(() => {
|
||||
if (props.blueprint !== null) {
|
||||
getApp()
|
||||
?.getMap()
|
||||
?.setState(SPAWN_UNIT, {
|
||||
spawnRequestTable: {
|
||||
category: getUnitCategoryByBlueprint(props.blueprint),
|
||||
unit: {
|
||||
unitType: props.blueprint.name,
|
||||
location: new LatLng(0, 0), // This will be filled when the user clicks on the map to spawn the unit
|
||||
skill: "High",
|
||||
liveryID: "",
|
||||
altitude: ftToM(spawnAltitude),
|
||||
loadout:
|
||||
props.blueprint.loadouts?.find((loadout) => {
|
||||
return loadout.name === spawnLoadoutName;
|
||||
})?.code ?? "",
|
||||
if (props.coalition && props.coalition !== spawnCoalition) {
|
||||
setSpawnCoalition(props.coalition);
|
||||
}
|
||||
if (props.spawnAtLocation) {
|
||||
if (props.blueprint !== null) {
|
||||
getApp()
|
||||
?.getMap()
|
||||
?.setState(SPAWN_UNIT, {
|
||||
spawnRequestTable: {
|
||||
category: getUnitCategoryByBlueprint(props.blueprint),
|
||||
unit: {
|
||||
unitType: props.blueprint.name,
|
||||
location: new LatLng(0, 0), // This will be filled when the user clicks on the map to spawn the unit
|
||||
skill: "High",
|
||||
liveryID: "",
|
||||
altitude: ftToM(spawnAltitude),
|
||||
loadout:
|
||||
props.blueprint.loadouts?.find((loadout) => {
|
||||
return loadout.name === spawnLoadoutName;
|
||||
})?.code ?? "",
|
||||
},
|
||||
coalition: spawnCoalition,
|
||||
},
|
||||
coalition: spawnCoalition,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
if (getApp()?.getMap()?.getState() === SPAWN_UNIT) getApp().getMap().setState(IDLE);
|
||||
});
|
||||
} else {
|
||||
if (getApp()?.getMap()?.getState() === SPAWN_UNIT) getApp().getMap().setState(IDLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function spawnAtAirbase() {
|
||||
getApp()
|
||||
.getUnitsManager()
|
||||
.spawnUnits(
|
||||
getUnitCategoryByBlueprint(props.blueprint),
|
||||
[
|
||||
{
|
||||
unitType: props.blueprint.name,
|
||||
location: new LatLng(0, 0), // Not relevant spawning at airbase
|
||||
skill: "High",
|
||||
liveryID: "",
|
||||
altitude: 0,
|
||||
loadout:
|
||||
props.blueprint.loadouts?.find((loadout) => {
|
||||
return loadout.name === spawnLoadoutName;
|
||||
})?.code ?? "",
|
||||
},
|
||||
],
|
||||
props.coalition,
|
||||
false,
|
||||
props.airbase?.getName()
|
||||
);
|
||||
}
|
||||
|
||||
/* Get a list of all the roles */
|
||||
const roles: string[] = [];
|
||||
(props.blueprint as UnitBlueprint).loadouts?.forEach((loadout) => {
|
||||
@ -87,14 +117,16 @@ export function UnitSpawnMenu(props: { blueprint: UnitBlueprint }) {
|
||||
inline-flex w-full flex-row content-center justify-between
|
||||
`}
|
||||
>
|
||||
<OlCoalitionToggle
|
||||
coalition={spawnCoalition}
|
||||
onClick={() => {
|
||||
spawnCoalition === "blue" && setSpawnCoalition("neutral");
|
||||
spawnCoalition === "neutral" && setSpawnCoalition("red");
|
||||
spawnCoalition === "red" && setSpawnCoalition("blue");
|
||||
}}
|
||||
/>
|
||||
{!props.coalition && (
|
||||
<OlCoalitionToggle
|
||||
coalition={spawnCoalition}
|
||||
onClick={() => {
|
||||
spawnCoalition === "blue" && setSpawnCoalition("neutral");
|
||||
spawnCoalition === "neutral" && setSpawnCoalition("red");
|
||||
spawnCoalition === "red" && setSpawnCoalition("blue");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<OlNumberInput
|
||||
value={spawnNumber}
|
||||
min={minNumber}
|
||||
@ -203,14 +235,14 @@ export function UnitSpawnMenu(props: { blueprint: UnitBlueprint }) {
|
||||
</OlDropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
flex h-fit flex-col gap-1 p-4
|
||||
dark:bg-olympus-200/30
|
||||
`}
|
||||
>
|
||||
{spawnLoadout &&
|
||||
spawnLoadout.items.map((item) => {
|
||||
{spawnLoadout && spawnLoadout.items.length > 0 && (
|
||||
<div
|
||||
className={`
|
||||
flex h-fit flex-col gap-1 p-4
|
||||
dark:bg-olympus-200/30
|
||||
`}
|
||||
>
|
||||
{spawnLoadout.items.map((item) => {
|
||||
return (
|
||||
<div className="flex content-center gap-2">
|
||||
<div
|
||||
@ -233,7 +265,25 @@ export function UnitSpawnMenu(props: { blueprint: UnitBlueprint }) {
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!props.spawnAtLocation && (
|
||||
<button
|
||||
type="button"
|
||||
className={`
|
||||
m-2 rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium
|
||||
text-white
|
||||
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
|
||||
focus:outline-none focus:ring-4 focus:ring-blue-300
|
||||
hover:bg-blue-800
|
||||
`}
|
||||
onClick={() => {
|
||||
spawnAtAirbase();
|
||||
}}
|
||||
>
|
||||
Spawn
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -18,16 +18,19 @@ import { sha256 } from "js-sha256";
|
||||
import { MiniMapPanel } from "./panels/minimappanel";
|
||||
import { UnitMouseControlBar } from "./panels/unitmousecontrolbar";
|
||||
import { DrawingMenu } from "./panels/drawingmenu";
|
||||
import { ControlsPanel } from "./panels/controls";
|
||||
import { ControlsPanel } from "./panels/controlspanel";
|
||||
import { MapContextMenu } from "./contextmenus/mapcontextmenu";
|
||||
import { AirbaseMenu } from "./panels/airbasemenu";
|
||||
import { Airbase } from "../mission/airbase";
|
||||
|
||||
export type OlympusState = {
|
||||
export type OlympusUIState = {
|
||||
mainMenuVisible: boolean;
|
||||
spawnMenuVisible: boolean;
|
||||
unitControlMenuVisible: boolean;
|
||||
measureMenuVisible: boolean;
|
||||
drawingMenuVisible: boolean;
|
||||
optionsMenuVisible: boolean;
|
||||
airbaseMenuVisible: boolean;
|
||||
mapHiddenTypes: MapHiddenTypes;
|
||||
mapOptions: MapOptions;
|
||||
};
|
||||
@ -40,6 +43,7 @@ export function UI() {
|
||||
const [measureMenuVisible, setMeasureMenuVisible] = useState(false);
|
||||
const [drawingMenuVisible, setDrawingMenuVisible] = useState(false);
|
||||
const [optionsMenuVisible, setOptionsMenuVisible] = useState(false);
|
||||
const [airbaseMenuVisible, setAirbaseMenuVisible] = useState(false);
|
||||
const [mapHiddenTypes, setMapHiddenTypes] = useState(MAP_HIDDEN_TYPES_DEFAULTS);
|
||||
const [mapOptions, setMapOptions] = useState(MAP_OPTIONS_DEFAULTS);
|
||||
const [checkingPassword, setCheckingPassword] = useState(false);
|
||||
@ -48,6 +52,7 @@ export function UI() {
|
||||
const [mapSources, setMapSources] = useState([] as string[]);
|
||||
const [activeMapSource, setActiveMapSource] = useState("");
|
||||
const [mapState, setMapState] = useState(IDLE);
|
||||
const [airbase, setAirbase] = useState(null as null | Airbase);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener("hiddenTypesChanged", (ev) => {
|
||||
@ -75,6 +80,13 @@ export function UI() {
|
||||
setMapSources(sources);
|
||||
setActiveMapSource(sources[0]);
|
||||
});
|
||||
|
||||
document.addEventListener("airbaseclick", (ev) => {
|
||||
hideAllMenus();
|
||||
getApp().getMap().setState(IDLE);
|
||||
setAirbase((ev as CustomEvent).detail);
|
||||
setAirbaseMenuVisible(true);
|
||||
});
|
||||
}, []);
|
||||
|
||||
function hideAllMenus() {
|
||||
@ -84,6 +96,7 @@ export function UI() {
|
||||
setMeasureMenuVisible(false);
|
||||
setDrawingMenuVisible(false);
|
||||
setOptionsMenuVisible(false);
|
||||
setAirbaseMenuVisible(false);
|
||||
}
|
||||
|
||||
function checkPassword(password: string) {
|
||||
@ -139,6 +152,7 @@ export function UI() {
|
||||
measureMenuVisible: measureMenuVisible,
|
||||
drawingMenuVisible: drawingMenuVisible,
|
||||
optionsMenuVisible: optionsMenuVisible,
|
||||
airbaseMenuVisible: airbaseMenuVisible,
|
||||
mapOptions: mapOptions,
|
||||
mapHiddenTypes: mapHiddenTypes,
|
||||
mapSources: mapSources,
|
||||
@ -154,6 +168,7 @@ export function UI() {
|
||||
setDrawingMenuVisible: setDrawingMenuVisible,
|
||||
setMeasureMenuVisible: setMeasureMenuVisible,
|
||||
setOptionsMenuVisible: setOptionsMenuVisible,
|
||||
setAirbaseMenuVisible: setAirbaseMenuVisible,
|
||||
toggleMainMenuVisible: () => {
|
||||
hideAllMenus();
|
||||
setMainMenuVisible(!mainMenuVisible);
|
||||
@ -178,6 +193,10 @@ export function UI() {
|
||||
hideAllMenus();
|
||||
setOptionsMenuVisible(!optionsMenuVisible);
|
||||
},
|
||||
toggleAirbaseMenuVisible: () => {
|
||||
hideAllMenus();
|
||||
setAirbaseMenuVisible(!airbaseMenuVisible);
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Header />
|
||||
@ -211,6 +230,7 @@ export function UI() {
|
||||
<Options open={optionsMenuVisible} onClose={() => setOptionsMenuVisible(false)} options={mapOptions} />
|
||||
<UnitControlMenu open={unitControlMenuVisible} onClose={() => setUnitControlMenuVisible(false)} />
|
||||
<DrawingMenu open={drawingMenuVisible} onClose={() => setDrawingMenuVisible(false)} />
|
||||
<AirbaseMenu open={airbaseMenuVisible} onClose={() => setAirbaseMenuVisible(false)} airbase={airbase}/>
|
||||
|
||||
<MiniMapPanel />
|
||||
<ControlsPanel />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user