fix: duplicate chords crash

fix: duplicate confirm dialog does not show affected chord
fixes #137
fixes #163
This commit is contained in:
2025-02-14 15:17:22 +01:00
parent fb1f5b7ec7
commit f319714489
4 changed files with 56 additions and 31 deletions

View File

@@ -1,13 +1,14 @@
<script lang="ts">
import Dialog from "$lib/dialogs/Dialog.svelte";
import ActionString from "$lib/components/ActionString.svelte";
import type { Chord } from "$lib/serial/chord";
import ChordActionEdit from "../../routes/(app)/config/chords/ChordActionEdit.svelte";
let {
title,
message,
abortTitle,
confirmTitle,
actions = [],
chord,
onabort,
onconfirm,
}: {
@@ -15,7 +16,7 @@
message?: string;
abortTitle: string;
confirmTitle: string;
actions: number[];
chord: Chord & { deleted: boolean };
onabort: () => void;
onconfirm: () => void;
} = $props();
@@ -26,7 +27,20 @@
{#if message}
<p>{@html message}</p>
{/if}
<p><ActionString {actions} /></p>
<p>
<ChordActionEdit
chord={{
...chord,
isApplied: false,
phraseChanged: false,
actionsChanged: false,
sortBy: "",
id: chord.actions,
}}
interactive={false}
onsubmit={() => {}}
/>
</p>
<div class="buttons">
<button onclick={onabort}>{abortTitle}</button>
<button class="primary" onclick={onconfirm}>{confirmTitle}</button>

View File

@@ -1,33 +1,34 @@
import ConfirmDialog from "$lib/dialogs/ConfirmDialog.svelte";
import { mount, unmount } from "svelte";
import type { Chord } from "$lib/serial/chord";
export async function askForConfirmation(
title: string,
message: string,
confirmTitle: string,
abortTitle: string,
actions: number[],
chord: Chord,
): Promise<boolean> {
const dialog = new ConfirmDialog({
let resolvePromise: (value: boolean) => void;
const resultPromise = new Promise<boolean>((resolve) => {
resolvePromise = resolve;
});
const dialog = mount(ConfirmDialog, {
target: document.body,
props: {
title,
message,
confirmTitle,
abortTitle,
actions,
chord,
onabort: () => resolvePromise(false),
onconfirm: () => resolvePromise(true),
},
});
let resolvePromise: (value: boolean) => void;
const resultPromise = new Promise<boolean>((resolve) => {
resolvePromise = resolve;
});
dialog.$on("abort", () => resolvePromise(false));
dialog.$on("confirm", () => resolvePromise(true));
const result = await resultPromise;
dialog.$destroy();
unmount(dialog);
return result;
}

View File

@@ -39,7 +39,7 @@
});
}
}
let redoQueue: Change[] = $state([]);
let redoQueue: Change[][] = $state([]);
async function save() {
try {
@@ -47,10 +47,10 @@
if (!port) return;
$syncStatus = "uploading";
for (const [id, { actions, phrase, deleted }] of $overlay.chords) {
if (!deleted) {
if (id !== JSON.stringify(actions)) {
const existingChord = await port.getChordPhrase(actions);
for (const [id, chord] of $overlay.chords) {
if (!chord.deleted) {
if (id !== JSON.stringify(chord.actions)) {
const existingChord = await port.getChordPhrase(chord.actions);
if (
existingChord !== undefined &&
!(await askForConfirmation(
@@ -58,26 +58,30 @@
$LL.configure.chords.conflict.DESCRIPTION(),
$LL.configure.chords.conflict.CONFIRM(),
$LL.configure.chords.conflict.ABORT(),
actions.slice(0, actions.lastIndexOf(0)),
chord,
))
) {
changes.update((changes) =>
changes.filter(
(it) =>
!(
it.type === ChangeType.Chord &&
JSON.stringify(it.id) === id
changes
.map((it) =>
it.filter(
(it) =>
!(
it.type === ChangeType.Chord &&
JSON.stringify(it.id) === id
),
),
),
)
.filter((it) => it.length > 0),
);
continue;
}
await port.deleteChord({ actions: JSON.parse(id) });
}
await port.setChord({ actions, phrase });
await port.setChord({ actions: chord.actions, phrase: chord.phrase });
} else {
await port.deleteChord({ actions });
await port.deleteChord({ actions: chord.actions });
}
}

View File

@@ -13,7 +13,12 @@
let {
chord = undefined,
onsubmit,
}: { chord?: ChordInfo; onsubmit: (actions: number[]) => void } = $props();
interactive = true,
}: {
chord?: ChordInfo;
interactive?: boolean;
onsubmit: (actions: number[]) => void;
} = $props();
let pressedKeys = new SvelteSet<number>();
let editing = $state(false);
@@ -129,6 +134,7 @@
onkeydown={keydown}
onkeyup={keyup}
onblur={keyup}
disabled={!interactive}
>
{#if editing && pressedKeys.size === 0}
<span>{$LL.configure.chords.HOLD_KEYS()}</span>