diff --git a/ts/editor/Tag.svelte b/ts/editor/Tag.svelte index 25e53a404..d220310b7 100644 --- a/ts/editor/Tag.svelte +++ b/ts/editor/Tag.svelte @@ -39,8 +39,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html if (shift) { dispatch("tagrange"); } else if (control) { - console.log("control", control); - selected = !selected; + dispatch("tagselect"); } else { dispatch("tagedit"); } diff --git a/ts/editor/TagEditor.svelte b/ts/editor/TagEditor.svelte index d0aec2b98..431a51b17 100644 --- a/ts/editor/TagEditor.svelte +++ b/ts/editor/TagEditor.svelte @@ -279,13 +279,46 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html } } + let selectionAnchor: number | null = null; + let selectionFocus: number | null = null; + + function select(index: number) { + tags[index].selected = !tags[index].selected; + tags = tags; + + selectionAnchor = index; + } + + function selectRange(index: number) { + if (selectionAnchor === null) { + select(index); + return; + } + + selectionFocus = index; + + const from = Math.min(selectionAnchor, selectionFocus); + const to = Math.max(selectionAnchor, selectionFocus); + + for (let index = from; index <= to; index++) { + tags[index].selected = true; + } + + tags = tags; + } + function deselect() { tags = tags.map((tag: TagType): TagType => ({ ...tag, selected: false })); + selectionAnchor = null; + selectionFocus = null; } function deselectIfLeave(event: FocusEvent) { const toolbar = event.currentTarget as HTMLDivElement; - if (!toolbar.contains(event.relatedTarget as Element)) { + if ( + event.relatedTarget === null || + !toolbar.contains(event.relatedTarget as Node) + ) { deselect(); } } @@ -357,7 +390,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html active = index; deselect(); }} - on:tagrange={console.log} + on:tagselect={() => select(index)} + on:tagrange={() => selectRange(index)} on:tagdelete={() => { deleteTagAt(index); saveTags();