thredded 0.16.11 → 0.16.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/controllers/thredded/moderation_controller.rb +2 -0
- data/app/helpers/thredded/moderation_helper.rb +23 -0
- data/app/models/concerns/thredded/post_common.rb +9 -2
- data/app/models/concerns/thredded/topic_common.rb +16 -4
- data/app/models/thredded/messageboard.rb +27 -10
- data/app/models/thredded/messageboard_group.rb +3 -1
- data/app/models/thredded/post_moderation_record.rb +25 -0
- data/app/models/thredded/user_detail.rb +3 -1
- data/app/views/thredded/moderation/_post_moderation_record.html.erb +9 -3
- data/app/views/thredded/moderation/_post_moderation_record_content.html.erb +3 -0
- data/app/views/thredded/moderation/activity.html.erb +1 -1
- data/app/views/thredded/moderation/history.html.erb +1 -1
- data/app/views/thredded/moderation/pending.html.erb +1 -1
- data/app/views/thredded/posts_common/_header_with_user_and_topic.html.erb +4 -2
- data/lib/thredded.rb +7 -0
- data/lib/thredded/db_tools.rb +6 -5
- data/lib/thredded/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd9dbf548a2ae13d2c77b2a49e4022af13b17e5df084dc22baf370e37d7b1a2f
|
|
4
|
+
data.tar.gz: 6f21adfcf7f040ab397637f03f47df3c4f9f15d3956dfd4fb3a2a09b9a871ddd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 80692ab8668d1fdbcc60309774f2dcab3e8a6893b1a78892e9507ad4a9f70d9d91d174ce9277058622faba6d562c3187f4cf6dfa2aec92c97a9863a32b858b4f
|
|
7
|
+
data.tar.gz: dd5c3253a6df6f69512eb5acd778beb0ef7370be4b53b30fb03c865b6669af3e7e5217cc46e5feaf4695c1354cd9b748743b05f66edc94eff5c55a8ef810b886
|
data/README.md
CHANGED
|
@@ -95,7 +95,7 @@ Then, see the rest of this Readme for more information about using and customizi
|
|
|
95
95
|
Add the gem to your Gemfile:
|
|
96
96
|
|
|
97
97
|
```ruby
|
|
98
|
-
gem 'thredded', '~> 0.16.
|
|
98
|
+
gem 'thredded', '~> 0.16.12'
|
|
99
99
|
```
|
|
100
100
|
|
|
101
101
|
Add the Thredded [initializer] to your parent app by running the install generator.
|
|
@@ -19,6 +19,8 @@ module Thredded
|
|
|
19
19
|
@post_moderation_records = accessible_post_moderation_records
|
|
20
20
|
.order(created_at: :desc)
|
|
21
21
|
.send(Kaminari.config.page_method_name, current_page)
|
|
22
|
+
.preload(:messageboard, :post_user, :moderator, post: :postable)
|
|
23
|
+
.preload_first_topic_post
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def activity
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Thredded
|
|
4
|
+
module ModerationHelper
|
|
5
|
+
include ::Thredded::RenderHelper
|
|
6
|
+
|
|
7
|
+
# @param records [Array<Thredded::PostModerationRecord>]
|
|
8
|
+
def render_post_moderation_records(records)
|
|
9
|
+
records_with_post_contents = render_collection_to_strings_with_cache(
|
|
10
|
+
partial: 'thredded/moderation/post_moderation_record_content',
|
|
11
|
+
collection: records, as: :post_moderation_record, expires_in: 1.week,
|
|
12
|
+
locals: {
|
|
13
|
+
options: {
|
|
14
|
+
users_provider: ::Thredded::UsersProviderWithCache.new
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
render partial: 'thredded/moderation/post_moderation_record',
|
|
19
|
+
collection: records_with_post_contents,
|
|
20
|
+
as: :record_and_post_content
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -21,13 +21,20 @@ module Thredded
|
|
|
21
21
|
scope :preload_first_topic_post, -> {
|
|
22
22
|
posts_table_name = quoted_table_name
|
|
23
23
|
result = all
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
owners_by_id = result.each_with_object({}) { |r, h| h[r.postable_id] = r.postable }
|
|
25
|
+
next result if owners_by_id.empty?
|
|
26
|
+
preloader = ActiveRecord::Associations::Preloader.new.preload(
|
|
27
|
+
owners_by_id.values, :first_post,
|
|
26
28
|
unscoped.where(<<~SQL.delete("\n"))
|
|
27
29
|
#{posts_table_name}.created_at = (
|
|
28
30
|
SELECT MAX(p2.created_at) from #{posts_table_name} p2 WHERE p2.postable_id = #{posts_table_name}.postable_id)
|
|
29
31
|
SQL
|
|
30
32
|
)
|
|
33
|
+
preloader[0].preloaded_records.each do |post|
|
|
34
|
+
topic = owners_by_id.delete(post.postable_id)
|
|
35
|
+
next unless topic
|
|
36
|
+
topic.association(:first_post).target = post
|
|
37
|
+
end
|
|
31
38
|
result
|
|
32
39
|
}
|
|
33
40
|
|
|
@@ -14,7 +14,9 @@ module Thredded
|
|
|
14
14
|
scope :order_recently_posted_first, -> { order(last_post_at: :desc, id: :desc) }
|
|
15
15
|
scope :on_page, ->(page_num) { page(page_num) }
|
|
16
16
|
|
|
17
|
-
validates :hash_id,
|
|
17
|
+
validates :hash_id,
|
|
18
|
+
presence: true,
|
|
19
|
+
uniqueness: { case_sensitive: true }
|
|
18
20
|
validates :posts_count, numericality: true
|
|
19
21
|
|
|
20
22
|
validates :title, presence: true, length: { within: Thredded.topic_title_length_range }
|
|
@@ -53,9 +55,19 @@ module Thredded
|
|
|
53
55
|
topics = arel_table
|
|
54
56
|
reads_class = reflect_on_association(:user_read_states).klass
|
|
55
57
|
reads = reads_class.arel_table
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
.
|
|
58
|
+
|
|
59
|
+
joins_reads =
|
|
60
|
+
topics.outer_join(reads)
|
|
61
|
+
.on(topics[:id].eq(reads[:postable_id]).and(reads[:user_id].eq(user.id))).join_sources
|
|
62
|
+
|
|
63
|
+
unread_scope = reads_class.where(reads[:id].eq(nil).or(reads[:unread_posts_count].not_eq(0)))
|
|
64
|
+
|
|
65
|
+
# Work around https://github.com/rails/rails/issues/36761
|
|
66
|
+
if Thredded.rails_gte_600_rc_2?
|
|
67
|
+
merge(unread_scope).joins(joins_reads)
|
|
68
|
+
else
|
|
69
|
+
joins(joins_reads).merge(unread_scope)
|
|
70
|
+
end
|
|
59
71
|
end
|
|
60
72
|
|
|
61
73
|
private
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Thredded
|
|
4
|
-
class Messageboard < ActiveRecord::Base
|
|
4
|
+
class Messageboard < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
|
|
5
5
|
extend FriendlyId
|
|
6
6
|
friendly_id :slug_candidates,
|
|
7
7
|
use: %i[slugged reserved],
|
|
@@ -21,7 +21,10 @@ module Thredded
|
|
|
21
21
|
]
|
|
22
22
|
)
|
|
23
23
|
|
|
24
|
-
validates :name,
|
|
24
|
+
validates :name,
|
|
25
|
+
uniqueness: { case_sensitive: false },
|
|
26
|
+
length: { within: Thredded.messageboard_name_length_range },
|
|
27
|
+
presence: true
|
|
25
28
|
validates :topics_count, numericality: true
|
|
26
29
|
validates :position, presence: true, on: :update
|
|
27
30
|
before_save :ensure_position
|
|
@@ -128,14 +131,28 @@ module Thredded
|
|
|
128
131
|
messageboards = arel_table
|
|
129
132
|
read_states = Thredded::UserTopicReadState.arel_table
|
|
130
133
|
topics = topics_scope.arel_table
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
|
|
135
|
+
read_states_join_cond =
|
|
136
|
+
messageboards[:id].eq(read_states[:messageboard_id])
|
|
137
|
+
.and(read_states[:postable_id].eq(topics[:id]))
|
|
138
|
+
.and(read_states[:user_id].eq(user.id))
|
|
139
|
+
.and(read_states[:unread_posts_count].eq(0))
|
|
140
|
+
|
|
141
|
+
scope =
|
|
142
|
+
# Work around https://github.com/rails/rails/issues/36761
|
|
143
|
+
if Thredded.rails_gte_600_rc_2?
|
|
144
|
+
merge(topics_scope).joins(
|
|
145
|
+
messageboards.join(topics)
|
|
146
|
+
.on(topics[:messageboard_id].eq(messageboards[:id]))
|
|
147
|
+
.outer_join(read_states).on(read_states_join_cond).join_sources
|
|
148
|
+
)
|
|
149
|
+
else
|
|
150
|
+
joins(:topics).merge(topics_scope).joins(
|
|
151
|
+
messageboards.outer_join(read_states).on(read_states_join_cond).join_sources
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
scope.group(messageboards[:id]).pluck(
|
|
139
156
|
:id,
|
|
140
157
|
Arel::Nodes::Subtraction.new(topics[:id].count, read_states[:id].count)
|
|
141
158
|
).to_h
|
|
@@ -8,7 +8,9 @@ module Thredded
|
|
|
8
8
|
dependent: :nullify
|
|
9
9
|
|
|
10
10
|
scope :ordered, -> { order(position: :asc, id: :asc) }
|
|
11
|
-
validates :name,
|
|
11
|
+
validates :name,
|
|
12
|
+
presence: true,
|
|
13
|
+
uniqueness: { case_sensitive: false }
|
|
12
14
|
validates :position, presence: true, on: :update
|
|
13
15
|
before_save :ensure_position
|
|
14
16
|
|
|
@@ -27,8 +27,33 @@ module Thredded
|
|
|
27
27
|
record.errors.add attr, "Post moderation_state is already #{value}" if record.previous_moderation_state == value
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
scope :preload_first_topic_post, -> {
|
|
31
|
+
posts_table_name = Thredded::Post.quoted_table_name
|
|
32
|
+
result = all
|
|
33
|
+
owners_by_id = result.each_with_object({}) { |r, h| h[r.post.postable_id] = r.post.postable }
|
|
34
|
+
next result if owners_by_id.empty?
|
|
35
|
+
preloader = ActiveRecord::Associations::Preloader.new.preload(
|
|
36
|
+
owners_by_id.values, :first_post,
|
|
37
|
+
Thredded::Post.unscoped.where(<<~SQL.delete("\n"))
|
|
38
|
+
#{posts_table_name}.created_at = (
|
|
39
|
+
SELECT MAX(p2.created_at) from #{posts_table_name} p2 WHERE p2.postable_id = #{posts_table_name}.postable_id)
|
|
40
|
+
SQL
|
|
41
|
+
)
|
|
42
|
+
preloader[0].preloaded_records.each do |post|
|
|
43
|
+
topic = owners_by_id.delete(post.postable_id)
|
|
44
|
+
next unless topic
|
|
45
|
+
topic.association(:first_post).target = post
|
|
46
|
+
end
|
|
47
|
+
result
|
|
48
|
+
}
|
|
49
|
+
|
|
30
50
|
paginates_per Thredded.posts_per_page
|
|
31
51
|
|
|
52
|
+
# @return [ActiveRecord::Relation<Thredded.user_class>] users that can read the moderated post.
|
|
53
|
+
def post_readers
|
|
54
|
+
Thredded.user_class.thredded_messageboards_readers([messageboard])
|
|
55
|
+
end
|
|
56
|
+
|
|
32
57
|
# @param [Thredded.user_class] moderator
|
|
33
58
|
# @param [Thredded::Post] post
|
|
34
59
|
# @param [Symbol, String] previous_moderation_state
|
|
@@ -5,7 +5,9 @@ module Thredded
|
|
|
5
5
|
include Thredded::ModerationState
|
|
6
6
|
|
|
7
7
|
belongs_to :user, class_name: Thredded.user_class_name, inverse_of: :thredded_user_detail
|
|
8
|
-
validates :user_id,
|
|
8
|
+
validates :user_id,
|
|
9
|
+
uniqueness: { case_sensitive: true },
|
|
10
|
+
**(Thredded.rails_gte_51? ? {} : { presence: true })
|
|
9
11
|
|
|
10
12
|
with_options foreign_key: :user_id, primary_key: :user_id, inverse_of: :user_detail, dependent: :nullify do
|
|
11
13
|
has_many :topics, class_name: 'Thredded::Topic'
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<%
|
|
2
|
-
|
|
2
|
+
if local_assigns.key?(:record_and_post_content)
|
|
3
|
+
record, post_content = record_and_post_content
|
|
4
|
+
else
|
|
5
|
+
record = post_moderation_record
|
|
6
|
+
end
|
|
3
7
|
post = record.post
|
|
4
8
|
if post
|
|
5
9
|
post_view = Thredded::PostView.new(post, policy(post))
|
|
@@ -34,12 +38,14 @@
|
|
|
34
38
|
<% end %>
|
|
35
39
|
<% end %>
|
|
36
40
|
<% if post %>
|
|
37
|
-
<%= render 'thredded/posts_common/header_with_user_and_topic',
|
|
41
|
+
<%= render 'thredded/posts_common/header_with_user_and_topic',
|
|
42
|
+
post: post_view, user: record.post_user, post_user_link: post_user_link %>
|
|
38
43
|
<% else %>
|
|
39
44
|
<header><h2 class="thredded--post--user"><%= post_user_link %></h2></header>
|
|
40
45
|
<% end %>
|
|
41
46
|
<div class="thredded--post--content">
|
|
42
|
-
<%=
|
|
47
|
+
<%= post_content ||
|
|
48
|
+
render('thredded/moderation/post_moderation_record_content', post_moderation_record: record) %>
|
|
43
49
|
</div>
|
|
44
50
|
</article>
|
|
45
51
|
<%= render 'post_moderation_actions', post: post if post %>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<h1><%= t 'thredded.recent_activity' %></h1>
|
|
8
8
|
<% if @last_moderated_record %>
|
|
9
9
|
<div class="thredded--moderated-notice">
|
|
10
|
-
<%=
|
|
10
|
+
<%= render_post_moderation_records([@last_moderated_record]) %>
|
|
11
11
|
</div>
|
|
12
12
|
<% end %>
|
|
13
13
|
<% if @posts.present? %>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<%= thredded_page do %>
|
|
7
7
|
<section class="thredded--main-section">
|
|
8
8
|
<% if @post_moderation_records.present? %>
|
|
9
|
-
<%=
|
|
9
|
+
<%= render_post_moderation_records @post_moderation_records %>
|
|
10
10
|
<%= paginate @post_moderation_records %>
|
|
11
11
|
<% end %>
|
|
12
12
|
</section>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<section class="thredded--main-section">
|
|
7
7
|
<% if @last_moderated_record %>
|
|
8
8
|
<div class="thredded--moderated-notice">
|
|
9
|
-
<%=
|
|
9
|
+
<%= render_post_moderation_records([@last_moderated_record]) %>
|
|
10
10
|
</div>
|
|
11
11
|
<% end %>
|
|
12
12
|
<% if @posts.present? %>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<%# @param post [Thredded::PostView] %>
|
|
2
|
+
<%# @param user [Thredded.user_class] optional %>
|
|
2
3
|
<%# @param post_user_link [String] optional %>
|
|
3
4
|
<% topic = post.to_model.postable %>
|
|
4
|
-
<%
|
|
5
|
+
<% user ||= post.user %>
|
|
6
|
+
<% post_user_link ||= user_link(user) %>
|
|
5
7
|
<header>
|
|
6
|
-
<%= image_tag
|
|
8
|
+
<%= image_tag Thredded.avatar_url.call(user), class: 'thredded--post--avatar' if user %>
|
|
7
9
|
<h2 class="thredded--post--user-and-topic">
|
|
8
10
|
<%=
|
|
9
11
|
topic_link = link_to(topic.title, post.permalink_path)
|
data/lib/thredded.rb
CHANGED
|
@@ -251,6 +251,13 @@ module Thredded # rubocop:disable Metrics/ModuleLength
|
|
|
251
251
|
@rails_gte_51
|
|
252
252
|
end
|
|
253
253
|
|
|
254
|
+
# @api private
|
|
255
|
+
# Mainly to work around https://github.com/rails/rails/issues/36761
|
|
256
|
+
def rails_gte_600_rc_2?
|
|
257
|
+
@rails_gte_600_rc_2 = (Rails.gem_version >= Gem::Version.new('6.0.0.rc2')) if @rails_gte_600_rc_2.nil?
|
|
258
|
+
@rails_gte_600_rc_2
|
|
259
|
+
end
|
|
260
|
+
|
|
254
261
|
# @api private
|
|
255
262
|
def rails_supports_csp_nonce?
|
|
256
263
|
@rails_supports_csp_nonce = (Rails.gem_version >= Gem::Version.new('5.2.0')) if @rails_supports_csp_nonce.nil?
|
data/lib/thredded/db_tools.rb
CHANGED
|
@@ -9,13 +9,14 @@ module Thredded
|
|
|
9
9
|
def migrate(paths:, quiet:, &filter)
|
|
10
10
|
verbose_was = ActiveRecord::Migration.verbose
|
|
11
11
|
ActiveRecord::Migration.verbose = !quiet
|
|
12
|
-
migrate =
|
|
13
|
-
if Rails
|
|
14
|
-
ActiveRecord::MigrationContext.new(paths).migrate(nil, &filter)
|
|
12
|
+
migrate =
|
|
13
|
+
if Rails.gem_version >= Gem::Version.new('6.0.0.rc2')
|
|
14
|
+
-> { ActiveRecord::MigrationContext.new(paths, ActiveRecord::SchemaMigration).migrate(nil, &filter) }
|
|
15
|
+
elsif Rails::VERSION::STRING >= '5.2'
|
|
16
|
+
-> { ActiveRecord::MigrationContext.new(paths).migrate(nil, &filter) }
|
|
15
17
|
else
|
|
16
|
-
ActiveRecord::Migrator.migrate(paths, &filter)
|
|
18
|
+
-> { ActiveRecord::Migrator.migrate(paths, &filter) }
|
|
17
19
|
end
|
|
18
|
-
}
|
|
19
20
|
if quiet
|
|
20
21
|
silence_active_record(&migrate)
|
|
21
22
|
else
|
data/lib/thredded/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: thredded
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.16.
|
|
4
|
+
version: 0.16.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joel Oliveira
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2019-
|
|
12
|
+
date: 2019-07-26 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: active_record_union
|
|
@@ -130,6 +130,9 @@ dependencies:
|
|
|
130
130
|
- - ">="
|
|
131
131
|
- !ruby/object:Gem::Version
|
|
132
132
|
version: 4.2.10
|
|
133
|
+
- - "<="
|
|
134
|
+
- !ruby/object:Gem::Version
|
|
135
|
+
version: 6.0.0.rc2
|
|
133
136
|
type: :runtime
|
|
134
137
|
prerelease: false
|
|
135
138
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -137,6 +140,9 @@ dependencies:
|
|
|
137
140
|
- - ">="
|
|
138
141
|
- !ruby/object:Gem::Version
|
|
139
142
|
version: 4.2.10
|
|
143
|
+
- - "<="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: 6.0.0.rc2
|
|
140
146
|
- !ruby/object:Gem::Dependency
|
|
141
147
|
name: rb-gravatar
|
|
142
148
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -751,6 +757,7 @@ files:
|
|
|
751
757
|
- app/forms/thredded/user_preferences_form.rb
|
|
752
758
|
- app/helpers/thredded/application_helper.rb
|
|
753
759
|
- app/helpers/thredded/icon_helper.rb
|
|
760
|
+
- app/helpers/thredded/moderation_helper.rb
|
|
754
761
|
- app/helpers/thredded/nav_helper.rb
|
|
755
762
|
- app/helpers/thredded/render_helper.rb
|
|
756
763
|
- app/helpers/thredded/urls_helper.rb
|
|
@@ -854,6 +861,7 @@ files:
|
|
|
854
861
|
- app/views/thredded/moderation/_post.html.erb
|
|
855
862
|
- app/views/thredded/moderation/_post_moderation_actions.html.erb
|
|
856
863
|
- app/views/thredded/moderation/_post_moderation_record.html.erb
|
|
864
|
+
- app/views/thredded/moderation/_post_moderation_record_content.html.erb
|
|
857
865
|
- app/views/thredded/moderation/_user_moderation_state.html.erb
|
|
858
866
|
- app/views/thredded/moderation/_user_post.html.erb
|
|
859
867
|
- app/views/thredded/moderation/_users_search_form.html.erb
|