mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
155 lines
5.8 KiB
TypeScript
155 lines
5.8 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
import { Modal } from "./components/modal";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import { faArrowRight } from "@fortawesome/free-solid-svg-icons";
|
|
import { getApp } from "../../olympusapp";
|
|
import { OlympusState } from "../../constants/constants";
|
|
import { Shortcut } from "../../shortcut/shortcut";
|
|
import { BindShortcutRequestEvent, ShortcutsChangedEvent } from "../../events";
|
|
|
|
export function KeybindModal(props: { open: boolean }) {
|
|
const [shortcuts, setShortcuts] = useState({} as { [key: string]: Shortcut });
|
|
const [shortcut, setShortcut] = useState(null as null | Shortcut);
|
|
const [code, setCode] = useState(null as null | string);
|
|
const [shiftKey, setShiftKey] = useState(false as boolean | undefined);
|
|
const [ctrlKey, setCtrlKey] = useState(false as boolean | undefined);
|
|
const [altKey, setAltKey] = useState(false as boolean | undefined);
|
|
|
|
useEffect(() => {
|
|
ShortcutsChangedEvent.on((shortcuts) => setShortcuts({ ...shortcuts }));
|
|
BindShortcutRequestEvent.on((shortcut) => setShortcut(shortcut));
|
|
|
|
document.addEventListener("keydown", (ev) => {
|
|
if (ev.code) {
|
|
setCode(ev.code);
|
|
if (ev.code.indexOf("Control") < 0) setCtrlKey(ev.ctrlKey);
|
|
else setCtrlKey(false);
|
|
if (ev.code.indexOf("Shift") < 0) setShiftKey(ev.shiftKey);
|
|
else setShiftKey(false);
|
|
if (ev.code.indexOf("Alt") < 0) setAltKey(ev.altKey);
|
|
else setAltKey(false);
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
setCode(shortcut?.getOptions().code ?? null);
|
|
setShiftKey(shortcut?.getOptions().shiftKey);
|
|
setAltKey(shortcut?.getOptions().altKey);
|
|
setCtrlKey(shortcut?.getOptions().ctrlKey);
|
|
}, [shortcut]);
|
|
|
|
let available: null | boolean = code ? true : null;
|
|
let inUseShortcuts: Shortcut[] = [];
|
|
for (let id in shortcuts) {
|
|
if (
|
|
id !== shortcut?.getId() &&
|
|
code === shortcuts[id].getOptions().code &&
|
|
((shiftKey === undefined && shortcuts[id].getOptions().shiftKey !== undefined) ||
|
|
(shiftKey !== undefined && shortcuts[id].getOptions().shiftKey === undefined) ||
|
|
shiftKey === shortcuts[id].getOptions().shiftKey) &&
|
|
((altKey === undefined && shortcuts[id].getOptions().altKey !== undefined) ||
|
|
(altKey !== undefined && shortcuts[id].getOptions().altKey === undefined) ||
|
|
altKey === shortcuts[id].getOptions().altKey) &&
|
|
((ctrlKey === undefined && shortcuts[id].getOptions().ctrlKey !== undefined) ||
|
|
(ctrlKey !== undefined && shortcuts[id].getOptions().ctrlKey === undefined) ||
|
|
ctrlKey === shortcuts[id].getOptions().ctrlKey)
|
|
) {
|
|
available = false;
|
|
inUseShortcuts.push(shortcuts[id]);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Modal open={props.open} size={"sm"}>
|
|
<div className="flex h-full w-full flex-col gap-4">
|
|
<div className={`flex flex-col gap-2`}>
|
|
<span
|
|
className={`
|
|
text-gray-800 text-md
|
|
dark:text-white
|
|
`}
|
|
>
|
|
{shortcut?.getOptions().label}
|
|
</span>
|
|
<span
|
|
className={`
|
|
text-gray-800 text-md
|
|
dark:text-gray-400
|
|
`}
|
|
>
|
|
Press the key you want to bind to this event
|
|
</span>
|
|
</div>
|
|
<div className="w-full text-center text-white">
|
|
{ctrlKey && "Ctrl + "}
|
|
{altKey && "Alt + "}
|
|
{shiftKey && "Shift + "}
|
|
{code}
|
|
</div>
|
|
<div className="text-white">
|
|
{available === true && <div className="text-green-600">Keybind is free!</div>}
|
|
{available === false && (
|
|
<div className="flex flex-col gap-2">
|
|
<div className="flex gap-2">
|
|
Keybind is already in use:{" "}
|
|
<div
|
|
className={`flex flex-wrap gap-2 font-bold text-orange-600`}
|
|
>
|
|
{inUseShortcuts.map((shortcut) => (
|
|
<span key={shortcut.getId()}>{shortcut.getOptions().label}</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
<div className="text-gray-400">A key combination can be assigned to multiple actions, and all bound actions will fire</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="mt-auto flex justify-end">
|
|
{shortcut && (
|
|
<button
|
|
type="button"
|
|
onClick={() => {
|
|
if (shortcut && code) {
|
|
let options = shortcut.getOptions();
|
|
options.code = code;
|
|
options.altKey = altKey;
|
|
options.shiftKey = shiftKey;
|
|
options.ctrlKey = ctrlKey;
|
|
getApp().getShortcutManager().setShortcutOption(shortcut.getId(), options);
|
|
|
|
getApp().setState(OlympusState.OPTIONS);
|
|
}
|
|
}}
|
|
className={`
|
|
mb-2 me-2 ml-auto flex content-center items-center gap-2
|
|
rounded-sm bg-blue-700 px-5 py-2.5 text-sm font-medium text-white
|
|
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
|
|
focus:outline-none focus:ring-4 focus:ring-blue-300
|
|
hover:bg-blue-800
|
|
`}
|
|
>
|
|
Continue
|
|
<FontAwesomeIcon icon={faArrowRight} />
|
|
</button>
|
|
)}
|
|
<button
|
|
type="button"
|
|
onClick={() => getApp().setState(OlympusState.OPTIONS)}
|
|
className={`
|
|
mb-2 me-2 flex content-center items-center gap-2 rounded-sm
|
|
border-[1px] bg-blue-700 px-5 py-2.5 text-sm font-medium text-white
|
|
dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400
|
|
dark:hover:bg-gray-700 dark:focus:ring-blue-800
|
|
focus:outline-none focus:ring-4 focus:ring-blue-300
|
|
hover:bg-blue-800
|
|
`}
|
|
>
|
|
Back
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</Modal>
|
|
);
|
|
}
|