mirror of https://github.com/jetkvm/kvm.git
				
				
				
			Move keyboardmapping store to stores.ts, simplified some things, updated settings.tsx to set the keyboard layout properly.
This commit is contained in:
		
							parent
							
								
									0e855adc35
								
							
						
					
					
						commit
						7c40e2e011
					
				| 
						 | 
					@ -5,18 +5,18 @@ import {
 | 
				
			||||||
  useRTCStore,
 | 
					  useRTCStore,
 | 
				
			||||||
  useSettingsStore,
 | 
					  useSettingsStore,
 | 
				
			||||||
  useVideoStore,
 | 
					  useVideoStore,
 | 
				
			||||||
 | 
					  useKeyboardMappingsStore,
 | 
				
			||||||
} from "@/hooks/stores";
 | 
					} from "@/hooks/stores";
 | 
				
			||||||
import { useEffect, useState } from "react";
 | 
					import { useEffect, useState } from "react";
 | 
				
			||||||
import { keyboardMappingsStore } from "@/keyboardMappings/KeyboardMappingStore";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function InfoBar() {
 | 
					export default function InfoBar() {
 | 
				
			||||||
  const [keys, setKeys] = useState(keyboardMappingsStore.keys);
 | 
					  const [keys, setKeys] = useState(useKeyboardMappingsStore.keys);
 | 
				
			||||||
  const [modifiers, setModifiers] = useState(keyboardMappingsStore.modifiers);
 | 
					  const [modifiers, setModifiers] = useState(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    const unsubscribeKeyboardStore = keyboardMappingsStore.subscribe(() => {
 | 
					    const unsubscribeKeyboardStore = useKeyboardMappingsStore.subscribe(() => {
 | 
				
			||||||
      setKeys(keyboardMappingsStore.keys); 
 | 
					      setKeys(useKeyboardMappingsStore.keys); 
 | 
				
			||||||
      setModifiers(keyboardMappingsStore.modifiers);
 | 
					      setModifiers(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
					    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
				
			||||||
  }, []); 
 | 
					  }, []); 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,11 +4,9 @@ import { Button } from "@components/Button";
 | 
				
			||||||
import Card from "@components/Card";
 | 
					import Card from "@components/Card";
 | 
				
			||||||
import { ChevronDownIcon } from "@heroicons/react/16/solid";
 | 
					import { ChevronDownIcon } from "@heroicons/react/16/solid";
 | 
				
			||||||
import "react-simple-keyboard/build/css/index.css";
 | 
					import "react-simple-keyboard/build/css/index.css";
 | 
				
			||||||
import { useHidStore, useUiStore } from "@/hooks/stores";
 | 
					import { useHidStore, useUiStore, useKeyboardMappingsStore } from "@/hooks/stores";
 | 
				
			||||||
import { Transition } from "@headlessui/react";
 | 
					import { Transition } from "@headlessui/react";
 | 
				
			||||||
import { cx } from "@/cva.config";
 | 
					import { cx } from "@/cva.config";
 | 
				
			||||||
//import { keys, modifiers } from "@/keyboardMappings/KeyboardMappingStore";
 | 
					 | 
				
			||||||
import { keyboardMappingsStore } from "@/keyboardMappings/KeyboardMappingStore";
 | 
					 | 
				
			||||||
import useKeyboard from "@/hooks/useKeyboard";
 | 
					import useKeyboard from "@/hooks/useKeyboard";
 | 
				
			||||||
import DetachIconRaw from "@/assets/detach-icon.svg";
 | 
					import DetachIconRaw from "@/assets/detach-icon.svg";
 | 
				
			||||||
import AttachIconRaw from "@/assets/attach-icon.svg";
 | 
					import AttachIconRaw from "@/assets/attach-icon.svg";
 | 
				
			||||||
| 
						 | 
					@ -22,13 +20,13 @@ const AttachIcon = ({ className }: { className?: string }) => {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function KeyboardWrapper() {
 | 
					function KeyboardWrapper() {
 | 
				
			||||||
  const [keys, setKeys] = useState(keyboardMappingsStore.keys);
 | 
					  const [keys, setKeys] = useState(useKeyboardMappingsStore.keys);
 | 
				
			||||||
  const [modifiers, setModifiers] = useState(keyboardMappingsStore.modifiers);
 | 
					  const [modifiers, setModifiers] = useState(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    const unsubscribeKeyboardStore = keyboardMappingsStore.subscribe(() => {
 | 
					    const unsubscribeKeyboardStore = useKeyboardMappingsStore.subscribe(() => {
 | 
				
			||||||
      setKeys(keyboardMappingsStore.keys); 
 | 
					      setKeys(useKeyboardMappingsStore.keys); 
 | 
				
			||||||
      setModifiers(keyboardMappingsStore.modifiers);
 | 
					      setModifiers(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
					    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
				
			||||||
  }, []); 
 | 
					  }, []); 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,8 @@ import {
 | 
				
			||||||
  useSettingsStore,
 | 
					  useSettingsStore,
 | 
				
			||||||
  useUiStore,
 | 
					  useUiStore,
 | 
				
			||||||
  useVideoStore,
 | 
					  useVideoStore,
 | 
				
			||||||
 | 
					  useKeyboardMappingsStore,
 | 
				
			||||||
} from "@/hooks/stores";
 | 
					} from "@/hooks/stores";
 | 
				
			||||||
import { keyboardMappingsStore } from "@/keyboardMappings/KeyboardMappingStore";
 | 
					 | 
				
			||||||
import { useResizeObserver } from "@/hooks/useResizeObserver";
 | 
					import { useResizeObserver } from "@/hooks/useResizeObserver";
 | 
				
			||||||
import { cx } from "@/cva.config";
 | 
					import { cx } from "@/cva.config";
 | 
				
			||||||
import VirtualKeyboard from "@components/VirtualKeyboard";
 | 
					import VirtualKeyboard from "@components/VirtualKeyboard";
 | 
				
			||||||
| 
						 | 
					@ -18,13 +18,13 @@ import { useJsonRpc } from "@/hooks/useJsonRpc";
 | 
				
			||||||
import { ConnectionErrorOverlay, HDMIErrorOverlay, LoadingOverlay } from "./VideoOverlay";
 | 
					import { ConnectionErrorOverlay, HDMIErrorOverlay, LoadingOverlay } from "./VideoOverlay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function WebRTCVideo() {
 | 
					export default function WebRTCVideo() {
 | 
				
			||||||
  const [keys, setKeys] = useState(keyboardMappingsStore.keys);
 | 
					  const [keys, setKeys] = useState(useKeyboardMappingsStore.keys);
 | 
				
			||||||
  const [modifiers, setModifiers] = useState(keyboardMappingsStore.modifiers);
 | 
					  const [modifiers, setModifiers] = useState(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    const unsubscribeKeyboardStore = keyboardMappingsStore.subscribe(() => {
 | 
					    const unsubscribeKeyboardStore = useKeyboardMappingsStore.subscribe(() => {
 | 
				
			||||||
      setKeys(keyboardMappingsStore.keys); 
 | 
					      setKeys(useKeyboardMappingsStore.keys); 
 | 
				
			||||||
      setModifiers(keyboardMappingsStore.modifiers);
 | 
					      setModifiers(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
					    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
				
			||||||
  }, []); 
 | 
					  }, []); 
 | 
				
			||||||
| 
						 | 
					@ -218,12 +218,15 @@ export default function WebRTCVideo() {
 | 
				
			||||||
      const prev = useHidStore.getState();
 | 
					      const prev = useHidStore.getState();
 | 
				
			||||||
      let code = e.code;
 | 
					      let code = e.code;
 | 
				
			||||||
      const key = e.key;
 | 
					      const key = e.key;
 | 
				
			||||||
 | 
					      console.log(e);
 | 
				
			||||||
 | 
					      console.log(key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // if (document.activeElement?.id !== "videoFocusTrap") {
 | 
					      // if (document.activeElement?.id !== "videoFocusTrap") {hH
 | 
				
			||||||
      //   console.log("KEYUP: Not focusing on the video", document.activeElement);
 | 
					      //   console.log("KEYUP: Not focusing on the video", document.activeElement);
 | 
				
			||||||
      //   return;
 | 
					      //   return;
 | 
				
			||||||
      // }
 | 
					      // }
 | 
				
			||||||
      console.log(document.activeElement);
 | 
					      //
 | 
				
			||||||
 | 
					      // console.log(document.activeElement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      setIsNumLockActive(e.getModifierState("NumLock"));
 | 
					      setIsNumLockActive(e.getModifierState("NumLock"));
 | 
				
			||||||
      setIsCapsLockActive(e.getModifierState("CapsLock"));
 | 
					      setIsCapsLockActive(e.getModifierState("CapsLock"));
 | 
				
			||||||
| 
						 | 
					@ -289,6 +292,7 @@ export default function WebRTCVideo() {
 | 
				
			||||||
        prev.activeModifiers.filter(k => k !== modifiers[e.code]),
 | 
					        prev.activeModifiers.filter(k => k !== modifiers[e.code]),
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      console.log(e.key);
 | 
				
			||||||
      sendKeyboardEvent([...new Set(newKeys)], [...new Set(newModifiers)]);
 | 
					      sendKeyboardEvent([...new Set(newKeys)], [...new Set(newModifiers)]);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,28 +3,27 @@ import { GridCard } from "@components/Card";
 | 
				
			||||||
import { TextAreaWithLabel } from "@components/TextArea";
 | 
					import { TextAreaWithLabel } from "@components/TextArea";
 | 
				
			||||||
import { SectionHeader } from "@components/SectionHeader";
 | 
					import { SectionHeader } from "@components/SectionHeader";
 | 
				
			||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
 | 
					import { useJsonRpc } from "@/hooks/useJsonRpc";
 | 
				
			||||||
import { useHidStore, useRTCStore, useUiStore } from "@/hooks/stores";
 | 
					import { useHidStore, useRTCStore, useUiStore, useKeyboardMappingsStore } from "@/hooks/stores";
 | 
				
			||||||
import notifications from "../../notifications";
 | 
					import notifications from "../../notifications";
 | 
				
			||||||
import { useCallback, useEffect, useRef, useState } from "react";
 | 
					import { useCallback, useEffect, useRef, useState } from "react";
 | 
				
			||||||
import { LuCornerDownLeft } from "react-icons/lu";
 | 
					import { LuCornerDownLeft } from "react-icons/lu";
 | 
				
			||||||
import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
 | 
					import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
 | 
				
			||||||
import { useClose } from "@headlessui/react";
 | 
					import { useClose } from "@headlessui/react";
 | 
				
			||||||
import { keyboardMappingsStore } from "@/keyboardMappings/KeyboardMappingStore";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const hidKeyboardPayload = (keys: number[], modifier: number) => {
 | 
					const hidKeyboardPayload = (keys: number[], modifier: number) => {
 | 
				
			||||||
  return { keys, modifier };
 | 
					  return { keys, modifier };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function PasteModal() {
 | 
					export default function PasteModal() {
 | 
				
			||||||
  const [keys, setKeys] = useState(keyboardMappingsStore.keys);
 | 
					  const [keys, setKeys] = useState(useKeyboardMappingsStore.keys);
 | 
				
			||||||
  const [chars, setChars] = useState(keyboardMappingsStore.chars);
 | 
					  const [chars, setChars] = useState(useKeyboardMappingsStore.chars);
 | 
				
			||||||
  const [modifiers, setModifiers] = useState(keyboardMappingsStore.modifiers);
 | 
					  const [modifiers, setModifiers] = useState(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    const unsubscribeKeyboardStore = keyboardMappingsStore.subscribe(() => {
 | 
					    const unsubscribeKeyboardStore = useKeyboardMappingsStore.subscribe(() => {
 | 
				
			||||||
      setKeys(keyboardMappingsStore.keys); 
 | 
					      setKeys(useKeyboardMappingsStore.keys); 
 | 
				
			||||||
      setChars(keyboardMappingsStore.chars);
 | 
					      setChars(useKeyboardMappingsStore.chars);
 | 
				
			||||||
      setModifiers(keyboardMappingsStore.modifiers);
 | 
					      setModifiers(useKeyboardMappingsStore.modifiers);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
					    return unsubscribeKeyboardStore; // Cleanup on unmount
 | 
				
			||||||
  }, []); 
 | 
					  }, []); 
 | 
				
			||||||
| 
						 | 
					@ -54,13 +53,14 @@ export default function PasteModal() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      for (const char of text) {
 | 
					      for (const char of text) {
 | 
				
			||||||
        const { key, shift, alt } = chars[char] ?? {};
 | 
					        const { key, shift, altLeft, altRight } = chars[char] ?? {};
 | 
				
			||||||
        if (!key) continue;
 | 
					        if (!key) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Build the modifier bitmask
 | 
					        // Build the modifier bitmask
 | 
				
			||||||
        const modifier =
 | 
					        const modifier =
 | 
				
			||||||
        (shift ? modifiers["ShiftLeft"] : 0) |
 | 
					        (shift ? modifiers["ShiftLeft"] : 0) |
 | 
				
			||||||
        (alt ? modifiers["AltLeft"] : 0);
 | 
					        (altLeft ? modifiers["AltLeft"] : 0) |
 | 
				
			||||||
 | 
					        (altRight ? modifiers["AltRight"] : 0); // This is important for a lot of keyboard layouts, right and left alt have different functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await new Promise<void>((resolve, reject) => {
 | 
					        await new Promise<void>((resolve, reject) => {
 | 
				
			||||||
          send(
 | 
					          send(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ import {
 | 
				
			||||||
  useSettingsStore,
 | 
					  useSettingsStore,
 | 
				
			||||||
  useUiStore,
 | 
					  useUiStore,
 | 
				
			||||||
  useUpdateStore,
 | 
					  useUpdateStore,
 | 
				
			||||||
 | 
					  useKeyboardMappingsStore,
 | 
				
			||||||
} from "@/hooks/stores";
 | 
					} from "@/hooks/stores";
 | 
				
			||||||
import { Checkbox } from "@components/Checkbox";
 | 
					import { Checkbox } from "@components/Checkbox";
 | 
				
			||||||
import { Button, LinkButton } from "@components/Button";
 | 
					import { Button, LinkButton } from "@components/Button";
 | 
				
			||||||
| 
						 | 
					@ -25,8 +26,6 @@ import LocalAuthPasswordDialog from "@/components/LocalAuthPasswordDialog";
 | 
				
			||||||
import { LocalDevice } from "@routes/devices.$id";
 | 
					import { LocalDevice } from "@routes/devices.$id";
 | 
				
			||||||
import { useRevalidator } from "react-router-dom";
 | 
					import { useRevalidator } from "react-router-dom";
 | 
				
			||||||
import { ShieldCheckIcon } from "@heroicons/react/20/solid";
 | 
					import { ShieldCheckIcon } from "@heroicons/react/20/solid";
 | 
				
			||||||
import { keyboardMappingsStore } from "@/keyboardMappings/KeyboardMappingStore";
 | 
					 | 
				
			||||||
import { KeyboardLayout } from "@/keyboardMappings/KeyboardLayouts";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function SettingsItem({
 | 
					export function SettingsItem({
 | 
				
			||||||
  title,
 | 
					  title,
 | 
				
			||||||
| 
						 | 
					@ -157,8 +156,7 @@ export default function SettingsSidebar() {
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      // TODO set this to update to the actual layout chosen
 | 
					      useKeyboardMappingsStore.setLayout(keyboardLayout)
 | 
				
			||||||
      keyboardMappingsStore.setLayout(KeyboardLayout.UKApple)
 | 
					 | 
				
			||||||
      setKeyboardLayout(keyboardLayout);
 | 
					      setKeyboardLayout(keyboardLayout);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
| 
						 | 
					@ -294,6 +292,7 @@ export default function SettingsSidebar() {
 | 
				
			||||||
    send("getKeyboardLayout", {}, resp => {
 | 
					    send("getKeyboardLayout", {}, resp => {
 | 
				
			||||||
      if ("error" in resp) return;
 | 
					      if ("error" in resp) return;
 | 
				
			||||||
      setKeyboardLayout(String(resp.result));
 | 
					      setKeyboardLayout(String(resp.result));
 | 
				
			||||||
 | 
					      useKeyboardMappingsStore.setLayout(String(resp.result))
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    send("getStreamQualityFactor", {}, resp => {
 | 
					    send("getStreamQualityFactor", {}, resp => {
 | 
				
			||||||
| 
						 | 
					@ -545,7 +544,7 @@ export default function SettingsSidebar() {
 | 
				
			||||||
                size="SM"
 | 
					                size="SM"
 | 
				
			||||||
                label=""
 | 
					                label=""
 | 
				
			||||||
                // TODO figure out how to make this selector wider like the EDID one?
 | 
					                // TODO figure out how to make this selector wider like the EDID one?
 | 
				
			||||||
                //fullWidth
 | 
					                //fullWidthƒ
 | 
				
			||||||
                value={keyboardLayout}
 | 
					                value={keyboardLayout}
 | 
				
			||||||
                options={[
 | 
					                options={[
 | 
				
			||||||
                  { value: "uk", label: "GB" },
 | 
					                  { value: "uk", label: "GB" },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
import { create } from "zustand";
 | 
					import { create } from "zustand";
 | 
				
			||||||
import { createJSONStorage, persist } from "zustand/middleware";
 | 
					import { createJSONStorage, persist } from "zustand/middleware";
 | 
				
			||||||
 | 
					import { getKeyboardMappings } from "@/keyboardMappings/KeyboardLayouts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Utility function to append stats to a Map
 | 
					// Utility function to append stats to a Map
 | 
				
			||||||
const appendStatToMap = <T extends { timestamp: number }>(
 | 
					const appendStatToMap = <T extends { timestamp: number }>(
 | 
				
			||||||
| 
						 | 
					@ -528,3 +529,39 @@ export const useLocalAuthModalStore = create<LocalAuthModalState>(set => ({
 | 
				
			||||||
  setModalView: view => set({ modalView: view }),
 | 
					  setModalView: view => set({ modalView: view }),
 | 
				
			||||||
  setErrorMessage: message => set({ errorMessage: message }),
 | 
					  setErrorMessage: message => set({ errorMessage: message }),
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class KeyboardMappingsStore {
 | 
				
			||||||
 | 
					  private _layout: string = 'us';
 | 
				
			||||||
 | 
					  private _subscribers: (() => void)[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public keys = getKeyboardMappings(this._layout).keys;
 | 
				
			||||||
 | 
					  public chars = getKeyboardMappings(this._layout).chars;
 | 
				
			||||||
 | 
					  public modifiers = getKeyboardMappings(this._layout).modifiers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setLayout(newLayout: string) {
 | 
				
			||||||
 | 
					    if (this._layout === newLayout) return;
 | 
				
			||||||
 | 
					    this._layout = newLayout;
 | 
				
			||||||
 | 
					    const updatedMappings = getKeyboardMappings(newLayout);
 | 
				
			||||||
 | 
					    this.keys = updatedMappings.keys;
 | 
				
			||||||
 | 
					    this.chars = updatedMappings.chars;
 | 
				
			||||||
 | 
					    this.modifiers = updatedMappings.modifiers;
 | 
				
			||||||
 | 
					    this._notifySubscribers(); 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getLayout() {
 | 
				
			||||||
 | 
					    return this._layout;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  subscribe(callback: () => void) {
 | 
				
			||||||
 | 
					    this._subscribers.push(callback);
 | 
				
			||||||
 | 
					    return () => {
 | 
				
			||||||
 | 
					      this._subscribers = this._subscribers.filter(sub => sub !== callback); // Cleanup
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private _notifySubscribers() {
 | 
				
			||||||
 | 
					    this._subscribers.forEach(callback => callback());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useKeyboardMappingsStore = new KeyboardMappingsStore();
 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,15 @@
 | 
				
			||||||
import {keysUKApple, charsUKApple, modifiersUKApple } from './layouts/uk_apple';
 | 
					import {keysUKApple, charsUKApple, modifiersUKApple } from './layouts/uk_apple';
 | 
				
			||||||
import {keysUS, charsUS, modifiersUS } from './layouts/us';
 | 
					import {keysUS, charsUS, modifiersUS } from './layouts/us';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum KeyboardLayout {
 | 
					export function getKeyboardMappings(layout: string) {
 | 
				
			||||||
    US = "us",
 | 
					  switch (layout) {
 | 
				
			||||||
    UKApple = "uk_apple",
 | 
					    case "uk_apple":
 | 
				
			||||||
  }
 | 
					      return {
 | 
				
			||||||
 | 
					        keys: keysUKApple,
 | 
				
			||||||
export function getKeyboardMappings(layout: KeyboardLayout) {
 | 
					        chars: charsUKApple,
 | 
				
			||||||
    switch (layout) {
 | 
					        modifiers: modifiersUKApple,
 | 
				
			||||||
      case KeyboardLayout.UKApple:
 | 
					      };
 | 
				
			||||||
        return {
 | 
					    case "us":
 | 
				
			||||||
          keys: keysUKApple,
 | 
					 | 
				
			||||||
          chars: charsUKApple,
 | 
					 | 
				
			||||||
          modifiers: modifiersUKApple,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
      case KeyboardLayout.US:
 | 
					 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
          keys: keysUS,
 | 
					          keys: keysUS,
 | 
				
			||||||
| 
						 | 
					@ -22,4 +17,4 @@ export function getKeyboardMappings(layout: KeyboardLayout) {
 | 
				
			||||||
          modifiers: modifiersUS,
 | 
					          modifiers: modifiersUS,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,39 +0,0 @@
 | 
				
			||||||
import { getKeyboardMappings, KeyboardLayout } from "@/keyboardMappings/KeyboardLayouts";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO Move this in with all the other stores?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class KeyboardMappingsStore {
 | 
					 | 
				
			||||||
  private _layout: KeyboardLayout = KeyboardLayout.US;
 | 
					 | 
				
			||||||
  private _subscribers: (() => void)[] = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public keys = getKeyboardMappings(this._layout).keys;
 | 
					 | 
				
			||||||
  public chars = getKeyboardMappings(this._layout).chars;
 | 
					 | 
				
			||||||
  public modifiers = getKeyboardMappings(this._layout).modifiers;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  setLayout(newLayout: KeyboardLayout) {
 | 
					 | 
				
			||||||
    if (this._layout === newLayout) return;
 | 
					 | 
				
			||||||
    this._layout = newLayout;
 | 
					 | 
				
			||||||
    const updatedMappings = getKeyboardMappings(newLayout);
 | 
					 | 
				
			||||||
    this.keys = updatedMappings.keys;
 | 
					 | 
				
			||||||
    this.chars = updatedMappings.chars;
 | 
					 | 
				
			||||||
    this.modifiers = updatedMappings.modifiers;
 | 
					 | 
				
			||||||
    this._notifySubscribers(); 
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getLayout() {
 | 
					 | 
				
			||||||
    return this._layout;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  subscribe(callback: () => void) {
 | 
					 | 
				
			||||||
    this._subscribers.push(callback);
 | 
					 | 
				
			||||||
    return () => {
 | 
					 | 
				
			||||||
      this._subscribers = this._subscribers.filter(sub => sub !== callback); // Cleanup
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private _notifySubscribers() {
 | 
					 | 
				
			||||||
    this._subscribers.forEach(callback => callback());
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const keyboardMappingsStore = new KeyboardMappingsStore();
 | 
					 | 
				
			||||||
| 
						 | 
					@ -12,11 +12,11 @@ export const charsUKApple = {
 | 
				
			||||||
    "~": { key: "Backquote", shift: true },
 | 
					    "~": { key: "Backquote", shift: true },
 | 
				
			||||||
    "\\" : { key: "Backslash", shift: false },
 | 
					    "\\" : { key: "Backslash", shift: false },
 | 
				
			||||||
    "|": { key: "Backslash", shift: true },
 | 
					    "|": { key: "Backslash", shift: true },
 | 
				
			||||||
    "#": { key: "Digit3", shift: false, alt: true },
 | 
					    "#": { key: "Digit3", shift: false, altLeft: true },
 | 
				
			||||||
    "£": { key: "Digit3", shift: true },
 | 
					    "£": { key: "Digit3", shift: true },
 | 
				
			||||||
    "@": { key: "Digit2", shift: true },
 | 
					    "@": { key: "Digit2", shift: true },
 | 
				
			||||||
    "\"": { key: "Quote", shift: true },
 | 
					    "\"": { key: "Quote", shift: true },
 | 
				
			||||||
} as Record<string, { key: string | number; shift: boolean; alt?: boolean; }>;
 | 
					} as Record<string, { key: string | number; shift: boolean; altLeft?: boolean; altRight?: boolean; }>;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
// Modifiers are typically the same between UK and US layouts
 | 
					// Modifiers are typically the same between UK and US layouts
 | 
				
			||||||
export const modifiersUKApple = {
 | 
					export const modifiersUKApple = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,7 +200,7 @@ export const charsUS = {
 | 
				
			||||||
    "\n": { key: "Enter", shift: false },
 | 
					    "\n": { key: "Enter", shift: false },
 | 
				
			||||||
    Enter: { key: "Enter", shift: false },
 | 
					    Enter: { key: "Enter", shift: false },
 | 
				
			||||||
    Tab: { key: "Tab", shift: false },
 | 
					    Tab: { key: "Tab", shift: false },
 | 
				
			||||||
} as Record<string, { key: string | number; shift: boolean; alt?: boolean; }>;
 | 
					} as Record<string, { key: string | number; shift: boolean; altLeft?: boolean; altRight?: boolean; }>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const modifiersUS = {
 | 
					export const modifiersUS = {
 | 
				
			||||||
    ControlLeft: 0x01,
 | 
					    ControlLeft: 0x01,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue