refactor: refactor autocomplete tag input in separate components and move shared logic to state

This commit is contained in:
Antonella Sgarlatta
2021-06-03 12:47:14 -03:00
parent d49d89f0d5
commit c42f1cedda
7 changed files with 224 additions and 146 deletions

View File

@@ -1,17 +1,12 @@
import {
SNNote,
ContentType,
SNTag,
} from '@standardnotes/snjs';
import {
action,
makeObservable,
observable,
} from 'mobx';
import { SNNote, ContentType, SNTag } from '@standardnotes/snjs';
import { action, computed, makeObservable, observable } from 'mobx';
import { WebApplication } from '../application';
import { AppState } from './app_state';
export class ActiveNoteState {
autocompleteSearchQuery = '';
autocompleteTagResultElements: (HTMLButtonElement | undefined)[] = [];
autocompleteTagResults: SNTag[] = [];
tagElements: (HTMLButtonElement | undefined)[] = [];
tags: SNTag[] = [];
tagsContainerMaxWidth: number | 'auto' = 0;
@@ -22,11 +17,22 @@ export class ActiveNoteState {
appEventListeners: (() => void)[]
) {
makeObservable(this, {
autocompleteSearchQuery: observable,
autocompleteTagResultElements: observable,
autocompleteTagResults: observable,
tagElements: observable,
tags: observable,
tagsContainerMaxWidth: observable,
autocompleteTagHintVisible: computed,
clearAutocompleteSearch: action,
setAutocompleteSearchQuery: action,
setAutocompleteTagResultElement: action,
setAutocompleteTagResultElements: action,
setAutocompleteTagResults: action,
setTagElement: action,
setTagElements: action,
setTags: action,
setTagsContainerMaxWidth: action,
reloadTags: action,
@@ -43,8 +49,41 @@ export class ActiveNoteState {
return this.appState.notes.activeEditor?.note;
}
get autocompleteTagHintVisible(): boolean {
return (
this.autocompleteSearchQuery !== '' &&
!this.autocompleteTagResults.some(
(tagResult) => tagResult.title === this.autocompleteSearchQuery
)
);
}
setAutocompleteSearchQuery(query: string): void {
this.autocompleteSearchQuery = query;
}
setAutocompleteTagResultElement(
tagResult: SNTag,
element: HTMLButtonElement
): void {
const tagIndex = this.getTagIndex(tagResult, this.autocompleteTagResults);
if (tagIndex > -1) {
this.autocompleteTagResultElements.splice(tagIndex, 1, element);
}
}
setAutocompleteTagResultElements(
elements: (HTMLButtonElement | undefined)[]
): void {
this.autocompleteTagResultElements = elements;
}
setAutocompleteTagResults(results: SNTag[]): void {
this.autocompleteTagResults = results;
}
setTagElement(tag: SNTag, element: HTMLButtonElement): void {
const tagIndex = this.getTagIndex(tag);
const tagIndex = this.getTagIndex(tag, this.tags);
if (tagIndex > -1) {
this.tagElements.splice(tagIndex, 1, element);
}
@@ -62,19 +101,38 @@ export class ActiveNoteState {
this.tagsContainerMaxWidth = width;
}
getTagIndex(tag: SNTag): number {
return this.tags.findIndex(t => t.uuid === tag.uuid);
clearAutocompleteSearch(): void {
this.setAutocompleteSearchQuery('');
this.searchActiveNoteAutocompleteTags();
}
async createAndAddNewTag(): Promise<void> {
const newTag = await this.application.findOrCreateTag(this.autocompleteSearchQuery);
await this.addTagToActiveNote(newTag);
this.clearAutocompleteSearch();
}
searchActiveNoteAutocompleteTags(): void {
const newResults = this.application.searchTags(
this.autocompleteSearchQuery,
this.activeNote
);
this.setAutocompleteTagResults(newResults);
}
getTagIndex(tag: SNTag, tagsArr: SNTag[]): number {
return tagsArr.findIndex((t) => t.uuid === tag.uuid);
}
getPreviousTagElement(tag: SNTag): HTMLButtonElement | undefined {
const previousTagIndex = this.getTagIndex(tag) - 1;
const previousTagIndex = this.getTagIndex(tag, this.tags) - 1;
if (previousTagIndex > -1 && this.tagElements.length > previousTagIndex) {
return this.tagElements[previousTagIndex];
}
}
getNextTagElement(tag: SNTag): HTMLButtonElement | undefined {
const nextTagIndex = this.getTagIndex(tag) + 1;
const nextTagIndex = this.getTagIndex(tag, this.tags) + 1;
if (nextTagIndex > -1 && this.tagElements.length > nextTagIndex) {
return this.tagElements[nextTagIndex];
}
@@ -94,9 +152,7 @@ export class ActiveNoteState {
const EDITOR_ELEMENT_ID = 'editor-column';
const editorWidth = document.getElementById(EDITOR_ELEMENT_ID)?.clientWidth;
if (editorWidth) {
this.appState.activeNote.setTagsContainerMaxWidth(
editorWidth
);
this.setTagsContainerMaxWidth(editorWidth);
}
}