diff --git a/frontend/react/src/index.css b/frontend/react/src/index.css index 2903cdc7..09eaf891 100644 --- a/frontend/react/src/index.css +++ b/frontend/react/src/index.css @@ -23,4 +23,12 @@ .z-ui-2 { z-index: 2002; +} + +.z-ui-3 { + z-index: 2003; +} + +.z-ui-4 { + z-index: 2004; } \ No newline at end of file diff --git a/frontend/react/src/olympusapp.ts b/frontend/react/src/olympusapp.ts index a7a6b175..972d58d4 100644 --- a/frontend/react/src/olympusapp.ts +++ b/frontend/react/src/olympusapp.ts @@ -41,8 +41,8 @@ import { navyUnitDatabase } from "./unit/databases/navyunitdatabase"; //import { ContextManager } from "./context/contextmanager"; //import { Context } from "./context/context"; export var VERSION = "{{OLYMPUS_VERSION_NUMBER}}"; -export var IP = "{{IP ADDRESS OF SERVER}}"; -export var connectedToServer = true; +export var IP = window.location.toString(); +export var connectedToServer = true; // Temporary export class OlympusApp { /* Global data */ @@ -271,6 +271,7 @@ export class OlympusApp { }) /* Load the config file from the server */ + // Temporary const configRequest = new Request("http://localhost:3000/" + "resources/config"); fetch(configRequest).then((response) => { if (response.status === 200) { diff --git a/frontend/react/src/server/servermanager.ts b/frontend/react/src/server/servermanager.ts index 26af704f..f8085c8c 100644 --- a/frontend/react/src/server/servermanager.ts +++ b/frontend/react/src/server/servermanager.ts @@ -12,7 +12,7 @@ export class ServerManager { #connected: boolean = false; #paused: boolean = false; #REST_ADDRESS = "http://localhost:3001/olympus"; - #username = ""; + #username = "no-username"; #password = ""; #sessionHash: string | null = null; #lastUpdateTimes: { [key: string]: number } = {} @@ -30,12 +30,15 @@ export class ServerManager { this.#lastUpdateTimes[MISSION_URI] = Date.now(); } - setCredentials(newUsername: string, newPassword: string) { + setUsername(newUsername: string) { this.#username = newUsername; + } + + setPassword(newPassword: string) { this.#password = newPassword; } - GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType: string = 'text', force: boolean = false) { + GET(callback: CallableFunction, errorCallback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType: string = 'text', force: boolean = false) { var xmlHttp = new XMLHttpRequest(); /* If a request on this uri is still pending (meaning it's not done or did not yet fail), skip the request, to avoid clogging the TCP workers */ @@ -84,15 +87,18 @@ export class ServerManager { /* Bad credentials */ console.error("Incorrect username/password"); getApp().setLoginStatus("failed"); + errorCallback && errorCallback(xmlHttp.status); } else { /* Failure, probably disconnected */ this.setConnected(false); + errorCallback && errorCallback(xmlHttp.status); } }; xmlHttp.onreadystatechange = (res) => { if (xmlHttp.readyState == 4 && xmlHttp.status === 0) { console.error("An error occurred during the XMLHttpRequest"); this.setConnected(false); + errorCallback && errorCallback(xmlHttp.status); } }; xmlHttp.send(null); @@ -131,32 +137,32 @@ export class ServerManager { console.log(`Setting REST address to ${this.#REST_ADDRESS}`) } - getAirbases(callback: CallableFunction) { - this.GET(callback, AIRBASES_URI); + getAirbases(callback: CallableFunction, errorCallback: CallableFunction = () => {}) { + this.GET(callback, errorCallback, AIRBASES_URI); } - getBullseye(callback: CallableFunction) { - this.GET(callback, BULLSEYE_URI); + getBullseye(callback: CallableFunction, errorCallback: CallableFunction = () => {}) { + this.GET(callback, errorCallback, BULLSEYE_URI); } - getLogs(callback: CallableFunction, refresh: boolean = false) { - this.GET(callback, LOGS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[LOGS_URI] }, 'text', refresh); + getLogs(callback: CallableFunction, refresh: boolean = false, errorCallback: CallableFunction = () => {}) { + this.GET(callback, errorCallback, LOGS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[LOGS_URI] }, 'text', refresh); } - getMission(callback: CallableFunction) { - this.GET(callback, MISSION_URI); + getMission(callback: CallableFunction, errorCallback: CallableFunction = () => {}) { + this.GET(callback, errorCallback, MISSION_URI); } - getUnits(callback: CallableFunction, refresh: boolean = false) { - this.GET(callback, UNITS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[UNITS_URI] }, 'arraybuffer', refresh); + getUnits(callback: CallableFunction, refresh: boolean = false, errorCallback: CallableFunction = () => {}) { + this.GET(callback, errorCallback, UNITS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[UNITS_URI] }, 'arraybuffer', refresh); } - getWeapons(callback: CallableFunction, refresh: boolean = false) { - this.GET(callback, WEAPONS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer', refresh); + getWeapons(callback: CallableFunction, refresh: boolean = false, errorCallback: CallableFunction = () => {}) { + this.GET(callback, errorCallback, WEAPONS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer', refresh); } - isCommandExecuted(callback: CallableFunction, commandHash: string) { - this.GET(callback, COMMANDS_URI, { commandHash: commandHash }); + isCommandExecuted(callback: CallableFunction, commandHash: string, errorCallback: CallableFunction = () => {}) { + this.GET(callback, errorCallback, COMMANDS_URI, { commandHash: commandHash }); } addDestination(ID: number, path: any, callback: CallableFunction = () => { }) { diff --git a/frontend/react/src/types/types.ts b/frontend/react/src/types/types.ts index d0daebf7..638683a7 100644 --- a/frontend/react/src/types/types.ts +++ b/frontend/react/src/types/types.ts @@ -1,4 +1,3 @@ - /* Types definition */ export type MapMarkerVisibilityControl = { "category"?: string; diff --git a/frontend/react/src/ui/modals/components/modal.tsx b/frontend/react/src/ui/modals/components/modal.tsx index 2edcb5c6..b873652f 100644 --- a/frontend/react/src/ui/modals/components/modal.tsx +++ b/frontend/react/src/ui/modals/components/modal.tsx @@ -5,7 +5,7 @@ export function Modal(props: { children?: JSX.Element | JSX.Element[], className?: string }) { - return
+ return
{props.children}
} \ No newline at end of file diff --git a/frontend/react/src/ui/modals/login.tsx b/frontend/react/src/ui/modals/login.tsx index 996042dd..65c8e8c8 100644 --- a/frontend/react/src/ui/modals/login.tsx +++ b/frontend/react/src/ui/modals/login.tsx @@ -8,11 +8,15 @@ import { VERSION, connectedToServer } from '../../olympusapp' export function LoginModal(props: { checkingPassword: boolean, loginError: boolean, - onLogin: (password: string) => void + commandMode: string | null, + onLogin: (password: string) => void, + onContinue: (username: string) => void, + onBack: () => void }) { const [password, setPassword] = useState(""); + const [displayName, setDisplayName] = useState(""); - return + return
@@ -30,18 +34,37 @@ export function LoginModal(props: { { !props.loginError ? <> -
- - setPassword(ev.currentTarget.value)} className="w-full max-w-80 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter password" required /> -
-
- - -
+ { props.commandMode === null? + <> +
+ + setPassword(ev.currentTarget.value)} className="w-full max-w-80 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter password" required /> +
+
+ + +
+ + : + <> +
+ + setDisplayName(ev.currentTarget.value)} className="w-full max-w-80 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter display name" required /> +
+
+ + +
+ + } :
diff --git a/frontend/react/src/ui/ui.tsx b/frontend/react/src/ui/ui.tsx index 3ab52c0c..5901a4b9 100644 --- a/frontend/react/src/ui/ui.tsx +++ b/frontend/react/src/ui/ui.tsx @@ -28,6 +28,7 @@ export type OlympusState = { } export function UI() { + var [loginModalVisible, setLoginModalVisible] = useState(true); var [mainMenuVisible, setMainMenuVisible] = useState(false); var [spawnMenuVisible, setSpawnMenuVisible] = useState(false); var [unitControlMenuVisible, setUnitControlMenuVisible] = useState(false); @@ -60,7 +61,7 @@ export function UI() { function checkPassword(password: string) { setCheckingPassword(true); var hash = sha256.create(); - getApp().getServerManager().setCredentials("no-username", hash.update(password).hex()); + getApp().getServerManager().setPassword(hash.update(password).hex()); getApp().getServerManager().getMission((response) => { const commandMode = response.mission.commandModeOptions.commandMode; try { @@ -69,7 +70,18 @@ export function UI() { setLoginError(true); } setCheckingPassword(false); - }) + }, + () => { + setLoginError(true); + setCheckingPassword(false); + }, + ) + } + + function connect(username: string) { + getApp().getServerManager().setUsername(username); + getApp().getServerManager().startUpdate(); + setLoginModalVisible(false); } return ( @@ -103,11 +115,19 @@ export function UI() {
- { checkPassword(password) }} - checkingPassword={checkingPassword} - loginError={loginError} - /> + {loginModalVisible && + <> +
+ { checkPassword(password) }} + onContinue={(username) => { connect(username) }} + onBack={() => { setCommandMode(null) }} + checkingPassword={checkingPassword} + loginError={loginError} + commandMode={commandMode} + /> + + }