diff --git a/app/assets/javascripts/components/TagsListItem.tsx b/app/assets/javascripts/components/TagsListItem.tsx index 091c8e68f..593edea10 100644 --- a/app/assets/javascripts/components/TagsListItem.tsx +++ b/app/assets/javascripts/components/TagsListItem.tsx @@ -1,5 +1,6 @@ +import { TagsState } from '@/ui_models/app_state/tags_state'; import { SNTag } from '@standardnotes/snjs'; -import { runInAction } from 'mobx'; +import { computed, runInAction } from 'mobx'; import { observer } from 'mobx-react-lite'; import { FunctionComponent, JSX } from 'preact'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; @@ -14,6 +15,7 @@ type Props = { export type TagsListState = { readonly selectedTag: SNTag | undefined; + tags: TagsState; editingTag: SNTag | undefined; }; @@ -24,7 +26,7 @@ export const TagsListItem: FunctionComponent = observer( const isSelected = appState.selectedTag === tag; const isEditing = appState.editingTag === tag; - const noteCounts = tag.noteCount; + const noteCounts = computed(() => appState.tags.getNotesCount(tag)); useEffect(() => { setTitle(tag.title || ''); @@ -97,7 +99,7 @@ export const TagsListItem: FunctionComponent = observer( spellCheck={false} ref={inputRef} /> -
{noteCounts}
+
{noteCounts.get()}
) : null} {tag.conflictOf && ( diff --git a/app/assets/javascripts/ui_models/app_state/tags_state.ts b/app/assets/javascripts/ui_models/app_state/tags_state.ts index a2e2377e6..3aeb99d10 100644 --- a/app/assets/javascripts/ui_models/app_state/tags_state.ts +++ b/app/assets/javascripts/ui_models/app_state/tags_state.ts @@ -1,15 +1,25 @@ import { ContentType, SNSmartTag, SNTag } from '@standardnotes/snjs'; -import { computed, makeObservable, observable, runInAction } from 'mobx'; +import { + action, + computed, + makeAutoObservable, + makeObservable, + observable, + runInAction, +} from 'mobx'; import { WebApplication } from '../application'; export class TagsState { tags: SNTag[] = []; smartTags: SNSmartTag[] = []; + private readonly tagsCountsState: TagsCountsState; constructor( private application: WebApplication, appEventListeners: (() => void)[] ) { + this.tagsCountsState = new TagsCountsState(this.application); + makeObservable(this, { tags: observable, smartTags: observable, @@ -26,13 +36,46 @@ export class TagsState { ContentType.Tag ) as SNTag[]; this.smartTags = this.application.getSmartTags(); + + this.tagsCountsState.update(this.tags); }); } ) ); } + public getNotesCount(tag: SNTag): number { + return this.tagsCountsState.counts[tag.uuid] || 0; + } + get tagsCount(): number { return this.tags.length; } } + +/** + * Bug fix for issue 1201550111577311, + */ +class TagsCountsState { + public counts: { [uuid: string]: number } = {}; + + public constructor(private application: WebApplication) { + makeAutoObservable(this, { + counts: observable.ref, + update: action, + }); + } + + public update(tags: SNTag[]) { + const newCounts: { [uuid: string]: number } = {}; + + tags.forEach((tag) => { + newCounts[tag.uuid] = this.application.referencesForItem( + tag, + ContentType.Note + ).length; + }); + + this.counts = newCounts; + } +}