mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Multiple updates
- Added bottom buttons to sidebar - Fixed up various UI issues - Added options panel that now works
This commit is contained in:
@@ -9,13 +9,13 @@ export function OlNumberInput(props: {
|
||||
onChange: (e: ChangeEvent<HTMLInputElement>) => void
|
||||
}) {
|
||||
return <div className="w-fit">
|
||||
<div className="relative flex items-center max-w-[7rem]">
|
||||
<div className="relative flex items-center max-w-[8rem]">
|
||||
<button type="button" onClick={props.onDecrease} className="bg-gray-100 dark:bg-gray-700 dark:hover:bg-gray-600 hover:bg-gray-200 rounded-s-lg p-3 h-10 focus:ring-gray-100 dark:focus:ring-blue-700 focus:ring-2 focus:outline-none">
|
||||
<svg className="w-3 h-3 text-gray-900 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 2">
|
||||
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M1 1h16"/>
|
||||
</svg>
|
||||
</button>
|
||||
<input type="text" onChange={props.onChange} min={props.min} max={props.max} className="bg-gray-50 h-10 text-center text-gray-900 text-sm focus:ring-blue-500 focus:border-blue-700 block w-full py-2.5 border-[2px] dark:border-gray-700 dark:bg-olympus-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-700 dark:focus:border-blue-700" value={"x" + props.value} />
|
||||
<input type="text" onChange={props.onChange} min={props.min} max={props.max} className="bg-gray-50 h-10 text-center text-gray-900 text-sm focus:ring-blue-500 focus:border-blue-700 block w-full py-2.5 border-[2px] dark:border-gray-700 dark:bg-olympus-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-700 dark:focus:border-blue-700" value={props.value} />
|
||||
<button type="button" onClick={props.onIncrease} className="bg-gray-100 dark:bg-gray-700 dark:hover:bg-gray-600 hover:bg-gray-200 rounded-e-lg p-3 h-10 focus:ring-gray-100 dark:focus:ring-blue-500 focus:ring-2 focus:outline-none">
|
||||
<svg className="w-3 h-3 text-gray-900 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 18">
|
||||
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 1v16M1 9h16"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
||||
import { faLock, faLockOpen, faUnlock, faUnlockAlt } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faExternalLink, faLock, faLockOpen, faUnlock, faUnlockAlt } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import React from "react"
|
||||
|
||||
@@ -9,7 +9,7 @@ export function OlStateButton(props: {
|
||||
icon: IconProp,
|
||||
onClick: () => void
|
||||
}) {
|
||||
const className = (props.className ?? '') + ` h-[40px] w-[40px] flex-none font-medium rounded-md text-md dark:bg-gray-700 dark:hover:bg-gray-600 dark:data-[checked='true']:bg-blue-500 dark:text-white dark:border-gray-600 `;
|
||||
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 onClick={props.onClick} data-checked={props.checked} type="button" className={className}>
|
||||
<FontAwesomeIcon icon={props.icon} />
|
||||
|
||||
@@ -19,8 +19,8 @@ export function Header() {
|
||||
<div className="flex flex-row items-center justify-center gap-6 flex-none">
|
||||
<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-200 font-light text-xs">Connected to</div>
|
||||
<div className="flex text-gray-800 dark:text-gray-200 font-bold 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 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">
|
||||
|
||||
@@ -17,7 +17,7 @@ export function MainMenu(props: {
|
||||
onClose={props.onClose}
|
||||
>
|
||||
<div className="flex flex-col p-5 gap-1 font-normal text-gray-900 dark:text-white">
|
||||
<div className="p-2 mb-1">
|
||||
<div className="mb-1">
|
||||
<div className="flex gap-2 mb-2 select-none rounded-sm content-center text-green-700 dark:text-green-400 font-bold text-lg"><FontAwesomeIcon icon={faCheckCircle} className="my-auto" />Olympus Version {VERSION}</div>
|
||||
<div className="text-gray-400 text-sm">You can use the Olympus Manager to update port, passwords or other settings.</div>
|
||||
</div>
|
||||
|
||||
77
frontend/react/src/ui/panels/options.tsx
Normal file
77
frontend/react/src/ui/panels/options.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
import React from "react";
|
||||
import { Menu } from "./components/menu";
|
||||
import { faArrowRightLong, faCheckCircle, faDatabase, faExternalLink, faExternalLinkAlt, faFile, faFileAlt, faFileExport, faFileImport, faTimesCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faGithub } from "@fortawesome/free-brands-svg-icons";
|
||||
import { OlCheckbox } from "../components/olcheckbox";
|
||||
import { OlLabelToggle } from "../components/ollabeltoggle";
|
||||
import { OlRangeSlider } from "../components/olrangeslider";
|
||||
import { OlNumberInput } from "../components/olnumberinput";
|
||||
|
||||
export function Options(props: {
|
||||
open: boolean,
|
||||
onClose: () => void,
|
||||
children?: JSX.Element | JSX.Element[],
|
||||
}) {
|
||||
return <Menu
|
||||
title="User preferences"
|
||||
open={props.open}
|
||||
showBackButton={false}
|
||||
onClose={props.onClose}
|
||||
>
|
||||
<div className="flex flex-col p-5 gap-2 font-normal text-gray-900 text-gray-800 dark:text-white ">
|
||||
<div className="group flex flex-row rounded-md justify-content gap-4 p-2 dark:hover:bg-olympus-400 cursor-pointer">
|
||||
<OlCheckbox checked={true} onChange={() => { }}></OlCheckbox>
|
||||
<span>Toggle Unit Labels</span>
|
||||
</div>
|
||||
<div className="group flex flex-row rounded-md justify-content gap-4 p-2 dark:hover:bg-olympus-400 cursor-pointer">
|
||||
<OlCheckbox checked={true} onChange={() => { }}></OlCheckbox>
|
||||
<span>Toggle Threat Rings</span>
|
||||
</div>
|
||||
<div className="group flex flex-row rounded-md justify-content gap-4 p-2 dark:hover:bg-olympus-400 cursor-pointer">
|
||||
<OlCheckbox checked={true} onChange={() => { }}></OlCheckbox>
|
||||
<span>Toggle Detection rings</span>
|
||||
</div>
|
||||
<div className="group flex flex-row rounded-md justify-content gap-4 p-2 dark:hover:bg-olympus-400 cursor-pointer">
|
||||
<OlCheckbox checked={true} onChange={() => { }}></OlCheckbox>
|
||||
<span>Toggle Detection lines</span>
|
||||
</div>
|
||||
<div className="group flex flex-row rounded-md justify-content gap-4 p-2 dark:hover:bg-olympus-400 cursor-pointer">
|
||||
<OlCheckbox checked={true} onChange={() => { }}></OlCheckbox>
|
||||
<span>Toggle Radar lines</span>
|
||||
</div>
|
||||
<div className="group flex flex-row rounded-md justify-content gap-4 p-2 dark:hover:bg-olympus-400 cursor-pointer">
|
||||
<OlCheckbox checked={true} onChange={() => { }}></OlCheckbox>
|
||||
<span>Toggle Something Else</span>
|
||||
</div>
|
||||
<hr className="w-auto m-2 my-1 bg-gray-700 border-[1px] dark:border-olympus-500"></hr>
|
||||
<div className="flex flex-col content-center items-start justify-between p-2 gap-2">
|
||||
<div className="flex flex-col">
|
||||
<span className="font-normal dark:text-white">DCS Camera Zoom Scaling</span>
|
||||
<span className="dark:text-blue-500 font-bold"> x5
|
||||
</span>
|
||||
</div>
|
||||
<OlRangeSlider
|
||||
onChange={() => { }}
|
||||
value={5}
|
||||
min={1}
|
||||
max={10}
|
||||
step={2}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col content-center items-start justify-between p-2 gap-2">
|
||||
<span className="font-normal dark:text-white">DCS Camera Port</span>
|
||||
<div className="flex">
|
||||
<OlNumberInput
|
||||
value={3004}
|
||||
min={0}
|
||||
max={9999}
|
||||
onDecrease={() => { }}
|
||||
onIncrease={() => { }}
|
||||
onChange={(ev) => { }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu>
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { OlStateButton } from '../components/olstatebutton';
|
||||
import { faPlus, faGamepad, faRuler, faPencil, faEllipsisV, faCog } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faPlus, faGamepad, faRuler, faPencil, faEllipsisV, faCog, faQuestionCircle, faPlusSquare } from '@fortawesome/free-solid-svg-icons';
|
||||
import { EventsConsumer } from '../../eventscontext';
|
||||
import { StateConsumer } from '../../statecontext';
|
||||
|
||||
@@ -9,14 +9,19 @@ export function SideBar() {
|
||||
{(appState) =>
|
||||
<EventsConsumer>
|
||||
{(events) =>
|
||||
<nav className="z-ui-1 h-full bg-gray-300 dark:bg-olympus-900">
|
||||
<div className="flex flex-wrap items-center justify-center p-4 w-16">
|
||||
<nav className="flex flex-col z-ui-1 h-full bg-gray-300 dark:bg-olympus-900">
|
||||
<div className="flex-1 flex-wrap items-center justify-center p-4 w-16">
|
||||
<div className="flex flex-col items-center justify-center gap-2.5">
|
||||
<OlStateButton onClick={events.toggleMainMenuVisible} checked={appState.mainMenuVisible} icon={faEllipsisV}></OlStateButton>
|
||||
<OlStateButton onClick={events.toggleSpawnMenuVisible} checked={appState.spawnMenuVisible} icon={faPlus}></OlStateButton>
|
||||
<OlStateButton onClick={events.toggleUnitControlMenuVisible} checked={appState.unitControlMenuVisible} icon={faGamepad}></OlStateButton>
|
||||
<OlStateButton onClick={events.toggleSpawnMenuVisible} checked={appState.spawnMenuVisible} icon={faPlusSquare}></OlStateButton>
|
||||
<OlStateButton onClick={events.toggleUnitControlMenuVisible} checked={appState.unitControlMenuVisible} icon={faGamepad}></OlStateButton>
|
||||
<OlStateButton onClick={events.toggleMeasureMenuVisible} checked={appState.measureMenuVisible} icon={faRuler}></OlStateButton>
|
||||
<OlStateButton onClick={events.toggleDrawingMenuVisible} checked={appState.drawingMenuVisible} icon={faPencil}></OlStateButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap content-end justify-center p-4 w-16">
|
||||
<div className="flex flex-col items-center justify-center gap-2.5">
|
||||
<OlStateButton onClick={() => window.open("https://github.com/Pax1601/DCSOlympus/wiki")} checked={false} icon={faQuestionCircle}></OlStateButton>
|
||||
<OlStateButton onClick={events.toggleOptionsMenuVisible} checked={appState.optionsMenuVisible} icon={faCog}></OlStateButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { SpawnMenu } from './panels/spawnmenu'
|
||||
import { UnitControlMenu } from './panels/unitcontrolmenu'
|
||||
import { MainMenu } from './panels/mainmenu'
|
||||
import { SideBar } from './panels/sidebar';
|
||||
import { Options } from './panels/options';
|
||||
import { MapHiddenTypes, MapOptions } from '../types/types'
|
||||
import { MAP_HIDDEN_TYPES_DEFAULTS, MAP_OPTIONS_DEFAULTS } from '../constants/constants'
|
||||
import { getApp, setupApp } from '../olympusapp'
|
||||
@@ -19,6 +20,7 @@ export type OlympusState = {
|
||||
unitControlMenuVisible: boolean,
|
||||
measureMenuVisible: boolean,
|
||||
drawingMenuVisible: boolean,
|
||||
optionsMenuVisible: boolean,
|
||||
mapHiddenTypes: MapHiddenTypes;
|
||||
mapOptions: MapOptions;
|
||||
}
|
||||
@@ -29,6 +31,7 @@ export function UI() {
|
||||
var [unitControlMenuVisible, setUnitControlMenuVisible] = useState(false);
|
||||
var [measureMenuVisible, setMeasureMenuVisible] = useState(false);
|
||||
var [drawingMenuVisible, setDrawingMenuVisible] = useState(false);
|
||||
var [optionsMenuVisible, setOptionsMenuVisible] = useState(false);
|
||||
var [mapHiddenTypes, setMapHiddenTypes] = useState(MAP_HIDDEN_TYPES_DEFAULTS);
|
||||
var [mapOptions, setMapOptions] = useState(MAP_OPTIONS_DEFAULTS);
|
||||
|
||||
@@ -46,6 +49,7 @@ export function UI() {
|
||||
setUnitControlMenuVisible(false);
|
||||
setMeasureMenuVisible(false);
|
||||
setDrawingMenuVisible(false);
|
||||
setOptionsMenuVisible(false);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -56,6 +60,7 @@ export function UI() {
|
||||
unitControlMenuVisible: unitControlMenuVisible,
|
||||
measureMenuVisible: measureMenuVisible,
|
||||
drawingMenuVisible: drawingMenuVisible,
|
||||
optionsMenuVisible: optionsMenuVisible,
|
||||
mapOptions: mapOptions,
|
||||
mapHiddenTypes: mapHiddenTypes
|
||||
}}>
|
||||
@@ -66,11 +71,13 @@ export function UI() {
|
||||
setUnitControlMenuVisible: setUnitControlMenuVisible,
|
||||
setDrawingMenuVisible: setDrawingMenuVisible,
|
||||
setMeasureMenuVisible: setMeasureMenuVisible,
|
||||
setOptionsMenuVisible: setOptionsMenuVisible,
|
||||
toggleMainMenuVisible: () => { hideAllMenus(); setMainMenuVisible(!mainMenuVisible) },
|
||||
toggleSpawnMenuVisible: () => { hideAllMenus(); setSpawnMenuVisible(!spawnMenuVisible) },
|
||||
toggleUnitControlMenuVisible: () => { hideAllMenus(); setUnitControlMenuVisible(!unitControlMenuVisible) },
|
||||
toggleMeasureMenuVisible: () => { hideAllMenus(); setMeasureMenuVisible(!measureMenuVisible) },
|
||||
toggleDrawingMenuVisible: () => { hideAllMenus(); setDrawingMenuVisible(!drawingMenuVisible) },
|
||||
toggleOptionsMenuVisible: () => { hideAllMenus(); setOptionsMenuVisible(!optionsMenuVisible) },
|
||||
}
|
||||
}>
|
||||
<div className='absolute top-0 left-0 h-full w-full flex flex-col'>
|
||||
@@ -79,6 +86,7 @@ export function UI() {
|
||||
<SideBar />
|
||||
<MainMenu open={mainMenuVisible} onClose={() => setMainMenuVisible(false)} />
|
||||
<SpawnMenu open={spawnMenuVisible} onClose={() => setSpawnMenuVisible(false)} />
|
||||
<Options open={optionsMenuVisible} onClose={() => setOptionsMenuVisible(false)} />
|
||||
<UnitControlMenu />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user