mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
Added background save every 10 minutes to the lexical editor (#16732)
refs TryGhost/Team#3133 - the backend previously had logic to save a revision if more than 10 mins had elapsed since the last revision - however, the frontend would autosave after 3 seconds of inactivity (which doesn't trigger a revision), and never send another save request at 10 minutes, so the backend logic to save a revision was never triggered - this change will save the current contents of the editor every 10 minutes, even if nothing has changed since the last save
This commit is contained in:
parent
53071dccd6
commit
b62a642084
2 changed files with 26 additions and 4 deletions
|
@ -30,6 +30,8 @@ const DEFAULT_TITLE = '(Untitled)';
|
||||||
const AUTOSAVE_TIMEOUT = 3000;
|
const AUTOSAVE_TIMEOUT = 3000;
|
||||||
// time in ms to force a save if the user is continuously typing
|
// time in ms to force a save if the user is continuously typing
|
||||||
const TIMEDSAVE_TIMEOUT = 60000;
|
const TIMEDSAVE_TIMEOUT = 60000;
|
||||||
|
// time in ms to force a save even if the post is already saved so we trigger a new revision on the server
|
||||||
|
const REVISIONSAVE_TIMEOUT = 1000 * 60 * 10; // 10 minutes
|
||||||
|
|
||||||
// this array will hold properties we need to watch for this.hasDirtyAttributes
|
// this array will hold properties we need to watch for this.hasDirtyAttributes
|
||||||
let watchedProps = [
|
let watchedProps = [
|
||||||
|
@ -190,12 +192,13 @@ export default class LexicalEditorController extends Controller {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed('_autosaveTask.isRunning', '_timedSaveTask.isRunning')
|
@computed('_autosaveTask.isRunning', '_timedSaveTask.isRunning', '_revisionSaveTask.isRunning')
|
||||||
get _autosaveRunning() {
|
get _autosaveRunning() {
|
||||||
let autosave = this.get('_autosaveTask.isRunning');
|
let autosave = this.get('_autosaveTask.isRunning');
|
||||||
let timedsave = this.get('_timedSaveTask.isRunning');
|
let timedsave = this.get('_timedSaveTask.isRunning');
|
||||||
|
let revisionsave = this.get('_revisionSaveTask.isRunning');
|
||||||
|
|
||||||
return autosave || timedsave;
|
return autosave || timedsave || revisionsave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed('post.isDraft')
|
@computed('post.isDraft')
|
||||||
|
@ -211,6 +214,8 @@ export default class LexicalEditorController extends Controller {
|
||||||
this._autosaveTask.perform();
|
this._autosaveTask.perform();
|
||||||
// force save at 60 seconds
|
// force save at 60 seconds
|
||||||
this._timedSaveTask.perform();
|
this._timedSaveTask.perform();
|
||||||
|
// force save at 10 minutes to trigger revision
|
||||||
|
this._revisionSaveTask.perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -245,6 +250,7 @@ export default class LexicalEditorController extends Controller {
|
||||||
cancelAutosave() {
|
cancelAutosave() {
|
||||||
this._autosaveTask.cancelAll();
|
this._autosaveTask.cancelAll();
|
||||||
this._timedSaveTask.cancelAll();
|
this._timedSaveTask.cancelAll();
|
||||||
|
this._revisionSaveTask.cancelAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by the "are you sure?" modal
|
// called by the "are you sure?" modal
|
||||||
|
@ -427,7 +433,7 @@ export default class LexicalEditorController extends Controller {
|
||||||
|
|
||||||
this.cancelAutosave();
|
this.cancelAutosave();
|
||||||
|
|
||||||
if (options.backgroundSave && !this.hasDirtyAttributes && !options.leavingEditor) {
|
if (options.backgroundSave && !this.hasDirtyAttributes && !options.leavingEditor && !options.saveRevision) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,6 +487,9 @@ export default class LexicalEditorController extends Controller {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Even if we've just saved and nothing else has changed, we want to save in 10 minutes to force a revision
|
||||||
|
this._revisionSaveTask.perform();
|
||||||
|
|
||||||
return post;
|
return post;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!this.session.isAuthenticated) {
|
if (!this.session.isAuthenticated) {
|
||||||
|
@ -968,6 +977,19 @@ export default class LexicalEditorController extends Controller {
|
||||||
}).drop())
|
}).drop())
|
||||||
_timedSaveTask;
|
_timedSaveTask;
|
||||||
|
|
||||||
|
// save at 10 minutes even if the post is already saved
|
||||||
|
@(task(function* () {
|
||||||
|
if (!this._canAutosave) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (config.environment !== 'test' && true) {
|
||||||
|
yield timeout(REVISIONSAVE_TIMEOUT);
|
||||||
|
this.autosaveTask.perform({saveRevision: true});
|
||||||
|
}
|
||||||
|
}).drop())
|
||||||
|
_revisionSaveTask;
|
||||||
|
|
||||||
/* Private methods -------------------------------------------------------*/
|
/* Private methods -------------------------------------------------------*/
|
||||||
|
|
||||||
_hasDirtyAttributes() {
|
_hasDirtyAttributes() {
|
||||||
|
|
|
@ -915,7 +915,7 @@ Post = ghostBookshelf.Model.extend({
|
||||||
const revisionModels = await ghostBookshelf.model('PostRevision')
|
const revisionModels = await ghostBookshelf.model('PostRevision')
|
||||||
.findAll(Object.assign({
|
.findAll(Object.assign({
|
||||||
filter: `post_id:${model.id}`,
|
filter: `post_id:${model.id}`,
|
||||||
columns: ['id', 'lexical', 'created_at', 'author_id', 'title', 'reason', 'post_status', 'created_at_ts']
|
columns: ['id', 'lexical', 'created_at', 'author_id', 'title', 'reason', 'post_status', 'created_at_ts', 'feature_image']
|
||||||
}, _.pick(options, 'transacting')));
|
}, _.pick(options, 'transacting')));
|
||||||
|
|
||||||
const revisions = revisionModels.toJSON();
|
const revisions = revisionModels.toJSON();
|
||||||
|
|
Loading…
Add table
Reference in a new issue