Keybind setting change (#480)
This commit is contained in:
parent
a659624fec
commit
871de99ad7
2 changed files with 201 additions and 14 deletions
|
|
@ -5,23 +5,145 @@
|
|||
*/
|
||||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import { EquicordDevs, IS_MAC } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { useState } from "@webpack/common";
|
||||
|
||||
import { cleanupCommandPaletteRuntime, registerBuiltInCommands, wrapChatBarChildren } from "./registry";
|
||||
import { CommandPaletteSettingsPanel } from "./settingsPanel";
|
||||
import { openCommandPalette } from "./ui";
|
||||
|
||||
const DEFAULT_KEYS = IS_MAC ? ["Meta", "Shift", "P"] : ["Control", "Shift", "P"];
|
||||
const DEFAULT_HOTKEY = DEFAULT_KEYS.join("+");
|
||||
|
||||
const cl = classNameFactory("vc-cp-");
|
||||
let isRecordingGlobal = false;
|
||||
let openScheduled = false;
|
||||
|
||||
export const settings = definePluginSettings({
|
||||
hotkey: {
|
||||
description: "Hotkey used to open the command palette (format: Ctrl+Shift+P)",
|
||||
type: OptionType.STRING,
|
||||
default: DEFAULT_HOTKEY
|
||||
description: "Hotkey used to open the command palette",
|
||||
type: OptionType.COMPONENT,
|
||||
default: DEFAULT_KEYS,
|
||||
component: () => {
|
||||
const [isRecording, setIsRecording] = useState(false);
|
||||
const [currentKeys, setCurrentKeys] = useState<string[]>([]);
|
||||
|
||||
const recordKeybind = (setIsRecording: (value: boolean) => void) => {
|
||||
const pressedKeys: Set<string> = new Set();
|
||||
const keyLists: string[][] = [];
|
||||
let recordingTimeout: number | null = null;
|
||||
|
||||
setIsRecording(true);
|
||||
setCurrentKeys([]);
|
||||
isRecordingGlobal = true;
|
||||
|
||||
const updateKeys = () => {
|
||||
const currentKeyArray = Array.from(pressedKeys);
|
||||
setCurrentKeys(currentKeyArray);
|
||||
keyLists.push(currentKeyArray);
|
||||
|
||||
if (recordingTimeout) {
|
||||
clearTimeout(recordingTimeout);
|
||||
}
|
||||
recordingTimeout = window.setTimeout(() => {
|
||||
const longestArray = keyLists.reduce((a, b) => a.length > b.length ? a : b);
|
||||
if (longestArray.length > 0) {
|
||||
settings.store.hotkey = longestArray.map(key => key.toLowerCase());
|
||||
}
|
||||
setIsRecording(false);
|
||||
setCurrentKeys([]);
|
||||
isRecordingGlobal = false;
|
||||
document.removeEventListener("keydown", keydownListener);
|
||||
document.removeEventListener("keyup", keyupListener);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const getKeyName = (key: string) => {
|
||||
const keyMap: Record<string, string> = {
|
||||
"Control": "Control",
|
||||
"Shift": "Shift",
|
||||
"Alt": "Alt",
|
||||
"Meta": "Meta"
|
||||
};
|
||||
return keyMap[key] || key;
|
||||
};
|
||||
|
||||
const keydownListener = (e: KeyboardEvent) => {
|
||||
if (e.ctrlKey) pressedKeys.add("Control");
|
||||
else pressedKeys.delete("Control");
|
||||
|
||||
if (e.shiftKey) pressedKeys.add("Shift");
|
||||
else pressedKeys.delete("Shift");
|
||||
|
||||
if (e.altKey) pressedKeys.add("Alt");
|
||||
else pressedKeys.delete("Alt");
|
||||
|
||||
if (e.metaKey) pressedKeys.add("Meta");
|
||||
else pressedKeys.delete("Meta");
|
||||
|
||||
const keyName = getKeyName(e.key);
|
||||
pressedKeys.add(keyName);
|
||||
|
||||
updateKeys();
|
||||
};
|
||||
|
||||
const keyupListener = (e: KeyboardEvent) => {
|
||||
if (e.ctrlKey) pressedKeys.add("Control");
|
||||
else pressedKeys.delete("Control");
|
||||
|
||||
if (e.shiftKey) pressedKeys.add("Shift");
|
||||
else pressedKeys.delete("Shift");
|
||||
|
||||
if (e.altKey) pressedKeys.add("Alt");
|
||||
else pressedKeys.delete("Alt");
|
||||
|
||||
if (e.metaKey) pressedKeys.add("Meta");
|
||||
else pressedKeys.delete("Meta");
|
||||
|
||||
const keyName = getKeyName(e.key);
|
||||
pressedKeys.delete(keyName);
|
||||
|
||||
updateKeys();
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", keydownListener);
|
||||
document.addEventListener("keyup", keyupListener);
|
||||
};
|
||||
|
||||
const getKeySymbol = (key: string) => {
|
||||
const normalizedKey = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase();
|
||||
const keySymbols: Record<string, string> = {
|
||||
"Control": "⌃",
|
||||
"Shift": "⇧",
|
||||
"Alt": "⌥",
|
||||
"Meta": "⌘"
|
||||
};
|
||||
return keySymbols[normalizedKey] || "";
|
||||
};
|
||||
|
||||
const displayKeys = isRecording ? currentKeys : settings.store.hotkey;
|
||||
const displayText = displayKeys.length > 0
|
||||
? displayKeys.map(word => {
|
||||
const symbol = getKeySymbol(word);
|
||||
const displayWord = word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
||||
return symbol ? `${symbol}${displayWord}` : displayWord;
|
||||
}).join(" + ")
|
||||
: "No keybind set";
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={cl("key-recorder-container")}>
|
||||
<div className={`${cl("key-recorder")} ${isRecording ? cl("recording") : ""}`}>
|
||||
<span className={cl("key-display")}>{displayText}</span>
|
||||
<button className={`${cl("key-recorder-button")} ${isRecording ? cl("recording-button") : ""}`} onClick={() => recordKeybind(setIsRecording)} disabled={isRecording}>
|
||||
{isRecording ? "Recording..." : "Record keybind"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
},
|
||||
visualStyle: {
|
||||
description: "Palette appearance",
|
||||
|
|
@ -50,16 +172,13 @@ export const settings = definePluginSettings({
|
|||
|
||||
function getConfiguredHotkey() {
|
||||
const raw = settings.store.hotkey;
|
||||
const hotkeyString = typeof raw === "string" ? raw.trim() : "";
|
||||
|
||||
if (!hotkeyString) return DEFAULT_KEYS;
|
||||
|
||||
const parts = hotkeyString
|
||||
.split("+")
|
||||
.map(part => part.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
return parts.length > 0 ? parts : DEFAULT_KEYS;
|
||||
if (Array.isArray(raw) && raw.length > 0) {
|
||||
return raw;
|
||||
}
|
||||
if (typeof raw === "string" && (raw as string).trim()) {
|
||||
return (raw as string).split("+").map(part => part.trim()).filter(Boolean);
|
||||
}
|
||||
return DEFAULT_KEYS;
|
||||
}
|
||||
|
||||
function matchesHotkey(e: KeyboardEvent) {
|
||||
|
|
@ -142,6 +261,7 @@ export default definePlugin({
|
|||
},
|
||||
|
||||
handleKeydown(e: KeyboardEvent) {
|
||||
if (isRecordingGlobal) return;
|
||||
if (!matchesHotkey(e)) return;
|
||||
if (shouldIgnoreTarget(e.target) && !hotkeyUsesModifiers()) return;
|
||||
e.preventDefault();
|
||||
|
|
|
|||
|
|
@ -681,6 +681,73 @@
|
|||
background: rgb(255 255 255 / 12%);
|
||||
}
|
||||
|
||||
/* Keybind recorder styles */
|
||||
.vc-cp-key-recorder-container {
|
||||
position: relative;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
width: 20rem;
|
||||
}
|
||||
|
||||
.vc-cp-key-recorder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-radius: 3px;
|
||||
background-color: hsl(var(--black-500-hsl) / 10%);
|
||||
color: var(--header-primary);
|
||||
line-height: 22px;
|
||||
font-weight: 600;
|
||||
padding: 10px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
border: 1px solid;
|
||||
border-color: hsl(var(--black-500-hsl) / 30%);
|
||||
transition: border .15s ease;
|
||||
user-select: none;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
.vc-cp-key-display {
|
||||
flex: 1;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.vc-cp-recording {
|
||||
animation: shadowPulse_b16790 1s ease-in infinite;
|
||||
box-shadow: 0 0 6px hsl(var(--red-400-hsl) / 30%);
|
||||
border-color: hsl(var(--red-400-hsl) / 30%);
|
||||
color: var(--status-danger);
|
||||
}
|
||||
|
||||
.vc-cp-key-recorder:hover {
|
||||
border-color: hsl(var(--red-400-hsl) / 30%);
|
||||
}
|
||||
|
||||
.vc-cp-recording-button {
|
||||
color: var(--status-danger) !important;
|
||||
background-color: hsl(var(--red-400-hsl) / 10%) !important;
|
||||
opacity: 1;
|
||||
transition: opacity .2s ease-in-out, transform .2s ease-in-out;
|
||||
}
|
||||
|
||||
.vc-cp-key-recorder-button {
|
||||
flex-shrink: 0;
|
||||
height: 30px;
|
||||
width: 128px;
|
||||
color: var(--white-500);
|
||||
background-color: var(--button-secondary-background);
|
||||
border-radius: 10px;
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
|
||||
.vc-cp-key-recorder-button:hover {
|
||||
background-color: var(--button-secondary-background-hover);
|
||||
}
|
||||
|
||||
/* stylelint-enable no-descending-specificity */
|
||||
|
||||
/* fuck you css */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue