feat: move save method into snjs controller (#809)
* feat: move editor save method to snjs note controller
This commit is contained in:
@@ -25,13 +25,6 @@ export const STRING_DELETE_TAG =
|
||||
export const STRING_MISSING_SYSTEM_TAG = 'We are missing a System Tag.';
|
||||
|
||||
/** @editor */
|
||||
export const STRING_SAVING_WHILE_DOCUMENT_HIDDEN =
|
||||
'Attempting to save an item while the application is hidden. To protect data integrity, please refresh the application window and try again.';
|
||||
export const STRING_DELETED_NOTE =
|
||||
'The note you are attempting to edit has been deleted, and is awaiting sync. Changes you make will be disregarded.';
|
||||
export const STRING_INVALID_NOTE =
|
||||
"The note you are attempting to save can not be found or has been deleted. Changes you make will not be synced. Please copy this note's text and start a new note.";
|
||||
export const STRING_ELLIPSES = '...';
|
||||
export const STRING_GENERIC_SAVE_ERROR =
|
||||
'There was an error saving your note. Please try again.';
|
||||
export const STRING_DELETE_PLACEHOLDER_ATTEMPT =
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { STRING_SAVING_WHILE_DOCUMENT_HIDDEN } from './../../strings';
|
||||
import { WebApplication } from '@/ui_models/application';
|
||||
import { PanelPuppet, WebDirective } from '@/types';
|
||||
import angular from 'angular';
|
||||
@@ -27,9 +26,6 @@ import template from './note-view.pug';
|
||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||
import { EventSource } from '@/ui_models/app_state';
|
||||
import {
|
||||
STRING_DELETED_NOTE,
|
||||
STRING_INVALID_NOTE,
|
||||
STRING_ELLIPSES,
|
||||
STRING_DELETE_PLACEHOLDER_ATTEMPT,
|
||||
STRING_DELETE_LOCKED_ATTEMPT,
|
||||
STRING_EDIT_LOCKED_ATTEMPT,
|
||||
@@ -37,10 +33,7 @@ import {
|
||||
} from '@/strings';
|
||||
import { confirmDialog } from '@/services/alertService';
|
||||
|
||||
const NOTE_PREVIEW_CHAR_LIMIT = 80;
|
||||
const MINIMUM_STATUS_DURATION = 400;
|
||||
const SAVE_TIMEOUT_DEBOUNCE = 350;
|
||||
const SAVE_TIMEOUT_NO_DEBOUNCE = 100;
|
||||
const EDITOR_DEBOUNCE = 100;
|
||||
|
||||
const ElementIds = {
|
||||
@@ -97,7 +90,6 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
|
||||
private leftPanelPuppet?: PanelPuppet;
|
||||
private rightPanelPuppet?: PanelPuppet;
|
||||
private saveTimeout?: ng.IPromise<void>;
|
||||
private statusTimeout?: ng.IPromise<void>;
|
||||
private lastEditorFocusEventSource?: EventSource;
|
||||
public editorValues: EditorValues = { title: '', text: '' };
|
||||
@@ -152,7 +144,6 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
this.leftPanelPuppet = undefined;
|
||||
this.rightPanelPuppet = undefined;
|
||||
this.onEditorComponentLoad = undefined;
|
||||
this.saveTimeout = undefined;
|
||||
this.statusTimeout = undefined;
|
||||
(this.onPanelResizeFinish as unknown) = undefined;
|
||||
(this.editorMenuOnSelect as unknown) = undefined;
|
||||
@@ -483,13 +474,16 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
const transactions: TransactionalMutation[] = [];
|
||||
|
||||
this.setMenuState('showEditorMenu', false);
|
||||
|
||||
if (this.appState.getActiveNoteController()?.isTemplateNote) {
|
||||
await this.appState.getActiveNoteController().insertTemplatedNote();
|
||||
}
|
||||
|
||||
if (this.note.locked) {
|
||||
this.application.alertService.alert(STRING_EDIT_LOCKED_ATTEMPT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!component) {
|
||||
if (!this.note.prefersPlainEditor) {
|
||||
transactions.push({
|
||||
@@ -546,83 +540,6 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bypassDebouncer Calling save will debounce by default. You can pass true to save
|
||||
* immediately.
|
||||
* @param isUserModified This field determines if the item will be saved as a user
|
||||
* modification, thus updating the user modified date displayed in the UI
|
||||
* @param dontUpdatePreviews Whether this change should update the note's plain and HTML
|
||||
* preview.
|
||||
* @param customMutate A custom mutator function.
|
||||
* @param closeAfterSync Whether this editor should be closed after the sync starts.
|
||||
* This allows us to make a destructive change, wait for sync to be triggered, then
|
||||
* close the editor (if we closed the editor before sync began, we'd get an exception,
|
||||
* since the debouncer will be triggered on a non-existent editor)
|
||||
*/
|
||||
async save(
|
||||
note: SNNote,
|
||||
editorValues: EditorValues,
|
||||
bypassDebouncer = false,
|
||||
isUserModified = false,
|
||||
dontUpdatePreviews = false,
|
||||
customMutate?: (mutator: NoteMutator) => void,
|
||||
closeAfterSync = false
|
||||
) {
|
||||
const title = editorValues.title;
|
||||
const text = editorValues.text;
|
||||
const isTemplate = this.controller.isTemplateNote;
|
||||
if (document.hidden) {
|
||||
this.application.alertService.alert(STRING_SAVING_WHILE_DOCUMENT_HIDDEN);
|
||||
return;
|
||||
}
|
||||
if (note.deleted) {
|
||||
this.application.alertService.alert(STRING_DELETED_NOTE);
|
||||
return;
|
||||
}
|
||||
if (isTemplate) {
|
||||
await this.controller.insertTemplatedNote();
|
||||
}
|
||||
if (!this.application.findItem(note.uuid)) {
|
||||
this.application.alertService.alert(STRING_INVALID_NOTE);
|
||||
return;
|
||||
}
|
||||
await this.application.changeItem(
|
||||
note.uuid,
|
||||
(mutator) => {
|
||||
const noteMutator = mutator as NoteMutator;
|
||||
if (customMutate) {
|
||||
customMutate(noteMutator);
|
||||
}
|
||||
noteMutator.title = title;
|
||||
noteMutator.text = text;
|
||||
if (!dontUpdatePreviews) {
|
||||
const noteText = text || '';
|
||||
const truncate = noteText.length > NOTE_PREVIEW_CHAR_LIMIT;
|
||||
const substring = noteText.substring(0, NOTE_PREVIEW_CHAR_LIMIT);
|
||||
const previewPlain = substring + (truncate ? STRING_ELLIPSES : '');
|
||||
// eslint-disable-next-line camelcase
|
||||
noteMutator.preview_plain = previewPlain;
|
||||
// eslint-disable-next-line camelcase
|
||||
noteMutator.preview_html = undefined;
|
||||
}
|
||||
},
|
||||
isUserModified
|
||||
);
|
||||
if (this.saveTimeout) {
|
||||
this.$timeout.cancel(this.saveTimeout);
|
||||
}
|
||||
const noDebounce = bypassDebouncer || this.application.noAccount();
|
||||
const syncDebouceMs = noDebounce
|
||||
? SAVE_TIMEOUT_NO_DEBOUNCE
|
||||
: SAVE_TIMEOUT_DEBOUNCE;
|
||||
this.saveTimeout = this.$timeout(() => {
|
||||
this.application.sync();
|
||||
if (closeAfterSync) {
|
||||
this.appState.closeNoteController(this.controller);
|
||||
}
|
||||
}, syncDebouceMs);
|
||||
}
|
||||
|
||||
showSavingStatus() {
|
||||
this.setStatus({ message: 'Saving…' }, false);
|
||||
}
|
||||
@@ -676,7 +593,10 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
}
|
||||
|
||||
contentChanged() {
|
||||
this.save(this.note, copyEditorValues(this.editorValues), false, true);
|
||||
this.controller.save({
|
||||
editorValues: copyEditorValues(this.editorValues),
|
||||
isUserModified: true,
|
||||
});
|
||||
}
|
||||
|
||||
onTitleEnter($event: Event) {
|
||||
@@ -686,13 +606,11 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
}
|
||||
|
||||
onTitleChange() {
|
||||
this.save(
|
||||
this.note,
|
||||
copyEditorValues(this.editorValues),
|
||||
false,
|
||||
true,
|
||||
true
|
||||
);
|
||||
this.controller.save({
|
||||
editorValues: copyEditorValues(this.editorValues),
|
||||
isUserModified: true,
|
||||
dontUpdatePreviews: true,
|
||||
});
|
||||
}
|
||||
|
||||
focusEditor() {
|
||||
@@ -744,16 +662,14 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
if (permanently) {
|
||||
this.performNoteDeletion(this.note);
|
||||
} else {
|
||||
this.save(
|
||||
this.note,
|
||||
copyEditorValues(this.editorValues),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
(mutator) => {
|
||||
this.controller.save({
|
||||
editorValues: copyEditorValues(this.editorValues),
|
||||
bypassDebouncer: true,
|
||||
dontUpdatePreviews: true,
|
||||
customMutate: (mutator) => {
|
||||
mutator.trashed = true;
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1022,7 +938,11 @@ export class NoteView extends PureViewCtrl<unknown, EditorState> {
|
||||
editor.selectionStart = editor.selectionEnd = start + 4;
|
||||
}
|
||||
this.editorValues.text = editor.value;
|
||||
this.save(this.note, copyEditorValues(this.editorValues), true);
|
||||
|
||||
this.controller.save({
|
||||
editorValues: copyEditorValues(this.editorValues),
|
||||
bypassDebouncer: true,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"@reach/disclosure": "^0.16.2",
|
||||
"@reach/visually-hidden": "^0.16.0",
|
||||
"@standardnotes/components": "^1.2.4",
|
||||
"@standardnotes/components": "^1.2.5",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"@types/angular": "^1.8.3",
|
||||
"@types/jest": "^27.0.3",
|
||||
@@ -87,9 +87,9 @@
|
||||
"@reach/dialog": "^0.16.2",
|
||||
"@reach/listbox": "^0.16.2",
|
||||
"@reach/tooltip": "^0.16.2",
|
||||
"@standardnotes/features": "1.20.5",
|
||||
"@standardnotes/features": "1.20.6",
|
||||
"@standardnotes/sncrypto-web": "1.5.3",
|
||||
"@standardnotes/snjs": "2.34.2",
|
||||
"@standardnotes/snjs": "2.35.0",
|
||||
"mobx": "^6.3.5",
|
||||
"mobx-react-lite": "^3.2.2",
|
||||
"preact": "^10.5.15",
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
"binary": "1928aa349a04471afd273725cc4befe711eeda91aca70aee00c7ad356241c252"
|
||||
},
|
||||
"org.standardnotes.theme-dynamic": {
|
||||
"version": "1.0.1",
|
||||
"base64": "ead03c37f6cb3b1858793db4433331143f916aebb3a13ab07637c27dcf310034",
|
||||
"binary": "fb93157b0249f577e7a5e58f8bb562e68435f683cc66f7adace12b935fa3eee1"
|
||||
"version": "1.0.2",
|
||||
"base64": "7a5075a265e67ae54cb7c49bad6aa8b6f84f8fb4883ca859327e8e794cbfff0c",
|
||||
"binary": "01a1356c879aa1ef38e856ee0028e6afbff1fa40544e24e3297af863d6cac669"
|
||||
},
|
||||
"org.standardnotes.code-editor": {
|
||||
"version": "1.3.8",
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
.section.tags {
|
||||
.section.tags,
|
||||
navigation {
|
||||
flex: none !important;
|
||||
width: 120px !important;
|
||||
transition: width 0.25s;
|
||||
}
|
||||
|
||||
.section.tags:hover {
|
||||
.section.tags:hover,
|
||||
navigation:hover {
|
||||
flex: initial;
|
||||
width: 180px !important;
|
||||
transition: width 0.25s;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAAA,aAAc;EACZ,IAAI,EAAE,eAAe;EACrB,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW;;;AAGzB,mBAAoB;EAClB,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW;;;AAGzB;UACW;EACT,IAAI,EAAE,eAAe;EACrB,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW;;;AAGzB;gBACiB;EACf,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW",
|
||||
"mappings": "AAAA;UACW;EACT,IAAI,EAAE,eAAe;EACrB,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW;;;AAGzB;gBACiB;EACf,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW;;;AAGzB;UACW;EACT,IAAI,EAAE,eAAe;EACrB,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW;;;AAGzB;gBACiB;EACf,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,gBAAgB;EACvB,UAAU,EAAE,WAAW",
|
||||
"sources": ["../src/main.scss"],
|
||||
"names": [],
|
||||
"file": "dist.css"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sn-theme-dynamic",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"main": "dist/dist.css",
|
||||
"devDependencies": {
|
||||
"grunt": "^1.0.1",
|
||||
|
||||
26
yarn.lock
26
yarn.lock
@@ -2616,10 +2616,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/common/-/common-1.2.1.tgz#9db212db86ccbf08b347da02549b3dbe4bedbb02"
|
||||
integrity sha512-HilBxS50CBlC6TJvy1mrnhGVDzOH63M/Jf+hyMxQ0Vt1nYzpd0iyxVEUrgMh7ZiyO1b9CLnCDED99Jy9rnZWVQ==
|
||||
|
||||
"@standardnotes/components@^1.2.4":
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/components/-/components-1.2.4.tgz#29cab333551e91d8c88c920a7d5e3bd863d55f17"
|
||||
integrity sha512-Ous0tCCnzIH4IHN/3y0C03XYlpTfxP+mfsPNJN/kPhC0Z+91OV+z6Y/qK1zxe6khsegUEO6k01qyPu5EJLhorg==
|
||||
"@standardnotes/components@^1.2.5":
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/components/-/components-1.2.5.tgz#3e1e959bc40e5e0d34a0a44ac68fda4b29807f8e"
|
||||
integrity sha512-/E87R6wpMK0nLeS6ugCyjHht3M5hqZUH4lWA179jE9N4A6WXYvlqcFYO4t2RiG6yErRPZOHfpUFFsL1agXVuwA==
|
||||
|
||||
"@standardnotes/domain-events@2.5.1":
|
||||
version "2.5.1"
|
||||
@@ -2628,10 +2628,10 @@
|
||||
dependencies:
|
||||
"@standardnotes/auth" "^3.8.1"
|
||||
|
||||
"@standardnotes/features@1.20.5", "@standardnotes/features@^1.20.5":
|
||||
version "1.20.5"
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/features/-/features-1.20.5.tgz#443e3ae84d13f0aaa35708c5c237dac8041cb50d"
|
||||
integrity sha512-4QQeWLk2frEF9UYOfnuQoulkUJ3PooVLasPUA+zva+KIokBiyPmVPsi3HAYXlHqowu+lDhKU2pUklLhm1ePvJw==
|
||||
"@standardnotes/features@1.20.6", "@standardnotes/features@^1.20.6":
|
||||
version "1.20.6"
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/features/-/features-1.20.6.tgz#94d397892dd12f76a10c89c70092933627a9c457"
|
||||
integrity sha512-/w8+/8J8UNJ+DAsOud8XbWkeUBN6eb+5+Ic4NgkXYkx/wv6sTDk9XVc+mOhxOkYlb2iy85JDmoLAwu+GW/3Gtg==
|
||||
dependencies:
|
||||
"@standardnotes/auth" "3.8.3"
|
||||
"@standardnotes/common" "1.2.1"
|
||||
@@ -2655,15 +2655,15 @@
|
||||
buffer "^6.0.3"
|
||||
libsodium-wrappers "^0.7.9"
|
||||
|
||||
"@standardnotes/snjs@2.34.2":
|
||||
version "2.34.2"
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.34.2.tgz#540f32252083f99ee635b900cc70aa19ed68e1f2"
|
||||
integrity sha512-JhhjAQ66sSHTnGSgTY5VSJU7Lv9fnX0X+SR/pPPi0Kv3gk+aqVi2Zmgf8htmigJSFtrmn2pXGSaJk1v92LFckw==
|
||||
"@standardnotes/snjs@2.35.0":
|
||||
version "2.35.0"
|
||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.35.0.tgz#c24d13d7be68767b865b9f3e728d21b473bbe006"
|
||||
integrity sha512-dbjFMlEShsgo8sjaiwEFtbvm6vZHIgylZEtzqcJxl0TzEEIO1q4baomzUFj0ayzmM7g7S38o7zBfj+2AoXxPeA==
|
||||
dependencies:
|
||||
"@standardnotes/auth" "3.8.1"
|
||||
"@standardnotes/common" "1.2.1"
|
||||
"@standardnotes/domain-events" "2.5.1"
|
||||
"@standardnotes/features" "^1.20.5"
|
||||
"@standardnotes/features" "^1.20.6"
|
||||
"@standardnotes/settings" "^1.9.0"
|
||||
"@standardnotes/sncrypto-common" "1.5.2"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user