diff --git a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx index a1a7c8b1d..dcebefe12 100644 --- a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx +++ b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx @@ -196,7 +196,7 @@ const NotesOptions = ({ const unpinned = notes.some((note) => !note.pinned) const editorForNote = useMemo( - () => application.componentManager.editorForNote(notes[0]), + () => (notes[0] ? application.componentManager.editorForNote(notes[0]) : undefined), [application.componentManager, notes], ) diff --git a/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts b/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts index b909dae27..b658a19e1 100644 --- a/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts +++ b/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts @@ -32,7 +32,15 @@ const MinNoteCellHeight = 51.0 const DefaultListNumNotes = 20 const ElementIdSearchBar = 'search-bar' const ElementIdScrollContainer = 'notes-scrollable' -const SupportsFileSelectionState = false + +enum ItemsReloadSource { + ItemStream, + SyncEvent, + DisplayOptionsChange, + Pagination, + TagChange, + FilterTextChange, +} export class ItemListController extends AbstractViewController implements InternalEventHandlerInterface { completedFullSync = false @@ -95,7 +103,7 @@ export class ItemListController extends AbstractViewController implements Intern this.disposers.push( application.streamItems(ContentType.Note, () => { - void this.reloadItems() + void this.reloadItems(ItemsReloadSource.ItemStream) }), ) @@ -106,7 +114,7 @@ export class ItemListController extends AbstractViewController implements Intern /** A tag could have changed its relationships, so we need to reload the filter */ this.reloadNotesDisplayOptions() - void this.reloadItems() + void this.reloadItems(ItemsReloadSource.ItemStream) if (this.navigationController.selected && findInArray(tags, 'uuid', this.navigationController.selected.uuid)) { /** Tag title could have changed */ @@ -131,7 +139,7 @@ export class ItemListController extends AbstractViewController implements Intern this.disposers.push( application.addEventObserver(async () => { - void this.reloadItems().then(() => { + void this.reloadItems(ItemsReloadSource.SyncEvent).then(() => { if ( this.notes.length === 0 && this.navigationController.selected instanceof SmartView && @@ -163,7 +171,7 @@ export class ItemListController extends AbstractViewController implements Intern ], () => { this.reloadNotesDisplayOptions() - void this.reloadItems() + void this.reloadItems(ItemsReloadSource.DisplayOptionsChange) }, ), ) @@ -242,17 +250,17 @@ export class ItemListController extends AbstractViewController implements Intern this.panelTitle = title } - reloadItems = async (): Promise => { + reloadItems = async (source: ItemsReloadSource): Promise => { if (this.reloadItemsPromise) { await this.reloadItemsPromise } - this.reloadItemsPromise = this.performReloadItems() + this.reloadItemsPromise = this.performReloadItems(source) await this.reloadItemsPromise } - private async performReloadItems() { + private async performReloadItems(source: ItemsReloadSource) { const tag = this.navigationController.selected if (!tag) { return @@ -270,12 +278,12 @@ export class ItemListController extends AbstractViewController implements Intern this.renderedItems = renderedItems }) - await this.recomputeSelectionAfterItemsReload() + await this.recomputeSelectionAfterItemsReload(source) this.reloadPanelTitle() } - private async recomputeSelectionAfterItemsReload() { + private async recomputeSelectionAfterItemsReload(itemsReloadSource: ItemsReloadSource) { const activeController = this.getActiveNoteController() const activeNote = activeController?.note const isSearching = this.noteFilterText.length > 0 @@ -285,12 +293,9 @@ export class ItemListController extends AbstractViewController implements Intern return } - const selectedItem = Object.values(this.selectionController.selectedItems)[0] + if (itemsReloadSource === ItemsReloadSource.TagChange) { + await this.selectFirstItem() - const isSelectedItemFile = - this.items.includes(selectedItem) && selectedItem && selectedItem.content_type === ContentType.File - - if (isSelectedItemFile && !SupportsFileSelectionState) { return } @@ -305,22 +310,20 @@ export class ItemListController extends AbstractViewController implements Intern } const noteExistsInUpdatedResults = this.notes.find((note) => note.uuid === activeNote.uuid) - if (!noteExistsInUpdatedResults && !isSearching) { + const shouldCloseActiveNote = + !noteExistsInUpdatedResults && !isSearching && this.navigationController.isInAnySystemView() + + if (shouldCloseActiveNote) { this.closeNoteController(activeController) - this.selectNextItem() - return } const showTrashedNotes = - (this.navigationController.selected instanceof SmartView && - this.navigationController.selected?.uuid === SystemViewId.TrashedNotes) || - this.searchOptionsController.includeTrashed + this.navigationController.isInSystemView(SystemViewId.TrashedNotes) || this.searchOptionsController.includeTrashed const showArchivedNotes = - (this.navigationController.selected instanceof SmartView && - this.navigationController.selected.uuid === SystemViewId.ArchivedNotes) || + this.navigationController.isInSystemView(SystemViewId.ArchivedNotes) || this.searchOptionsController.includeArchived || this.application.getPreference(PrefKey.NotesShowArchived, false) @@ -408,7 +411,7 @@ export class ItemListController extends AbstractViewController implements Intern this.reloadNotesDisplayOptions() } - await this.reloadItems() + await this.reloadItems(ItemsReloadSource.DisplayOptionsChange) const width = this.application.getPreference(PrefKey.NotesPanelWidth) if (width) { @@ -482,7 +485,7 @@ export class ItemListController extends AbstractViewController implements Intern paginate = () => { this.notesToDisplay += this.pageSize - void this.reloadItems() + void this.reloadItems(ItemsReloadSource.Pagination) if (this.searchSubmitted) { this.application.getDesktopService()?.searchText(this.noteFilterText) @@ -663,7 +666,7 @@ export class ItemListController extends AbstractViewController implements Intern this.reloadNotesDisplayOptions() - void this.reloadItems() + void this.reloadItems(ItemsReloadSource.TagChange) } onFilterEnter = () => { @@ -696,7 +699,7 @@ export class ItemListController extends AbstractViewController implements Intern this.reloadNotesDisplayOptions() - void this.reloadItems() + void this.reloadItems(ItemsReloadSource.FilterTextChange) } clearFilterText = () => { diff --git a/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts b/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts index ec8473158..1cedcc6b2 100644 --- a/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts +++ b/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts @@ -193,6 +193,20 @@ export class NavigationController extends AbstractViewController { return this.selected instanceof SmartView && this.selected.uuid === SystemViewId.AllNotes } + public get isInFilesView(): boolean { + return this.selectedUuid === SystemViewId.Files + } + + public isInAnySystemView(): boolean { + return ( + this.selected instanceof SmartView && Object.values(SystemViewId).includes(this.selected.uuid as SystemViewId) + ) + } + + public isInSystemView(id: SystemViewId): boolean { + return this.selected instanceof SmartView && this.selected.uuid === id + } + setAddingSubtagTo(tag: SNTag | undefined): void { this.addingSubtagTo = tag } @@ -259,10 +273,6 @@ export class NavigationController extends AbstractViewController { } } - public get isInFilesView(): boolean { - return this.selectedUuid === SystemViewId.Files - } - public get allLocalRootTags(): SNTag[] { if (this.editing_ instanceof SNTag && this.application.items.isTemplateItem(this.editing_)) { return [this.editing_, ...this.rootTags] @@ -389,7 +399,7 @@ export class NavigationController extends AbstractViewController { } private setSelectedTagInstance(tag: AnyTag | undefined): void { - this.selected_ = tag + runInAction(() => (this.selected_ = tag)) } public setExpanded(tag: SNTag, expanded: boolean) { diff --git a/packages/web/src/javascripts/Controllers/NoteTagsController.ts b/packages/web/src/javascripts/Controllers/NoteTagsController.ts index 8e7e9f236..8d794e5dc 100644 --- a/packages/web/src/javascripts/Controllers/NoteTagsController.ts +++ b/packages/web/src/javascripts/Controllers/NoteTagsController.ts @@ -63,7 +63,7 @@ export class NoteTagsController extends AbstractViewController { this.addNoteToParentFolders = application.getPreference(PrefKey.NoteAddToParentFolders, true) } - public setServicestPostConstruction(itemListController: ItemListController) { + public setServicesPostConstruction(itemListController: ItemListController) { this.itemListController = itemListController this.disposers.push( diff --git a/packages/web/src/javascripts/Controllers/NotesController.ts b/packages/web/src/javascripts/Controllers/NotesController.ts index 757fa5cf9..32204c099 100644 --- a/packages/web/src/javascripts/Controllers/NotesController.ts +++ b/packages/web/src/javascripts/Controllers/NotesController.ts @@ -66,7 +66,7 @@ export class NotesController extends AbstractViewController { }) } - public setServicestPostConstruction(itemListController: ItemListController) { + public setServicesPostConstruction(itemListController: ItemListController) { this.itemListController = itemListController this.disposers.push( diff --git a/packages/web/src/javascripts/Controllers/SelectedItemsController.ts b/packages/web/src/javascripts/Controllers/SelectedItemsController.ts index e8084fd97..42308dbef 100644 --- a/packages/web/src/javascripts/Controllers/SelectedItemsController.ts +++ b/packages/web/src/javascripts/Controllers/SelectedItemsController.ts @@ -43,7 +43,7 @@ export class SelectedItemsController extends AbstractViewController { }) } - public setServicestPostConstruction(itemListController: ItemListController, notesController: NotesController) { + public setServicesPostConstruction(itemListController: ItemListController, notesController: NotesController) { this.itemListController = itemListController this.notesController = notesController diff --git a/packages/web/src/javascripts/Services/ViewControllerManager.ts b/packages/web/src/javascripts/Services/ViewControllerManager.ts index 81cd84213..595b7a6a8 100644 --- a/packages/web/src/javascripts/Services/ViewControllerManager.ts +++ b/packages/web/src/javascripts/Services/ViewControllerManager.ts @@ -82,9 +82,9 @@ export class ViewControllerManager { this.eventBus, ) - this.notesController.setServicestPostConstruction(this.itemListController) - this.noteTagsController.setServicestPostConstruction(this.itemListController) - this.selectionController.setServicestPostConstruction(this.itemListController, this.notesController) + this.notesController.setServicesPostConstruction(this.itemListController) + this.noteTagsController.setServicesPostConstruction(this.itemListController) + this.selectionController.setServicesPostConstruction(this.itemListController, this.notesController) this.noAccountWarningController = new NoAccountWarningController(application, this.eventBus)