Work on reactive design

This commit is contained in:
Davide Passoni
2024-07-01 15:51:43 +02:00
parent b3f8eb96ad
commit 1acb7d6762
8 changed files with 35 additions and 31 deletions

View File

@@ -8,7 +8,7 @@
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8080",
"url": "http://localhost:3000/vite/",
"webRoot": "${workspaceFolder}",
"preLaunchTask": "npm: dev"
}

View File

@@ -8,7 +8,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<title>Olympus v2</title>
</head>
<body>

View File

@@ -16,7 +16,7 @@ export function OlStateButton(props: {
const className = (props.className ?? '') + ` h-[40px] w-[40px] flex-none font-medium rounded-md text-lg dark:bg-olympus-600 dark:hover:bg-olympus-300 dark:data-[checked='true']:bg-blue-500 dark:data-[checked='true']:text-white dark:text-gray-300 dark:border-gray-600 `;
return <><button ref={buttonRef} onClick={props.onClick} data-checked={props.checked} type="button" className={className} onMouseEnter={() => { setHover(true) }} onMouseLeave={() => { setHover(false) }}>
return <><button ref={buttonRef} onClick={() => { props.onClick(); setHover(false); }} data-checked={props.checked} type="button" className={className} onMouseEnter={() => { setHover(true) }} onMouseLeave={() => { setHover(false) }}>
<FontAwesomeIcon icon={props.icon} />
</button>
{hover && <OlTooltip buttonRef={buttonRef} content={props.tooltip} />}
@@ -35,7 +35,7 @@ export function OlRoundStateButton(props: {
const className = (props.className ?? '') + ` h-8 w-8 flex-none m-auto border-2 border-gray-900 font-medium rounded-full text-sm dark:bg-[transparent] dark:data-[checked='true']:bg-white dark:text-gray-400 dark:data-[checked='true']:text-gray-900 dark:data-[checked='true']:border-white dark:border-gray-400 dark:data-[checked='true']:hover:bg-gray-200 dark:data-[checked='true']:hover:border-gray-200 dark:hover:bg-gray-800`;
return <><button ref={buttonRef} onClick={props.onClick} data-checked={props.checked} type="button" className={className} onMouseEnter={() => { setHover(true) }} onMouseLeave={() => { setHover(false) }}>
return <><button ref={buttonRef} onClick={() => { props.onClick(); setHover(false); }} data-checked={props.checked} type="button" className={className} onMouseEnter={() => { setHover(true) }} onMouseLeave={() => { setHover(false) }}>
<FontAwesomeIcon className="pt-[3px]" icon={props.icon} />
</button>
{ hover && <OlTooltip buttonRef={buttonRef} content={props.tooltip} /> }
@@ -53,7 +53,7 @@ export function OlLockStateButton(props: {
const className = (props.className ?? '') + ` h-8 w-8 flex-none m-auto border-gray-900 font-medium rounded-full text-sm dark:bg-red-500 dark:data-[checked='true']:bg-green-500 dark:text-olympus-900 dark:data-[checked='true']:text-green-900 dark:data-[checked='true']:hover:bg-green-400 dark:hover:bg-red-400`;
return <><button ref={buttonRef} onClick={props.onClick} data-checked={props.checked} type="button" className={className} onMouseEnter={() => { setHover(true) }} onMouseLeave={() => { setHover(false) }}>
return <><button ref={buttonRef} onClick={() => { props.onClick(); setHover(false); }} data-checked={props.checked} type="button" className={className} onMouseEnter={() => { setHover(true) }} onMouseLeave={() => { setHover(false) }}>
<FontAwesomeIcon className="pt-[3px]" icon={props.checked == true ? faUnlockAlt : faLock} />
</button>
{ hover && <OlTooltip buttonRef={buttonRef} content={props.tooltip} /> }

View File

@@ -34,7 +34,7 @@ export function LoginModal(props: {
<div className="flex text-gray-800 dark:text-gray-200 text-md font-bold items-center justify-center gap-2">{window.location.toString()} </div>
</div>
<div className='flex flex-row gap-2 content-center items-center w-[100%]'>
<span className='size-[80px] min-w-14'><img src="..\public\images\olympus-500x500.png" className='flex w-full'></img></span>
<span className='size-[80px] min-w-14'><img src="..\images\olympus-500x500.png" className='flex w-full'></img></span>
<div className="flex flex-col items-start gap-1">
<h1 className="flex text-4xl text-gray-800 dark:text-white font-bold text-wrap">DCS Olympus</h1>
<div className="flex gap-2 select-none rounded-sm content-center text-green-700 dark:text-green-400 text-sm font-semibold"><FontAwesomeIcon icon={faCheckCircle} className="my-auto" />Version {VERSION}</div>

View File

@@ -1,6 +1,6 @@
import React from 'react'
import React, { useState } from 'react'
import { OlRoundStateButton, OlStateButton, OlLockStateButton } from '../components/olstatebutton';
import { faSkull, faCamera, faFlag, faLink, faUnlink } from '@fortawesome/free-solid-svg-icons';
import { faSkull, faCamera, faFlag, faLink, faUnlink, faBars } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { EventsConsumer } from '../../eventscontext';
import { StateConsumer } from '../../statecontext';
@@ -10,20 +10,23 @@ import { getApp, IP, connectedToServer } from '../../olympusapp';
import { olButtonsVisibilityAirbase, olButtonsVisibilityAircraft, olButtonsVisibilityDcs, olButtonsVisibilityGroundunit, olButtonsVisibilityGroundunitSam, olButtonsVisibilityHelicopter, olButtonsVisibilityHuman, olButtonsVisibilityNavyunit, olButtonsVisibilityOlympus } from '../components/olicons';
export function Header() {
const [collapsed, setCollapsed] = useState(true);
return <StateConsumer>
{(appState) =>
<EventsConsumer>
{(events) =>
<nav className="flex w-screen h-[66px] bg-gray-300 border-gray-200 dark:bg-olympus-900 dark:border-gray-800 px-3 z-ui-2 drop-shadow-md">
<div className="w-full max-w-full flex flex-nowrap items-center justify-between gap-3 my-auto">
<div className="flex flex-row items-center justify-center gap-6 flex-none">
<nav className={`${collapsed? 'h-[60px]': 'h-fit'} flex w-screen bg-gray-300 border-gray-200 dark:bg-olympus-900 dark:border-gray-800 px-3 z-ui-2 drop-shadow-md`}>
<div className="w-full max-w-full flex flex-wrap overflow-hidden items-center justify-end gap-3 my-2">
<div className="flex flex-row items-center justify-start gap-6 flex-none mr-auto basis-5/6 sm:basis-0">
<img src="images/icon.png" className='h-10 w-10 p-0 rounded-md'></img>
<div className="flex flex-col items-start">
<div className="pt-1 text-gray-800 dark:text-gray-400 text-xs">Connected to</div>
<div className="flex text-gray-800 dark:text-gray-200 text-sm font-extrabold items-center justify-center gap-2">{IP} <FontAwesomeIcon icon={connectedToServer ? faLink : faUnlink} data-connected={connectedToServer} className="py-auto text-green-400 data-[connected='true']:dark:text-green-400 dark:text-red-500" /></div>
</div>
</div>
<div className="ml-auto">
<OlStateButton onClick={() => setCollapsed(!collapsed) } checked={!collapsed} icon={faBars} tooltip={"Show more options"}></OlStateButton>
<div>
<OlLockStateButton checked={false} onClick={() => {}} tooltip="Lock/unlock protected units (from scripted mission)"/>
</div>
<div className="flex flex-row h-fit items-center justify-start gap-1">
@@ -42,23 +45,6 @@ export function Header() {
}
</div>
<div className='h-8 w-0 border-l-[2px] border-gray-700'></div>
<div className="flex flex-row h-fit items-center justify-start gap-1">
{
Object.entries({
'aircraft': olButtonsVisibilityAircraft,'helicopter': olButtonsVisibilityHelicopter, 'groundunit-sam': olButtonsVisibilityGroundunitSam,
'groundunit': olButtonsVisibilityGroundunit, 'navyunit': olButtonsVisibilityNavyunit, 'airbase': olButtonsVisibilityAirbase, 'dead': faSkull
}).map((entry) => {
return <OlRoundStateButton
onClick={() => {
getApp().getMap().setHiddenType(entry[0], !appState.mapHiddenTypes[entry[0]]);
}}
checked={!appState.mapHiddenTypes[entry[0]]}
icon={entry[1]}
tooltip={"Hide/show " + entry[0] + " units" } />
})
}
</div>
<div className='h-8 w-0 border-l-[2px] border-gray-700'></div>
<div className="flex flex-row h-fit items-center justify-start gap-1">
<OlRoundStateButton
onClick={() => getApp().getMap().setHiddenType( 'blue', !appState.mapHiddenTypes['blue'] )}
@@ -76,6 +62,24 @@ export function Header() {
icon={faFlag} className={"!text-gray-500"}
tooltip={"Hide/show neutral units" } />
</div>
<div className='h-8 w-0 border-l-[2px] border-gray-700'></div>
<div className="flex flex-row h-fit items-center justify-start gap-1">
{
Object.entries({
'aircraft': olButtonsVisibilityAircraft,'helicopter': olButtonsVisibilityHelicopter, 'groundunit-sam': olButtonsVisibilityGroundunitSam,
'groundunit': olButtonsVisibilityGroundunit, 'navyunit': olButtonsVisibilityNavyunit, 'airbase': olButtonsVisibilityAirbase, 'dead': faSkull
}).map((entry) => {
return <OlRoundStateButton
onClick={() => {
getApp().getMap().setHiddenType(entry[0], !appState.mapHiddenTypes[entry[0]]);
}}
checked={!appState.mapHiddenTypes[entry[0]]}
icon={entry[1]}
tooltip={"Hide/show " + entry[0] + " units" } />
})
}
</div>
<OlLabelToggle toggled={false} leftLabel={"Live"} rightLabel={"Map"} onClick={() => {}}></OlLabelToggle>
<OlStateButton checked={false} icon={faCamera} onClick={() => {}} tooltip="Activate/deactivate camera plugin" />
<OlDropdown label={appState.activeMapSource} className="w-80">

View File

@@ -4,5 +4,5 @@ import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
base: "/vite"
base: "/vite",
})

View File

@@ -37,6 +37,7 @@ module.exports = function (configLocation) {
/* Define middleware */
app.use(logger('dev'));
app.use('/olympus', createProxyMiddleware({ target: `http://${backendAddress === '*'? 'localhost': backendAddress}:${config["backend"]["port"]}`, changeOrigin: true }));
app.use('/vite', createProxyMiddleware({ target: `http://localhost:8080/`, ws: true }));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
app.use(express.static(path.join(__dirname, 'public')));

View File

@@ -501,7 +501,6 @@ module.exports = function (configLocation) {
if (auth) {
var username = Buffer.from(auth.replace("Basic ", ""), 'base64').toString('binary').split(":")[0];
var password = Buffer.from(auth.replace("Basic ", ""), 'base64').toString('binary').split(":")[1];
console.log(password)
switch (password) {
case "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918":
ret.mission.commandModeOptions.commandMode = "Game master";