mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-01-05 09:32:53 +00:00
fix: duplicate chords crash
fix: duplicate confirm dialog does not show affected chord fixes #137 fixes #163
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog from "$lib/dialogs/Dialog.svelte";
|
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 {
|
let {
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
abortTitle,
|
abortTitle,
|
||||||
confirmTitle,
|
confirmTitle,
|
||||||
actions = [],
|
chord,
|
||||||
onabort,
|
onabort,
|
||||||
onconfirm,
|
onconfirm,
|
||||||
}: {
|
}: {
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
message?: string;
|
message?: string;
|
||||||
abortTitle: string;
|
abortTitle: string;
|
||||||
confirmTitle: string;
|
confirmTitle: string;
|
||||||
actions: number[];
|
chord: Chord & { deleted: boolean };
|
||||||
onabort: () => void;
|
onabort: () => void;
|
||||||
onconfirm: () => void;
|
onconfirm: () => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
@@ -26,7 +27,20 @@
|
|||||||
{#if message}
|
{#if message}
|
||||||
<p>{@html message}</p>
|
<p>{@html message}</p>
|
||||||
{/if}
|
{/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">
|
<div class="buttons">
|
||||||
<button onclick={onabort}>{abortTitle}</button>
|
<button onclick={onabort}>{abortTitle}</button>
|
||||||
<button class="primary" onclick={onconfirm}>{confirmTitle}</button>
|
<button class="primary" onclick={onconfirm}>{confirmTitle}</button>
|
||||||
|
|||||||
@@ -1,33 +1,34 @@
|
|||||||
import ConfirmDialog from "$lib/dialogs/ConfirmDialog.svelte";
|
import ConfirmDialog from "$lib/dialogs/ConfirmDialog.svelte";
|
||||||
|
import { mount, unmount } from "svelte";
|
||||||
|
import type { Chord } from "$lib/serial/chord";
|
||||||
|
|
||||||
export async function askForConfirmation(
|
export async function askForConfirmation(
|
||||||
title: string,
|
title: string,
|
||||||
message: string,
|
message: string,
|
||||||
confirmTitle: string,
|
confirmTitle: string,
|
||||||
abortTitle: string,
|
abortTitle: string,
|
||||||
actions: number[],
|
chord: Chord,
|
||||||
): Promise<boolean> {
|
): 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,
|
target: document.body,
|
||||||
props: {
|
props: {
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
confirmTitle,
|
confirmTitle,
|
||||||
abortTitle,
|
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;
|
const result = await resultPromise;
|
||||||
dialog.$destroy();
|
unmount(dialog);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let redoQueue: Change[] = $state([]);
|
let redoQueue: Change[][] = $state([]);
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
try {
|
try {
|
||||||
@@ -47,10 +47,10 @@
|
|||||||
if (!port) return;
|
if (!port) return;
|
||||||
$syncStatus = "uploading";
|
$syncStatus = "uploading";
|
||||||
|
|
||||||
for (const [id, { actions, phrase, deleted }] of $overlay.chords) {
|
for (const [id, chord] of $overlay.chords) {
|
||||||
if (!deleted) {
|
if (!chord.deleted) {
|
||||||
if (id !== JSON.stringify(actions)) {
|
if (id !== JSON.stringify(chord.actions)) {
|
||||||
const existingChord = await port.getChordPhrase(actions);
|
const existingChord = await port.getChordPhrase(chord.actions);
|
||||||
if (
|
if (
|
||||||
existingChord !== undefined &&
|
existingChord !== undefined &&
|
||||||
!(await askForConfirmation(
|
!(await askForConfirmation(
|
||||||
@@ -58,26 +58,30 @@
|
|||||||
$LL.configure.chords.conflict.DESCRIPTION(),
|
$LL.configure.chords.conflict.DESCRIPTION(),
|
||||||
$LL.configure.chords.conflict.CONFIRM(),
|
$LL.configure.chords.conflict.CONFIRM(),
|
||||||
$LL.configure.chords.conflict.ABORT(),
|
$LL.configure.chords.conflict.ABORT(),
|
||||||
actions.slice(0, actions.lastIndexOf(0)),
|
chord,
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
changes.update((changes) =>
|
changes.update((changes) =>
|
||||||
changes.filter(
|
changes
|
||||||
(it) =>
|
.map((it) =>
|
||||||
!(
|
it.filter(
|
||||||
it.type === ChangeType.Chord &&
|
(it) =>
|
||||||
JSON.stringify(it.id) === id
|
!(
|
||||||
|
it.type === ChangeType.Chord &&
|
||||||
|
JSON.stringify(it.id) === id
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
|
.filter((it) => it.length > 0),
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await port.deleteChord({ actions: JSON.parse(id) });
|
await port.deleteChord({ actions: JSON.parse(id) });
|
||||||
}
|
}
|
||||||
await port.setChord({ actions, phrase });
|
await port.setChord({ actions: chord.actions, phrase: chord.phrase });
|
||||||
} else {
|
} else {
|
||||||
await port.deleteChord({ actions });
|
await port.deleteChord({ actions: chord.actions });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,12 @@
|
|||||||
let {
|
let {
|
||||||
chord = undefined,
|
chord = undefined,
|
||||||
onsubmit,
|
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 pressedKeys = new SvelteSet<number>();
|
||||||
let editing = $state(false);
|
let editing = $state(false);
|
||||||
@@ -129,6 +134,7 @@
|
|||||||
onkeydown={keydown}
|
onkeydown={keydown}
|
||||||
onkeyup={keyup}
|
onkeyup={keyup}
|
||||||
onblur={keyup}
|
onblur={keyup}
|
||||||
|
disabled={!interactive}
|
||||||
>
|
>
|
||||||
{#if editing && pressedKeys.size === 0}
|
{#if editing && pressedKeys.size === 0}
|
||||||
<span>{$LL.configure.chords.HOLD_KEYS()}</span>
|
<span>{$LL.configure.chords.HOLD_KEYS()}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user