Refactor the keyboardLayouts

Change  pasteModel.tsx to use the new structure and vastly clarified the way that keys are emitted.
Make each layout export just the KeyboardLayout object (which is a package of isoCode, name, and chars)
Made keyboardLayouts.ts export a function to select keyboard by `isoCode`, export the keyboards as label . value pairs (for a select list) and the list of keyboards.
Changed devices.$id.settings.keyboard.tsx use the exported keyboard option list.
This commit is contained in:
Marc Brooks 2025-05-21 18:49:00 -05:00
parent 77a91da2d4
commit 06bb4b80b6
No known key found for this signature in database
GPG Key ID: 583A6AF2D6AE1DC6
16 changed files with 182 additions and 117 deletions

View File

@ -10,11 +10,11 @@ import { SettingsPageHeader } from "@components/SettingsPageheader";
import { useJsonRpc } from "@/hooks/useJsonRpc"; import { useJsonRpc } from "@/hooks/useJsonRpc";
import { useHidStore, useRTCStore, useUiStore, useSettingsStore } from "@/hooks/stores"; import { useHidStore, useRTCStore, useUiStore, useSettingsStore } from "@/hooks/stores";
import { keys, modifiers } from "@/keyboardMappings"; import { keys, modifiers } from "@/keyboardMappings";
import { layouts, chars } from "@/keyboardLayouts"; import { KeyStroke, KeyboardLayout, selectedKeyboard } from "@/keyboardLayouts";
import notifications from "@/notifications"; import notifications from "@/notifications";
const hidKeyboardPayload = (keys: number[], modifier: number) => { const hidKeyboardPayload = (modifier: number, keys: number[]) => {
return { keys, modifier }; return { modifier, keys };
}; };
const modifierCode = (shift?: boolean, altRight?: boolean) => { const modifierCode = (shift?: boolean, altRight?: boolean) => {
@ -57,47 +57,53 @@ export default function PasteModal() {
setDisableVideoFocusTrap(false); setDisableVideoFocusTrap(false);
if (rpcDataChannel?.readyState !== "open" || !TextAreaRef.current) return; if (rpcDataChannel?.readyState !== "open" || !TextAreaRef.current) return;
if (!keyboardLayout) return; if (!keyboardLayout) return;
if (!chars[keyboardLayout]) return; const keyboard: KeyboardLayout = selectedKeyboard(keyboardLayout);
if (!keyboard) return;
const text = TextAreaRef.current.value; const text = TextAreaRef.current.value;
try { try {
for (const char of text) { for (const char of text) {
const { key, shift, altRight, deadKey, accentKey } = chars[keyboardLayout][char] const keyprops = keyboard.chars[char];
if (!keyprops) continue;
const { key, shift, altRight, deadKey, accentKey } = keyprops;
if (!key) continue; if (!key) continue;
const keyz = [ keys[key] ]; // if this is an accented character, we need to send that accent FIRST
const modz = [ modifierCode(shift, altRight) ]; if (accentKey) {
await sendKeystroke({modifier: modifierCode(accentKey.shift, accentKey.altRight), keys: [ keys[accentKey.key] ] })
}
if (deadKey) { // now send the actual key
keyz.push(keys["Space"]); await sendKeystroke({ modifier: modifierCode(shift, altRight), keys: [ keys[key] ]});
modz.push(noModifier);
}
if (accentKey) {
keyz.unshift(keys[accentKey.key])
modz.unshift(modifierCode(accentKey.shift, accentKey.altRight))
}
for (const [index, kei] of keyz.entries()) { // if what was requested was a dead key, we need to send an unmodified space to emit
await new Promise<void>((resolve, reject) => { // just the accent character
send( if (deadKey) {
"keyboardReport", await sendKeystroke({ modifier: noModifier, keys: [ keys["Space"] ] });
hidKeyboardPayload([kei], modz[index]), }
params => {
if ("error" in params) return reject(params.error); // now send a message with no keys down to "release" the keys
send("keyboardReport", hidKeyboardPayload([], 0), params => { await sendKeystroke({ modifier: 0, keys: [] });
if ("error" in params) return reject(params.error);
resolve();
});
},
);
});
}
} }
} catch (error) { } catch (error) {
console.error(error); console.error("Failed to paste text:", error);
notifications.error("Failed to paste text"); notifications.error("Failed to paste text");
} }
async function sendKeystroke(stroke: KeyStroke) {
await new Promise<void>((resolve, reject) => {
send(
"keyboardReport",
hidKeyboardPayload(stroke.modifier, stroke.keys),
params => {
if ("error" in params) return reject(params.error);
resolve();
}
);
});
}
}, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode, keyboardLayout]); }, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode, keyboardLayout]);
useEffect(() => { useEffect(() => {
@ -148,7 +154,7 @@ export default function PasteModal() {
// @ts-expect-error TS doesn't recognize Intl.Segmenter in some environments // @ts-expect-error TS doesn't recognize Intl.Segmenter in some environments
[...new Intl.Segmenter().segment(value)] [...new Intl.Segmenter().segment(value)]
.map(x => x.segment) .map(x => x.segment)
.filter(char => !chars[keyboardLayout][char]), .filter(char => !selectedKeyboard(keyboardLayout).chars[char]),
), ),
]; ];
@ -167,11 +173,11 @@ export default function PasteModal() {
)} )}
</div> </div>
</div> </div>
<div className="space-y-4"> <div className="space-y-4">
<p className="text-xs text-slate-600 dark:text-slate-400"> <p className="text-xs text-slate-600 dark:text-slate-400">
Sending text using keyboard layout: {layouts[keyboardLayout]} Sending text using keyboard layout: {selectedKeyboard(keyboardLayout).name}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -884,5 +884,5 @@ export const useMacrosStore = create<MacrosState>((set, get) => ({
} finally { } finally {
set({ loading: false }); set({ loading: false });
} }
}, }
})); }));

View File

@ -1,45 +1,31 @@
import { chars as chars_fr_BE, name as name_fr_BE } from "@/keyboardLayouts/fr_BE" export interface KeyStroke { modifier: number; keys: number[]; }
import { chars as chars_cs_CZ, name as name_cs_CZ } from "@/keyboardLayouts/cs_CZ" export interface KeyInfo { key: string | number; shift?: boolean, altRight?: boolean }
import { chars as chars_en_UK, name as name_en_UK } from "@/keyboardLayouts/en_UK" export interface KeyCombo extends KeyInfo { deadKey?: boolean, accentKey?: KeyInfo }
import { chars as chars_en_US, name as name_en_US } from "@/keyboardLayouts/en_US" export interface KeyboardLayout { isoCode: string, name: string, chars: Record<string, KeyCombo> }
import { chars as chars_fr_FR, name as name_fr_FR } from "@/keyboardLayouts/fr_FR"
import { chars as chars_de_DE, name as name_de_DE } from "@/keyboardLayouts/de_DE"
import { chars as chars_it_IT, name as name_it_IT } from "@/keyboardLayouts/it_IT"
import { chars as chars_nb_NO, name as name_nb_NO } from "@/keyboardLayouts/nb_NO"
import { chars as chars_es_ES, name as name_es_ES } from "@/keyboardLayouts/es_ES"
import { chars as chars_sv_SE, name as name_sv_SE } from "@/keyboardLayouts/sv_SE"
import { chars as chars_fr_CH, name as name_fr_CH } from "@/keyboardLayouts/fr_CH"
import { chars as chars_de_CH, name as name_de_CH } from "@/keyboardLayouts/de_CH"
type KeyInfo = { key: string | number; shift?: boolean, altRight?: boolean } // to add a new layout, create a file like the above and add it to the list
export type KeyCombo = KeyInfo & { deadKey?: boolean, accentKey?: KeyInfo } import { cs_CZ } from "@/keyboardLayouts/cs_CZ"
import { de_CH } from "@/keyboardLayouts/de_CH"
import { de_DE } from "@/keyboardLayouts/de_DE"
import { en_US } from "@/keyboardLayouts/en_US"
import { en_UK } from "@/keyboardLayouts/en_UK"
import { es_ES } from "@/keyboardLayouts/es_ES"
import { fr_BE } from "@/keyboardLayouts/fr_BE"
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 { sv_SE } from "@/keyboardLayouts/sv_SE"
export const layouts: Record<string, string> = { 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 ];
be_FR: name_fr_BE,
cs_CZ: name_cs_CZ,
en_UK: name_en_UK,
en_US: name_en_US,
fr_FR: name_fr_FR,
de_DE: name_de_DE,
it_IT: name_it_IT,
nb_NO: name_nb_NO,
es_ES: name_es_ES,
sv_SE: name_sv_SE,
fr_CH: name_fr_CH,
de_CH: name_de_CH,
}
export const chars: Record<string, Record<string, KeyCombo>> = { export const selectedKeyboard = (isoCode: string): KeyboardLayout => {
be_FR: chars_fr_BE, // fallback to original behaviour of en-US if no isoCode given
cs_CZ: chars_cs_CZ, return keyboards.find(keyboard => keyboard.isoCode == (isoCode ?? "en-US"))!;
en_UK: chars_en_UK,
en_US: chars_en_US,
fr_FR: chars_fr_FR,
de_DE: chars_de_DE,
it_IT: chars_it_IT,
nb_NO: chars_nb_NO,
es_ES: chars_es_ES,
sv_SE: chars_sv_SE,
fr_CH: chars_fr_CH,
de_CH: chars_de_CH,
}; };
export const keyboardOptions = () => {
return keyboards.map((keyboard) => {
return { label: keyboard.name, value: keyboard.isoCode }
});
}

View File

@ -1,6 +1,6 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Čeština"; const name = "Čeština";
const keyTrema = { key: "Backslash" } // tréma (umlaut), two dots placed above a vowel const keyTrema = { key: "Backslash" } // tréma (umlaut), two dots placed above a vowel
const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter
@ -13,7 +13,7 @@ const keyOverdot = { key: "Digit8", shift: true, altRight: true } // overdot (do
const keyHook = { key: "Digit6", shift: true, altRight: true } // ogonoek (little hook), mark ˛ placed beneath a letter const keyHook = { key: "Digit6", shift: true, altRight: true } // ogonoek (little hook), mark ˛ placed beneath a letter
const keyCedille = { key: "Equal", shift: true, altRight: true } // accent cedille (cedilla), mark ¸ placed beneath a letter const keyCedille = { key: "Equal", shift: true, altRight: true } // accent cedille (cedilla), mark ¸ placed beneath a letter
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema }, "Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
"Á": { key: "KeyA", shift: true, accentKey: keyAcute }, "Á": { key: "KeyA", shift: true, accentKey: keyAcute },
@ -242,3 +242,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const cs_CZ: KeyboardLayout = {
isoCode: "cs-CZ",
name: name,
chars: chars
};

View File

@ -1,6 +1,6 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Schwiizerdütsch"; const name = "Schwiizerdütsch";
const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel
const keyAcute = { key: "Minus", altRight: true } // accent aigu (acute accent), mark ´ placed above the letter const keyAcute = { key: "Minus", altRight: true } // accent aigu (acute accent), mark ´ placed above the letter
@ -8,7 +8,7 @@ const keyHat = { key: "Equal" } // accent circonflexe (accent hat), mark ^ place
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
const keyTilde = { key: "Equal", altRight: true } // tilde, mark ~ placed above the letter const keyTilde = { key: "Equal", altRight: true } // tilde, mark ~ placed above the letter
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema }, "Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
"Á": { key: "KeyA", shift: true, accentKey: keyAcute }, "Á": { key: "KeyA", shift: true, accentKey: keyAcute },
@ -163,3 +163,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const de_CH: KeyboardLayout = {
isoCode: "de-CH",
name: name,
chars: chars
};

View File

@ -1,12 +1,12 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Deutsch"; const name = "Deutsch";
const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter
const keyHat = { key: "Backquote" } // accent circonflexe (accent hat), mark ^ placed above the letter const keyHat = { key: "Backquote" } // accent circonflexe (accent hat), mark ^ placed above the letter
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
"Á": { key: "KeyA", shift: true, accentKey: keyAcute }, "Á": { key: "KeyA", shift: true, accentKey: keyAcute },
"Â": { key: "KeyA", shift: true, accentKey: keyHat }, "Â": { key: "KeyA", shift: true, accentKey: keyHat },
@ -150,3 +150,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const de_DE: KeyboardLayout = {
isoCode: "de-DE",
name: name,
chars: chars
};

View File

@ -1,8 +1,8 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "English (UK)"; const name = "English (UK)";
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
B: { key: "KeyB", shift: true }, B: { key: "KeyB", shift: true },
C: { key: "KeyC", shift: true }, C: { key: "KeyC", shift: true },
@ -105,3 +105,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo> } as Record<string, KeyCombo>
export const en_UK: KeyboardLayout = {
isoCode: "en-UK",
name: name,
chars: chars
};

View File

@ -1,8 +1,8 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "English (US)"; const name = "English (US)";
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
B: { key: "KeyB", shift: true }, B: { key: "KeyB", shift: true },
C: { key: "KeyC", shift: true }, C: { key: "KeyC", shift: true },
@ -111,3 +111,9 @@ export const chars = {
Insert: { key: "Insert", shift: false }, Insert: { key: "Insert", shift: false },
Delete: { key: "Delete", shift: false }, Delete: { key: "Delete", shift: false },
} as Record<string, KeyCombo> } as Record<string, KeyCombo>
export const en_US: KeyboardLayout = {
isoCode: "en-US",
name: name,
chars: chars
};

View File

@ -1,6 +1,6 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Español"; const name = "Español";
const keyTrema = { key: "Quote", shift: true } // tréma (umlaut), two dots placed above a vowel const keyTrema = { key: "Quote", shift: true } // tréma (umlaut), two dots placed above a vowel
const keyAcute = { key: "Quote" } // accent aigu (acute accent), mark ´ placed above the letter const keyAcute = { key: "Quote" } // accent aigu (acute accent), mark ´ placed above the letter
@ -8,7 +8,7 @@ const keyHat = { key: "BracketRight", shift: true } // accent circonflexe (accen
const keyGrave = { key: "BracketRight" } // accent grave, mark ` placed above the letter const keyGrave = { key: "BracketRight" } // accent grave, mark ` placed above the letter
const keyTilde = { key: "Key4", altRight: true } // tilde, mark ~ placed above the letter const keyTilde = { key: "Key4", altRight: true } // tilde, mark ~ placed above the letter
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema }, "Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
"Á": { key: "KeyA", shift: true, accentKey: keyAcute }, "Á": { key: "KeyA", shift: true, accentKey: keyAcute },
@ -166,3 +166,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const es_ES: KeyboardLayout = {
isoCode: "es-ES",
name: name,
chars: chars
};

View File

@ -1,6 +1,6 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Belgisch Nederlands"; const name = "Belgisch Nederlands";
const keyTrema = { key: "BracketLeft", shift: true } // tréma (umlaut), two dots placed above a vowel const keyTrema = { key: "BracketLeft", shift: true } // tréma (umlaut), two dots placed above a vowel
const keyHat = { key: "BracketLeft" } // accent circonflexe (accent hat), mark ^ placed above the letter const keyHat = { key: "BracketLeft" } // accent circonflexe (accent hat), mark ^ placed above the letter
@ -8,7 +8,7 @@ const keyAcute = { key: "Semicolon", altRight: true } // accent aigu (acute acce
const keyGrave = { key: "Quote", shift: true } // accent grave, mark ` placed above the letter const keyGrave = { key: "Quote", shift: true } // accent grave, mark ` placed above the letter
const keyTilde = { key: "Slash", altRight: true } // tilde, mark ~ placed above the letter const keyTilde = { key: "Slash", altRight: true } // tilde, mark ~ placed above the letter
export const chars = { const chars = {
A: { key: "KeyQ", shift: true }, A: { key: "KeyQ", shift: true },
"Ä": { key: "KeyQ", shift: true, accentKey: keyTrema }, "Ä": { key: "KeyQ", shift: true, accentKey: keyTrema },
"Â": { key: "KeyQ", shift: true, accentKey: keyHat }, "Â": { key: "KeyQ", shift: true, accentKey: keyHat },
@ -165,3 +165,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const fr_BE: KeyboardLayout = {
isoCode: "fr-BE",
name: name,
chars: chars
};

View File

@ -1,10 +1,11 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
import { chars as chars_de_CH } from "./de_CH"
export const name = "Français de Suisse"; import { de_CH } from "./de_CH"
export const chars = { const name = "Français de Suisse";
...chars_de_CH,
const chars = {
...de_CH.chars,
"è": { key: "BracketLeft" }, "è": { key: "BracketLeft" },
"ü": { key: "BracketLeft", shift: true }, "ü": { key: "BracketLeft", shift: true },
"é": { key: "Semicolon" }, "é": { key: "Semicolon" },
@ -12,3 +13,9 @@ export const chars = {
"à": { key: "Quote" }, "à": { key: "Quote" },
"ä": { key: "Quote", shift: true }, "ä": { key: "Quote", shift: true },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const fr_CH: KeyboardLayout = {
isoCode: "fr-CH",
name: name,
chars: chars
};

View File

@ -1,11 +1,11 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Français"; const name = "Français";
const keyTrema = { key: "BracketLeft", shift: true } // tréma (umlaut), two dots placed above a vowel const keyTrema = { key: "BracketLeft", shift: true } // tréma (umlaut), two dots placed above a vowel
const keyHat = { key: "BracketLeft" } // accent circonflexe (accent hat), mark ^ placed above the letter const keyHat = { key: "BracketLeft" } // accent circonflexe (accent hat), mark ^ placed above the letter
export const chars = { const chars = {
A: { key: "KeyQ", shift: true }, A: { key: "KeyQ", shift: true },
"Ä": { key: "KeyQ", shift: true, accentKey: keyTrema }, "Ä": { key: "KeyQ", shift: true, accentKey: keyTrema },
"Â": { key: "KeyQ", shift: true, accentKey: keyHat }, "Â": { key: "KeyQ", shift: true, accentKey: keyHat },
@ -137,3 +137,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const fr_FR: KeyboardLayout = {
isoCode: "fr-FR",
name: name,
chars: chars
};

View File

@ -1,8 +1,8 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Italiano"; const name = "Italiano";
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
B: { key: "KeyB", shift: true }, B: { key: "KeyB", shift: true },
C: { key: "KeyC", shift: true }, C: { key: "KeyC", shift: true },
@ -111,3 +111,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const it_IT: KeyboardLayout = {
isoCode: "it-IT",
name: name,
chars: chars
};

View File

@ -1,6 +1,6 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Norsk bokmål"; const name = "Norsk bokmål";
const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel
const keyAcute = { key: "Equal", altRight: true } // accent aigu (acute accent), mark ´ placed above the letter const keyAcute = { key: "Equal", altRight: true } // accent aigu (acute accent), mark ´ placed above the letter
@ -8,7 +8,7 @@ const keyHat = { key: "BracketRight", shift: true } // accent circonflexe (accen
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
const keyTilde = { key: "BracketRight", altRight: true } // tilde, mark ~ placed above the letter const keyTilde = { key: "BracketRight", altRight: true } // tilde, mark ~ placed above the letter
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
"Ä": { key: "KeyA", shift: true, accentKey: keyTrema }, "Ä": { key: "KeyA", shift: true, accentKey: keyTrema },
"Á": { key: "KeyA", shift: true, accentKey: keyAcute }, "Á": { key: "KeyA", shift: true, accentKey: keyAcute },
@ -165,3 +165,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const nb_NO: KeyboardLayout = {
isoCode: "nb-NO",
name: name,
chars: chars
};

View File

@ -1,6 +1,6 @@
import { KeyCombo } from "../keyboardLayouts" import { KeyboardLayout, KeyCombo } from "../keyboardLayouts"
export const name = "Svenska"; const name = "Svenska";
const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel const keyTrema = { key: "BracketRight" } // tréma (umlaut), two dots placed above a vowel
const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter const keyAcute = { key: "Equal" } // accent aigu (acute accent), mark ´ placed above the letter
@ -8,7 +8,7 @@ const keyHat = { key: "BracketRight", shift: true } // accent circonflexe (accen
const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter const keyGrave = { key: "Equal", shift: true } // accent grave, mark ` placed above the letter
const keyTilde = { key: "BracketRight", altRight: true } // tilde, mark ~ placed above the letter const keyTilde = { key: "BracketRight", altRight: true } // tilde, mark ~ placed above the letter
export const chars = { const chars = {
A: { key: "KeyA", shift: true }, A: { key: "KeyA", shift: true },
"Á": { key: "KeyA", shift: true, accentKey: keyAcute }, "Á": { key: "KeyA", shift: true, accentKey: keyAcute },
"Â": { key: "KeyA", shift: true, accentKey: keyHat }, "Â": { key: "KeyA", shift: true, accentKey: keyHat },
@ -162,3 +162,9 @@ export const chars = {
Enter: { key: "Enter" }, Enter: { key: "Enter" },
Tab: { key: "Tab" }, Tab: { key: "Tab" },
} as Record<string, KeyCombo>; } as Record<string, KeyCombo>;
export const sv_SE: KeyboardLayout = {
isoCode: "sv-SE",
name: name,
chars: chars
};

View File

@ -4,7 +4,7 @@ import { useSettingsStore } from "@/hooks/stores";
import { useJsonRpc } from "@/hooks/useJsonRpc"; import { useJsonRpc } from "@/hooks/useJsonRpc";
import notifications from "@/notifications"; import notifications from "@/notifications";
import { SettingsPageHeader } from "@components/SettingsPageheader"; import { SettingsPageHeader } from "@components/SettingsPageheader";
import { layouts } from "@/keyboardLayouts"; import { keyboardOptions } from "@/keyboardLayouts";
import { SelectMenuBasic } from "../components/SelectMenuBasic"; import { SelectMenuBasic } from "../components/SelectMenuBasic";
@ -16,7 +16,7 @@ export default function SettingsKeyboardRoute() {
state => state.setKeyboardLayout, state => state.setKeyboardLayout,
); );
const layoutOptions = Object.entries(layouts).map(([code, language]) => { return { value: code, label: language } }) const layoutOptions = keyboardOptions();
const [send] = useJsonRpc(); const [send] = useJsonRpc();