From 62d2c700b8647c3aa7ace040de92bde39c5a3d04 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Fri, 14 Jun 2019 11:38:43 -0500 Subject: [PATCH] Handle changes in same ms as lastCommitTime, committed but not finished, when sending --- .../composer-editor/composer-editor.tsx | 5 +-- app/src/flux/stores/draft-change-set.ts | 36 +++++++++++++------ app/src/flux/stores/draft-editing-session.ts | 2 +- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/app/src/components/composer-editor/composer-editor.tsx b/app/src/components/composer-editor/composer-editor.tsx index afcef3cc2..5ff8aa5b6 100644 --- a/app/src/components/composer-editor/composer-editor.tsx +++ b/app/src/components/composer-editor/composer-editor.tsx @@ -284,10 +284,7 @@ export class ComposerEditor extends React.Component { }} onDrop={(e: any, editor, next) => { if (onDrop) onDrop(e as React.DragEvent); - if (!e.isPropagationStopped()) { - console.log('Running default darg drop'); - next(); - } + if (!e.isPropagationStopped()) next(); }} onCut={this.onCut} onCopy={this.onCopy} diff --git a/app/src/flux/stores/draft-change-set.ts b/app/src/flux/stores/draft-change-set.ts index b4f363181..22c3ceaca 100644 --- a/app/src/flux/stores/draft-change-set.ts +++ b/app/src/flux/stores/draft-change-set.ts @@ -1,5 +1,4 @@ import EventEmitter from 'events'; -import { Message } from '../models/message'; const MetadataChangePrefix = 'metadata.'; @@ -29,13 +28,14 @@ export class DraftChangeSet extends EventEmitter { pluginMetadata?: number; } = {}; _lastCommitTime = 0; + _commitPromise: Promise = null; constructor(callbacks) { super(); this.callbacks = callbacks; } - cancelCommit() { + clearDelayedCommit() { if (this._timer) { clearTimeout(this._timer); this._timerStarted = null; @@ -48,9 +48,9 @@ export class DraftChangeSet extends EventEmitter { changes.pristine = false; // update the per-attribute flags that track our dirty state - for (const key of Object.keys(changes)) this._lastModifiedTimes[key] = Date.now(); - if (changes.bodyEditorState) this._lastModifiedTimes.body = Date.now(); - if (changes.body) this._lastModifiedTimes.bodyEditorState = Date.now(); + for (const key of Object.keys(changes)) this._lastModifiedTimes[key] = performance.now(); + if (changes.bodyEditorState) this._lastModifiedTimes.body = performance.now(); + if (changes.body) this._lastModifiedTimes.bodyEditorState = performance.now(); this.debounceCommit(); } @@ -58,7 +58,7 @@ export class DraftChangeSet extends EventEmitter { } addPluginMetadata(pluginId, metadata) { - this._lastModifiedTimes.pluginMetadata = Date.now(); + this._lastModifiedTimes.pluginMetadata = performance.now(); this.callbacks.onAddChanges({ [`${MetadataChangePrefix}${pluginId}`]: metadata }); this.debounceCommit(); } @@ -82,15 +82,29 @@ export class DraftChangeSet extends EventEmitter { if (this._timer && now - this._timerStarted < SaveAfterIdleSlushMSec) { return; } - this.cancelCommit(); + this.clearDelayedCommit(); this._timerStarted = now; this._timer = setTimeout(() => this.commit(), SaveAfterIdleMSec); } + /* + The `commit` method flushes the changes from the editor to SQLite. It's extremely important + that this method does not resolve until everything has been saved. However: + + - A commit (triggered by a timer) may already be running when this function is called. + We may not need to save again, but we need to block until that save completes. + */ async commit() { - if (this.dirtyFields().length === 0) return; - if (this._timer) clearTimeout(this._timer); - await this.callbacks.onCommit(); - this._lastCommitTime = Date.now(); + if (this._commitPromise) { + await this._commitPromise; + } + + if (this.dirtyFields().length > 0) { + this.clearDelayedCommit(); + this._commitPromise = this.callbacks.onCommit(); + await this._commitPromise; + this._lastCommitTime = performance.now(); + this._commitPromise = null; + } } } diff --git a/app/src/flux/stores/draft-editing-session.ts b/app/src/flux/stores/draft-editing-session.ts index 61bdaabef..1209197f0 100644 --- a/app/src/flux/stores/draft-editing-session.ts +++ b/app/src/flux/stores/draft-editing-session.ts @@ -158,7 +158,7 @@ export class DraftEditingSession extends MailspringStore { teardown() { this.stopListeningToAll(); - this.changes.cancelCommit(); + this.changes.clearDelayedCommit(); this._destroyed = true; this._mountedEditor = null; }