diff --git a/frontend/react/src/events.ts b/frontend/react/src/events.ts
index ae526fc0..b95f20b9 100644
--- a/frontend/react/src/events.ts
+++ b/frontend/react/src/events.ts
@@ -140,6 +140,8 @@ export class InfoPopupEvent {
}
}
+export class WrongCredentialsEvent extends BaseOlympusEvent {}
+
export class ShortcutsChangedEvent {
static on(callback: (shortcuts: { [key: string]: Shortcut }) => void, singleShot = false) {
document.addEventListener(
@@ -818,6 +820,23 @@ export class MissionDataChangedEvent {
}
}
+export class EnabledCommandModesChangedEvent {
+ static on(callback: (enabledCommandModes: string[]) => void, singleShot = false) {
+ document.addEventListener(
+ this.name,
+ (ev: CustomEventInit) => {
+ callback(ev.detail.enabledCommandModes);
+ },
+ { once: singleShot }
+ );
+ }
+
+ static dispatch(enabledCommandModes: string[]) {
+ document.dispatchEvent(new CustomEvent(this.name, { detail: { enabledCommandModes } }));
+ // Logging disabled since periodic
+ }
+}
+
/************** Other events ***************/
export class WeaponsRefreshedEvent {
static on(callback: (weapons: Weapon[]) => void, singleShot = false) {
diff --git a/frontend/react/src/mission/missionmanager.ts b/frontend/react/src/mission/missionmanager.ts
index 44ebfb7c..4c87b105 100644
--- a/frontend/react/src/mission/missionmanager.ts
+++ b/frontend/react/src/mission/missionmanager.ts
@@ -6,7 +6,7 @@ import { BLUE_COMMANDER, GAME_MASTER, NONE, RED_COMMANDER } from "../constants/c
import { AirbasesData, BullseyesData, CommandModeOptions, DateAndTime, MissionData } from "../interfaces";
import { Coalition } from "../types/types";
import { Carrier } from "./carrier";
-import { AirbaseSelectedEvent, AppStateChangedEvent, BullseyesDataChangedEvent, CommandModeOptionsChangedEvent, MissionDataChangedEvent } from "../events";
+import { AirbaseSelectedEvent, AppStateChangedEvent, BullseyesDataChangedEvent, CommandModeOptionsChangedEvent, EnabledCommandModesChangedEvent, MissionDataChangedEvent } from "../events";
/** The MissionManager */
export class MissionManager {
@@ -225,6 +225,7 @@ export class MissionManager {
setEnabledCommandModes(enabledCommandModes: string[]) {
this.#enabledCommandModes = enabledCommandModes;
+ EnabledCommandModesChangedEvent.dispatch(enabledCommandModes);
}
getEnabledCommandModes() {
diff --git a/frontend/react/src/server/servermanager.ts b/frontend/react/src/server/servermanager.ts
index ca74781e..d393ba44 100644
--- a/frontend/react/src/server/servermanager.ts
+++ b/frontend/react/src/server/servermanager.ts
@@ -14,7 +14,7 @@ import {
reactionsToThreat,
} from "../constants/constants";
import { AirbasesData, BullseyesData, CommandModeOptions, GeneralSettings, MissionData, Radio, ServerRequestOptions, ServerStatus, TACAN } from "../interfaces";
-import { MapOptionsChangedEvent, ServerStatusUpdatedEvent } from "../events";
+import { MapOptionsChangedEvent, ServerStatusUpdatedEvent, WrongCredentialsEvent } from "../events";
export class ServerManager {
#connected: boolean = false;
@@ -130,6 +130,7 @@ export class ServerManager {
} else if (xmlHttp.status == 401) {
/* Bad credentials */
console.error("Incorrect username/password");
+ WrongCredentialsEvent.dispatch();
errorCallback && errorCallback(xmlHttp.status);
} else {
/* Failure, probably disconnected */
diff --git a/frontend/react/src/ui/modals/loginmodal.tsx b/frontend/react/src/ui/modals/loginmodal.tsx
index 2d9141dc..6dd3546e 100644
--- a/frontend/react/src/ui/modals/loginmodal.tsx
+++ b/frontend/react/src/ui/modals/loginmodal.tsx
@@ -8,10 +8,9 @@ import { getApp, VERSION } from "../../olympusapp";
import { sha256 } from "js-sha256";
import { LoginSubState, NO_SUBSTATE, OlympusState } from "../../constants/constants";
import { OlDropdown, OlDropdownItem } from "../components/oldropdown";
-import { AppStateChangedEvent } from "../../events";
+import { AppStateChangedEvent, EnabledCommandModesChangedEvent, MissionDataChangedEvent, WrongCredentialsEvent } from "../../events";
export function LoginModal(props: { open: boolean }) {
- // TODO: add warning if not in secure context and some features are disabled
const [subState, setSubState] = useState(NO_SUBSTATE);
const [password, setPassword] = useState("");
const [username, setUsername] = useState("");
@@ -24,6 +23,10 @@ export function LoginModal(props: { open: boolean }) {
AppStateChangedEvent.on((state, subState) => {
setSubState(subState);
});
+ WrongCredentialsEvent.on(() => {
+ setLoginError(true);
+ setCheckingPassword(false);
+ });
}, []);
const usernameCallback = useCallback(() => getApp()?.getServerManager().setUsername(username), [username]);
@@ -37,28 +40,21 @@ export function LoginModal(props: { open: boolean }) {
const login = useCallback(() => {
setCheckingPassword(true);
-
+ EnabledCommandModesChangedEvent.on((commandModes) => {
+ if (commandModes.length > 1) {
+ setCommandModes(commandModes);
+ setActiveCommandMode(commandModes[0]);
+ } else if (commandModes.length == 1) {
+ setActiveCommandMode(commandModes[0]);
+ getApp().setState(OlympusState.LOGIN, LoginSubState.CONNECT);
+ } else {
+ setLoginError(true);
+ }
+ setCheckingPassword(false);
+ }, true);
getApp()
.getServerManager()
- .getMission(
- (response) => {
- const commandModes = getApp().getMissionManager().getEnabledCommandModes();
- if (commandModes.length > 1) {
- setCommandModes(commandModes);
- setActiveCommandMode(commandModes[0]);
- } else if (commandModes.length == 1) {
- setActiveCommandMode(commandModes[0]);
- getApp().setState(OlympusState.LOGIN, LoginSubState.CONNECT);
- } else {
- setLoginError(true);
- }
- setCheckingPassword(false);
- },
- () => {
- setLoginError(true);
- setCheckingPassword(false);
- }
- );
+ .getMission(() => {});
}, [commandModes, username, password]);
const connect = useCallback(() => {
@@ -94,9 +90,10 @@ export function LoginModal(props: { open: boolean }) {
max-md:border-none
`}
>
-
+
+