fix: hotkeys

fixes #20
This commit is contained in:
2024-04-06 19:00:14 +02:00
parent 3af65106bf
commit 4b738bb340
8 changed files with 66 additions and 52 deletions

10
package-lock.json generated
View File

@@ -34,7 +34,6 @@
"flexsearch": "^0.7.43", "flexsearch": "^0.7.43",
"fontkit": "^2.0.2", "fontkit": "^2.0.2",
"glob": "^10.3.12", "glob": "^10.3.12",
"hotkeys-js": "^3.13.7",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^3.2.5", "prettier": "^3.2.5",
@@ -6216,15 +6215,6 @@
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true "dev": true
}, },
"node_modules/hotkeys-js": {
"version": "3.13.7",
"resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.13.7.tgz",
"integrity": "sha512-ygFIdTqqwG4fFP7kkiYlvayZppeIQX2aPpirsngkv1xM1lP0piDY5QEh68nQnIKvz64hfocxhBaD/uK3sSK1yQ==",
"dev": true,
"funding": {
"url": "https://jaywcjlove.github.io/#/sponsor"
}
},
"node_modules/html-encoding-sniffer": { "node_modules/html-encoding-sniffer": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",

View File

@@ -55,7 +55,6 @@
"flexsearch": "^0.7.43", "flexsearch": "^0.7.43",
"fontkit": "^2.0.2", "fontkit": "^2.0.2",
"glob": "^10.3.12", "glob": "^10.3.12",
"hotkeys-js": "^3.13.7",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^3.2.5", "prettier": "^3.2.5",

View File

@@ -40,9 +40,7 @@
} }
function keyboardNavigation(event: KeyboardEvent) { function keyboardNavigation(event: KeyboardEvent) {
if (event.key === "Escape") { if (event.shiftKey && event.key === "Enter") {
dispatch("close");
} else if (event.shiftKey && event.key === "Enter") {
dispatch("select", exact); dispatch("select", exact);
} else if (event.key === "ArrowDown") { } else if (event.key === "ArrowDown") {
const element = const element =

View File

@@ -7,7 +7,7 @@
import type { VisualLayout } from "$lib/serialization/visual-layout"; import type { VisualLayout } from "$lib/serialization/visual-layout";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
$: device = $serialPort?.device ?? "ONE"; $: device = $serialPort?.device;
const activeLayer = getContext<Writable<number>>("active-layer"); const activeLayer = getContext<Writable<number>>("active-layer");
const layers = [ const layers = [
@@ -33,22 +33,24 @@
</script> </script>
<div class="container"> <div class="container">
{#await layouts[device]() then visualLayout} {#if device}
<fieldset transition:fade> {#await layouts[device]() then visualLayout}
{#each layers as [title, icon, value]} <fieldset transition:fade>
<button {#each layers as [title, icon, value]}
class="icon" <button
use:action={{ title, shortcut: `alt+${value + 1}` }} class="icon"
on:click={() => ($activeLayer = value)} use:action={{ title, shortcut: `alt+${value + 1}` }}
class:active={$activeLayer === value} on:click={() => ($activeLayer = value)}
> class:active={$activeLayer === value}
{icon} >
</button> {icon}
{/each} </button>
</fieldset> {/each}
</fieldset>
<GenericLayout {visualLayout} /> <GenericLayout {visualLayout} />
{/await} {/await}
{/if}
</div> </div>
<style lang="scss"> <style lang="scss">

View File

@@ -2,7 +2,8 @@ import type { Action } from "svelte/action";
import tippy from "tippy.js"; import tippy from "tippy.js";
import type { SvelteComponent } from "svelte"; import type { SvelteComponent } from "svelte";
import Tooltip from "$lib/components/Tooltip.svelte"; import Tooltip from "$lib/components/Tooltip.svelte";
import hotkeys from "hotkeys-js";
export const hotkeys = new Map<string, HTMLElement>();
export const action: Action<Element, { title?: string; shortcut?: string }> = ( export const action: Action<Element, { title?: string; shortcut?: string }> = (
node: Element, node: Element,
@@ -26,20 +27,15 @@ export const action: Action<Element, { title?: string; shortcut?: string }> = (
}); });
if (shortcut && node instanceof HTMLElement) { if (shortcut && node instanceof HTMLElement) {
hotkeys(shortcut, function (keyboardEvent) { hotkeys.set(shortcut, node);
keyboardEvent.preventDefault();
node.click();
});
} }
return { return {
update(updated) {
title = updated.title;
shortcut = updated.shortcut;
},
destroy() { destroy() {
tooltip.destroy(); tooltip.destroy();
hotkeys.unbind(shortcut); if (shortcut && node instanceof HTMLElement) {
hotkeys.delete(shortcut);
}
}, },
}; };
}; };

View File

@@ -25,10 +25,12 @@
import { detectLocale } from "../i18n/i18n-util"; import { detectLocale } from "../i18n/i18n-util";
import type { Locales } from "../i18n/i18n-types"; import type { Locales } from "../i18n/i18n-types";
import Footer from "./Footer.svelte"; import Footer from "./Footer.svelte";
import { runLayoutDetection } from "$lib/os-layout.js"; import { osLayout, runLayoutDetection } from "$lib/os-layout.js";
import PageTransition from "./PageTransition.svelte"; import PageTransition from "./PageTransition.svelte";
import { restoreFromFile } from "$lib/backup/backup"; import { restoreFromFile } from "$lib/backup/backup";
import { goto } from "$app/navigation"; import { goto } from "$app/navigation";
import { hotkeys } from "$lib/title";
import { KEYMAP_CODES, KEYMAP_KEYCODES } from "$lib/serial/keymap-codes";
const locale = const locale =
((browser && localStorage.getItem("locale")) as Locales) || detectLocale(); ((browser && localStorage.getItem("locale")) as Locales) || detectLocale();
@@ -79,6 +81,31 @@
}); });
let webManifestLink = ""; let webManifestLink = "";
function handleHotkey(event: KeyboardEvent) {
let key = $osLayout.get(event.code);
if (!key && event.code === "Escape") key = "esc";
if (!key && event.code === "ArrowLeft") key = "left";
if (!key && event.code === "ArrowRight") key = "right";
if (!key && event.code === "ArrowUp") key = "up";
if (!key && event.code === "ArrowDown") key = "down";
if (!key) return;
const str = [
event.ctrlKey ? "ctrl" : undefined,
event.shiftKey ? "shift" : undefined,
event.altKey ? "alt" : undefined,
key,
]
.filter((it) => !!it)
.join("+");
const node = hotkeys.get(str);
if (node) {
event.preventDefault();
node.click();
}
}
</script> </script>
<svelte:head> <svelte:head>
@@ -88,6 +115,8 @@
<meta name="theme-color" content={data.themeColor} /> <meta name="theme-color" content={data.themeColor} />
</svelte:head> </svelte:head>
<svelte:window on:keydown={handleHotkey} />
<Navigation /> <Navigation />
<!-- <PickChangesDialog /> --> <!-- <PickChangesDialog /> -->

View File

@@ -65,7 +65,7 @@
</div> </div>
<ul> <ul>
<li> <li>
<a href={import.meta.VITE_STORE_URL} rel="noreferrer" target="_blank" <a href={import.meta.env.VITE_STORE_URL} rel="noreferrer" target="_blank"
><span class="icon">shopping_bag</span> Store</a ><span class="icon">shopping_bag</span> Store</a
> >
</li> </li>

View File

@@ -156,9 +156,9 @@
</div> </div>
<section bind:this={results}> <section bind:this={results}>
<div class="results"> <!-- fixes some unresponsiveness -->
<!-- fixes some unresponsiveness --> {#await tick() then}
{#await tick() then} <div class="results">
<table transition:fly={{ y: 48, easing: expoOut }}> <table transition:fly={{ y: 48, easing: expoOut }}>
{#if $lastPage !== -1} {#if $lastPage !== -1}
{#if page === 0} {#if page === 0}
@@ -181,13 +181,13 @@
<caption>{$LL.configure.chords.search.NO_RESULTS()}</caption> <caption>{$LL.configure.chords.search.NO_RESULTS()}</caption>
{/if} {/if}
</table> </table>
{/await} </div>
</div> <textarea
<textarea placeholder={$LL.configure.chords.TRY_TYPING() +
placeholder={$LL.configure.chords.TRY_TYPING() + "\n\nDid you know? " +
"\n\nDid you know? " + randomTips[Math.floor(randomTips.length * Math.random())]}
randomTips[Math.floor(randomTips.length * Math.random())]} ></textarea>
></textarea> {/await}
</section> </section>
<style lang="scss"> <style lang="scss">