mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
fix: Small fixes to responsive design
This commit is contained in:
@@ -73,7 +73,7 @@ export function AirbaseMenu(props: { open: boolean; onClose: () => void; childre
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu title={airbase?.getName() ?? "No airbase selected"} open={props.open} onClose={props.onClose} showBackButton={false} canBeHidden={true}>
|
||||
<Menu title={airbase?.getName() ?? "No airbase selected"} open={props.open} onClose={props.onClose} showBackButton={false}>
|
||||
<div
|
||||
className={`
|
||||
flex flex-col gap-2 font-normal text-gray-800
|
||||
|
||||
@@ -32,7 +32,7 @@ export function AWACSMenu(props: { open: boolean; onClose: () => void; children?
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Menu title={"AWACS Tools"} open={props.open} onClose={props.onClose} showBackButton={false} canBeHidden={true}>
|
||||
<Menu title={"AWACS Tools"} open={props.open} onClose={props.onClose} showBackButton={false}>
|
||||
<div
|
||||
className={`
|
||||
flex flex-col gap-4 p-4 font-normal text-gray-800
|
||||
|
||||
@@ -1,46 +1,62 @@
|
||||
import { faArrowLeft, faCircleQuestion, faClose } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faArrowLeft, faCircleQuestion, faClose, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { FaChevronDown, FaChevronUp } from "react-icons/fa";
|
||||
import { FaChevronRight } from "react-icons/fa6";
|
||||
|
||||
export function Menu(props: {
|
||||
title: string;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
canBeHidden?: boolean;
|
||||
onBack?: () => void;
|
||||
showBackButton?: boolean;
|
||||
children?: JSX.Element | JSX.Element[];
|
||||
wiki?: () => (JSX.Element | JSX.Element[]);
|
||||
wiki?: () => JSX.Element | JSX.Element[];
|
||||
}) {
|
||||
const [hide, setHide] = useState(true);
|
||||
const [wiki, setWiki] = useState(false);
|
||||
|
||||
if (!props.open && hide) setHide(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.innerWidth > 640) setHide(false);
|
||||
}, [props.open]);
|
||||
|
||||
return (
|
||||
<div
|
||||
data-open={props.open}
|
||||
data-wiki={wiki}
|
||||
className={`
|
||||
pointer-events-none absolute left-16 right-0 top-[58px] z-10
|
||||
h-[calc(100vh-58px)] bg-transparent transition-all ol-panel-container
|
||||
pointer-events-none absolute left-16 right-0 top-[58px] z-10 flex
|
||||
h-[calc(100vh-58px)] transition-all ol-panel-container
|
||||
data-[open='false']:-translate-x-full
|
||||
data-[wiki='true']:w-[calc(100%-58px)] data-[wiki='true']:lg:w-[800px]
|
||||
sm:w-[400px]
|
||||
`}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{props.open && (
|
||||
<div className="absolute flex h-full w-[30px]">
|
||||
<div
|
||||
className={`
|
||||
pointer-events-auto my-auto flex h-[80px] w-full cursor-pointer
|
||||
justify-center rounded-r-lg bg-olympus-800/90 backdrop-blur-lg
|
||||
backdrop-grayscale
|
||||
hover:bg-olympus-400/90
|
||||
`}
|
||||
onClick={() => setHide(!hide)}
|
||||
>
|
||||
<FaChevronRight className={`my-auto text-gray-400`} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
data-hide={hide}
|
||||
data-canbehidden={props.canBeHidden}
|
||||
className={`
|
||||
pointer-events-auto h-[calc(100vh-58px)] overflow-y-auto
|
||||
pointer-events-auto h-[calc(100vh-58px)] w-full overflow-y-auto
|
||||
overflow-x-hidden backdrop-blur-lg backdrop-grayscale
|
||||
transition-transform no-scrollbar
|
||||
dark:bg-olympus-800/90
|
||||
data-[canbehidden='true']:h-[calc(100vh-58px-2rem)]
|
||||
data-[hide='true']:translate-y-[calc(100vh-58px)]
|
||||
data-[hide='true']:-translate-x-full
|
||||
`}
|
||||
>
|
||||
<h5
|
||||
@@ -71,6 +87,16 @@ export function Menu(props: {
|
||||
hover:bg-gray-200
|
||||
`}
|
||||
/>
|
||||
<FontAwesomeIcon
|
||||
onClick={() => setHide(true)}
|
||||
icon={faEyeSlash}
|
||||
className={`
|
||||
flex cursor-pointer items-center justify-center rounded-md p-2
|
||||
text-lg
|
||||
dark:text-gray-500 dark:hover:bg-gray-700 dark:hover:text-white
|
||||
hover:bg-gray-200
|
||||
`}
|
||||
/>
|
||||
<FontAwesomeIcon
|
||||
onClick={props.onClose}
|
||||
icon={faClose}
|
||||
@@ -82,37 +108,27 @@ export function Menu(props: {
|
||||
`}
|
||||
/>
|
||||
</h5>
|
||||
<div className="flex h-[calc(100%-3rem)]">
|
||||
<div data-wiki={wiki} className={`
|
||||
w-0 overflow-hidden transition-all
|
||||
data-[wiki='true']:w-[50%]
|
||||
`}>
|
||||
{props.wiki ? props.wiki() : <div className={`p-4 text-gray-200`}>Work in progress</div>}
|
||||
</div>
|
||||
<div data-wiki={wiki} className={`
|
||||
w-full
|
||||
sm:w-[400px]
|
||||
`}>{props.children}</div>
|
||||
<div className="flex h-[calc(100%-3rem)] w-full">
|
||||
<div
|
||||
data-wiki={wiki}
|
||||
className={`
|
||||
w-0 overflow-hidden transition-all
|
||||
data-[wiki='true']:w-[50%]
|
||||
`}
|
||||
>
|
||||
{props.wiki ? props.wiki() : <div className={`p-4 text-gray-200`}>Work in progress</div>}
|
||||
</div>
|
||||
<div
|
||||
data-wiki={wiki}
|
||||
className={`
|
||||
min-w-full
|
||||
sm:w-[400px]
|
||||
`}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{props.canBeHidden == true && (
|
||||
<div
|
||||
className={`
|
||||
pointer-events-auto flex h-8 cursor-pointer justify-center
|
||||
bg-olympus-800/90 backdrop-blur-lg backdrop-grayscale
|
||||
hover:bg-olympus-400/90
|
||||
`}
|
||||
onClick={() => setHide(!hide)}
|
||||
>
|
||||
{hide ? (
|
||||
<FaChevronUp className="mx-auto my-auto text-gray-400" />
|
||||
) : (
|
||||
<FaChevronDown
|
||||
className={`mx-auto my-auto text-gray-400`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { DrawSubState, MAP_OPTIONS_DEFAULTS, NO_SUBSTATE, OlympusState, OlympusS
|
||||
import { AppStateChangedEvent, ContextActionSetChangedEvent, MapOptionsChangedEvent, ShortcutsChangedEvent } from "../../events";
|
||||
import { ContextActionSet } from "../../unit/contextactionset";
|
||||
import { MapToolBar } from "./maptoolbar";
|
||||
import { CoordinatesPanel } from "./coordinatespanel";
|
||||
|
||||
export function ControlsPanel(props: {}) {
|
||||
const [controls, setControls] = useState(
|
||||
@@ -200,12 +201,12 @@ export function ControlsPanel(props: {}) {
|
||||
className={`
|
||||
absolute right-[0px] top-16
|
||||
${mapOptions.showMinimap ? `bottom-[233px]` : `bottom-[65px]`}
|
||||
pointer-events-none flex w-[310px] flex-col items-center justify-between
|
||||
pointer-events-none flex w-[288px] flex-col items-center justify-between
|
||||
gap-1 p-3 text-sm
|
||||
`}
|
||||
>
|
||||
<MapToolBar />
|
||||
{controls?.map((control) => {
|
||||
{/*controls?.map((control) => {
|
||||
return (
|
||||
<div
|
||||
key={control.text}
|
||||
@@ -246,7 +247,7 @@ export function ControlsPanel(props: {}) {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
})*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ export function CoordinatesPanel(props: {}) {
|
||||
const [elevation, setElevation] = useState(0);
|
||||
const [bullseyes, setBullseyes] = useState(null as null | { [name: string]: Bullseye });
|
||||
const [selectedUnits, setSelectedUnits] = useState([] as Unit[]);
|
||||
const [open, setOpen] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
MouseMovedEvent.on((latlng, elevation) => {
|
||||
@@ -27,18 +28,30 @@ export function CoordinatesPanel(props: {}) {
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
absolute bottom-[20px] right-[310px] flex min-h-12 w-[380px] flex-col
|
||||
items-center justify-between gap-2 rounded-lg bg-gray-200 px-3 py-3
|
||||
text-sm backdrop-blur-lg backdrop-grayscale
|
||||
flex w-full flex-col items-center justify-between gap-2 rounded-lg
|
||||
bg-gray-200 px-3 py-3 text-sm backdrop-blur-lg backdrop-grayscale
|
||||
dark:bg-olympus-800/90 dark:text-gray-200
|
||||
`}
|
||||
onClick={() => setOpen(!open)}
|
||||
>
|
||||
{bullseyes && (
|
||||
<div className="flex w-full items-center justify-start">
|
||||
<div className="absolute right-[12px] top-[15px]">
|
||||
{open ? (
|
||||
<FaChevronDown className="cursor-pointer" />
|
||||
) : (
|
||||
<FaChevronUp
|
||||
className={`cursor-pointer`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{open && bullseyes && (
|
||||
<div
|
||||
className={`
|
||||
flex w-full flex-col items-start justify-start gap-2
|
||||
`}
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
mr-[11px] flex min-w-64 max-w-64 items-center justify-between
|
||||
gap-2
|
||||
flex flex min-w-64 max-w-64 items-start justify-between gap-2
|
||||
`}
|
||||
>
|
||||
{bullseyes[2] && (
|
||||
@@ -84,18 +97,27 @@ export function CoordinatesPanel(props: {}) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div
|
||||
className={`
|
||||
flex w-full items-center justify-between pointer-events-all
|
||||
`}
|
||||
>
|
||||
<OlLocation className="!min-w-64 !max-w-64 bg-transparent !p-0" location={latlng} />
|
||||
<span
|
||||
className={`
|
||||
mr-2 rounded-sm bg-white px-1 py-1 text-center font-bold
|
||||
text-olympus-700
|
||||
`}
|
||||
>
|
||||
<FaMountain />
|
||||
</span>
|
||||
<div className="min-w-12">{mToFt(elevation).toFixed()}ft</div>
|
||||
</div>
|
||||
|
||||
{open && (
|
||||
<div className="flex w-full items-center justify-start">
|
||||
<span
|
||||
className={`
|
||||
mr-2 rounded-sm bg-white px-1 py-1 text-center font-bold
|
||||
text-olympus-700
|
||||
`}
|
||||
>
|
||||
<FaMountain />
|
||||
</span>
|
||||
<div className="min-w-12">{mToFt(elevation).toFixed()}ft</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
||||
open={props.open}
|
||||
title="Draw"
|
||||
onClose={props.onClose}
|
||||
canBeHidden={true}
|
||||
showBackButton={appSubState !== DrawSubState.NO_SUBSTATE}
|
||||
onBack={() => {
|
||||
getApp().getCoalitionAreasManager().setSelectedArea(null);
|
||||
|
||||
@@ -102,7 +102,8 @@ export function Header() {
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
z-10 flex w-full gap-4 border-gray-200 bg-gray-300 px-3 align-center
|
||||
relative z-10 flex w-full gap-4 border-gray-200 bg-gray-300 px-3
|
||||
align-center
|
||||
dark:border-gray-800 dark:bg-olympus-900
|
||||
`}
|
||||
>
|
||||
@@ -147,6 +148,7 @@ export function Header() {
|
||||
{IP}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-8">
|
||||
{savingSessionData ? (
|
||||
<div className="text-white">
|
||||
<FaSpinner className={`animate-spin text-2xl`} />
|
||||
@@ -162,6 +164,7 @@ export function Header() {
|
||||
<FaCheck className={`absolute left-3 top-0 text-green-500`} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{commandModeOptions.commandMode === BLUE_COMMANDER && (
|
||||
|
||||
@@ -60,7 +60,7 @@ export function JTACMenu(props: { open: boolean; onClose: () => void; children?:
|
||||
let targetPosition = (targetUnit ? targetUnit.getPosition() : targetLocation) ?? new LatLng(0, 0);
|
||||
|
||||
return (
|
||||
<Menu title={"JTAC Tools"} open={props.open} onClose={props.onClose} showBackButton={false} canBeHidden={true}>
|
||||
<Menu title={"JTAC Tools"} open={props.open} onClose={props.onClose} showBackButton={false}>
|
||||
<div
|
||||
className={`
|
||||
flex flex-col gap-2 p-4 font-normal text-gray-800
|
||||
|
||||
@@ -5,6 +5,8 @@ import { getApp } from "../../olympusapp";
|
||||
import { FaChevronDown, FaChevronUp } from "react-icons/fa6";
|
||||
import { MapOptionsChangedEvent, ServerStatusUpdatedEvent } from "../../events";
|
||||
import { colors, MAP_OPTIONS_DEFAULTS } from "../../constants/constants";
|
||||
import { CoordinatesPanel } from "./coordinatespanel";
|
||||
import { RadiosSummaryPanel } from "./radiossummarypanel";
|
||||
|
||||
export function MiniMapPanel(props: {}) {
|
||||
const [serverStatus, setServerStatus] = useState({} as ServerStatus);
|
||||
@@ -54,47 +56,65 @@ export function MiniMapPanel(props: {}) {
|
||||
className={`
|
||||
absolute right-[10px]
|
||||
${mapOptions.showMinimap ? `bottom-[188px]` : `bottom-[20px]`}
|
||||
flex w-[288px] items-center justify-between
|
||||
${mapOptions.showMinimap ? `rounded-t-lg` : `rounded-lg`}
|
||||
h-12 bg-gray-200 px-3 text-sm backdrop-blur-lg backdrop-grayscale
|
||||
dark:bg-olympus-800/90 dark:text-gray-200
|
||||
flex w-[288px] cursor-pointer flex-col items-center justify-between
|
||||
gap-2 text-sm backdrop-blur-lg
|
||||
`}
|
||||
|
||||
>
|
||||
{!serverStatus.connected ? (
|
||||
<div className={`flex animate-pulse items-center gap-2 font-semibold`}>
|
||||
<div className={`relative h-4 w-4 rounded-full bg-[#F05252]`}></div>
|
||||
Server disconnected
|
||||
</div>
|
||||
) : serverStatus.paused ? (
|
||||
<div className={`flex animate-pulse items-center gap-2 font-semibold`}>
|
||||
<div className={`relative h-4 w-4 rounded-full bg-[#FF9900]`}></div>
|
||||
Server paused
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex gap-2 font-semibold">
|
||||
FPS:
|
||||
<span style={{ color: frameRateColor }} className={`font-semibold`}>
|
||||
{serverStatus.frameRate}
|
||||
</span>
|
||||
<RadiosSummaryPanel />
|
||||
<CoordinatesPanel />
|
||||
<div className={`
|
||||
flex h-12 w-full items-center justify-between gap-2 px-3
|
||||
backdrop-grayscale
|
||||
dark:bg-olympus-800/90 dark:text-gray-200
|
||||
${mapOptions.showMinimap ? `rounded-t-lg` : `rounded-lg`}
|
||||
`}
|
||||
onClick={(ev) => {
|
||||
getApp().getMap().setOption("showMinimap", !mapOptions.showMinimap);
|
||||
}}>
|
||||
{!serverStatus.connected ? (
|
||||
<div className={`flex animate-pulse items-center gap-2 font-semibold`}>
|
||||
<div className={`relative h-4 w-4 rounded-full bg-[#F05252]`}></div>
|
||||
Server disconnected
|
||||
</div>
|
||||
<div className="flex gap-2 font-semibold">
|
||||
Load:
|
||||
<span style={{ color: loadColor }} className={`font-semibold`}>
|
||||
{serverStatus.load}
|
||||
</span>
|
||||
) : serverStatus.paused ? (
|
||||
<div className={`flex animate-pulse items-center gap-2 font-semibold`}>
|
||||
<div className={`relative h-4 w-4 rounded-full bg-[#FF9900]`}></div>
|
||||
Server paused
|
||||
</div>
|
||||
<div className="flex cursor-pointer gap-2 font-semibold" onClick={() => setShowMissionTime(!showMissionTime)}>
|
||||
{showMissionTime ? "MT" : "ET"}: {timeString}
|
||||
</div>
|
||||
<div className={`relative h-4 w-4 rounded-full bg-[#8BFF63]`}></div>
|
||||
</>
|
||||
)}
|
||||
{mapOptions.showMinimap ? (
|
||||
<FaChevronDown className="cursor-pointer" onClick={() => getApp().getMap().setOption("showMinimap", false)} />
|
||||
) : (
|
||||
<FaChevronUp className="cursor-pointer" onClick={() => getApp().getMap().setOption("showMinimap", true)} />
|
||||
)}
|
||||
) : (
|
||||
<>
|
||||
<div className="flex w-16 gap-1 font-semibold">
|
||||
FPS:
|
||||
<span style={{ color: frameRateColor }} className={`font-semibold`}>
|
||||
{serverStatus.frameRate}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex gap-1 font-semibold">
|
||||
Load:
|
||||
<span style={{ color: loadColor }} className={`font-semibold`}>
|
||||
{serverStatus.load}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="ml-auto flex w-24 cursor-pointer gap-2 font-semibold"
|
||||
onClick={(ev) => {
|
||||
setShowMissionTime(!showMissionTime);
|
||||
ev.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{showMissionTime ? "MT" : "ET"}: {timeString}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{mapOptions.showMinimap ? (
|
||||
<FaChevronDown className="cursor-pointer" />
|
||||
) : (
|
||||
<FaChevronUp
|
||||
className={`cursor-pointer`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,12 +19,10 @@ export function RadiosSummaryPanel(props: {}) {
|
||||
{audioSinks.length > 0 && (
|
||||
<div
|
||||
className={`
|
||||
absolute bottom-[20px] right-[700px] flex w-fit flex-col
|
||||
items-center justify-between gap-2 rounded-lg bg-transparent text-sm
|
||||
text-gray-200
|
||||
flex w-full gap-2 rounded-lg text-sm text-gray-200
|
||||
`}
|
||||
>
|
||||
<div className="flex w-full items-center justify-between gap-2">
|
||||
<div className="flex w-full flex-wrap gap-2">
|
||||
|
||||
{audioSinks.filter((audioSinks) => audioSinks instanceof RadioSink).length > 0 &&
|
||||
audioSinks
|
||||
|
||||
@@ -113,7 +113,6 @@ export function SpawnMenu(props: { open: boolean; onClose: () => void; children?
|
||||
{...props}
|
||||
title="Spawn menu"
|
||||
showBackButton={blueprint !== null || effect !== null}
|
||||
canBeHidden={true}
|
||||
onBack={() => {
|
||||
getApp().setState(OlympusState.SPAWN);
|
||||
setBlueprint(null);
|
||||
|
||||
@@ -295,7 +295,6 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
||||
open={props.open}
|
||||
title={selectedUnits.length > 0 ? `Units selected (x${selectedUnits.length})` : `No units selected`}
|
||||
onClose={props.onClose}
|
||||
canBeHidden={true}
|
||||
wiki={() => {
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user