BetterDiscordApp-rauenzi/renderer/src/ui/settings/components/keybind.jsx

53 lines
2.4 KiB
React
Raw Normal View History

2023-05-19 23:14:55 +02:00
import React from "@modules/react";
2022-10-03 05:08:10 +02:00
2023-08-29 05:47:20 +02:00
import Button from "../../base/button";
2023-05-20 00:37:21 +02:00
import Keyboard from "@ui/icons/keyboard";
import Close from "@ui/icons/close";
2022-10-03 05:08:10 +02:00
2023-03-07 01:17:28 +01:00
const {useState, useCallback, useEffect} = React;
2022-10-03 05:08:10 +02:00
2023-03-07 01:17:28 +01:00
export default function Keybind({value: initialValue, onChange, max = 2, clearable = true}) {
const [state, setState] = useState({value: initialValue, isRecording: false, accum: []});
2022-10-03 05:08:10 +02:00
2023-03-07 01:17:28 +01:00
useEffect(() => {
2023-03-22 17:23:40 +01:00
window.addEventListener("keydown", keyHandler, true);
return () => window.removeEventListener("keydown", keyHandler, true);
2023-03-07 01:17:28 +01:00
});
const keyHandler = useCallback((event) => {
if (!state.isRecording) return;
2022-10-03 05:08:10 +02:00
event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
2023-03-07 01:17:28 +01:00
if (event.repeat || state.accum.includes(event.key)) return;
2022-10-03 05:08:10 +02:00
2023-03-07 01:17:28 +01:00
state.accum.push(event.key);
if (state.accum.length == max) {
if (onChange) onChange(state.accum);
setState({value: state.accum.slice(0), isRecording: false, accum: []});
2022-10-03 05:08:10 +02:00
}
2023-03-20 03:23:11 +01:00
}, [state, max, onChange]);
2022-10-03 05:08:10 +02:00
2023-03-07 01:17:28 +01:00
const clearKeybind = useCallback((event) => {
2022-10-03 05:08:10 +02:00
event.stopPropagation();
event.preventDefault();
2023-03-07 01:17:28 +01:00
if (onChange) onChange([]);
2023-03-22 17:23:40 +01:00
setState({...state, isRecording: false, value: [], accum: []});
2023-03-20 03:23:11 +01:00
}, [onChange, state]);
const onClick = useCallback((e) => {
if (e.target?.className?.includes?.("bd-keybind-clear") || e.target?.closest(".bd-button")?.className?.includes("bd-keybind-clear")) return clearKeybind(e);
setState({...state, isRecording: !state.isRecording});
}, [state, clearKeybind]);
2023-03-07 01:17:28 +01:00
const displayValue = state.isRecording ? "Recording..." : !state.value.length ? "N/A" : state.value.join(" + ");
return <div className={"bd-keybind-wrap" + (state.isRecording ? " recording" : "")} onClick={onClick}>
<input readOnly={true} type="text" className="bd-keybind-input" value={displayValue} />
<div className="bd-keybind-controls">
2023-08-29 05:47:20 +02:00
<Button size={Button.Sizes.ICON} look={Button.Looks.FILLED} color={state.isRecording ? Button.Colors.RED : Button.Colors.BRAND} className="bd-keybind-record" onClick={onClick}><Keyboard size="24px" /></Button>
{clearable && <Button size={Button.Sizes.ICON} look={Button.Looks.BLANK} onClick={clearKeybind} className="bd-keybind-clear"><Close size="24px" /></Button>}
2023-03-07 01:17:28 +01:00
</div>
</div>;
2022-10-03 05:08:10 +02:00
}