feat: added support for callsigns

This commit is contained in:
Pax1601
2025-03-25 13:05:40 +01:00
parent f91daed25e
commit bc65bf546f
6 changed files with 40 additions and 23 deletions

View File

@@ -419,7 +419,8 @@ export const MAP_OPTIONS_DEFAULTS: MapOptions = {
hideChromeWarning: false, hideChromeWarning: false,
hideSecureWarning: false, hideSecureWarning: false,
showMissionDrawings: false, showMissionDrawings: false,
clusterGroundUnits: true clusterGroundUnits: true,
showUnitCallsigns: true,
}; };
export const MAP_HIDDEN_TYPES_DEFAULTS = { export const MAP_HIDDEN_TYPES_DEFAULTS = {

View File

@@ -787,7 +787,3 @@ export function secondsToTimeString(seconds: number) {
return `${zeroPad(hours, 2)}:${zeroPad(minutes, 2)}:${zeroPad(secs, 2)}`; return `${zeroPad(hours, 2)}:${zeroPad(minutes, 2)}:${zeroPad(secs, 2)}`;
} }
export function isTrustedEnvironment() {
return window.location.protocol === "https:";
}

View File

@@ -32,6 +32,7 @@ export type MapOptions = {
hideSecureWarning: boolean; hideSecureWarning: boolean;
showMissionDrawings: boolean; showMissionDrawings: boolean;
clusterGroundUnits: boolean; clusterGroundUnits: boolean;
showUnitCallsigns: boolean;
}; };
export type MapHiddenTypes = { export type MapHiddenTypes = {

View File

@@ -3,7 +3,7 @@ import { OlLocation } from "../components/ollocation";
import { LatLng } from "leaflet"; import { LatLng } from "leaflet";
import { FaBullseye, FaChevronDown, FaChevronUp, FaJetFighter, FaMountain, FaCopy, FaXmark } from "react-icons/fa6"; import { FaBullseye, FaChevronDown, FaChevronUp, FaJetFighter, FaMountain, FaCopy, FaXmark } from "react-icons/fa6";
import { BullseyesDataChangedEvent, CoordinatesFreezeEvent, MouseMovedEvent, SelectedUnitsChangedEvent, SelectionClearedEvent } from "../../events"; import { BullseyesDataChangedEvent, CoordinatesFreezeEvent, MouseMovedEvent, SelectedUnitsChangedEvent, SelectionClearedEvent } from "../../events";
import { computeBearingRangeString, ConvertDDToDMS, DDToDDM, isTrustedEnvironment, latLngToMGRS, mToFt, zeroAppend } from "../../other/utils"; import { computeBearingRangeString, ConvertDDToDMS, DDToDDM, latLngToMGRS, mToFt, zeroAppend } from "../../other/utils";
import { Bullseye } from "../../mission/bullseye"; import { Bullseye } from "../../mission/bullseye";
import { Unit } from "../../unit/unit"; import { Unit } from "../../unit/unit";
import { getApp } from "../../olympusapp"; import { getApp } from "../../olympusapp";
@@ -50,7 +50,7 @@ export function CoordinatesPanel(props: {}) {
break; break;
} }
returnString += ` Elevation: ${Math.round(elevation)}`; returnString += ` Elevation: ${Math.round(elevation)}ft`;
return returnString; return returnString;
}; };
@@ -152,15 +152,17 @@ export function CoordinatesPanel(props: {}) {
className="ml-auto flex w-[50%]" className="ml-auto flex w-[50%]"
onClick={async (evt) => { onClick={async (evt) => {
evt.stopPropagation(); evt.stopPropagation();
setCopyCoordsOpen(true);
if (isSecureContext && navigator.clipboard) {
if (isTrustedEnvironment()) {
try { try {
await navigator.clipboard.writeText(copyableCoordinates); await navigator.clipboard.writeText(copyableCoordinates);
getApp().addInfoMessage(`Coordinates copied to clipboard: ${copyableCoordinates}`); getApp().addInfoMessage(`Coordinates copied to clipboard: ${copyableCoordinates}`);
} catch (err) { } catch (err) {
setCopyCoordsOpen(true);
console.error('Failed to copy text: ', err); console.error('Failed to copy text: ', err);
} }
} else {
setCopyCoordsOpen(true);
} }
}} }}
> >
@@ -172,18 +174,21 @@ export function CoordinatesPanel(props: {}) {
> >
<FaCopy /> <FaCopy />
</span> </span>
<div className="min-w-12">Copy Coords</div> <div className="min-w-12">Copy last click</div>
</div> </div>
</div>, </div>,
open && copyCoordsOpen && ( open && copyCoordsOpen && (
<div <div
className={` className={`
relative mt-4 flex w-full min-w-64 items-center justify-between relative mt-2 flex w-full min-w-64 items-center justify-between
`} `}
onClick={(evt) => evt.stopPropagation()} onClick={(evt) => evt.stopPropagation()}
> >
<textarea readOnly={true} className="resize-none p-2 text-black" name="coordsTextArea" id="coordsTextArea" cols={25} rows={2} value={copyableCoordinates}></textarea> <textarea readOnly={true} className={`
resize-none rounded-md border-2 border-gray-600 bg-olympus-600 p-2
text-gray-200
`} name="coordsTextArea" id="coordsTextArea" cols={25} rows={2} value={copyableCoordinates}></textarea>
<div className="absolute right-[0] top-[0px] background-transparent" onClick={() => setCopyCoordsOpen(false)}> <div className="absolute right-[0] top-[0px] background-transparent" onClick={() => setCopyCoordsOpen(false)}>
<FaXmark className="cursor-pointer" /> <FaXmark className="cursor-pointer" />

View File

@@ -121,6 +121,17 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
<OlCheckbox checked={mapOptions.showUnitLabels} onChange={() => {}}></OlCheckbox> <OlCheckbox checked={mapOptions.showUnitLabels} onChange={() => {}}></OlCheckbox>
<span className="my-auto">Show unit labels</span> <span className="my-auto">Show unit labels</span>
</div> </div>
<div
className={`
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("showUnitCallsigns", !mapOptions.showUnitCallsigns)}
>
<OlCheckbox checked={mapOptions.showUnitCallsigns} onChange={() => {}}></OlCheckbox>
<span className="my-auto">Show unit Mission Editor callsigns</span>
</div>
<div <div
className={` className={`
group flex cursor-pointer flex-row content-center justify-start group flex cursor-pointer flex-row content-center justify-start
@@ -149,9 +160,9 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
gap-4 rounded-md p-2 gap-4 rounded-md p-2
dark:hover:bg-olympus-400 dark:hover:bg-olympus-400
`} `}
onClick={() => getApp().getMap().setOption("showUnitTargets", !mapOptions.showUnitTargets)} onClick={() => getApp().getMap().setOption("showUnitContacts", !mapOptions.showUnitContacts)}
> >
<OlCheckbox checked={mapOptions.showUnitTargets} onChange={() => {}}></OlCheckbox> <OlCheckbox checked={mapOptions.showUnitContacts} onChange={() => {}}></OlCheckbox>
<span className="my-auto">Show detection lines</span> <span className="my-auto">Show detection lines</span>
</div> </div>
<div <div

View File

@@ -1773,6 +1773,9 @@ export abstract class Unit extends CustomMarker {
/* Draw the velocity vector */ /* Draw the velocity vector */
element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${15 + this.#speed / 5}px;`); element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${15 + this.#speed / 5}px;`);
/* Set the unit name or callsign */
if (element.querySelector(".unit-callsign")) (element.querySelector(".unit-callsign") as HTMLElement).innerText = getApp().getMap().getOptions().showUnitCallsigns? this.#callsign: this.#unitName;
/* Set fuel data */ /* Set fuel data */
element.querySelector(".unit-fuel-level")?.setAttribute("style", `width: ${this.#fuel}%`); element.querySelector(".unit-fuel-level")?.setAttribute("style", `width: ${this.#fuel}%`);
element.querySelector(".unit")?.toggleAttribute("data-has-low-fuel", this.#fuel < 20); element.querySelector(".unit")?.toggleAttribute("data-has-low-fuel", this.#fuel < 20);
@@ -1809,9 +1812,9 @@ export abstract class Unit extends CustomMarker {
/* Set altitude and speed */ /* Set altitude and speed */
if (element.querySelector(".unit-altitude")) if (element.querySelector(".unit-altitude"))
(<HTMLElement>element.querySelector(".unit-altitude")).innerText = "FL" + zeroAppend(Math.floor(mToFt(this.#position.alt as number) / 100), 3); (element.querySelector(".unit-altitude") as HTMLElement).innerText = "FL" + zeroAppend(Math.floor(mToFt(this.#position.alt as number) / 100), 3);
if (element.querySelector(".unit-speed")) if (element.querySelector(".unit-speed"))
(<HTMLElement>element.querySelector(".unit-speed")).innerText = String(Math.floor(msToKnots(this.#speed))) + "GS"; (element.querySelector(".unit-speed") as HTMLElement).innerText = String(Math.floor(msToKnots(this.#speed))) + "GS";
/* Rotate elements according to heading */ /* Rotate elements according to heading */
element.querySelectorAll("[data-rotate-to-heading]").forEach((el) => { element.querySelectorAll("[data-rotate-to-heading]").forEach((el) => {
@@ -1856,10 +1859,10 @@ export abstract class Unit extends CustomMarker {
?.toggleAttribute( ?.toggleAttribute(
"data-is-cluster-leader", "data-is-cluster-leader",
this.#isClusterLeader && this.#isClusterLeader &&
this.#clusterUnits.length > 1 && this.#clusterUnits.length > 1 &&
getApp().getMap().getOptions().clusterGroundUnits && getApp().getMap().getOptions().clusterGroundUnits &&
getApp().getMap().getZoom() < CLUSTERING_ZOOM_TRANSITION && getApp().getMap().getZoom() < CLUSTERING_ZOOM_TRANSITION &&
!this.getSelected() !this.getSelected()
); );
if (this.#isClusterLeader && this.#clusterUnits.length > 1) { if (this.#isClusterLeader && this.#clusterUnits.length > 1) {
const clusterEl = element.querySelector(".unit-cluster-id") as HTMLElement; const clusterEl = element.querySelector(".unit-cluster-id") as HTMLElement;
@@ -2433,7 +2436,7 @@ export abstract class AirUnit extends Unit {
showCallsign: belongsToCommandedCoalition && /*TODO !getApp().getMap().getOptions().AWACSMode || */ this.getHuman(), showCallsign: belongsToCommandedCoalition && /*TODO !getApp().getMap().getOptions().AWACSMode || */ this.getHuman(),
rotateToHeading: false, rotateToHeading: false,
showCluster: false, showCluster: false,
showAlarmState: false showAlarmState: false,
} as ObjectIconOptions; } as ObjectIconOptions;
} }
@@ -2590,7 +2593,7 @@ export class NavyUnit extends Unit {
showCallsign: belongsToCommandedCoalition && /*TODO !getApp().getMap().getOptions().AWACSMode || */ this.getHuman(), showCallsign: belongsToCommandedCoalition && /*TODO !getApp().getMap().getOptions().AWACSMode || */ this.getHuman(),
rotateToHeading: false, rotateToHeading: false,
showCluster: false, showCluster: false,
showAlarmState: true showAlarmState: true,
} as ObjectIconOptions; } as ObjectIconOptions;
} }