diff --git a/app/models/Collection.js b/app/models/Collection.js index 91881f2e..625bb87b 100644 --- a/app/models/Collection.js +++ b/app/models/Collection.js @@ -11,7 +11,6 @@ import type { NavigationNode } from 'types'; class Collection extends BaseModel { isSaving: boolean = false; - hasPendingChanges: boolean = false; ui: UiStore; data: Object; @@ -109,7 +108,6 @@ class Collection extends BaseModel { runInAction('Collection#save', () => { invariant(res && res.data, 'Data should be available'); this.updateData(res.data); - this.hasPendingChanges = false; }); } catch (e) { this.ui.showToast('Collection failed saving'); diff --git a/app/models/Document.js b/app/models/Document.js index 883effcf..d45601cc 100644 --- a/app/models/Document.js +++ b/app/models/Document.js @@ -15,7 +15,6 @@ type SaveOptions = { publish?: boolean, done?: boolean, autosave?: boolean }; class Document extends BaseModel { isSaving: boolean = false; - hasPendingChanges: boolean = false; ui: *; store: *; @@ -209,7 +208,6 @@ class Document extends BaseModel { runInAction('Document#save', () => { invariant(res && res.data, 'Data should be available'); this.updateData(res.data); - this.hasPendingChanges = false; if (isCreating) { this.emit('documents.create', this); @@ -288,13 +286,12 @@ class Document extends BaseModel { a.click(); }; - updateData(data: Object = {}, dirty: boolean = false) { + updateData(data: Object = {}) { if (data.text) { const { title, emoji } = parseTitle(data.text); data.title = title; data.emoji = emoji; } - if (dirty) this.hasPendingChanges = true; extendObservable(this, data); } diff --git a/app/scenes/Document/Document.js b/app/scenes/Document/Document.js index 9b62fcb4..8bfc2999 100644 --- a/app/scenes/Document/Document.js +++ b/app/scenes/Document/Document.js @@ -70,6 +70,7 @@ class DocumentScene extends React.Component { @observable isUploading = false; @observable isSaving = false; @observable isPublishing = false; + @observable isDirty = false; @observable notFound = false; @observable moveModalOpen: boolean = false; @@ -117,6 +118,7 @@ class DocumentScene extends React.Component { props.match.params.documentSlug, { shareId } ); + this.isDirty = false; const document = this.document; @@ -167,7 +169,7 @@ class DocumentScene extends React.Component { if (!document) return; // get the latest version of the editor text value - const text = this.getEditorText(); + const text = this.getEditorText ? this.getEditorText() : document.text; // prevent autosave if nothing has changed if (options.autosave && document.text.trim() === text.trim()) return; @@ -183,6 +185,7 @@ class DocumentScene extends React.Component { this.isSaving = true; this.isPublishing = !!options.publish; document = await document.save(options); + this.isDirty = false; this.isSaving = false; this.isPublishing = false; @@ -199,6 +202,10 @@ class DocumentScene extends React.Component { this.onSave({ done: false, autosave: true }); }, AUTOSAVE_INTERVAL); + updateIsDirty = debounce(() => { + this.isDirty = this.getEditorText().trim() !== this.document.text.trim(); + }, 500); + onImageUploadStart = () => { this.isUploading = true; }; @@ -209,6 +216,7 @@ class DocumentScene extends React.Component { onChange = getEditorText => { this.getEditorText = getEditorText; + this.updateIsDirty(); this.autosave(); }; @@ -312,7 +320,7 @@ class DocumentScene extends React.Component { {this.isEditing && ( @@ -322,6 +330,7 @@ class DocumentScene extends React.Component {
{ document, isEditing, isDraft, + isDirty, isPublishing, isSaving, savingIsDisabled, @@ -161,13 +163,6 @@ class Header extends React.Component { Edit )} - {isEditing && - !isSaving && - document.hasPendingChanges && ( - - Discard - - )} {!isEditing && (