Merge remote-tracking branch 'origin/release-candidate' into 1054-drawings-control-panel-separate-global-mission-drawings-control-from-navpoints-control

This commit is contained in:
MarcoJayUsai
2025-03-26 16:17:29 +01:00
8 changed files with 205 additions and 132 deletions

View File

@@ -43,7 +43,7 @@ export interface OlympusConfig {
authentication?: {
// Only sent when in localhost mode for autologin
gameMasterPassword: string;
blueCommanderPasword: string;
blueCommanderPassword: string;
redCommanderPassword: string;
};
}

View File

@@ -275,11 +275,9 @@ export class MissionManager {
var requestRefresh = false;
if (this.#commandModeOptions.commandMode === NONE && commandModeOptions.commandMode !== NONE) requestRefresh = true;
/* Refresh the page if we have lost Game Master priviledges */
if (this.#commandModeOptions.commandMode === GAME_MASTER && commandModeOptions.commandMode !== GAME_MASTER) location.reload();
/* Check if any option has changed */
var commandModeOptionsChanged =
commandModeOptions.commandMode !== this.getCommandModeOptions().commandMode ||
!commandModeOptions.eras.every((value: string, idx: number) => {
return value === this.getCommandModeOptions().eras[idx];
}) ||

View File

@@ -16,7 +16,7 @@ import { DrawSubState, ERAS_ORDER, IADSTypes, NO_SUBSTATE, OlympusState, Olympus
import { AppStateChangedEvent, CoalitionAreasChangedEvent, CoalitionAreaSelectedEvent, DrawingsInitEvent, DrawingsUpdatedEvent } from "../../events";
import { FaCopy, FaPencil, FaRegCompass, FaXmark } from "react-icons/fa6";
import { deepCopyTable } from "../../other/utils";
import { DCSDrawingsContainer, DCSEmptyLayer } from "../../map/drawings/drawingsmanager";
import { DCSDrawing, DCSDrawingsContainer, DCSEmptyLayer } from "../../map/drawings/drawingsmanager";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { OlSearchBar } from "../components/olsearchbar";
@@ -67,6 +67,10 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
CoalitionAreasChangedEvent.on((coalitionAreas) => setCoalitionAreas([...coalitionAreas]));
}, []);
function getDrawingLabelColor(drawing: DCSDrawingsContainer | DCSDrawing) {
return drawing.getVisibility() ? `text-gray-200` : `text-gray-600`;
}
function renderDrawingsContainerControls(container: DCSDrawingsContainer, containerSearchString: string) {
if (container.hasSearchString(containerSearchString)) {
/* The following snippet automatically open containers that contains searched drawings */
@@ -98,8 +102,10 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
<FontAwesomeIcon
icon={container.getVisibility() ? faEye : faEyeSlash}
className={`
my-auto w-6 cursor-pointer text-gray-400 transition-transform
hover:scale-125 hover:text-gray-200
my-auto w-6 cursor-pointer
${getDrawingLabelColor(container)}
transition-transform
hover:scale-125 hover:text-gray-50
`}
onClick={() => {
if (container === mainDrawingsContainer.container) {
@@ -111,7 +117,9 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
/>
<div
className={`
w-40 w-max-40 overflow-hidden text-ellipsis text-nowrap bg-
w-40
${getDrawingLabelColor(container)}
w-max-40 overflow-hidden text-ellipsis text-nowrap bg-
`}
>
{container.getName()}
@@ -139,15 +147,20 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
<FontAwesomeIcon
icon={drawing.getVisibility() ? faEye : faEyeSlash}
className={`
my-auto w-6 cursor-pointer text-gray-400
my-auto w-6 cursor-pointer
${getDrawingLabelColor(drawing)}
transition-transform
hover:scale-125 hover:text-gray-200
hover:scale-125 hover:text-gray-50
`}
onClick={() => {
drawing.setVisibility(!drawing.getVisibility());
}}
/>
<div className={`overflow-hidden text-ellipsis text-nowrap`}>{drawing.getName()}</div>
<div className={`
overflow-hidden
${getDrawingLabelColor(drawing)}
text-ellipsis text-nowrap
`}>{drawing.getName()}</div>
<FontAwesomeIcon
icon={faMapLocation}
className={`

View File

@@ -5,7 +5,7 @@ import { OlNumberInput } from "../components/olnumberinput";
import { getApp } from "../../olympusapp";
import { ServerStatus } from "../../interfaces";
import { CommandModeOptionsChangedEvent, ServerStatusUpdatedEvent } from "../../events";
import { BLUE_COMMANDER, COMMAND_MODE_OPTIONS_DEFAULTS, ERAS_ORDER, GAME_MASTER, RED_COMMANDER } from "../../constants/constants";
import { COMMAND_MODE_OPTIONS_DEFAULTS, ERAS_ORDER, GAME_MASTER } from "../../constants/constants";
import { secondsToTimeString } from "../../other/utils";
import { FaQuestionCircle } from "react-icons/fa";
import { FaMinus, FaPlus } from "react-icons/fa6";

View File

@@ -19,15 +19,25 @@ import { FaChevronLeft, FaChevronRight, FaFloppyDisk } from "react-icons/fa6";
import {
CommandModeOptionsChangedEvent,
ConfigLoadedEvent,
EnabledCommandModesChangedEvent,
HiddenTypesChangedEvent,
MapOptionsChangedEvent,
MapSourceChangedEvent,
SessionDataChangedEvent,
SessionDataSavedEvent,
} from "../../events";
import { BLUE_COMMANDER, COMMAND_MODE_OPTIONS_DEFAULTS, MAP_HIDDEN_TYPES_DEFAULTS, MAP_OPTIONS_DEFAULTS, RED_COMMANDER } from "../../constants/constants";
import {
BLUE_COMMANDER,
COMMAND_MODE_OPTIONS_DEFAULTS,
GAME_MASTER,
LoginSubState,
MAP_HIDDEN_TYPES_DEFAULTS,
MAP_OPTIONS_DEFAULTS,
OlympusState,
RED_COMMANDER,
} from "../../constants/constants";
import { OlympusConfig } from "../../interfaces";
import { FaCheck, FaSpinner } from "react-icons/fa";
import { FaCheck, FaRedo, FaSpinner } from "react-icons/fa";
import { OlExpandingTooltip } from "../components/olexpandingtooltip";
export function Header() {
@@ -44,6 +54,8 @@ export function Header() {
const [isLatestVersion, setIsLatestVersion] = useState(false);
const [isBetaVersion, setIsBetaVersion] = useState(false);
const [isDevVersion, setIsDevVersion] = useState(false);
const [enabledCommandModes, setEnabledCommandModes] = useState([] as string[]);
const [loadingNewCommandMode, setLoadingNewCommandMode] = useState(false);
useEffect(() => {
HiddenTypesChangedEvent.on((hiddenTypes) => setMapHiddenTypes({ ...hiddenTypes }));
@@ -60,9 +72,11 @@ export function Header() {
});
CommandModeOptionsChangedEvent.on((commandModeOptions) => {
setCommandModeOptions(commandModeOptions);
setLoadingNewCommandMode(false);
});
SessionDataChangedEvent.on(() => setSavingSessionData(true));
SessionDataSavedEvent.on(() => setSavingSessionData(false));
EnabledCommandModesChangedEvent.on((enabledCommandModes) => setEnabledCommandModes(enabledCommandModes));
/* Check if we are running the latest version */
const request = new Request("https://raw.githubusercontent.com/Pax1601/DCSOlympus/main/version.json");
@@ -213,14 +227,79 @@ export function Header() {
)}
</div>
{commandModeOptions.commandMode === GAME_MASTER && (
<div
className={`
flex h-full cursor-pointer rounded-md border-2 border-transparent
bg-olympus-600 px-4 text-gray-200
hover:bg-olympus-400
`}
onClick={() => {
if (enabledCommandModes.length > 0) {
let blueCommandModeIndex = enabledCommandModes.indexOf(BLUE_COMMANDER);
let redCommandModeIndex = enabledCommandModes.indexOf(RED_COMMANDER);
if (blueCommandModeIndex >= 0) getApp().getServerManager().setActiveCommandMode(BLUE_COMMANDER);
else if (redCommandModeIndex >= 0) getApp().getServerManager().setActiveCommandMode(RED_COMMANDER);
setLoadingNewCommandMode(true);
}
}}
>
<span className="my-auto font-bold">Game Master</span>
{enabledCommandModes.length > 0 && (
<>{loadingNewCommandMode ? <FaSpinner className={`
my-auto ml-2 animate-spin text-white
`} /> : <FaRedo className={`my-auto ml-2 text-gray-200`} />}</>
)}
</div>
)}
{commandModeOptions.commandMode === BLUE_COMMANDER && (
<div className={`flex h-full rounded-md bg-blue-600 px-4 text-white`}>
<span className="my-auto font-bold">BLUE Commander ({commandModeOptions.spawnPoints.blue} points)</span>
<div
className={`
flex h-full cursor-pointer rounded-md border-2 border-transparent
bg-blue-600 px-4 text-gray-200
hover:bg-blue-400
`}
onClick={() => {
if (enabledCommandModes.length > 0) {
let gameMasterCommandModeIndex = enabledCommandModes.indexOf(GAME_MASTER);
let redCommandModeIndex = enabledCommandModes.indexOf(RED_COMMANDER);
if (redCommandModeIndex >= 0) getApp().getServerManager().setActiveCommandMode(RED_COMMANDER);
else if (gameMasterCommandModeIndex >= 0) getApp().getServerManager().setActiveCommandMode(GAME_MASTER);
setLoadingNewCommandMode(true);
}
}}
>
<span className="my-auto font-bold">BLUE Commander</span>
{enabledCommandModes.length > 0 && (
<>{loadingNewCommandMode ? <FaSpinner className={`
my-auto ml-2 animate-spin text-gray-200
`} /> : <FaRedo className={`my-auto ml-2 text-gray-200`} />}</>
)}
</div>
)}
{commandModeOptions.commandMode === RED_COMMANDER && (
<div className={`flex h-full rounded-md bg-red-600 px-4 text-white`}>
<span className="my-auto font-bold">BLUE Commander ({commandModeOptions.spawnPoints.blue} points)</span>
<div
className={`
flex h-full cursor-pointer rounded-md border-2 border-transparent
bg-red-600 px-4 text-gray-200
hover:bg-red-500
`}
onClick={() => {
if (enabledCommandModes.length > 0) {
let gameMasterCommandModeIndex = enabledCommandModes.indexOf(GAME_MASTER);
let blueCommandModeIndex = enabledCommandModes.indexOf(BLUE_COMMANDER);
if (gameMasterCommandModeIndex >= 0) getApp().getServerManager().setActiveCommandMode(GAME_MASTER);
else if (blueCommandModeIndex >= 0) getApp().getServerManager().setActiveCommandMode(BLUE_COMMANDER);
setLoadingNewCommandMode(true);
}
}}
>
<span className="my-auto font-bold">RED Commander</span>
{enabledCommandModes.length > 0 && (
<>{loadingNewCommandMode ? <FaSpinner className={`
my-auto ml-2 animate-spin text-gray-200
`} /> : <FaRedo className={`my-auto ml-2 text-gray-200`} />}</>
)}
</div>
)}
<div className={`flex h-fit flex-row items-center justify-start gap-1`}>