chore: rename editor model to note controller

This commit is contained in:
Mo
2021-12-27 18:46:56 -06:00
parent 54e5fc9184
commit 15aea42d4f
12 changed files with 184 additions and 182 deletions

View File

@@ -2,7 +2,7 @@ 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 { Editor } from '@/ui_models/editor';
import { NoteController } from '@/ui_models/note_controller';
import { isDesktopApplication } from '@/utils';
import {
ApplicationEvent,
@@ -226,9 +226,9 @@ export class AppState {
storage.set(StorageKey.ShowBetaWarning, true);
}
async createEditor(title?: string) {
async openNewNote(title?: string) {
if (!this.multiEditorSupport) {
this.closeActiveEditor();
this.closeActiveNoteController();
}
const activeTagUuid = this.selectedTag
? this.selectedTag.isSmartTag
@@ -236,37 +236,37 @@ export class AppState {
: this.selectedTag.uuid
: undefined;
await this.application.editorGroup.createEditor(
await this.application.noteControllerGroup.createNoteController(
undefined,
title,
activeTagUuid
);
}
getActiveEditor() {
return this.application.editorGroup.editors[0];
getActiveNoteController() {
return this.application.noteControllerGroup.noteControllers[0];
}
getEditors() {
return this.application.editorGroup.editors;
getNoteControllers() {
return this.application.noteControllerGroup.noteControllers;
}
closeEditor(editor: Editor) {
this.application.editorGroup.closeEditor(editor);
closeNoteController(controller: NoteController) {
this.application.noteControllerGroup.closeController(controller);
}
closeActiveEditor() {
this.application.editorGroup.closeActiveEditor();
closeActiveNoteController() {
this.application.noteControllerGroup.closeActiveController();
}
closeAllEditors() {
this.application.editorGroup.closeAllEditors();
closeAllNoteControllers() {
this.application.noteControllerGroup.closeAllControllers();
}
editorForNote(note: SNNote) {
for (const editor of this.getEditors()) {
if (editor.note.uuid === note.uuid) {
return editor;
noteControllerForNote(note: SNNote) {
for (const controller of this.getNoteControllers()) {
if (controller.note.uuid === note.uuid) {
return controller;
}
}
}
@@ -275,31 +275,31 @@ export class AppState {
this.application.streamItems(
[ContentType.Note, ContentType.Tag],
async (items, source) => {
/** Close any editors for deleted/trashed/archived notes */
/** Close any note controllers for deleted/trashed/archived notes */
if (source === PayloadSource.PreSyncSave) {
const notes = items.filter(
(candidate) => candidate.content_type === ContentType.Note
) as SNNote[];
for (const note of notes) {
const editor = this.editorForNote(note);
if (!editor) {
const noteController = this.noteControllerForNote(note);
if (!noteController) {
continue;
}
if (note.deleted) {
this.closeEditor(editor);
this.closeNoteController(noteController);
} else if (
note.trashed &&
!this.selectedTag?.isTrashTag &&
!this.searchOptions.includeTrashed
) {
this.closeEditor(editor);
this.closeNoteController(noteController);
} else if (
note.archived &&
!this.selectedTag?.isArchiveTag &&
!this.searchOptions.includeArchived &&
!this.application.getPreference(PrefKey.NotesShowArchived, false)
) {
this.closeEditor(editor);
this.closeNoteController(noteController);
}
}
}

View File

@@ -48,7 +48,7 @@ export class NoteTagsState {
}
get activeNote(): SNNote | undefined {
return this.appState.notes.activeEditor?.note;
return this.appState.notes.activeNoteController?.note;
}
get autocompleteTagHintVisible(): boolean {

View File

@@ -17,7 +17,7 @@ import {
runInAction,
} from 'mobx';
import { WebApplication } from '../application';
import { Editor } from '../editor';
import { NoteController } from '../note_controller';
import { AppState } from './app_state';
export class NotesState {
@@ -68,8 +68,8 @@ export class NotesState {
);
}
get activeEditor(): Editor | undefined {
return this.application.editorGroup.editors[0];
get activeNoteController(): NoteController | undefined {
return this.application.noteControllerGroup.noteControllers[0];
}
get selectedNotesCount(): number {
@@ -151,13 +151,13 @@ export class NotesState {
}
if (this.selectedNotesCount === 1) {
await this.openEditor(Object.keys(this.selectedNotes)[0]);
await this.openNote(Object.keys(this.selectedNotes)[0]);
}
}
}
private async openEditor(noteUuid: string): Promise<void> {
if (this.activeEditor?.note?.uuid === noteUuid) {
private async openNote(noteUuid: string): Promise<void> {
if (this.activeNoteController?.note?.uuid === noteUuid) {
return;
}
@@ -167,11 +167,11 @@ export class NotesState {
return;
}
if (this.activeEditor) {
this.application.editorGroup.closeActiveEditor();
if (this.activeNoteController) {
this.application.noteControllerGroup.closeActiveController();
}
await this.application.editorGroup.createEditor(noteUuid);
await this.application.noteControllerGroup.createNoteController(noteUuid);
this.appState.noteTags.reloadTags();
await this.onActiveEditorChanged();

View File

@@ -70,7 +70,7 @@ export class NotesViewState {
appObservers.push(
application.streamItems(ContentType.Note, () => {
this.reloadNotes();
const activeNote = this.appState.notes.activeEditor?.note;
const activeNote = this.appState.notes.activeNoteController?.note;
if (this.application.getAppState().notes.selectedNotesCount < 2) {
if (activeNote) {
const discarded = activeNote.deleted || activeNote.trashed;
@@ -102,7 +102,7 @@ export class NotesViewState {
this.reloadPreferences();
}, ApplicationEvent.PreferencesChanged),
application.addEventObserver(async () => {
this.appState.closeAllEditors();
this.appState.closeAllNoteControllers();
this.selectFirstNote();
this.setCompletedFullSync(false);
}, ApplicationEvent.SignedIn),
@@ -112,7 +112,7 @@ export class NotesViewState {
this.notes.length === 0 &&
this.appState.selectedTag?.isAllTag &&
this.noteFilterText === '' &&
!this.appState.notes.activeEditor
!this.appState.notes.activeNoteController
) {
this.createPlaceholderNote();
}
@@ -192,7 +192,7 @@ export class NotesViewState {
}
get activeEditorNote() {
return this.appState.notes.activeEditor?.note;
return this.appState.notes.activeNoteController?.note;
}
reloadPanelTitle = () => {
@@ -325,7 +325,7 @@ export class NotesViewState {
if (this.isFiltering) {
title = this.noteFilterText;
}
await this.appState.createEditor(title);
await this.appState.openNewNote(title);
this.reloadNotes();
this.appState.noteTags.reloadTags();
};
@@ -433,7 +433,7 @@ export class NotesViewState {
if (note) {
this.selectNote(note, false, false);
} else {
this.appState.closeActiveEditor();
this.appState.closeActiveNoteController();
}
};
@@ -464,7 +464,7 @@ export class NotesViewState {
};
handleEditorChange = async () => {
const activeNote = this.appState.getActiveEditor()?.note;
const activeNote = this.appState.getActiveNoteController()?.note;
if (activeNote && activeNote.conflictOf) {
this.application.changeAndSaveItem(activeNote.uuid, (mutator) => {
mutator.conflictOf = undefined;
@@ -502,7 +502,7 @@ export class NotesViewState {
this.activeEditorNote &&
!this.notes.includes(this.activeEditorNote)
) {
this.appState.closeActiveEditor();
this.appState.closeActiveNoteController();
}
}
};

View File

@@ -10,7 +10,7 @@ import { StatusManager } from '@/services/statusManager';
import { ThemeManager } from '@/services/themeManager';
import { PasswordWizardScope, PasswordWizardType } from '@/types';
import { AppState } from '@/ui_models/app_state';
import { EditorGroup } from '@/ui_models/editor_group';
import { NoteControllerGroup } from '@/ui_models/note_controller_group';
import { AppVersion } from '@/version';
import { WebDeviceInterface } from '@/web_device_interface';
import {
@@ -36,7 +36,7 @@ export class WebApplication extends SNApplication {
private scope?: angular.IScope;
private webServices!: WebServices;
private currentAuthenticationElement?: angular.IRootElementService;
public editorGroup: EditorGroup;
public noteControllerGroup: NoteControllerGroup;
/* @ngInject */
constructor(
@@ -66,7 +66,7 @@ export class WebApplication extends SNApplication {
this.$compile = $compile;
this.scope = scope;
deviceInterface.setApplication(this);
this.editorGroup = new EditorGroup(this);
this.noteControllerGroup = new NoteControllerGroup(this);
this.presentPermissionsDialog = this.presentPermissionsDialog.bind(this);
}
@@ -80,7 +80,7 @@ export class WebApplication extends SNApplication {
}
this.webServices = {} as WebServices;
(this.$compile as unknown) = undefined;
this.editorGroup.deinit();
this.noteControllerGroup.deinit();
(this.scope as any).application = undefined;
this.scope!.$destroy();
this.scope = undefined;

View File

@@ -1,79 +0,0 @@
import { removeFromArray, UuidString } from '@standardnotes/snjs';
import { Editor } from './editor';
import { WebApplication } from './application';
type EditorGroupChangeCallback = () => void;
export class EditorGroup {
public editors: Editor[] = [];
private application: WebApplication;
changeObservers: EditorGroupChangeCallback[] = [];
constructor(application: WebApplication) {
this.application = application;
}
public deinit() {
(this.application as unknown) = undefined;
for (const editor of this.editors) {
this.deleteEditor(editor);
}
}
async createEditor(
noteUuid?: string,
noteTitle?: string,
noteTag?: UuidString
) {
const editor = new Editor(this.application, noteUuid, noteTitle, noteTag);
await editor.initialize();
this.editors.push(editor);
this.notifyObservers();
}
deleteEditor(editor: Editor) {
editor.deinit();
removeFromArray(this.editors, editor);
}
closeEditor(editor: Editor) {
this.deleteEditor(editor);
this.notifyObservers();
}
closeActiveEditor() {
const activeEditor = this.activeEditor;
if (activeEditor) {
this.deleteEditor(activeEditor);
}
}
closeAllEditors() {
for (const editor of this.editors) {
this.deleteEditor(editor);
}
}
get activeEditor() {
return this.editors[0];
}
/**
* Notifies observer when the active editor has changed.
*/
public addChangeObserver(callback: EditorGroupChangeCallback) {
this.changeObservers.push(callback);
if (this.activeEditor) {
callback();
}
return () => {
removeFromArray(this.changeObservers, callback);
};
}
private notifyObservers() {
for (const observer of this.changeObservers) {
observer();
}
}
}

View File

@@ -7,7 +7,7 @@ import {
} from '@standardnotes/snjs';
import { WebApplication } from './application';
export class Editor {
export class NoteController {
public note!: SNNote;
private application: WebApplication;
private onNoteValueChange?: (note: SNNote, source: PayloadSource) => void;
@@ -28,7 +28,21 @@ export class Editor {
async initialize(): Promise<void> {
if (!this.note) {
await this.createTemplateNote(this.defaultTitle, this.defaultTag);
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();
}
@@ -67,29 +81,10 @@ export class Editor {
}
/**
* Reverts the editor to a blank state, removing any existing note from view,
* and creating a placeholder note.
*/
async createTemplateNote(defaultTitle?: string, noteTag?: UuidString) {
const note = (await this.application.createTemplateItem(ContentType.Note, {
text: '',
title: defaultTitle,
references: [],
})) as SNNote;
if (noteTag) {
const tag = this.application.findItem(noteTag) as SNTag;
await this.application.addTagHierarchyToNote(note, tag);
}
this.isTemplateNote = true;
this.note = note;
this.onNoteValueChange?.(this.note, this.note.payload.source);
}
/**
* Register to be notified when the editor's note's values change
* Register to be notified when the controller's note's inner values change
* (and thus a new object reference is created)
*/
public setOnNoteValueChange(
public setOnNoteInnerValueChange(
callback: (note: SNNote, source: PayloadSource) => void
) {
this.onNoteValueChange = callback;

View File

@@ -0,0 +1,84 @@
import { removeFromArray, UuidString } from '@standardnotes/snjs';
import { NoteController } from './note_controller';
import { WebApplication } from './application';
type NoteControllerGroupChangeCallback = () => void;
export class NoteControllerGroup {
public noteControllers: NoteController[] = [];
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.deleteController(controller);
}
}
async createNoteController(
noteUuid?: string,
noteTitle?: string,
noteTag?: UuidString
) {
const controller = new NoteController(
this.application,
noteUuid,
noteTitle,
noteTag
);
await controller.initialize();
this.noteControllers.push(controller);
this.notifyObservers();
}
deleteController(controller: NoteController) {
controller.deinit();
removeFromArray(this.noteControllers, controller);
}
closeController(controller: NoteController) {
this.deleteController(controller);
this.notifyObservers();
}
closeActiveController() {
const activeController = this.activeNoteController;
if (activeController) {
this.deleteController(activeController);
}
}
closeAllControllers() {
for (const controller of this.noteControllers) {
this.deleteController(controller);
}
}
get activeNoteController() {
return this.noteControllers[0];
}
/**
* Notifies observer when the active controller has changed.
*/
public addChangeObserver(callback: NoteControllerGroupChangeCallback) {
this.changeObservers.push(callback);
if (this.activeNoteController) {
callback();
}
return () => {
removeFromArray(this.changeObservers, callback);
};
}
private notifyObservers() {
for (const observer of this.changeObservers) {
observer();
}
}
}