mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
Implement blink on duplicate detected
This commit is contained in:
parent
11c6fe880b
commit
2de2f03db8
3 changed files with 61 additions and 13 deletions
|
@ -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>
|
||||||
|
|
|
@ -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)}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue