fix: action search

fix: can't browse actions after searching and clearing
fix: can't use esc to exit action search
fix: improve action search performance
This commit is contained in:
2024-04-06 18:04:13 +02:00
parent 5b6d369101
commit 2782966505

View File

@@ -1,7 +1,10 @@
<script lang="ts"> <script lang="ts">
import { KEYMAP_CATEGORIES, KEYMAP_CODES } from "$lib/serial/keymap-codes"; import {
import type { KeyInfo } from "$lib/serial/keymap-codes"; KEYMAP_CATEGORIES,
import flexsearch from "flexsearch"; KEYMAP_CODES,
KEYMAP_IDS,
} from "$lib/serial/keymap-codes";
import FlexSearch from "flexsearch";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import ActionListItem from "$lib/components/ActionListItem.svelte"; import ActionListItem from "$lib/components/ActionListItem.svelte";
import LL from "../../../i18n/i18n-svelte"; import LL from "../../../i18n/i18n-svelte";
@@ -10,24 +13,23 @@
export let currentAction: number | undefined = undefined; export let currentAction: number | undefined = undefined;
export let nextAction: number | undefined = undefined; export let nextAction: number | undefined = undefined;
const index = new flexsearch.Index({ tokenize: "full" }); const index = new FlexSearch.Index({ tokenize: "full" });
for (const action of Object.values(KEYMAP_CODES)) { createIndex();
index?.add(
action.code,
`${action.title || ""} ${action.variant || ""} ${action.category} ${action.id || ""} ${
action.description || ""
}`,
);
}
const exactIndex: Record<string, KeyInfo> = Object.fromEntries(
Object.values(KEYMAP_CODES)
.filter((it) => !!it.id)
.map((it) => [it.id, it] as const),
);
function search() { async function createIndex() {
results = index!.search(searchBox.value) as number[]; for (const [, action] of KEYMAP_CODES) {
exact = exactIndex[searchBox.value]?.code; await index?.addAsync(
action.code,
`${action.title || ""} ${action.variant || ""} ${action.category} ${action.id || ""} ${
action.description || ""
}`,
);
}
}
async function search() {
results = (await index!.searchAsync(searchBox.value)) as number[];
exact = KEYMAP_IDS.get(searchBox.value)?.code;
code = Number(searchBox.value); code = Number(searchBox.value);
} }
@@ -38,7 +40,9 @@
} }
function keyboardNavigation(event: KeyboardEvent) { function keyboardNavigation(event: KeyboardEvent) {
if (event.shiftKey && event.key === "Enter") { if (event.key === "Escape") {
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 =
@@ -61,7 +65,7 @@
event.preventDefault(); event.preventDefault();
} }
let results: number[] = Object.keys(KEYMAP_CODES).map(Number); let results: number[] = [];
let exact: number | undefined = undefined; let exact: number | undefined = undefined;
let code: number = Number.NaN; let code: number = Number.NaN;
@@ -144,9 +148,15 @@
<li>Action code is out of range</li> <li>Action code is out of range</li>
{/if} {/if}
{/if} {/if}
{#each filter ? results.filter( (it) => filter.has(it), ) : results as id (id)} {#if filter !== undefined || results.length > 0}
<li><ActionListItem {id} on:click={() => select(id)} /></li> {@const resultValue =
{/each} results.length === 0
? Array.from(KEYMAP_CODES, ([it]) => it)
: results}
{#each filter ? resultValue.filter( (it) => filter.has(it), ) : resultValue as id (id)}
<li><ActionListItem {id} on:click={() => select(id)} /></li>
{/each}
{/if}
</ul> </ul>
</div> </div>
</dialog> </dialog>