FIX: only send originalText when we need to

This commit is contained in:
Régis Hanol
2018-11-14 17:47:59 +01:00
parent 1e15c16f77
commit c78dcde973
5 changed files with 65 additions and 57 deletions

View File

@ -975,9 +975,18 @@ const Composer = RestModel.extend({
if (this.get("replyLength") < this.siteSettings.min_post_length) return; if (this.get("replyLength") < this.siteSettings.min_post_length) return;
} }
this.setProperties({
draftStatus: I18n.t("composer.saving_draft_tip"),
draftConflictUser: null
});
if (this._clearingStatus) {
Em.run.cancel(this._clearingStatus);
this._clearingStatus = null;
}
const data = { const data = {
reply: this.get("reply"), reply: this.get("reply"),
originalText: this.get("originalText"),
action: this.get("action"), action: this.get("action"),
title: this.get("title"), title: this.get("title"),
categoryId: this.get("categoryId"), categoryId: this.get("categoryId"),
@ -992,14 +1001,8 @@ const Composer = RestModel.extend({
noBump: this.get("noBump") noBump: this.get("noBump")
}; };
this.setProperties({ if (this.get("post.id") && !Ember.isEmpty(this.get("originalText"))) {
draftStatus: I18n.t("composer.saving_draft_tip"), data["originalText"] = this.get("originalText");
draftConflictUser: null
});
if (this._clearingStatus) {
Em.run.cancel(this._clearingStatus);
this._clearingStatus = null;
} }
return Draft.save(this.get("draftKey"), this.get("draftSequence"), data) return Draft.save(this.get("draftKey"), this.get("draftSequence"), data)

View File

@ -5,10 +5,7 @@ Draft.reopenClass({
clear(key, sequence) { clear(key, sequence) {
return ajax("/draft.json", { return ajax("/draft.json", {
type: "DELETE", type: "DELETE",
data: { data: { draft_key: key, sequence }
draft_key: key,
sequence: sequence
}
}); });
}, },
@ -25,16 +22,10 @@ Draft.reopenClass({
}, },
save(key, sequence, data) { save(key, sequence, data) {
const dataJson = typeof data === "string" ? dataJson : JSON.stringify(data); data = typeof(data) === "string" ? data : JSON.stringify(data);
return ajax("/draft.json", { return ajax("/draft.json", {
type: "POST", type: "POST",
data: { data: { draft_key: key, sequence, data }
draft_key: key,
data: dataJson,
sequence,
post_id: data.postId,
original_text: data.originalText
}
}); });
} }
}); });

View File

@ -11,11 +11,13 @@ class DraftController < ApplicationController
def update def update
Draft.set(current_user, params[:draft_key], params[:sequence].to_i, params[:data]) Draft.set(current_user, params[:draft_key], params[:sequence].to_i, params[:data])
if params[:post_id] && params[:original_text] if data = JSON::parse(params[:data])
post = Post.find_by(id: params[:post_id]) if data["postId"].present? && data["originalText"].present?
if post && post.raw != params[:original_text] post = Post.find_by(id: data["postId"])
conflict_user = BasicUserSerializer.new(post.last_editor, root: false) if post && post.raw != data["originalText"]
return render json: success_json.merge(conflict_user: conflict_user) conflict_user = BasicUserSerializer.new(post.last_editor, root: false)
return render json: success_json.merge(conflict_user: conflict_user)
end
end end
end end

View File

@ -1,19 +1,21 @@
# frozen_string_literal: true # frozen_string_literal: true
class Draft < ActiveRecord::Base class Draft < ActiveRecord::Base
NEW_TOPIC = 'new_topic' NEW_TOPIC ||= 'new_topic'
NEW_PRIVATE_MESSAGE = 'new_private_message' NEW_PRIVATE_MESSAGE ||= 'new_private_message'
EXISTING_TOPIC = 'topic_' EXISTING_TOPIC ||= 'topic_'
def self.set(user, key, sequence, data) def self.set(user, key, sequence, data)
d = find_draft(user, key) if d = find_draft(user, key)
if d
return if d.sequence > sequence return if d.sequence > sequence
DB.exec("UPDATE drafts
SET data = :data, DB.exec(<<~SQL, id: d.id, sequence: sequence, data: data)
sequence = :sequence, UPDATE drafts
revisions = revisions + 1 SET sequence = :sequence
WHERE id = :id", id: d.id, sequence: sequence, data: data) , data = :data
, revisions = revisions + 1
WHERE id = :id
SQL
else else
Draft.create!(user_id: user.id, draft_key: key, data: data, sequence: sequence) Draft.create!(user_id: user.id, draft_key: key, data: data, sequence: sequence)
end end
@ -23,16 +25,12 @@ class Draft < ActiveRecord::Base
def self.get(user, key, sequence) def self.get(user, key, sequence)
d = find_draft(user, key) d = find_draft(user, key)
if d && d.sequence == sequence d.data if d && d.sequence == sequence
d.data
end
end end
def self.clear(user, key, sequence) def self.clear(user, key, sequence)
d = find_draft(user, key) d = find_draft(user, key)
if d && d.sequence <= sequence d.destroy if d && d.sequence <= sequence
d.destroy
end
end end
def self.find_draft(user, key) def self.find_draft(user, key)
@ -83,11 +81,15 @@ class Draft < ActiveRecord::Base
end end
def self.cleanup! def self.cleanup!
DB.exec("DELETE FROM drafts where sequence < ( DB.exec(<<~SQL)
SELECT max(s.sequence) from draft_sequences s DELETE FROM drafts
WHERE s.draft_key = drafts.draft_key AND WHERE sequence < (
s.user_id = drafts.user_id SELECT MAX(s.sequence)
)") FROM draft_sequences s
WHERE s.draft_key = drafts.draft_key
AND s.user_id = drafts.user_id
)
SQL
# remove old drafts # remove old drafts
delete_drafts_older_than_n_days = SiteSetting.delete_drafts_older_than_n_days.days.ago delete_drafts_older_than_n_days = SiteSetting.delete_drafts_older_than_n_days.days.ago

View File

@ -8,9 +8,15 @@ describe DraftController do
it 'saves a draft on update' do it 'saves a draft on update' do
user = sign_in(Fabricate(:user)) user = sign_in(Fabricate(:user))
post "/draft.json", params: { draft_key: 'xyz', data: 'my data', sequence: 0 }
post "/draft.json", params: {
draft_key: 'xyz',
data: { my: "data" }.to_json,
sequence: 0
}
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(Draft.get(user, 'xyz', 0)).to eq('my data') expect(Draft.get(user, 'xyz', 0)).to eq(%q({"my":"data"}))
end end
it 'checks for an conflict on update' do it 'checks for an conflict on update' do
@ -21,9 +27,10 @@ describe DraftController do
username: user.username, username: user.username,
draft_key: "topic", draft_key: "topic",
sequence: 0, sequence: 0,
data: "{}", data: {
post_id: post.id, postId: post.id,
original_text: post.raw originalText: post.raw
}.to_json
} }
expect(JSON.parse(response.body)['conflict_user']).to eq(nil) expect(JSON.parse(response.body)['conflict_user']).to eq(nil)
@ -32,13 +39,16 @@ describe DraftController do
username: user.username, username: user.username,
draft_key: "topic", draft_key: "topic",
sequence: 0, sequence: 0,
data: "{}", data: {
post_id: post.id, postId: post.id,
original_text: "something else" originalText: "something else"
}.to_json
} }
expect(JSON.parse(response.body)['conflict_user']['id']).to eq(post.last_editor.id) json = JSON.parse(response.body)
expect(JSON.parse(response.body)['conflict_user']).to include('avatar_template')
expect(json['conflict_user']['id']).to eq(post.last_editor.id)
expect(json['conflict_user']).to include('avatar_template')
end end
it 'destroys drafts when required' do it 'destroys drafts when required' do