mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-01-22 01:42:47 +00:00
feat: improve responsiveness
This commit is contained in:
@@ -115,6 +115,7 @@ const de = {
|
|||||||
DUPLICATE: "Akkord existiert bereits",
|
DUPLICATE: "Akkord existiert bereits",
|
||||||
search: {
|
search: {
|
||||||
PLACEHOLDER: "{0} Akkord{{|e}} durchsuchen",
|
PLACEHOLDER: "{0} Akkord{{|e}} durchsuchen",
|
||||||
|
INDEXING: "{0} Akkord{{|e}} werden indiziert...",
|
||||||
NO_RESULTS: "Keine Ergebnisse",
|
NO_RESULTS: "Keine Ergebnisse",
|
||||||
},
|
},
|
||||||
conflict: {
|
conflict: {
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ const en = {
|
|||||||
DUPLICATE: "Chord already exists",
|
DUPLICATE: "Chord already exists",
|
||||||
search: {
|
search: {
|
||||||
PLACEHOLDER: "Search {0} chord{{|s}}",
|
PLACEHOLDER: "Search {0} chord{{|s}}",
|
||||||
|
INDEXING: "Indexing {0} chord{{|s}}...",
|
||||||
NO_RESULTS: "No results",
|
NO_RESULTS: "No results",
|
||||||
},
|
},
|
||||||
conflict: {
|
conflict: {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
import { getContext } from "svelte";
|
import { getContext } from "svelte";
|
||||||
import type { VisualLayoutConfig } from "./visual-layout.js";
|
import type { VisualLayoutConfig } from "./visual-layout.js";
|
||||||
import { changes, ChangeType, layout } from "$lib/undo-redo";
|
import { changes, ChangeType, layout } from "$lib/undo-redo";
|
||||||
|
import { fly } from "svelte/transition";
|
||||||
|
import { expoOut } from "svelte/easing";
|
||||||
|
|
||||||
const { scale, margin, strokeWidth, fontSize, iconFontSize } =
|
const { scale, margin, strokeWidth, fontSize, iconFontSize } =
|
||||||
getContext<VisualLayoutConfig>("visual-layout-config");
|
getContext<VisualLayoutConfig>("visual-layout-config");
|
||||||
@@ -194,6 +196,7 @@
|
|||||||
class="print"
|
class="print"
|
||||||
viewBox="0 0 {layoutInfo.size[0] * scale} {layoutInfo.size[1] * scale}"
|
viewBox="0 0 {layoutInfo.size[0] * scale} {layoutInfo.size[1] * scale}"
|
||||||
bind:this={groupParent}
|
bind:this={groupParent}
|
||||||
|
transition:fly={{ y: 48, easing: expoOut }}
|
||||||
>
|
>
|
||||||
{#each layoutInfo.keys as key, i}
|
{#each layoutInfo.keys as key, i}
|
||||||
<KeyboardKey
|
<KeyboardKey
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import { getContext } from "svelte";
|
import { getContext } from "svelte";
|
||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store";
|
||||||
import type { VisualLayout } from "$lib/serialization/visual-layout";
|
import type { VisualLayout } from "$lib/serialization/visual-layout";
|
||||||
|
import { fade } from "svelte/transition";
|
||||||
|
|
||||||
$: device = $serialPort?.device ?? "ONE";
|
$: device = $serialPort?.device ?? "ONE";
|
||||||
const activeLayer = getContext<Writable<number>>("active-layer");
|
const activeLayer = getContext<Writable<number>>("active-layer");
|
||||||
@@ -32,7 +33,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<fieldset>
|
{#await layouts[device]() then visualLayout}
|
||||||
|
<fieldset transition:fade>
|
||||||
{#each layers as [title, icon, value]}
|
{#each layers as [title, icon, value]}
|
||||||
<button
|
<button
|
||||||
class="icon"
|
class="icon"
|
||||||
@@ -45,7 +47,6 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
{#await layouts[device]() then visualLayout}
|
|
||||||
<GenericLayout {visualLayout} />
|
<GenericLayout {visualLayout} />
|
||||||
{/await}
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export async function initSerial(manual = false) {
|
|||||||
const device = get(serialPort) ?? new CharaDevice();
|
const device = get(serialPort) ?? new CharaDevice();
|
||||||
await device.init(manual);
|
await device.init(manual);
|
||||||
serialPort.set(device);
|
serialPort.set(device);
|
||||||
sync();
|
await sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sync() {
|
export async function sync() {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
const dark = it.mode === "dark"; // window.matchMedia("(prefers-color-scheme: dark)").matches
|
const dark = it.mode === "dark"; // window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
applyTheme(theme, { target: document.body, dark });
|
applyTheme(theme, { target: document.body, dark });
|
||||||
});
|
});
|
||||||
|
|
||||||
if (import.meta.env.TAURI_FAMILY === undefined) {
|
if (import.meta.env.TAURI_FAMILY === undefined) {
|
||||||
const { initPwa } = await import("./pwa-setup");
|
const { initPwa } = await import("./pwa-setup");
|
||||||
webManifestLink = await initPwa();
|
webManifestLink = await initPwa();
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
if (browser && $userPreferences.autoConnect && (await canAutoConnect())) {
|
if (browser && $userPreferences.autoConnect && (await canAutoConnect())) {
|
||||||
await initSerial();
|
await initSerial();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.importFile) {
|
if (data.importFile) {
|
||||||
restoreFromFile(data.importFile);
|
restoreFromFile(data.importFile);
|
||||||
const url = new URL(location.href);
|
const url = new URL(location.href);
|
||||||
|
|||||||
@@ -68,7 +68,6 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<SyncOverlay />
|
<SyncOverlay />
|
||||||
</div>
|
</div>
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
|
||||||
<ul>
|
<ul>
|
||||||
<li class="hide-forced-colors">
|
<li class="hide-forced-colors">
|
||||||
<input
|
<input
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { KEYMAP_CODES } from "$lib/serial/keymap-codes";
|
import { KEYMAP_CODES } from "$lib/serial/keymap-codes";
|
||||||
import flexsearch from "flexsearch";
|
import FlexSearch from "flexsearch";
|
||||||
import LL from "../../../i18n/i18n-svelte";
|
import LL from "../../../i18n/i18n-svelte";
|
||||||
import { action } from "$lib/title";
|
import { action } from "$lib/title";
|
||||||
import { onDestroy, onMount, setContext } from "svelte";
|
import { onDestroy, onMount, setContext } from "svelte";
|
||||||
@@ -8,8 +8,10 @@
|
|||||||
import type { ChordInfo } from "$lib/undo-redo";
|
import type { ChordInfo } from "$lib/undo-redo";
|
||||||
import { derived, writable } from "svelte/store";
|
import { derived, writable } from "svelte/store";
|
||||||
import ChordEdit from "./ChordEdit.svelte";
|
import ChordEdit from "./ChordEdit.svelte";
|
||||||
import { crossfade } from "svelte/transition";
|
import { crossfade, fly } from "svelte/transition";
|
||||||
import ChordActionEdit from "./ChordActionEdit.svelte";
|
import ChordActionEdit from "./ChordActionEdit.svelte";
|
||||||
|
import { browser } from "$app/environment";
|
||||||
|
import { expoOut } from "svelte/easing";
|
||||||
|
|
||||||
const resultSize = 38;
|
const resultSize = 38;
|
||||||
let results: HTMLElement;
|
let results: HTMLElement;
|
||||||
@@ -28,13 +30,15 @@
|
|||||||
resizeObserver?.disconnect();
|
resizeObserver?.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
$: searchIndex = $chords?.length > 0 ? buildIndex($chords) : undefined;
|
let searchIndex = derived(chords, (chords) => buildIndex(chords));
|
||||||
|
|
||||||
function buildIndex(chords: ChordInfo[]): flexsearch.Index {
|
async function buildIndex(chords: ChordInfo[]): Promise<FlexSearch.Index> {
|
||||||
const index = new flexsearch.Index({ tokenize: "full" });
|
const index = new FlexSearch.Index({ tokenize: "full" });
|
||||||
chords.forEach((chord, i) => {
|
if (chords.length === 0 || !browser) return index;
|
||||||
|
for (let i = 0; i < chords.length; i++) {
|
||||||
|
const chord = chords[i]!;
|
||||||
if ("phrase" in chord) {
|
if ("phrase" in chord) {
|
||||||
index.add(
|
await index.addAsync(
|
||||||
i,
|
i,
|
||||||
chord.phrase
|
chord.phrase
|
||||||
.map((it) => KEYMAP_CODES.get(it)?.id)
|
.map((it) => KEYMAP_CODES.get(it)?.id)
|
||||||
@@ -42,17 +46,17 @@
|
|||||||
.join(""),
|
.join(""),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchFilter = writable<number[] | undefined>(undefined);
|
const searchFilter = writable<number[] | undefined>(undefined);
|
||||||
|
|
||||||
function search(event: Event) {
|
async function search(index: FlexSearch.Index, event: Event) {
|
||||||
const query = (event.target as HTMLInputElement).value;
|
const query = (event.target as HTMLInputElement).value;
|
||||||
searchFilter.set(
|
searchFilter.set(
|
||||||
query && searchIndex
|
query && searchIndex
|
||||||
? (searchIndex.search(query) as number[])
|
? ((await index.searchAsync(query)) as number[])
|
||||||
: undefined,
|
: undefined,
|
||||||
);
|
);
|
||||||
page = 0;
|
page = 0;
|
||||||
@@ -97,11 +101,19 @@
|
|||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
|
{#await $searchIndex}
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
placeholder={$LL.configure.chords.search.INDEXING($chords.length)}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
{:then index}
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
placeholder={$LL.configure.chords.search.PLACEHOLDER($chords.length)}
|
placeholder={$LL.configure.chords.search.PLACEHOLDER($chords.length)}
|
||||||
on:input={search}
|
on:input={(event) => search(index, event)}
|
||||||
/>
|
/>
|
||||||
|
{/await}
|
||||||
<div class="paginator">
|
<div class="paginator">
|
||||||
{#if $lastPage !== -1}
|
{#if $lastPage !== -1}
|
||||||
{page + 1} / {$lastPage + 1}
|
{page + 1} / {$lastPage + 1}
|
||||||
@@ -122,7 +134,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section bind:this={results}>
|
<section bind:this={results}>
|
||||||
<table>
|
<div class="results">
|
||||||
|
{#await $searchIndex then}
|
||||||
|
<table transition:fly={{ y: 48, easing: expoOut }}>
|
||||||
|
{#if $lastPage !== -1}
|
||||||
{#if page === 0}
|
{#if page === 0}
|
||||||
<tr
|
<tr
|
||||||
><th class="new-chord"
|
><th class="new-chord"
|
||||||
@@ -132,7 +147,6 @@
|
|||||||
><td /><td /></tr
|
><td /><td /></tr
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $lastPage !== -1}
|
|
||||||
{#each $items.slice(page * $pageSize - (page === 0 ? 0 : 1), (page + 1) * $pageSize - 1) as [chord] (JSON.stringify(chord?.id))}
|
{#each $items.slice(page * $pageSize - (page === 0 ? 0 : 1), (page + 1) * $pageSize - 1) as [chord] (JSON.stringify(chord?.id))}
|
||||||
{#if chord}
|
{#if chord}
|
||||||
<tr>
|
<tr>
|
||||||
@@ -144,6 +158,8 @@
|
|||||||
<caption>{$LL.configure.chords.search.NO_RESULTS()}</caption>
|
<caption>{$LL.configure.chords.search.NO_RESULTS()}</caption>
|
||||||
{/if}
|
{/if}
|
||||||
</table>
|
</table>
|
||||||
|
{/await}
|
||||||
|
</div>
|
||||||
<textarea placeholder={$LL.configure.chords.TRY_TYPING()}></textarea>
|
<textarea placeholder={$LL.configure.chords.TRY_TYPING()}></textarea>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -187,8 +203,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
caption {
|
@keyframes pulse {
|
||||||
margin-top: 156px;
|
0% {
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="search"] {
|
input[type="search"] {
|
||||||
@@ -225,6 +249,10 @@
|
|||||||
border-style: solid;
|
border-style: solid;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
animation: pulse 1s infinite;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
@@ -239,10 +267,14 @@
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.results {
|
||||||
|
height: 100%;
|
||||||
|
min-width: min(90vw, 16.5cm);
|
||||||
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-width: min(90vw, 16.5cm);
|
|
||||||
transition: all 1s ease;
|
transition: all 1s ease;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user