Implement blink on duplicate detected

This commit is contained in:
Henrik Giesel 2021-06-26 14:10:11 +02:00
parent 11c6fe880b
commit 2de2f03db8
3 changed files with 61 additions and 13 deletions

View file

@ -10,11 +10,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let name: string; export let name: string;
export let active: boolean; export let active: boolean;
export let blink: boolean = false;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
let input: HTMLInputElement; let input: HTMLInputElement;
$: if (blink) {
setTimeout(() => (blink = false), 300);
}
function checkForActivation(): void { function checkForActivation(): void {
const selection = window.getSelection()!; const selection = window.getSelection()!;
active = selection.isCollapsed; active = selection.isCollapsed;
@ -56,6 +61,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{:else} {:else}
<button <button
class="d-inline-flex align-items-center tag text-nowrap rounded ps-2 pe-1 me-1" class="d-inline-flex align-items-center tag text-nowrap rounded ps-2 pe-1 me-1"
class:blink
tabindex="-1" tabindex="-1"
on:click={checkForActivation} on:click={checkForActivation}
> >
@ -69,6 +75,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<style lang="scss"> <style lang="scss">
$white-translucent: rgba(255, 255, 255, 0.5); $white-translucent: rgba(255, 255, 255, 0.5);
@keyframes blink {
0% {
filter: brightness(1);
}
50% {
filter: brightness(2);
}
100% {
filter: brightness(1);
}
}
.tag :global(.delete-icon > svg:hover) { .tag :global(.delete-icon > svg:hover) {
background-color: $white-translucent; background-color: $white-translucent;
} }
@ -80,5 +98,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
&:active { &:active {
outline: none; outline: none;
} }
&.blink {
animation: blink 0.2s linear;
}
} }
</style> </style>

View file

@ -26,25 +26,45 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
newInput.focus(); newInput.focus();
} }
function checkForDuplicateAt(index: number): void { function checkIfContains(newName: string, names: string[]): boolean {
const names = tags.map(getName); const contained = names.indexOf(newName);
const nameToUpdateTo = names.splice(index, 1)[0]; if (contained >= 0) {
tags[contained].blink = true;
return true;
}
if (names.includes(nameToUpdateTo)) { return false;
}
function checkIfContainsName(newName: string): boolean {
const names = tags.map(getName);
return checkIfContains(newName, names);
}
function checkIfContainsNameAt(index: number): boolean {
const names = tags.map(getName);
const newName = names.splice(index, 1, "")[0];
return checkIfContains(newName, names);
}
function checkForDuplicateNameAt(index: number): void {
if (checkIfContainsNameAt(index)) {
deleteTagAt(index); deleteTagAt(index);
} }
} }
function insertTagAt(index: number): void { function insertTagAt(index: number): boolean {
const names = tags.map(getName); const names = tags.map(getName);
const nameToInsert = names.splice(index, 1)[0]; const newName = names.splice(index, 1)[0];
let added = false;
if (names.includes(nameToInsert)) { if (!checkIfContainsNameAt(index) && newName.length > 0) {
return; tags.splice(index, 0, attachId(newName));
added = true;
} }
tags.splice(index, 0, attachId(nameToInsert));
tags = tags; tags = tags;
return added;
} }
function deleteTagAt(index: number): void { function deleteTagAt(index: number): void {
@ -98,10 +118,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
function appendTag(): boolean { function appendTag(): boolean {
const names = tags.map(getName);
let added = false; let added = false;
if (!names.includes(newName) && newName.length > 0) { if (!checkIfContainsName(newName)) {
tags.push(attachId(newName)); tags.push(attachId(newName));
added = true; added = true;
} }
@ -141,9 +160,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<Tag <Tag
bind:name={tag.name} bind:name={tag.name}
bind:active={tag.active} bind:active={tag.active}
bind:blink={tag.blink}
on:keydown={() => {}} on:keydown={() => {}}
on:blur={() => {}} on:blur={() => {}}
on:tagupdate={() => checkForDuplicateAt(index)} on:tagupdate={() => checkForDuplicateNameAt(index)}
on:tagadd={() => insertTagAt(index)} on:tagadd={() => insertTagAt(index)}
on:tagdelete={() => deleteTagAt(index)} on:tagdelete={() => deleteTagAt(index)}
on:tagjoinprevious={() => joinWithPreviousTag(index)} on:tagjoinprevious={() => joinWithPreviousTag(index)}

View file

@ -18,11 +18,17 @@ export function normalizeTagname(tagname: string): string {
interface Tag { interface Tag {
name: string; name: string;
active: boolean; active: boolean;
blink: boolean;
id: string; id: string;
} }
export function attachId(name: string): Tag { export function attachId(name: string): Tag {
return { name, active: false, id: Math.random().toString(36).substring(2) }; return {
name,
active: false,
blink: false,
id: Math.random().toString(36).substring(2),
};
} }
export function getName(tag: Tag): string { export function getName(tag: Tag): string {