2018-06-19 14:13:14 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2013-02-06 03:16:51 +08:00
|
|
|
class Draft < ActiveRecord::Base
|
2018-11-15 00:47:59 +08:00
|
|
|
NEW_TOPIC ||= 'new_topic'
|
|
|
|
NEW_PRIVATE_MESSAGE ||= 'new_private_message'
|
|
|
|
EXISTING_TOPIC ||= 'topic_'
|
2013-02-06 03:16:51 +08:00
|
|
|
|
|
|
|
def self.set(user, key, sequence, data)
|
2018-11-15 00:47:59 +08:00
|
|
|
if d = find_draft(user, key)
|
2013-02-06 03:16:51 +08:00
|
|
|
return if d.sequence > sequence
|
2018-11-15 00:47:59 +08:00
|
|
|
|
|
|
|
DB.exec(<<~SQL, id: d.id, sequence: sequence, data: data)
|
|
|
|
UPDATE drafts
|
|
|
|
SET sequence = :sequence
|
|
|
|
, data = :data
|
|
|
|
, revisions = revisions + 1
|
|
|
|
WHERE id = :id
|
|
|
|
SQL
|
2013-02-06 03:16:51 +08:00
|
|
|
else
|
2013-10-02 10:17:27 +08:00
|
|
|
Draft.create!(user_id: user.id, draft_key: key, data: data, sequence: sequence)
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|
2018-06-19 14:13:14 +08:00
|
|
|
|
|
|
|
true
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.get(user, key, sequence)
|
2017-07-28 09:20:09 +08:00
|
|
|
d = find_draft(user, key)
|
2018-11-15 00:47:59 +08:00
|
|
|
d.data if d && d.sequence == sequence
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.clear(user, key, sequence)
|
2017-07-28 09:20:09 +08:00
|
|
|
d = find_draft(user, key)
|
2018-11-15 00:47:59 +08:00
|
|
|
d.destroy if d && d.sequence <= sequence
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|
|
|
|
|
2014-03-26 06:56:21 +08:00
|
|
|
def self.find_draft(user, key)
|
|
|
|
if user.is_a?(User)
|
|
|
|
find_by(user_id: user.id, draft_key: key)
|
|
|
|
else
|
|
|
|
find_by(user_id: user, draft_key: key)
|
|
|
|
end
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|
2015-06-02 11:45:47 +08:00
|
|
|
|
FEATURE: Drafts view in user profile
* add drafts.json endpoint, user profile tab with drafts stream
* improve drafts stream display in user profile
* truncate excerpts in drafts list, better handling for resume draft action
* improve draft stream SQL query, add rspec tests
* if composer is open, quietly close it when user opens another draft from drafts stream; load PM draft only when user is in /u/username/messages (instead of /u/username)
* cleanup
* linting fixes
* apply prettier styling to modified files
* add client tests for drafts, includes a fixture for drafts.json
* improvements to code following review
* refresh drafts route when user deletes a draft open in the composer while being in the drafts route; minor prettier scss fix
* added more spec tests, deleted an acceptance test for removing drafts that was too finicky, formatting and code style fixes, added appEvent for draft:destroyed
* prettier, eslint fixes
* use "username_lower" from users table, added error handling for rejected promises
* adds guardian spec for can_see_drafts, adds improvements following code review
* move DraftsController spec to its own file
* fix failing drafts qunit test, use getOwner instead of deprecated this.container
* limit test fixture for draft.json testing to new_topic request only
2018-08-01 14:34:54 +08:00
|
|
|
def self.stream(opts = nil)
|
|
|
|
opts ||= {}
|
|
|
|
|
|
|
|
user_id = opts[:user].id
|
|
|
|
offset = (opts[:offset] || 0).to_i
|
|
|
|
limit = (opts[:limit] || 30).to_i
|
|
|
|
|
|
|
|
# JOIN of topics table based on manipulating draft_key seems imperfect
|
|
|
|
builder = DB.build <<~SQL
|
|
|
|
SELECT
|
|
|
|
d.*, t.title, t.id topic_id, t.archetype,
|
|
|
|
t.category_id, t.closed topic_closed, t.archived topic_archived,
|
|
|
|
pu.username, pu.name, pu.id user_id, pu.uploaded_avatar_id, pu.username_lower,
|
|
|
|
du.username draft_username, NULL as raw, NULL as cooked, NULL as post_number
|
|
|
|
FROM drafts d
|
2018-08-02 05:41:27 +08:00
|
|
|
LEFT JOIN LATERAL json_extract_path_text (d.data::json, 'postId') postId ON TRUE
|
|
|
|
LEFT JOIN posts p ON postId :: BIGINT = p.id
|
FEATURE: Drafts view in user profile
* add drafts.json endpoint, user profile tab with drafts stream
* improve drafts stream display in user profile
* truncate excerpts in drafts list, better handling for resume draft action
* improve draft stream SQL query, add rspec tests
* if composer is open, quietly close it when user opens another draft from drafts stream; load PM draft only when user is in /u/username/messages (instead of /u/username)
* cleanup
* linting fixes
* apply prettier styling to modified files
* add client tests for drafts, includes a fixture for drafts.json
* improvements to code following review
* refresh drafts route when user deletes a draft open in the composer while being in the drafts route; minor prettier scss fix
* added more spec tests, deleted an acceptance test for removing drafts that was too finicky, formatting and code style fixes, added appEvent for draft:destroyed
* prettier, eslint fixes
* use "username_lower" from users table, added error handling for rejected promises
* adds guardian spec for can_see_drafts, adds improvements following code review
* move DraftsController spec to its own file
* fix failing drafts qunit test, use getOwner instead of deprecated this.container
* limit test fixture for draft.json testing to new_topic request only
2018-08-01 14:34:54 +08:00
|
|
|
LEFT JOIN topics t ON
|
|
|
|
CASE
|
|
|
|
WHEN d.draft_key LIKE '%' || '#{EXISTING_TOPIC}' || '%'
|
|
|
|
THEN CAST(replace(d.draft_key, '#{EXISTING_TOPIC}', '') AS INT)
|
|
|
|
ELSE 0
|
|
|
|
END = t.id
|
2018-08-02 05:41:27 +08:00
|
|
|
JOIN users pu on pu.id = COALESCE(p.user_id, t.user_id, d.user_id)
|
FEATURE: Drafts view in user profile
* add drafts.json endpoint, user profile tab with drafts stream
* improve drafts stream display in user profile
* truncate excerpts in drafts list, better handling for resume draft action
* improve draft stream SQL query, add rspec tests
* if composer is open, quietly close it when user opens another draft from drafts stream; load PM draft only when user is in /u/username/messages (instead of /u/username)
* cleanup
* linting fixes
* apply prettier styling to modified files
* add client tests for drafts, includes a fixture for drafts.json
* improvements to code following review
* refresh drafts route when user deletes a draft open in the composer while being in the drafts route; minor prettier scss fix
* added more spec tests, deleted an acceptance test for removing drafts that was too finicky, formatting and code style fixes, added appEvent for draft:destroyed
* prettier, eslint fixes
* use "username_lower" from users table, added error handling for rejected promises
* adds guardian spec for can_see_drafts, adds improvements following code review
* move DraftsController spec to its own file
* fix failing drafts qunit test, use getOwner instead of deprecated this.container
* limit test fixture for draft.json testing to new_topic request only
2018-08-01 14:34:54 +08:00
|
|
|
JOIN users du on du.id = #{user_id}
|
|
|
|
/*where*/
|
|
|
|
/*order_by*/
|
|
|
|
/*offset*/
|
|
|
|
/*limit*/
|
|
|
|
SQL
|
|
|
|
|
|
|
|
builder
|
|
|
|
.where('d.user_id = :user_id', user_id: user_id.to_i)
|
|
|
|
.order_by('d.updated_at desc')
|
|
|
|
.offset(offset)
|
|
|
|
.limit(limit)
|
|
|
|
.query
|
|
|
|
end
|
|
|
|
|
2015-06-02 11:45:47 +08:00
|
|
|
def self.cleanup!
|
2018-11-15 00:47:59 +08:00
|
|
|
DB.exec(<<~SQL)
|
|
|
|
DELETE FROM drafts
|
|
|
|
WHERE sequence < (
|
|
|
|
SELECT MAX(s.sequence)
|
|
|
|
FROM draft_sequences s
|
|
|
|
WHERE s.draft_key = drafts.draft_key
|
|
|
|
AND s.user_id = drafts.user_id
|
|
|
|
)
|
|
|
|
SQL
|
2015-06-03 16:52:41 +08:00
|
|
|
|
|
|
|
# remove old drafts
|
|
|
|
delete_drafts_older_than_n_days = SiteSetting.delete_drafts_older_than_n_days.days.ago
|
|
|
|
Draft.where("updated_at < ?", delete_drafts_older_than_n_days).destroy_all
|
2015-06-02 11:45:47 +08:00
|
|
|
end
|
|
|
|
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|
2013-05-24 10:48:32 +08:00
|
|
|
|
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: drafts
|
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# user_id :integer not null
|
2018-02-20 14:28:58 +08:00
|
|
|
# draft_key :string not null
|
2013-05-24 10:48:32 +08:00
|
|
|
# data :text not null
|
2014-08-27 13:19:25 +08:00
|
|
|
# created_at :datetime not null
|
|
|
|
# updated_at :datetime not null
|
2013-05-24 10:48:32 +08:00
|
|
|
# sequence :integer default(0), not null
|
2015-09-18 08:41:10 +08:00
|
|
|
# revisions :integer default(1), not null
|
2013-05-24 10:48:32 +08:00
|
|
|
#
|
|
|
|
# Indexes
|
|
|
|
#
|
|
|
|
# index_drafts_on_user_id_and_draft_key (user_id,draft_key)
|
|
|
|
#
|