mirror of
https://github.com/discourse/discourse.git
synced 2025-02-20 11:48:26 -06:00
FIX: never save draft while it is saving
Previously if saving a draft took longer than 2 seconds there could be conditions where drafts could be saved concurrently. This meant the composer could race with itself and raise conflicts. This is likely to happen on bad internet connections or where latency is really high. Additionally a throttle was added so drafts save unconditionally every 15 seconds. Save draft in the model now properly and consistently returns a promise.
This commit is contained in:
parent
a849bdf0c9
commit
ce4b5b56e5
@ -1095,7 +1095,13 @@ export default Controller.extend({
|
||||
_saveDraft() {
|
||||
const model = this.model;
|
||||
if (model) {
|
||||
model.saveDraft();
|
||||
if (model.draftSaving) {
|
||||
debounce(this, this._saveDraft, 2000);
|
||||
} else {
|
||||
model.saveDraft().finally(() => {
|
||||
this._lastDraftSaved = Date.now();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1107,7 +1113,15 @@ export default Controller.extend({
|
||||
!this.skipAutoSave &&
|
||||
!this.model.disableDrafts
|
||||
) {
|
||||
debounce(this, this._saveDraft, 2000);
|
||||
if (!this._lastDraftSaved) {
|
||||
// pretend so we get a save unconditionally in 15 secs
|
||||
this._lastDraftSaved = Date.now();
|
||||
}
|
||||
if (Date.now() - this._lastDraftSaved > 15000) {
|
||||
this._saveDraft();
|
||||
} else {
|
||||
debounce(this, this._saveDraft, 2000);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1086,12 +1086,14 @@ const Composer = RestModel.extend({
|
||||
},
|
||||
|
||||
saveDraft() {
|
||||
if (this.draftSaving) return Promise.resolve();
|
||||
|
||||
// Do not save when drafts are disabled
|
||||
if (this.disableDrafts) return;
|
||||
if (this.disableDrafts) return Promise.resolve();
|
||||
|
||||
if (this.canEditTitle) {
|
||||
// Save title and/or post body
|
||||
if (!this.title && !this.reply) return;
|
||||
if (!this.title && !this.reply) return Promise.resolve();
|
||||
|
||||
if (
|
||||
this.title &&
|
||||
@ -1099,14 +1101,15 @@ const Composer = RestModel.extend({
|
||||
this.reply &&
|
||||
this.replyLength < this.siteSettings.min_post_length
|
||||
) {
|
||||
return;
|
||||
return Promise.resolve();
|
||||
}
|
||||
} else {
|
||||
// Do not save when there is no reply
|
||||
if (!this.reply) return;
|
||||
if (!this.reply) return Promise.resolve();
|
||||
|
||||
// Do not save when the reply's length is too small
|
||||
if (this.replyLength < this.siteSettings.min_post_length) return;
|
||||
if (this.replyLength < this.siteSettings.min_post_length)
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
this.setProperties({
|
||||
@ -1138,13 +1141,11 @@ const Composer = RestModel.extend({
|
||||
}
|
||||
if (result.conflict_user) {
|
||||
this.setProperties({
|
||||
draftSaving: false,
|
||||
draftStatus: I18n.t("composer.edit_conflict"),
|
||||
draftConflictUser: result.conflict_user
|
||||
});
|
||||
} else {
|
||||
this.setProperties({
|
||||
draftSaving: false,
|
||||
draftSaved: true,
|
||||
draftConflictUser: null
|
||||
});
|
||||
@ -1169,10 +1170,12 @@ const Composer = RestModel.extend({
|
||||
}
|
||||
|
||||
this.setProperties({
|
||||
draftSaving: false,
|
||||
draftStatus: draftStatus || I18n.t("composer.drafts_offline"),
|
||||
draftConflictUser: null
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
this.set("draftSaving", false);
|
||||
});
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user