diff --git a/app/assets/javascripts/ui_models/app_state/app_state.ts b/app/assets/javascripts/ui_models/app_state/app_state.ts index 124fa2e16..84128a8c6 100644 --- a/app/assets/javascripts/ui_models/app_state/app_state.ts +++ b/app/assets/javascripts/ui_models/app_state/app_state.ts @@ -2,7 +2,6 @@ import { Bridge } from '@/services/bridge'; import { storage, StorageKey } from '@/services/localStorage'; import { WebApplication } from '@/ui_models/application'; import { AccountMenuState } from '@/ui_models/app_state/account_menu_state'; -import { NoteViewController } from '@/views/note_view/note_view_controller'; import { isDesktopApplication } from '@/utils'; import { ApplicationEvent, @@ -17,6 +16,7 @@ import { SNSmartTag, ComponentViewer, SNTag, + NoteViewController, } from '@standardnotes/snjs'; import pull from 'lodash/pull'; import { diff --git a/app/assets/javascripts/ui_models/app_state/notes_state.ts b/app/assets/javascripts/ui_models/app_state/notes_state.ts index 8bfbae2c2..cc4187908 100644 --- a/app/assets/javascripts/ui_models/app_state/notes_state.ts +++ b/app/assets/javascripts/ui_models/app_state/notes_state.ts @@ -8,6 +8,7 @@ import { ContentType, SNTag, ChallengeReason, + NoteViewController, } from '@standardnotes/snjs'; import { makeObservable, @@ -17,7 +18,6 @@ import { runInAction, } from 'mobx'; import { WebApplication } from '../application'; -import { NoteViewController } from '@/views/note_view/note_view_controller'; import { AppState } from './app_state'; export class NotesState { diff --git a/app/assets/javascripts/ui_models/application.ts b/app/assets/javascripts/ui_models/application.ts index c99fd8a9f..96c24ccc0 100644 --- a/app/assets/javascripts/ui_models/application.ts +++ b/app/assets/javascripts/ui_models/application.ts @@ -10,13 +10,13 @@ import { StatusManager } from '@/services/statusManager'; import { ThemeManager } from '@/services/themeManager'; import { PasswordWizardScope, PasswordWizardType } from '@/types'; import { AppState } from '@/ui_models/app_state'; -import { NoteGroupController } from '@/views/note_group_view/note_group_controller'; import { WebDeviceInterface } from '@/web_device_interface'; import { DeinitSource, PermissionDialog, Platform, SNApplication, + NoteGroupController, } from '@standardnotes/snjs'; import angular from 'angular'; import { AccountSwitcherScope, PermissionsModalScope } from './../types'; diff --git a/app/assets/javascripts/views/note_group_view/note_group_controller.ts b/app/assets/javascripts/views/note_group_view/note_group_controller.ts deleted file mode 100644 index c625fc47c..000000000 --- a/app/assets/javascripts/views/note_group_view/note_group_controller.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { removeFromArray, UuidString } from '@standardnotes/snjs'; -import { NoteViewController } from '@/views/note_view/note_view_controller'; -import { WebApplication } from '@/ui_models/application'; - -type NoteControllerGroupChangeCallback = () => void; - -export class NoteGroupController { - public noteControllers: NoteViewController[] = []; - private application: WebApplication; - changeObservers: NoteControllerGroupChangeCallback[] = []; - - constructor(application: WebApplication) { - this.application = application; - } - - public deinit() { - (this.application as unknown) = undefined; - for (const controller of this.noteControllers) { - this.deleteNoteView(controller); - } - } - - async createNoteView( - noteUuid?: string, - noteTitle?: string, - noteTag?: UuidString - ) { - const controller = new NoteViewController( - this.application, - noteUuid, - noteTitle, - noteTag - ); - await controller.initialize(); - this.noteControllers.push(controller); - this.notifyObservers(); - } - - deleteNoteView(controller: NoteViewController) { - controller.deinit(); - removeFromArray(this.noteControllers, controller); - } - - closeNoteView(controller: NoteViewController) { - this.deleteNoteView(controller); - this.notifyObservers(); - } - - closeActiveNoteView() { - const activeController = this.activeNoteViewController; - if (activeController) { - this.deleteNoteView(activeController); - } - } - - closeAllNoteViews() { - for (const controller of this.noteControllers) { - this.deleteNoteView(controller); - } - } - - get activeNoteViewController() { - return this.noteControllers[0]; - } - - /** - * Notifies observer when the active controller has changed. - */ - public addChangeObserver(callback: NoteControllerGroupChangeCallback) { - this.changeObservers.push(callback); - if (this.activeNoteViewController) { - callback(); - } - return () => { - removeFromArray(this.changeObservers, callback); - }; - } - - private notifyObservers() { - for (const observer of this.changeObservers) { - observer(); - } - } -} diff --git a/app/assets/javascripts/views/note_group_view/note_group_view.ts b/app/assets/javascripts/views/note_group_view/note_group_view.ts index 8d598d1aa..5a659017f 100644 --- a/app/assets/javascripts/views/note_group_view/note_group_view.ts +++ b/app/assets/javascripts/views/note_group_view/note_group_view.ts @@ -1,7 +1,7 @@ import { WebDirective } from './../../types'; import template from './note-group-view.pug'; -import { NoteViewController } from '@/views/note_view/note_view_controller'; import { PureViewCtrl } from '../abstract/pure_view_ctrl'; +import { NoteViewController } from '@standardnotes/snjs'; class NoteGroupView extends PureViewCtrl< unknown, @@ -20,9 +20,11 @@ class NoteGroupView extends PureViewCtrl< } $onInit() { - this.application.noteControllerGroup.addChangeObserver(() => { - this.controllers = this.application.noteControllerGroup.noteControllers; - }); + this.application.noteControllerGroup.addActiveControllerChangeObserver( + () => { + this.controllers = this.application.noteControllerGroup.noteControllers; + } + ); this.autorun(() => { this.setState({ showMultipleSelectedNotes: this.appState.notes.selectedNotesCount > 1, diff --git a/app/assets/javascripts/views/note_view/note_view.ts b/app/assets/javascripts/views/note_view/note_view.ts index cd3857605..9bba09f67 100644 --- a/app/assets/javascripts/views/note_view/note_view.ts +++ b/app/assets/javascripts/views/note_view/note_view.ts @@ -1,5 +1,4 @@ import { STRING_SAVING_WHILE_DOCUMENT_HIDDEN } from './../../strings'; -import { NoteViewController } from '@/views/note_view/note_view_controller'; import { WebApplication } from '@/ui_models/application'; import { PanelPuppet, WebDirective } from '@/types'; import angular from 'angular'; @@ -20,6 +19,7 @@ import { TransactionalMutation, ItemMutator, ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction, + NoteViewController, } from '@standardnotes/snjs'; import { debounce, isDesktopApplication } from '@/utils'; import { KeyboardModifier, KeyboardKey } from '@/services/ioService'; @@ -108,6 +108,7 @@ export class NoteView extends PureViewCtrl { private removeTabObserver?: () => void; private removeComponentStreamObserver?: () => void; private removeComponentManagerObserver?: () => void; + private removeInnerNoteObserver?: () => void; private protectionTimeoutId: ReturnType | null = null; @@ -139,6 +140,8 @@ export class NoteView extends PureViewCtrl { deinit() { this.removeComponentStreamObserver?.(); (this.removeComponentStreamObserver as unknown) = undefined; + this.removeInnerNoteObserver?.(); + (this.removeInnerNoteObserver as unknown) = undefined; this.removeComponentManagerObserver?.(); (this.removeComponentManagerObserver as unknown) = undefined; this.removeTrashKeyObserver?.(); @@ -167,9 +170,10 @@ export class NoteView extends PureViewCtrl { $onInit() { super.$onInit(); this.registerKeyboardShortcuts(); - this.controller.setOnNoteInnerValueChange((note, source) => { - this.onNoteInnerChange(note, source); - }); + this.removeInnerNoteObserver = + this.controller.addNoteInnerValueChangeObserver((note, source) => { + this.onNoteInnerChange(note, source); + }); this.autorun(() => { this.setState({ showProtectedWarning: this.appState.notes.showProtectedWarning, diff --git a/app/assets/javascripts/views/note_view/note_view_controller.ts b/app/assets/javascripts/views/note_view/note_view_controller.ts deleted file mode 100644 index 5b6a81d14..000000000 --- a/app/assets/javascripts/views/note_view/note_view_controller.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - SNNote, - ContentType, - PayloadSource, - UuidString, - SNTag, -} from '@standardnotes/snjs'; -import { WebApplication } from '@/ui_models/application'; - -export class NoteViewController { - public note!: SNNote; - private application: WebApplication; - private onNoteValueChange?: (note: SNNote, source: PayloadSource) => void; - private removeStreamObserver?: () => void; - public isTemplateNote = false; - - constructor( - application: WebApplication, - noteUuid: string | undefined, - private defaultTitle: string | undefined, - private defaultTag: UuidString | undefined - ) { - this.application = application; - if (noteUuid) { - this.note = application.findItem(noteUuid) as SNNote; - } - } - - async initialize(): Promise { - if (!this.note) { - const note = (await this.application.createTemplateItem( - ContentType.Note, - { - text: '', - title: this.defaultTitle, - references: [], - } - )) as SNNote; - if (this.defaultTag) { - const tag = this.application.findItem(this.defaultTag) as SNTag; - await this.application.addTagHierarchyToNote(note, tag); - } - this.isTemplateNote = true; - this.note = note; - this.onNoteValueChange?.(this.note, this.note.payload.source); - } - this.streamItems(); - } - - private streamItems() { - this.removeStreamObserver = this.application.streamItems( - ContentType.Note, - (items, source) => { - this.handleNoteStream(items as SNNote[], source); - } - ); - } - - deinit() { - this.removeStreamObserver?.(); - (this.removeStreamObserver as unknown) = undefined; - (this.application as unknown) = undefined; - this.onNoteValueChange = undefined; - } - - private handleNoteStream(notes: SNNote[], source: PayloadSource) { - /** Update our note object reference whenever it changes */ - const matchingNote = notes.find((item) => { - return item.uuid === this.note.uuid; - }) as SNNote; - if (matchingNote) { - this.isTemplateNote = false; - this.note = matchingNote; - this.onNoteValueChange?.(matchingNote, source); - } - } - - insertTemplatedNote() { - this.isTemplateNote = false; - return this.application.insertItem(this.note); - } - - /** - * Register to be notified when the controller's note's inner values change - * (and thus a new object reference is created) - */ - public setOnNoteInnerValueChange( - callback: (note: SNNote, source: PayloadSource) => void - ) { - this.onNoteValueChange = callback; - if (this.note) { - this.onNoteValueChange(this.note, this.note.payload.source); - } - } -} diff --git a/package.json b/package.json index 24e491bec..34cb50637 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "@reach/tooltip": "^0.16.2", "@standardnotes/features": "1.20.5", "@standardnotes/sncrypto-web": "1.5.3", - "@standardnotes/snjs": "2.33.0", + "@standardnotes/snjs": "2.34.0", "mobx": "^6.3.5", "mobx-react-lite": "^3.2.2", "preact": "^10.5.15", diff --git a/yarn.lock b/yarn.lock index e55006170..461b57102 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2655,10 +2655,10 @@ buffer "^6.0.3" libsodium-wrappers "^0.7.9" -"@standardnotes/snjs@2.33.0": - version "2.33.0" - resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.33.0.tgz#f3d295740471136bf2ec52e1d0e1cdf553923226" - integrity sha512-KHzxt2CqeFnQgKp6cf+Jqvfx3P0DXP1myEr6a41NmXAQ5qu2ytugyzxiyDyakFvR+Cp7g7GjRA+DwLvO7i1kaA== +"@standardnotes/snjs@2.34.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.34.0.tgz#ba5ccc3e82a190d3284cea2936e3453ed49b0b2c" + integrity sha512-1qIahN+TFy51FZcouWSGpIqxe5kDZAl07n3quzv3WszzvfIeB2X+40bmhJAj7/qbWjvNfoA60jKZYxiAbMIiJQ== dependencies: "@standardnotes/auth" "3.8.1" "@standardnotes/common" "1.2.1"