mirror of https://github.com/jetkvm/kvm.git
Compare commits
6 Commits
b1c1ef8e51
...
4e25e1ed05
Author | SHA1 | Date |
---|---|---|
|
4e25e1ed05 | |
|
cbc3f2016f | |
|
580b3397bf | |
|
ce95be8af9 | |
|
c28f3b4cd0 | |
|
ad59ecea09 |
|
@ -12,7 +12,7 @@ import {
|
|||
MAX_KEYS_PER_STEP,
|
||||
} from "@/constants/macros";
|
||||
import { KeySequence } from "@/hooks/stores";
|
||||
import { useKeyboardLayout } from "@/hooks/useKeyboardLayout";
|
||||
import useKeyboardLayout from "@/hooks/useKeyboardLayout";
|
||||
|
||||
interface ValidationErrors {
|
||||
name?: string;
|
||||
|
@ -45,7 +45,7 @@ export function MacroForm({
|
|||
const [keyQueries, setKeyQueries] = useState<Record<number, string>>({});
|
||||
const [errors, setErrors] = useState<ValidationErrors>({});
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const { keyboard } = useKeyboardLayout();
|
||||
const { selectedKeyboard } = useKeyboardLayout();
|
||||
|
||||
const showTemporaryError = (message: string) => {
|
||||
setErrorMessage(message);
|
||||
|
@ -236,7 +236,7 @@ export function MacroForm({
|
|||
}
|
||||
onDelayChange={delay => handleDelayChange(stepIndex, delay)}
|
||||
isLastStep={stepIndex === (macro.steps?.length || 0) - 1}
|
||||
keyboard={keyboard}
|
||||
keyboard={selectedKeyboard}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { useMemo } from "react";
|
||||
import { LuArrowUp, LuArrowDown, LuX, LuTrash2 } from "react-icons/lu";
|
||||
|
||||
import { Button } from "@/components/Button";
|
||||
|
@ -12,15 +13,6 @@ import { keys, modifiers } from "@/keyboardMappings";
|
|||
// Filter out modifier keys since they're handled in the modifiers section
|
||||
const modifierKeyPrefixes = ['Alt', 'Control', 'Shift', 'Meta'];
|
||||
|
||||
const keyOptions = (keyDisplayMap: Record<string, string>) => {
|
||||
return Object.keys(keys)
|
||||
.filter(key => !modifierKeyPrefixes.some(prefix => key.startsWith(prefix)))
|
||||
.map(key => ({
|
||||
value: key,
|
||||
label: keyDisplayMap[key] || key,
|
||||
}));
|
||||
}
|
||||
|
||||
const modifierOptions = Object.keys(modifiers).map(modifier => ({
|
||||
value: modifier,
|
||||
label: modifier.replace(/^(Control|Alt|Shift|Meta)(Left|Right)$/, "$1 $2"),
|
||||
|
@ -93,16 +85,26 @@ export function MacroStepCard({
|
|||
}: MacroStepCardProps) {
|
||||
const { keyDisplayMap } = keyboard;
|
||||
|
||||
const getFilteredKeys = () => {
|
||||
const keyOptions = useMemo(() =>
|
||||
Object.keys(keys)
|
||||
.filter(key => !modifierKeyPrefixes.some(prefix => key.startsWith(prefix)))
|
||||
.map(key => ({
|
||||
value: key,
|
||||
label: keyDisplayMap[key] || key,
|
||||
})),
|
||||
[keyDisplayMap]
|
||||
);
|
||||
|
||||
const filteredKeys = useMemo(() => {
|
||||
const selectedKeys = ensureArray(step.keys);
|
||||
const availableKeys = keyOptions(keyDisplayMap).filter(option => !selectedKeys.includes(option.value));
|
||||
const availableKeys = keyOptions.filter(option => !selectedKeys.includes(option.value));
|
||||
|
||||
if (keyQuery === '') {
|
||||
return availableKeys;
|
||||
} else {
|
||||
return availableKeys.filter(option => option.label.toLowerCase().includes(keyQuery.toLowerCase()));
|
||||
}
|
||||
};
|
||||
}, [keyOptions, keyQuery, step.keys]);
|
||||
|
||||
return (
|
||||
<Card className="p-4">
|
||||
|
@ -211,7 +213,7 @@ export function MacroStepCard({
|
|||
}}
|
||||
displayValue={() => keyQuery}
|
||||
onInputChange={onKeyQueryChange}
|
||||
options={getFilteredKeys}
|
||||
options={() => filteredKeys}
|
||||
disabledMessage="Max keys reached"
|
||||
size="SM"
|
||||
immediate
|
||||
|
|
|
@ -14,7 +14,7 @@ import DetachIconRaw from "@/assets/detach-icon.svg";
|
|||
import { cx } from "@/cva.config";
|
||||
import { useHidStore, useUiStore } from "@/hooks/stores";
|
||||
import useKeyboard from "@/hooks/useKeyboard";
|
||||
import { useKeyboardLayout } from "@/hooks/useKeyboardLayout";
|
||||
import useKeyboardLayout from "@/hooks/useKeyboardLayout";
|
||||
import { keys, modifiers, latchingKeys, decodeModifiers } from "@/keyboardMappings";
|
||||
|
||||
export const DetachIcon = ({ className }: { className?: string }) => {
|
||||
|
@ -30,12 +30,19 @@ function KeyboardWrapper() {
|
|||
const { isAttachedVirtualKeyboardVisible, setAttachedVirtualKeyboardVisibility } = useUiStore();
|
||||
const { keysDownState, /* keyboardLedState,*/ isVirtualKeyboardEnabled, setVirtualKeyboardEnabled } = useHidStore();
|
||||
const { handleKeyPress, executeMacro } = useKeyboard();
|
||||
const { selectedKeyboard } = useKeyboardLayout();
|
||||
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||
const [newPosition, setNewPosition] = useState({ x: 0, y: 0 });
|
||||
|
||||
const { keyboard } = useKeyboardLayout();
|
||||
const keyDisplayMap = useMemo(() => {
|
||||
return selectedKeyboard.keyDisplayMap;
|
||||
}, [selectedKeyboard]);
|
||||
|
||||
const virtualKeyboard = useMemo(() => {
|
||||
return selectedKeyboard.virtualKeyboard;
|
||||
}, [selectedKeyboard]);
|
||||
|
||||
//const isCapsLockActive = useMemo(() => {
|
||||
// return (keyboardLedState.caps_lock);
|
||||
|
@ -269,18 +276,18 @@ function KeyboardWrapper() {
|
|||
buttons: keyNamesForDownKeys.join(" "),
|
||||
},
|
||||
]}
|
||||
display={keyboard.keyDisplayMap}
|
||||
layout={keyboard.virtualKeyboard.main}
|
||||
display={keyDisplayMap}
|
||||
layout={virtualKeyboard.main}
|
||||
disableButtonHold={true}
|
||||
debug={false}
|
||||
enableLayoutCandidates={false}
|
||||
preventMouseDownDefault={true}
|
||||
preventMouseUpDefault={true}
|
||||
stopMouseDownPropagation={true}
|
||||
stopMouseUpPropagation={true}
|
||||
physicalKeyboardHighlight={true}
|
||||
physicalKeyboardHighlightPress={true}
|
||||
physicalKeyboardHighlightPreventDefault={true}
|
||||
enableLayoutCandidates={false}
|
||||
physicalKeyboardHighlightTextColor="black"
|
||||
physicalKeyboardHighlightBgColor="lightblue"
|
||||
/>
|
||||
|
||||
<div className="controlArrows">
|
||||
|
@ -290,34 +297,36 @@ function KeyboardWrapper() {
|
|||
layoutName="default"
|
||||
onKeyPress={onKeyDown}
|
||||
onKeyReleased={onKeyUp}
|
||||
display={keyboard.keyDisplayMap}
|
||||
layout={keyboard.virtualKeyboard.control}
|
||||
debug={false}
|
||||
display={keyDisplayMap}
|
||||
layout={virtualKeyboard.control}
|
||||
disableButtonHold={true}
|
||||
enableLayoutCandidates={false}
|
||||
preventMouseDownDefault={true}
|
||||
preventMouseUpDefault={true}
|
||||
stopMouseDownPropagation={true}
|
||||
stopMouseUpPropagation={true}
|
||||
physicalKeyboardHighlight={true}
|
||||
physicalKeyboardHighlightPress={true}
|
||||
physicalKeyboardHighlightPreventDefault={true}
|
||||
enableLayoutCandidates={false}
|
||||
physicalKeyboardHighlightTextColor="black"
|
||||
physicalKeyboardHighlightBgColor="lightblue"
|
||||
/>
|
||||
<Keyboard
|
||||
baseClass="simple-keyboard-arrows"
|
||||
theme="simple-keyboard hg-theme-default hg-layout-default"
|
||||
onKeyPress={onKeyDown}
|
||||
onKeyReleased={onKeyUp}
|
||||
display={keyboard.keyDisplayMap}
|
||||
layout={keyboard.virtualKeyboard.arrows}
|
||||
debug={false}
|
||||
display={keyDisplayMap}
|
||||
layout={virtualKeyboard.arrows}
|
||||
disableButtonHold={true}
|
||||
enableLayoutCandidates={false}
|
||||
preventMouseDownDefault={true}
|
||||
preventMouseUpDefault={true}
|
||||
stopMouseDownPropagation={true}
|
||||
stopMouseUpPropagation={true}
|
||||
physicalKeyboardHighlight={true}
|
||||
physicalKeyboardHighlightPress={true}
|
||||
physicalKeyboardHighlightPreventDefault={true}
|
||||
enableLayoutCandidates={false}
|
||||
physicalKeyboardHighlightTextColor="black"
|
||||
physicalKeyboardHighlightBgColor="lightblue"
|
||||
/>
|
||||
</div>
|
||||
{ /* TODO add optional number pad */ }
|
||||
|
|
|
@ -11,7 +11,7 @@ import { useJsonRpc } from "@/hooks/useJsonRpc";
|
|||
import { useHidStore, useRTCStore, useUiStore, useSettingsStore } from "@/hooks/stores";
|
||||
import { keys, modifiers } from "@/keyboardMappings";
|
||||
import { KeyStroke } from "@/keyboardLayouts";
|
||||
import { useKeyboardLayout } from "@/hooks/useKeyboardLayout";
|
||||
import useKeyboardLayout from "@/hooks/useKeyboardLayout";
|
||||
import notifications from "@/notifications";
|
||||
|
||||
const hidKeyboardPayload = (modifier: number, keys: number[]) => {
|
||||
|
@ -36,7 +36,7 @@ export default function PasteModal() {
|
|||
const close = useClose();
|
||||
|
||||
const { setKeyboardLayout } = useSettingsStore();
|
||||
const { keyboard } = useKeyboardLayout();
|
||||
const { selectedKeyboard } = useKeyboardLayout();
|
||||
|
||||
useEffect(() => {
|
||||
send("getKeyboardLayout", {}, resp => {
|
||||
|
@ -56,13 +56,13 @@ export default function PasteModal() {
|
|||
setDisableVideoFocusTrap(false);
|
||||
|
||||
if (rpcDataChannel?.readyState !== "open" || !TextAreaRef.current) return;
|
||||
if (!keyboard) return;
|
||||
if (!selectedKeyboard) return;
|
||||
|
||||
const text = TextAreaRef.current.value;
|
||||
|
||||
try {
|
||||
for (const char of text) {
|
||||
const keyprops = keyboard.chars[char];
|
||||
const keyprops = selectedKeyboard.chars[char];
|
||||
if (!keyprops) continue;
|
||||
|
||||
const { key, shift, altRight, deadKey, accentKey } = keyprops;
|
||||
|
@ -102,7 +102,7 @@ export default function PasteModal() {
|
|||
);
|
||||
});
|
||||
}
|
||||
}, [keyboard, rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteModeEnabled]);
|
||||
}, [selectedKeyboard, rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteModeEnabled]);
|
||||
|
||||
useEffect(() => {
|
||||
if (TextAreaRef.current) {
|
||||
|
@ -152,7 +152,7 @@ export default function PasteModal() {
|
|||
// @ts-expect-error TS doesn't recognize Intl.Segmenter in some environments
|
||||
[...new Intl.Segmenter().segment(value)]
|
||||
.map(x => x.segment)
|
||||
.filter(char => !keyboard.chars[char]),
|
||||
.filter(char => !selectedKeyboard.chars[char]),
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -173,7 +173,7 @@ export default function PasteModal() {
|
|||
</div>
|
||||
<div className="space-y-4">
|
||||
<p className="text-xs text-slate-600 dark:text-slate-400">
|
||||
Sending text using keyboard layout: {keyboard.isoCode}-{keyboard.name}
|
||||
Sending text using keyboard layout: {selectedKeyboard.isoCode}-{selectedKeyboard.name}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,22 +1,35 @@
|
|||
import { useMemo } from "react";
|
||||
|
||||
import { useSettingsStore } from "@/hooks/stores";
|
||||
import { KeyboardLayout, selectedKeyboard } from "@/keyboardLayouts";
|
||||
import { keyboards } from "@/keyboardLayouts";
|
||||
|
||||
export function useKeyboardLayout(): { keyboard: KeyboardLayout } {
|
||||
export default function useKeyboardLayout() {
|
||||
const { keyboardLayout } = useSettingsStore();
|
||||
|
||||
const keyboardOptions = useMemo(() => {
|
||||
return keyboards.map((keyboard) => {
|
||||
return { label: keyboard.name, value: keyboard.isoCode }
|
||||
});
|
||||
}, []);
|
||||
|
||||
const isoCode = useMemo(() => {
|
||||
console.log("Current keyboard layout from store:", keyboardLayout);
|
||||
// If we don't have a specific layout, default to "en-US" because that was the original layout
|
||||
// developed so it is a good fallback. Additionally, we replace "en_US" with "en-US" because
|
||||
// the original server-side code used "en_US" as the default value, but that's not the correct
|
||||
// ISO code for English/United State. To ensure we remain backward compatible with devices that
|
||||
// have not had their Keyboard Layout selected by the user, we want to treat "en_US" as if it was
|
||||
// "en-US" to match the ISO standard codes now used in the keyboardLayouts.
|
||||
console.debug("Current keyboard layout from store:", keyboardLayout);
|
||||
if (keyboardLayout && keyboardLayout.length > 0)
|
||||
return keyboardLayout.replace("en_US", "en-US");
|
||||
return "en-US";
|
||||
}, [keyboardLayout]);
|
||||
|
||||
const keyboard = useMemo(() => {
|
||||
console.log("Selected keyboard layout:", isoCode);
|
||||
return selectedKeyboard(isoCode);
|
||||
const selectedKeyboard = useMemo(() => {
|
||||
// fallback to original behaviour of en-US if no isoCode given or matching layout not found
|
||||
return keyboards.find(keyboard => keyboard.isoCode === isoCode)
|
||||
?? keyboards.find(keyboard => keyboard.isoCode === "en-US")!;
|
||||
}, [isoCode]);
|
||||
|
||||
return { keyboard };
|
||||
return { keyboardOptions, isoCode, selectedKeyboard };
|
||||
}
|
|
@ -14,7 +14,7 @@ export interface KeyboardLayout {
|
|||
};
|
||||
}
|
||||
|
||||
// to add a new layout, create a file like the above and add it to the list
|
||||
// To add a new layout, create a file like the above and add it to the list
|
||||
import { cs_CZ } from "@/keyboardLayouts/cs_CZ"
|
||||
import { de_CH } from "@/keyboardLayouts/de_CH"
|
||||
import { de_DE } from "@/keyboardLayouts/de_DE"
|
||||
|
@ -26,19 +26,6 @@ import { fr_CH } from "@/keyboardLayouts/fr_CH"
|
|||
import { fr_FR } from "@/keyboardLayouts/fr_FR"
|
||||
import { it_IT } from "@/keyboardLayouts/it_IT"
|
||||
import { nb_NO } from "@/keyboardLayouts/nb_NO"
|
||||
import { pl_PL_t } from "@/keyboardLayouts/pl_PL_t"
|
||||
import { sv_SE } from "@/keyboardLayouts/sv_SE"
|
||||
|
||||
export const keyboards: KeyboardLayout[] = [ cs_CZ, de_CH, de_DE, en_UK, en_US, es_ES, fr_BE, fr_CH, fr_FR, it_IT, nb_NO, pl_PL_t, sv_SE ];
|
||||
|
||||
export const selectedKeyboard = (isoCode: string): KeyboardLayout => {
|
||||
// fallback to original behaviour of en-US if no isoCode given or matching layout not found
|
||||
return keyboards.find(keyboard => keyboard.isoCode == isoCode)
|
||||
?? keyboards.find(keyboard => keyboard.isoCode == "en-US")!;
|
||||
};
|
||||
|
||||
export const keyboardOptions = () => {
|
||||
return keyboards.map((keyboard) => {
|
||||
return { label: keyboard.name, value: keyboard.isoCode }
|
||||
});
|
||||
}
|
||||
export const keyboards: KeyboardLayout[] = [ cs_CZ, de_CH, de_DE, en_UK, en_US, es_ES, fr_BE, fr_CH, fr_FR, it_IT, nb_NO, sv_SE ];
|
||||
|
|
|
@ -1,244 +0,0 @@
|
|||
import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
|
||||
|
||||
import { en_US } from "./en_US" // for fallback of keyDisplayMap, modifierDisplayMap, and virtualKeyboard
|
||||
|
||||
const name = "Polski (Programista)";
|
||||
const isoCode = "pl-PL-t";
|
||||
|
||||
const keyAcute: KeyCombo = { key: "Quote" } // accent aigu (acute accent), mark ´ placed above the letter
|
||||
const keyCedilla: KeyCombo = { key: "OEM_2", altRight: true } // Cedilla mark ¸ placed below the letter in the center
|
||||
const keyDiaresis: KeyCombo = { key: "Plus", shift: true } // Diaresis (not umlaut!), two dots placed above a vowel to indicate each vowel should be pronounce
|
||||
const keyDotAbove: KeyCombo = { key: "", } // Dot above, single TODO!
|
||||
const keyDoubleAcute: KeyCombo = { key: "˝" } // Double acute mark ˝, placed above the letter in the center
|
||||
const keyGrave: KeyCombo = { key: "BracketRight" } // accent grave mark ` placed above the letter
|
||||
const keyHacek: KeyCombo = { key: "", } // TODO!
|
||||
const keyHat: KeyCombo = { key: "BracketRight", shift: true } // accent circonflexe (accent hat), mark ^ placed above the letter
|
||||
const keyOgonek: KeyCombo = { key: ""} // Ogonek mark ˛ placed below the letter on the right side
|
||||
const keyTylda: KeyCombo = { key: "Backquote", altRight: true } // Tilde mark ~ placed above the letter
|
||||
|
||||
const chars = {
|
||||
A: { key: "KeyA", shift: true },
|
||||
"Ä": { key: "KeyA", shift: true, accentKey: keyDiaresis },
|
||||
"Ą": { key: "KeyA", shift: true, ctrl: true, alt: true },
|
||||
"Á": { key: "KeyA", shift: true, accentKey: keyAcute },
|
||||
"Â": { key: "KeyA", shift: true, accentKey: keyHat },
|
||||
"À": { key: "KeyA", shift: true, accentKey: keyGrave },
|
||||
"Ã": { key: "KeyA", shift: true, accentKey: keyTylda },
|
||||
a: { key: "KeyA" },
|
||||
"ä": { key: "KeyA", accentKey: keyDiaresis },
|
||||
"ą": { key: "KeyA", accentKey: keyOgonek }, // "ą": { key: "KeyA", ctrl: true, alt: true },
|
||||
"á": { key: "KeyA", accentKey: keyAcute },
|
||||
"â": { key: "KeyA", accentKey: keyHat },
|
||||
"à": { key: "KeyA", accentKey: keyGrave },
|
||||
"ã": { key: "KeyA", accentKey: keyTylda },
|
||||
|
||||
B: { key: "KeyB", shift: true },
|
||||
b: { key: "KeyB" },
|
||||
|
||||
C: { key: "KeyC", shift: true },
|
||||
"Ć": { key: "KeyC", shift: true, accentKey: keyAcute },
|
||||
"Č": { key: "KeyC", shift: true, accentKey: keyHacek },
|
||||
"Ç": { key: "KeyC", shift: true, accentKey: keyCedilla }, // "Ç": { key: "Backslash", shift: true },
|
||||
c: { key: "KeyC" },
|
||||
"ć": { key: "KeyC", shift: false, accentKey: keyAcute },
|
||||
"č": { key: "KeyC", accentKey: keyHacek },
|
||||
"ç": { key: "KeyC", accentKey: keyCedilla }, // "ç": { key: "Backslash" },
|
||||
|
||||
D: { key: "KeyD", shift: true },
|
||||
"Ď": { key: "KeyD", shift: true, accentKey: keyHacek },
|
||||
d: { key: "KeyD" },
|
||||
"ď": { key: "KeyD", accentKey: keyHacek },
|
||||
|
||||
E: { key: "KeyE", shift: true },
|
||||
"Ë": { key: "KeyE", shift: true, accentKey: keyDiaresis },
|
||||
"Ę": { key: "KeyE", shift: true, ctrl: true, alt: true, accentKey: keyOgonek },
|
||||
"Ě": { key: "KeyE", shift: true, accentKey: keyHacek },
|
||||
"É": { key: "KeyE", shift: true, accentKey: keyAcute },
|
||||
"Ê": { key: "KeyE", shift: true, accentKey: keyHat },
|
||||
"È": { key: "KeyE", shift: true, accentKey: keyGrave },
|
||||
"Ẽ": { key: "KeyE", shift: true, accentKey: keyTylda },
|
||||
e: { key: "KeyE" },
|
||||
"ę": { key: "KeyE", ctrl: true, alt: true, accentKey: keyOgonek },
|
||||
"ë": { key: "KeyE", accentKey: keyDiaresis },
|
||||
"ě": { key: "KeyE", accentKey: keyHacek },
|
||||
"é": { key: "KeyE", accentKey: keyAcute },
|
||||
"ê": { key: "KeyE", accentKey: keyHat },
|
||||
"è": { key: "KeyE", accentKey: keyGrave },
|
||||
"ẽ": { key: "KeyE", accentKey: keyTylda },
|
||||
|
||||
F: { key: "KeyF", shift: true },
|
||||
f: { key: "KeyF" },
|
||||
|
||||
G: { key: "KeyG", shift: true },
|
||||
g: { key: "KeyG" },
|
||||
|
||||
H: { key: "KeyH", shift: true },
|
||||
h: { key: "KeyH" },
|
||||
|
||||
I: { key: "KeyI", shift: true },
|
||||
"Ï": { key: "KeyI", shift: true, accentKey: keyDiaresis },
|
||||
"Í": { key: "KeyI", shift: true, accentKey: keyAcute },
|
||||
"Î": { key: "KeyI", shift: true, accentKey: keyHat },
|
||||
"Ì": { key: "KeyI", shift: true, accentKey: keyGrave },
|
||||
"Ĩ": { key: "KeyI", shift: true, accentKey: keyTylda },
|
||||
i: { key: "KeyI" },
|
||||
"ï": { key: "KeyI", accentKey: keyDiaresis },
|
||||
"í": { key: "KeyI", accentKey: keyAcute },
|
||||
"î": { key: "KeyI", accentKey: keyHat },
|
||||
"ì": { key: "KeyI", accentKey: keyGrave },
|
||||
"ĩ": { key: "KeyI", accentKey: keyTylda },
|
||||
|
||||
J: { key: "KeyJ", shift: true },
|
||||
j: { key: "KeyJ" },
|
||||
|
||||
K: { key: "KeyK", shift: true },
|
||||
k: { key: "KeyK" },
|
||||
|
||||
L: { key: "KeyL", shift: true },
|
||||
l: { key: "KeyL" },
|
||||
|
||||
M: { key: "KeyM", shift: true },
|
||||
m: { key: "KeyM" },
|
||||
|
||||
N: { key: "KeyN", shift: true },
|
||||
"Ň": { key: "KeyN", shift: true, accentKey: keyHacek },
|
||||
n: { key: "KeyN" },
|
||||
"ň": { key: "KeyR", accentKey: keyHacek },
|
||||
|
||||
O: { key: "KeyO", shift: true },
|
||||
"Ö": { key: "KeyO", shift: true, accentKey: keyDiaresis },
|
||||
"Ő": { key: "KeyO", shift: true, accentKey: keyDoubleAcute },
|
||||
"Ó": { key: "KeyO", shift: true, accentKey: keyAcute }, // "Ó": { key: "KeyO", shift: true, ctrl: true, alt: true },
|
||||
"Ô": { key: "KeyO", shift: true, accentKey: keyHat },
|
||||
"Ò": { key: "KeyO", shift: true, accentKey: keyGrave },
|
||||
"Õ": { key: "KeyO", shift: true, accentKey: keyTylda },
|
||||
o: { key: "KeyO" },
|
||||
"ó": { key: "KeyO", ctrl: true, alt: true, accentKey: keyAcute },
|
||||
"ö": { key: "KeyO", accentKey: keyDiaresis },
|
||||
"ő": { key: "KeyO", accentKey: keyDoubleAcute },
|
||||
"ô": { key: "KeyO", accentKey: keyHat },
|
||||
"ò": { key: "KeyO", accentKey: keyGrave },
|
||||
"õ": { key: "KeyO", accentKey: keyTylda },
|
||||
|
||||
P: { key: "KeyP", shift: true },
|
||||
p: { key: "KeyP" },
|
||||
|
||||
Q: { key: "KeyQ", shift: true },
|
||||
q: { key: "KeyQ" },
|
||||
|
||||
R: { key: "KeyR", shift: true },
|
||||
"Ř": { key: "KeyR", shift: true, accentKey: keyHacek },
|
||||
r: { key: "KeyR" },
|
||||
"ř": { key: "KeyR", accentKey: keyHacek },
|
||||
|
||||
S: { key: "KeyS", shift: true },
|
||||
"Š": { key: "KeyS", shift: true, accentKey: keyHacek },
|
||||
"Ş": { key: "KeyS", shift: true, accentKey: keyCedilla },
|
||||
s: { key: "KeyS" },
|
||||
"š": { key: "KeyS", accentKey: keyHacek },
|
||||
"ş": { key: "KeyS", accentKey: keyCedilla },
|
||||
|
||||
T: { key: "KeyT", shift: true },
|
||||
"Ť": { key: "KeyT", shift: true, accentKey: keyHacek },
|
||||
"Ţ": { key: "KeyT", shift: true, accentKey: keyCedilla },
|
||||
t: { key: "KeyT" },
|
||||
"ť": { key: "KeyT", accentKey: keyHacek },
|
||||
"ţ": { key: "KeyS", accentKey: keyCedilla },
|
||||
|
||||
U: { key: "KeyU", shift: true },
|
||||
"Ü": { key: "KeyU", shift: true, accentKey: keyDiaresis },
|
||||
"Ű": { key: "KeyU", shift: true, accentKey: keyDoubleAcute },
|
||||
"Ú": { key: "KeyU", shift: true, accentKey: keyAcute },
|
||||
"Û": { key: "KeyU", shift: true, accentKey: keyHat },
|
||||
"Ù": { key: "KeyU", shift: true, accentKey: keyGrave },
|
||||
"Ũ": { key: "KeyU", shift: true, accentKey: keyTylda },
|
||||
u: { key: "KeyU" },
|
||||
"€": { key: "KeyU", ctrl: true, alt: true },
|
||||
"ü": { key: "KeyU", accentKey: keyDiaresis },
|
||||
"ű": { key: "KeyU", accentKey: keyDoubleAcute },
|
||||
"ú": { key: "KeyU", accentKey: keyAcute },
|
||||
"û": { key: "KeyU", accentKey: keyHat },
|
||||
"ù": { key: "KeyU", accentKey: keyGrave },
|
||||
"ũ": { key: "KeyU", accentKey: keyTylda },
|
||||
|
||||
V: { key: "KeyV", shift: true },
|
||||
v: { key: "KeyV" },
|
||||
|
||||
W: { key: "KeyW", shift: true },
|
||||
w: { key: "KeyW" },
|
||||
|
||||
X: { key: "KeyX", shift: true },
|
||||
x: { key: "KeyX" },
|
||||
|
||||
Y: { key: "KeyY", shift: true },
|
||||
y: { key: "KeyY" },
|
||||
|
||||
Z: { key: "KeyZ", shift: true },
|
||||
"Ž": { key: "KeyZ", shift: true, accentKey: keyHacek },
|
||||
"Ź": { key: "KeyZ", shift: true, ctrl: true, meta: true, accentKey: keyAcute },
|
||||
z: { key: "KeyZ" },
|
||||
"ž": { key: "KeyZ", accentKey: keyHacek },
|
||||
"ź": { key: "KeyX",ctrl: true, meta: true, accentKey: keyAcute }, // not a typo, it's on the X key
|
||||
"ż": { key: "KeyZ", ctrl: true, meta: true, accentKey: keyDotAbove },
|
||||
|
||||
"º": { key: "Backquote" },
|
||||
"ª": { key: "Backquote", shift: true },
|
||||
"\\": { key: "Backquote", altRight: true },
|
||||
1: { key: "Digit1" },
|
||||
"!": { key: "Digit1", shift: true },
|
||||
"|": { key: "Digit1", altRight: true },
|
||||
2: { key: "Digit2" },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"@": { key: "Digit2", altRight: true },
|
||||
3: { key: "Digit3" },
|
||||
"#": { key: "Digit3", shift: true },
|
||||
4: { key: "Digit4" },
|
||||
"$": { key: "Digit4", shift: true },
|
||||
5: { key: "Digit5" },
|
||||
"%": { key: "Digit5", shift: true },
|
||||
6: { key: "Digit6" },
|
||||
"^": { key: "Digit6", shift: true },
|
||||
"¬": { key: "Digit6", altRight: true },
|
||||
7: { key: "Digit7" },
|
||||
"&": { key: "Digit7", shift: true },
|
||||
8: { key: "Digit8" },
|
||||
"*": { key: "Digit8", shift: true },
|
||||
9: { key: "Digit9" },
|
||||
"(": { key: "Digit9", shift: true },
|
||||
0: { key: "Digit0" },
|
||||
")": { key: "Digit0", shift: true },
|
||||
"'": { key: "Minus" },
|
||||
"?": { key: "Minus", shift: true },
|
||||
"¡": { key: "Equal", deadKey: true },
|
||||
"¿": { key: "Equal", shift: true },
|
||||
"[": { key: "BracketLeft", altRight: true },
|
||||
"+": { key: "BracketRight" },
|
||||
//"*": { key: "BracketRight", shift: true },
|
||||
"]": { key: "BracketRight", altRight: true },
|
||||
"ñ": { key: "Semicolon" },
|
||||
"Ñ": { key: "Semicolon", shift: true },
|
||||
"{": { key: "Quote", altRight: true },
|
||||
"}": { key: "Backslash", altRight: true },
|
||||
",": { key: "Comma" },
|
||||
";": { key: "Comma", shift: true },
|
||||
".": { key: "Period" },
|
||||
":": { key: "Period", shift: true },
|
||||
"-": { key: "Slash" },
|
||||
"_": { key: "Slash", shift: true },
|
||||
"<": { key: "IntlBackslash" },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
" ": { key: "Space" },
|
||||
"ˇ": { key: "Space", accentKey: keyHacek },
|
||||
"\n": { key: "Enter" },
|
||||
Enter: { key: "Enter" },
|
||||
Tab: { key: "Tab" },
|
||||
} as Record<string, KeyCombo>;
|
||||
|
||||
export const pl_PL_t: KeyboardLayout = {
|
||||
isoCode: isoCode,
|
||||
name: name,
|
||||
chars: chars,
|
||||
keyDisplayMap: en_US.keyDisplayMap,
|
||||
modifierDisplayMap: en_US.modifierDisplayMap,
|
||||
virtualKeyboard: en_US.virtualKeyboard
|
||||
};
|
|
@ -2,11 +2,10 @@ import { useCallback, useEffect } from "react";
|
|||
|
||||
import { useSettingsStore } from "@/hooks/stores";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { useKeyboardLayout } from "@/hooks/useKeyboardLayout";
|
||||
import useKeyboardLayout from "@/hooks/useKeyboardLayout";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { Checkbox } from "@/components/Checkbox";
|
||||
import { SelectMenuBasic } from "@/components/SelectMenuBasic";
|
||||
import { keyboardOptions } from "@/keyboardLayouts";
|
||||
import notifications from "@/notifications";
|
||||
|
||||
import { SettingsItem } from "./devices.$id.settings";
|
||||
|
@ -14,8 +13,7 @@ import { SettingsItem } from "./devices.$id.settings";
|
|||
export default function SettingsKeyboardRoute() {
|
||||
const { setKeyboardLayout } = useSettingsStore();
|
||||
const { showPressedKeys, setShowPressedKeys } = useSettingsStore();
|
||||
const { keyboard } = useKeyboardLayout();
|
||||
const layoutOptions = keyboardOptions();
|
||||
const { selectedKeyboard, keyboardOptions } = useKeyboardLayout();
|
||||
|
||||
const { send } = useJsonRpc();
|
||||
|
||||
|
@ -62,9 +60,9 @@ export default function SettingsKeyboardRoute() {
|
|||
size="SM"
|
||||
label=""
|
||||
fullWidth
|
||||
value={keyboard.isoCode}
|
||||
value={selectedKeyboard.isoCode}
|
||||
onChange={onKeyboardLayoutChange}
|
||||
options={layoutOptions}
|
||||
options={keyboardOptions}
|
||||
/>
|
||||
</SettingsItem>
|
||||
<p className="text-xs text-slate-600 dark:text-slate-400">
|
||||
|
|
|
@ -20,7 +20,7 @@ import { MAX_TOTAL_MACROS, COPY_SUFFIX, DEFAULT_DELAY } from "@/constants/macros
|
|||
import notifications from "@/notifications";
|
||||
import { ConfirmDialog } from "@/components/ConfirmDialog";
|
||||
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||
import { useKeyboardLayout } from "@/hooks/useKeyboardLayout";
|
||||
import useKeyboardLayout from "@/hooks/useKeyboardLayout";
|
||||
|
||||
const normalizeSortOrders = (macros: KeySequence[]): KeySequence[] => {
|
||||
return macros.map((macro, index) => ({
|
||||
|
@ -35,7 +35,7 @@ export default function SettingsMacrosRoute() {
|
|||
const [actionLoadingId, setActionLoadingId] = useState<string | null>(null);
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||
const [macroToDelete, setMacroToDelete] = useState<KeySequence | null>(null);
|
||||
const { keyboard } = useKeyboardLayout();
|
||||
const { selectedKeyboard } = useKeyboardLayout();
|
||||
|
||||
const isMaxMacrosReached = useMemo(
|
||||
() => macros.length >= MAX_TOTAL_MACROS,
|
||||
|
@ -186,7 +186,7 @@ export default function SettingsMacrosRoute() {
|
|||
step.modifiers.map((modifier, idx) => (
|
||||
<Fragment key={`mod-${idx}`}>
|
||||
<span className="font-medium text-slate-600 dark:text-slate-200">
|
||||
{keyboard.modifierDisplayMap[modifier] || modifier}
|
||||
{selectedKeyboard.modifierDisplayMap[modifier] || modifier}
|
||||
</span>
|
||||
{idx < step.modifiers.length - 1 && (
|
||||
<span className="text-slate-400 dark:text-slate-600">
|
||||
|
@ -211,7 +211,7 @@ export default function SettingsMacrosRoute() {
|
|||
step.keys.map((key, idx) => (
|
||||
<Fragment key={`key-${idx}`}>
|
||||
<span className="font-medium text-blue-600 dark:text-blue-400">
|
||||
{keyboard.keyDisplayMap[key] || key}
|
||||
{selectedKeyboard.keyDisplayMap[key] || key}
|
||||
</span>
|
||||
{idx < step.keys.length - 1 && (
|
||||
<span className="text-slate-400 dark:text-slate-600">
|
||||
|
@ -298,8 +298,8 @@ export default function SettingsMacrosRoute() {
|
|||
actionLoadingId,
|
||||
handleDeleteMacro,
|
||||
handleMoveMacro,
|
||||
keyboard.modifierDisplayMap,
|
||||
keyboard.keyDisplayMap,
|
||||
selectedKeyboard.modifierDisplayMap,
|
||||
selectedKeyboard.keyDisplayMap,
|
||||
handleDuplicateMacro,
|
||||
navigate
|
||||
],
|
||||
|
|
|
@ -20,7 +20,6 @@ import { LinkButton } from "@/components/Button";
|
|||
import { FeatureFlag } from "@/components/FeatureFlag";
|
||||
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||
import { useUiStore } from "@/hooks/stores";
|
||||
import useKeyboard from "@/hooks/useKeyboard";
|
||||
|
||||
import { cx } from "../cva.config";
|
||||
|
||||
|
@ -28,7 +27,6 @@ import { cx } from "../cva.config";
|
|||
export default function SettingsRoute() {
|
||||
const location = useLocation();
|
||||
const { setDisableVideoFocusTrap } = useUiStore();
|
||||
const { resetKeyboardState } = useKeyboard();
|
||||
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||
const [showLeftGradient, setShowLeftGradient] = useState(false);
|
||||
const [showRightGradient, setShowRightGradient] = useState(false);
|
||||
|
@ -66,13 +64,12 @@ export default function SettingsRoute() {
|
|||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setDisableVideoFocusTrap(true);
|
||||
resetKeyboardState();
|
||||
}, 500);
|
||||
|
||||
return () => {
|
||||
setDisableVideoFocusTrap(false);
|
||||
};
|
||||
}, [resetKeyboardState, setDisableVideoFocusTrap]);
|
||||
}, [setDisableVideoFocusTrap]);
|
||||
|
||||
return (
|
||||
<div className="pointer-events-auto relative mx-auto max-w-4xl translate-x-0 transform text-left dark:text-white">
|
||||
|
|
Loading…
Reference in New Issue