decidim-comments 0.31.4 → 0.32.0.rc1
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 +18 -16
- data/app/cells/decidim/comments/comment/deletion_data.erb +3 -7
- data/app/cells/decidim/comments/comment/replies.erb +23 -3
- data/app/cells/decidim/comments/comment/show.erb +5 -19
- data/app/cells/decidim/comments/comment_cell.rb +10 -6
- data/app/cells/decidim/comments/comment_form/show.erb +1 -1
- data/app/cells/decidim/comments/comments/inline.erb +13 -10
- data/app/cells/decidim/comments/comments_cell.rb +7 -2
- data/app/cells/decidim/comments/two_columns_comments/column.erb +7 -2
- data/app/cells/decidim/comments/two_columns_comments/show.erb +7 -4
- data/app/cells/decidim/comments/two_columns_comments_cell.rb +30 -31
- data/app/controllers/decidim/comments/comments_controller.rb +32 -7
- data/app/models/decidim/comments/seed.rb +17 -7
- data/app/packs/entrypoints/decidim_comments.js +6 -0
- data/app/packs/src/decidim/comments/comments.component.js +1 -43
- data/app/packs/src/decidim/comments/comments.component.test.js +63 -62
- data/app/packs/src/decidim/comments/controllers/load_more_comments/controller.js +201 -0
- data/app/packs/src/decidim/comments/controllers/show_replies/controller.js +240 -0
- data/app/packs/stylesheets/comments.scss +62 -1
- data/app/queries/decidim/comments/sorted_comments.rb +77 -33
- data/app/views/decidim/comments/comments/_load_more_comments.html.erb +22 -0
- data/app/views/decidim/comments/comments/create.js.erb +38 -4
- data/app/views/decidim/comments/comments/index.js.erb +58 -23
- data/app/views/decidim/comments/comments/load_more_comments.js.erb +74 -0
- data/app/views/decidim/comments/comments/update.js.erb +3 -13
- data/config/locales/ar.yml +0 -1
- data/config/locales/bg.yml +0 -1
- data/config/locales/bs-BA.yml +0 -1
- data/config/locales/ca-IT.yml +6 -4
- data/config/locales/ca.yml +6 -4
- data/config/locales/cs.yml +3 -6
- data/config/locales/de.yml +6 -4
- data/config/locales/el.yml +0 -1
- data/config/locales/en.yml +6 -3
- data/config/locales/es-MX.yml +6 -4
- data/config/locales/es-PY.yml +6 -4
- data/config/locales/es.yml +6 -4
- data/config/locales/eu.yml +6 -4
- data/config/locales/fi-plain.yml +6 -4
- data/config/locales/fi.yml +6 -4
- data/config/locales/fr-CA.yml +3 -4
- data/config/locales/fr.yml +3 -4
- data/config/locales/ga-IE.yml +0 -1
- data/config/locales/gl.yml +0 -1
- data/config/locales/hu.yml +0 -1
- data/config/locales/id-ID.yml +0 -1
- data/config/locales/is-IS.yml +1 -2
- data/config/locales/it.yml +0 -1
- data/config/locales/ja.yml +5 -3
- data/config/locales/lb.yml +0 -1
- data/config/locales/lt.yml +0 -1
- data/config/locales/lv.yml +0 -1
- data/config/locales/nl.yml +0 -1
- data/config/locales/no.yml +0 -1
- data/config/locales/pl.yml +0 -1
- data/config/locales/pt-BR.yml +6 -4
- data/config/locales/pt.yml +0 -1
- data/config/locales/ro-RO.yml +0 -5
- data/config/locales/ru.yml +0 -1
- data/config/locales/si-LK.yml +0 -1
- data/config/locales/sk.yml +0 -1
- data/config/locales/sl.yml +0 -1
- data/config/locales/sq-AL.yml +0 -1
- data/config/locales/sr-CS.yml +0 -1
- data/config/locales/sv.yml +0 -4
- data/config/locales/tr-TR.yml +0 -1
- data/config/locales/uk.yml +0 -1
- data/config/locales/zh-CN.yml +0 -1
- data/config/locales/zh-TW.yml +0 -1
- data/db/migrate/20260208201401_remove_user_group_comments.rb +13 -0
- data/decidim-comments.gemspec +6 -9
- data/lib/decidim/api/comment_mutation_type.rb +12 -4
- data/lib/decidim/api/commentable_interface.rb +1 -0
- data/lib/decidim/api/commentable_mutation_type.rb +4 -0
- data/lib/decidim/comments/commentable.rb +5 -0
- data/lib/decidim/comments/commentable_with_component.rb +9 -0
- data/lib/decidim/comments/test/factories.rb +1 -1
- data/lib/decidim/comments/test/shared_examples/translatable_comment.rb +1 -0
- data/lib/decidim/comments/version.rb +1 -1
- metadata +15 -14
- data/app/resolvers/decidim/comments/vote_comment_resolver.rb +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31c9f9edb9b180b45de88f99e78665579abf750966bcd87eba5094a27f2b3ca9
|
|
4
|
+
data.tar.gz: 6a66c1581118aafa964547213c97454a5493fa0b38ef2e88bb70902d9ddef093
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d026ab1b9fb210f23ba6f50e8b94f6d1ab728c6c159dd9b790fc25cab52f6489e9de1c95db96b8b351f4c7e757d78a802cdbe1a21e3e37c3d6f8d82a4f6b9fdf
|
|
7
|
+
data.tar.gz: 9efa7deae0c784ace5ff6814868e54215d4cad7a4534b9f6da7236c6c26f8e950824d733a840fbe051a975bc81a165b05030dd23251e1dd62e2064a04bb052ed
|
data/README.md
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# decidim-comments
|
|
2
2
|
|
|
3
3
|
The Comments module adds the ability to include comments to any resource which can be commentable by users.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This is a module oriented for developers, as a building block to be used by other modules.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add this line to your module's gemspec:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
s.add_dependency "decidim-comments", Decidim::YourModule.version
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
And then execute:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bundle
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage on another modules
|
|
6
22
|
|
|
7
23
|
The Comments component is exposed as a Rails helper:
|
|
8
24
|
|
|
@@ -22,20 +38,6 @@ Finally, add the comments javascript module like this:
|
|
|
22
38
|
import "src/decidim/comments/comments";
|
|
23
39
|
```
|
|
24
40
|
|
|
25
|
-
## Installation
|
|
26
|
-
|
|
27
|
-
Add this line to your application's Gemfile.
|
|
28
|
-
|
|
29
|
-
```ruby
|
|
30
|
-
gem 'decidim-comments'
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
And then execute:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
bundle
|
|
37
|
-
```
|
|
38
|
-
|
|
39
41
|
## How to contribute
|
|
40
42
|
|
|
41
43
|
The technology stack used in this module is the following:
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
<%= render partial: "decidim/comments/comments/delete", formats: [:html], locals: { comment: model } %>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<%= render :replies %>
|
|
7
|
-
<% end %>
|
|
8
|
-
</div>
|
|
9
|
-
</div>
|
|
3
|
+
<% if has_replies_in_children? %>
|
|
4
|
+
<%= render :replies %>
|
|
5
|
+
<% end %>
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<div data-controller="show-replies"
|
|
2
|
+
data-show-replies-url-value="<%= decidim_comments.comments_path %>"
|
|
3
|
+
data-show-replies-comment-gid-value="<%= model.to_signed_global_id.to_s %>"
|
|
4
|
+
data-show-replies-order-value="<%= order %>"
|
|
5
|
+
data-show-replies-loaded-value="false">
|
|
6
|
+
<div class="show-replies-button">
|
|
7
|
+
<button class="button button__xs button__text-secondary"
|
|
8
|
+
data-action="click->show-replies#toggle"
|
|
9
|
+
data-show-replies-target="button"
|
|
10
|
+
aria-expanded="false"
|
|
11
|
+
aria-controls="comment-<%= model.id %>-replies"
|
|
12
|
+
id="comment-<%= model.id %>-replies-trigger">
|
|
13
|
+
<span class="font-normal"><%= t("decidim.components.comment.replies_count", count: replies_count) %></span>
|
|
14
|
+
<%= icon "arrow-down-s-line" %>
|
|
15
|
+
<%= icon "arrow-up-s-line" %>
|
|
16
|
+
</button>
|
|
17
|
+
<span data-show-replies-target="spinner" class="ml-2 hidden"><%= icon "loader-3-line", class: "animate-spin fill-secondary" %></span>
|
|
18
|
+
</div>
|
|
19
|
+
<div id="comment-<%= model.id %>-replies"
|
|
20
|
+
data-show-replies-target="container"
|
|
21
|
+
class="comment-reply hidden">
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
@@ -90,31 +90,17 @@
|
|
|
90
90
|
<%= votes %>
|
|
91
91
|
</div>
|
|
92
92
|
</div>
|
|
93
|
-
<div class="comment__reply-button">
|
|
94
|
-
<% if depth.zero? && has_replies_in_children? %>
|
|
95
|
-
<button class="button button__xs button__transparent-secondary border-white absolute top-4" data-comment-hide data-controls="comment-<%= model.id %>-replies" data-open="false" id="comment-<%= model.id %>-replies-trigger">
|
|
96
|
-
<span data-show-comment-reply class="font-normal" aria-label="<%= t("decidim.components.comment.show_replies", count: replies.size) %>">
|
|
97
|
-
<%= t("decidim.components.comment.answers", count: replies.size) %>
|
|
98
|
-
</span>
|
|
99
|
-
<%= icon "arrow-down-s-line" %>
|
|
100
|
-
<span data-hide-comment-reply class="font-normal" aria-label="<%= t("decidim.components.comment.hide_replies", count: replies.size) %>">
|
|
101
|
-
<%= t("decidim.components.comment.answers", count: replies.size) %>
|
|
102
|
-
</span>
|
|
103
|
-
<%= icon "arrow-up-s-line" %>
|
|
104
|
-
</button>
|
|
105
|
-
<% end %>
|
|
106
|
-
</div>
|
|
107
93
|
<% if can_reply? %>
|
|
108
94
|
<div id="panel-<%= reply_id %>" class="add-comment" data-additional-reply>
|
|
109
95
|
<%== cell("decidim/comments/comment_form", model, root_depth:, order:) %>
|
|
110
96
|
</div>
|
|
111
97
|
<% end %>
|
|
112
|
-
<div id="comment-<%= model.id %>-replies" class="<%= "comment-reply" if has_replies_in_children? %>">
|
|
113
|
-
<% if has_replies_in_children? %>
|
|
114
|
-
<%= render :replies %>
|
|
115
|
-
<% end %>
|
|
116
|
-
</div>
|
|
117
98
|
</div>
|
|
99
|
+
<% if has_replies_in_children? %>
|
|
100
|
+
<%= render :replies %>
|
|
101
|
+
<% elsif can_reply? %>
|
|
102
|
+
<div id="comment-<%= model.id %>-replies" class="comment-reply"></div>
|
|
103
|
+
<% end %>
|
|
118
104
|
<% end %>
|
|
119
105
|
<% if current_user.present? %>
|
|
120
106
|
<%= cell("decidim/report_button", model, modal_id: "flagModalComment#{model.id}").flag_modal %>
|
|
@@ -86,10 +86,6 @@ module Decidim
|
|
|
86
86
|
formatted_body
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
def replies
|
|
90
|
-
SortedComments.for(model, order_by: order)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
89
|
def order
|
|
94
90
|
options[:order] || "older"
|
|
95
91
|
end
|
|
@@ -126,7 +122,11 @@ module Decidim
|
|
|
126
122
|
def can_reply?
|
|
127
123
|
return false if two_columns_layout?
|
|
128
124
|
return false if model.depth >= Comment::MAX_DEPTH
|
|
129
|
-
|
|
125
|
+
|
|
126
|
+
if current_participatory_space
|
|
127
|
+
return true if user_has_any_role?(current_user, current_participatory_space)
|
|
128
|
+
return false unless current_participatory_space.can_participate?(current_user)
|
|
129
|
+
end
|
|
130
130
|
|
|
131
131
|
user_signed_in? && accepts_new_comments? &&
|
|
132
132
|
root_commentable.user_allowed_to_comment?(current_user)
|
|
@@ -234,7 +234,11 @@ module Decidim
|
|
|
234
234
|
end
|
|
235
235
|
|
|
236
236
|
def has_replies_in_children?
|
|
237
|
-
|
|
237
|
+
replies_count.positive?
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def replies_count
|
|
241
|
+
@replies_count ||= model.replies.count
|
|
238
242
|
end
|
|
239
243
|
|
|
240
244
|
# action_authorization_button expects current_component to be available
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<% end %>
|
|
32
32
|
<div class="<%= reply? ? "" : "publish-comment-button" %>">
|
|
33
33
|
<button type="submit"
|
|
34
|
-
class="button button__sm button__secondary <%= reply? ? "
|
|
34
|
+
class="button button__sm button__secondary <%= reply? ? "" : "h-9 close-comment-fullscreen" %>"
|
|
35
35
|
disabled="disabled">
|
|
36
36
|
<span>
|
|
37
37
|
<%= reply? ? t("decidim.components.add_comment_form.form.submit_reply") : t("decidim.components.add_comment_form.form.submit_root_comment") %>
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
<div id="comments">
|
|
2
2
|
<div class="comments">
|
|
3
|
-
|
|
3
|
+
<% if user_signed_in? %>
|
|
4
|
+
<button class="button button__lg button__secondary flex md:hidden w-full h-9 text-sm add-comment-mobile">
|
|
5
|
+
<%= t("add_comment", scope: "decidim.components.add_comment_form") %>
|
|
6
|
+
</button>
|
|
7
|
+
<% end %>
|
|
8
|
+
<%= add_comment %>
|
|
9
|
+
<%= user_comments_blocked_warning %>
|
|
10
|
+
<div class="comments__header mt-8">
|
|
4
11
|
<h2 class="h4">
|
|
5
12
|
<% if single_comment? %>
|
|
6
13
|
<%= t("decidim.components.comments.comment_details_title") %>
|
|
@@ -11,18 +18,14 @@
|
|
|
11
18
|
</span>
|
|
12
19
|
<% end %>
|
|
13
20
|
</h2>
|
|
14
|
-
|
|
21
|
+
<% if two_columns_layout? %>
|
|
22
|
+
<div class="md:hidden"><%= render :order_control %></div>
|
|
23
|
+
<% else %>
|
|
24
|
+
<%= render :order_control %>
|
|
25
|
+
<% end %>
|
|
15
26
|
</div>
|
|
16
27
|
<%= single_comment_warning %>
|
|
17
28
|
<%= blocked_comments_warning %>
|
|
18
29
|
<%= render_comments %>
|
|
19
|
-
<% if user_signed_in? %>
|
|
20
|
-
<button class="button button__lg button__secondary flex md:hidden w-full h-9 text-sm add-comment-mobile">
|
|
21
|
-
<%= t("add_comment", scope: "decidim.components.add_comment_form") %>
|
|
22
|
-
</button>
|
|
23
|
-
<% end %>
|
|
24
|
-
<%= add_comment %>
|
|
25
|
-
<%= user_comments_blocked_warning %>
|
|
26
30
|
</div>
|
|
27
|
-
<%= cell("decidim/announcement", t("decidim.components.comments.loading"), callout_class: "primary loading-comments hidden") %>
|
|
28
31
|
</div>
|
|
@@ -5,6 +5,7 @@ module Decidim
|
|
|
5
5
|
# A cell to display a comments section for a commentable object.
|
|
6
6
|
class CommentsCell < Decidim::ViewModel
|
|
7
7
|
include UserRoleChecker
|
|
8
|
+
|
|
8
9
|
delegate :user_signed_in?, to: :controller
|
|
9
10
|
|
|
10
11
|
def render_comments
|
|
@@ -67,7 +68,10 @@ module Decidim
|
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
def can_add_comments?
|
|
70
|
-
|
|
71
|
+
if current_participatory_space
|
|
72
|
+
return true if user_has_any_role?(current_user, current_participatory_space)
|
|
73
|
+
return false unless current_participatory_space.can_participate?(current_user)
|
|
74
|
+
end
|
|
71
75
|
return if single_comment?
|
|
72
76
|
return if comments_blocked?
|
|
73
77
|
return if user_comments_blocked?
|
|
@@ -108,7 +112,7 @@ module Decidim
|
|
|
108
112
|
end
|
|
109
113
|
|
|
110
114
|
def order
|
|
111
|
-
options[:order] || "older"
|
|
115
|
+
options[:order] || (two_columns_layout? ? "recent" : "older")
|
|
112
116
|
end
|
|
113
117
|
|
|
114
118
|
def decidim
|
|
@@ -158,6 +162,7 @@ module Decidim
|
|
|
158
162
|
|
|
159
163
|
def user_comments_blocked?
|
|
160
164
|
return false unless user_signed_in?
|
|
165
|
+
return true if current_participatory_space && !current_participatory_space.can_participate?(current_user)
|
|
161
166
|
|
|
162
167
|
!model.user_allowed_to_comment?(current_user)
|
|
163
168
|
end
|
|
@@ -14,7 +14,12 @@
|
|
|
14
14
|
<% @comments.each do |comment| %>
|
|
15
15
|
<%= cell("decidim/comments/comment_thread", comment, order:) %>
|
|
16
16
|
<% end %>
|
|
17
|
-
<%
|
|
18
|
-
<p class="comments-section__no-comments"><%=
|
|
17
|
+
<% elsif @top_comment.blank? %>
|
|
18
|
+
<p class="comments-section__no-comments"><%= t("decidim.components.comments.no_comments_yet") %></p>
|
|
19
|
+
<% end %>
|
|
20
|
+
|
|
21
|
+
<% if @has_more %>
|
|
22
|
+
<% offset = @comments.size + (@top_comment.present? ? 1 : 0) %>
|
|
23
|
+
<%= controller.view_context.render partial: "decidim/comments/comments/load_more_comments", locals: { commentable: model, order:, offset:, alignment: @alignment } %>
|
|
19
24
|
<% end %>
|
|
20
25
|
</div>
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<div id="desktopContainer" class="comments-two-columns card__grid-grid hidden md:grid">
|
|
2
|
-
<%= render_column(@top_comment_in_favor, @sorted_comments_in_favor, "thumb-up-line", t("decidim.components.comments.in_favor")) %>
|
|
3
|
-
<%= render_column(@top_comment_against, @sorted_comments_against, "thumb-down-line", t("decidim.components.comments.against")) %>
|
|
2
|
+
<%= render_column(@top_comment_in_favor, @sorted_comments_in_favor, "thumb-up-line", t("decidim.components.comments.in_favor"), 1, @has_more_in_favor) %>
|
|
3
|
+
<%= render_column(@top_comment_against, @sorted_comments_against, "thumb-down-line", t("decidim.components.comments.against"), -1, @has_more_against) %>
|
|
4
4
|
</div>
|
|
5
5
|
|
|
6
6
|
<div id="mobileContainer" class="comment-threads block md:hidden" aria-live="polite">
|
|
7
7
|
<%= comments_loading %>
|
|
8
|
-
<% @
|
|
9
|
-
<%= cell("decidim/comments/comment_thread", comment, order
|
|
8
|
+
<% @mobile_comments.each do |comment| %>
|
|
9
|
+
<%= cell("decidim/comments/comment_thread", comment, order:) %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<% if @has_more_mobile %>
|
|
12
|
+
<%= controller.view_context.render partial: "decidim/comments/comments/load_more_comments", locals: { commentable: model, order:, offset: @mobile_comments.size } %>
|
|
10
13
|
<% end %>
|
|
11
14
|
</div>
|
|
@@ -6,14 +6,15 @@ module Decidim
|
|
|
6
6
|
class TwoColumnsCommentsCell < Decidim::Comments::CommentsCell
|
|
7
7
|
def call
|
|
8
8
|
initialize_comments
|
|
9
|
-
@interleaved_comments = interleave_comments(@sorted_comments_in_favor, @sorted_comments_against)
|
|
10
9
|
render :show
|
|
11
10
|
end
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
# rubocop:disable Metrics/ParameterLists
|
|
13
|
+
def render_column(top_comment, comments, icon_name, title, alignment, has_more)
|
|
14
|
+
set_column_variables(top_comment, comments, icon_name, title, alignment, has_more)
|
|
15
15
|
render :column
|
|
16
16
|
end
|
|
17
|
+
# rubocop:enable Metrics/ParameterLists
|
|
17
18
|
|
|
18
19
|
private
|
|
19
20
|
|
|
@@ -21,19 +22,25 @@ module Decidim
|
|
|
21
22
|
if model.closed?
|
|
22
23
|
load_closed_comments
|
|
23
24
|
else
|
|
24
|
-
@sorted_comments_in_favor =
|
|
25
|
-
@sorted_comments_against =
|
|
25
|
+
@sorted_comments_in_favor = comments_in_favor_query.query
|
|
26
|
+
@sorted_comments_against = comments_against_query.query
|
|
26
27
|
end
|
|
28
|
+
|
|
29
|
+
counts = comments_count_by_alignment
|
|
30
|
+
@has_more_in_favor = (counts[1] || 0) > comments_in_favor_query.offset + comments_in_favor_query.limit
|
|
31
|
+
@has_more_against = (counts[-1] || 0) > comments_against_query.offset + comments_against_query.limit
|
|
32
|
+
|
|
33
|
+
load_mobile_comments(counts.values.sum)
|
|
27
34
|
end
|
|
28
35
|
|
|
29
36
|
def load_closed_comments
|
|
30
|
-
@top_comment_in_favor, @sorted_comments_in_favor = sorted_comments(
|
|
31
|
-
@top_comment_against, @sorted_comments_against = sorted_comments(
|
|
37
|
+
@top_comment_in_favor, @sorted_comments_in_favor = sorted_comments(comments_in_favor_query.query)
|
|
38
|
+
@top_comment_against, @sorted_comments_against = sorted_comments(comments_against_query.query)
|
|
32
39
|
end
|
|
33
40
|
|
|
34
41
|
def sorted_comments(comments)
|
|
35
42
|
top_comment = find_top_comment(comments)
|
|
36
|
-
sorted_comments = comments.where.not(id: top_comment&.id)
|
|
43
|
+
sorted_comments = comments.where.not(id: top_comment&.id)
|
|
37
44
|
[top_comment, sorted_comments]
|
|
38
45
|
end
|
|
39
46
|
|
|
@@ -45,42 +52,34 @@ module Decidim
|
|
|
45
52
|
.first
|
|
46
53
|
end
|
|
47
54
|
|
|
48
|
-
def
|
|
49
|
-
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def interleave_top_comments
|
|
53
|
-
return [] unless model.closed?
|
|
54
|
-
|
|
55
|
-
Array(@top_comment_in_favor) + Array(@top_comment_against)
|
|
55
|
+
def comments_in_favor_query
|
|
56
|
+
@comments_in_favor_query ||= SortedComments.new(model, order_by: order, alignment: 1, offset: 0)
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
max_length = [comments_in_favor.size, comments_against.size].max
|
|
61
|
-
|
|
62
|
-
max_length.times do |i|
|
|
63
|
-
interleaved << comments_in_favor[i] if comments_in_favor[i]
|
|
64
|
-
interleaved << comments_against[i] if comments_against[i]
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
interleaved
|
|
59
|
+
def comments_against_query
|
|
60
|
+
@comments_against_query ||= SortedComments.new(model, order_by: order, alignment: -1, offset: 0)
|
|
68
61
|
end
|
|
69
62
|
|
|
70
|
-
def
|
|
71
|
-
@
|
|
63
|
+
def load_mobile_comments(total_count)
|
|
64
|
+
@sorted_comments_query = SortedComments.new(model, order_by: order, offset: 0)
|
|
65
|
+
@mobile_comments = @sorted_comments_query.query
|
|
66
|
+
@has_more_mobile = total_count > @sorted_comments_query.offset + @sorted_comments_query.limit
|
|
72
67
|
end
|
|
73
68
|
|
|
74
|
-
def
|
|
75
|
-
@
|
|
69
|
+
def comments_count_by_alignment
|
|
70
|
+
@comments_count_by_alignment ||= Decidim::Comments::Comment.where(commentable: model).group(:alignment).count
|
|
76
71
|
end
|
|
77
72
|
|
|
78
|
-
|
|
73
|
+
# rubocop:disable Metrics/ParameterLists
|
|
74
|
+
def set_column_variables(top_comment, comments, icon_name, title, alignment, has_more)
|
|
79
75
|
@top_comment = top_comment
|
|
80
76
|
@comments = comments
|
|
81
77
|
@icon_name = icon_name
|
|
82
78
|
@title = title
|
|
79
|
+
@alignment = alignment
|
|
80
|
+
@has_more = has_more
|
|
83
81
|
end
|
|
82
|
+
# rubocop:enable Metrics/ParameterLists
|
|
84
83
|
end
|
|
85
84
|
end
|
|
86
85
|
end
|
|
@@ -13,21 +13,29 @@ module Decidim
|
|
|
13
13
|
before_action :set_commentable, except: [:destroy, :update]
|
|
14
14
|
before_action :ensure_commentable!, except: [:destroy, :update]
|
|
15
15
|
|
|
16
|
-
helper_method :root_depth, :commentable, :order, :reply?, :reload?, :root_comment
|
|
16
|
+
helper_method :root_depth, :commentable, :order, :reply?, :reload?, :root_comment, :load_more?, :comments_offset, :alignment
|
|
17
17
|
|
|
18
18
|
def index
|
|
19
19
|
enforce_permission_to(:read, :comment, commentable:)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
commentable,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
if commentable.is_a?(Decidim::Comments::Comment)
|
|
22
|
+
@comments = commentable.descendants.includes(:author, :up_votes, :down_votes).to_a
|
|
23
|
+
@has_more_comments = false
|
|
24
|
+
else
|
|
25
|
+
@sorted_comments_query = SortedComments.new(
|
|
26
|
+
commentable,
|
|
27
|
+
order_by: order,
|
|
28
|
+
offset: comments_offset,
|
|
29
|
+
alignment:
|
|
30
|
+
)
|
|
31
|
+
@comments = @sorted_comments_query.query
|
|
32
|
+
@has_more_comments = @sorted_comments_query.has_more?
|
|
33
|
+
end
|
|
26
34
|
@comments = @comments.reject do |comment|
|
|
27
35
|
next if comment.depth < 1
|
|
28
36
|
next if !comment.deleted? && !comment.hidden?
|
|
29
37
|
|
|
30
|
-
comment.commentable.
|
|
38
|
+
comment.commentable.replies.blank?
|
|
31
39
|
end
|
|
32
40
|
@comments_count = commentable.comments_count
|
|
33
41
|
|
|
@@ -35,6 +43,8 @@ module Decidim
|
|
|
35
43
|
format.js do
|
|
36
44
|
if reload?
|
|
37
45
|
render :reload
|
|
46
|
+
elsif load_more?
|
|
47
|
+
render :load_more_comments
|
|
38
48
|
else
|
|
39
49
|
render :index
|
|
40
50
|
end
|
|
@@ -187,10 +197,25 @@ module Decidim
|
|
|
187
197
|
params.fetch(:reload, 0).to_i == 1
|
|
188
198
|
end
|
|
189
199
|
|
|
200
|
+
def load_more?
|
|
201
|
+
params.fetch(:load_more, 0).to_i == 1
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def comments_offset
|
|
205
|
+
params.fetch(:offset, 0).to_i
|
|
206
|
+
end
|
|
207
|
+
|
|
190
208
|
def root_depth
|
|
191
209
|
params.fetch(:root_depth, 0).to_i
|
|
192
210
|
end
|
|
193
211
|
|
|
212
|
+
def alignment
|
|
213
|
+
value = params.fetch(:alignment, nil)
|
|
214
|
+
return nil if value.blank?
|
|
215
|
+
|
|
216
|
+
value.to_i
|
|
217
|
+
end
|
|
218
|
+
|
|
194
219
|
def commentable_path
|
|
195
220
|
return commentable.polymorphic_resource_path({}) if commentable.respond_to?(:polymorphic_resource_path)
|
|
196
221
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "decidim/seeds"
|
|
4
|
+
|
|
3
5
|
module Decidim
|
|
4
6
|
module Comments
|
|
5
7
|
# A comment can belong to many Commentable models. This class is responsible
|
|
@@ -10,7 +12,7 @@ module Decidim
|
|
|
10
12
|
# Adds a random amount of comments for a given resource.
|
|
11
13
|
#
|
|
12
14
|
# @param resource [Object] - the Decidim resource to add the comments to.
|
|
13
|
-
# examples: Decidim::Proposals::
|
|
15
|
+
# examples: Decidim::Proposals::Proposal
|
|
14
16
|
#
|
|
15
17
|
# @return nil
|
|
16
18
|
def comments_for(resource)
|
|
@@ -20,16 +22,16 @@ module Decidim
|
|
|
20
22
|
|
|
21
23
|
@organization = resource.organization
|
|
22
24
|
|
|
23
|
-
rand(0..
|
|
25
|
+
rand(0..config_value(:comments_count)).times do
|
|
24
26
|
comment1 = create_comment(resource)
|
|
25
27
|
NewCommentNotificationCreator.new(comment1, []).create
|
|
26
28
|
|
|
27
|
-
if
|
|
29
|
+
if rand < config_value(:comments_nested_probability)
|
|
28
30
|
comment2 = create_comment(comment1, resource)
|
|
29
31
|
NewCommentNotificationCreator.new(comment2, []).create
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
next if
|
|
34
|
+
next if rand < config_value(:comments_vote_skip_probability)
|
|
33
35
|
|
|
34
36
|
create_votes(comment1) if comment1
|
|
35
37
|
create_votes(comment2) if comment2
|
|
@@ -40,12 +42,20 @@ module Decidim
|
|
|
40
42
|
|
|
41
43
|
attr_reader :organization
|
|
42
44
|
|
|
45
|
+
def config_value(key)
|
|
46
|
+
slow_seeds? ? Decidim::Seeds::SEEDS_CONFIG[key][:slow] : Decidim::Seeds::SEEDS_CONFIG[key][:fast]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def slow_seeds?
|
|
50
|
+
Decidim::Env.new("SLOW_SEEDS").present?
|
|
51
|
+
end
|
|
52
|
+
|
|
43
53
|
# Creates a comment for a given resource.
|
|
44
54
|
#
|
|
45
55
|
# @private
|
|
46
56
|
#
|
|
47
57
|
# @param resource [Object] - the Decidim resource to add the comments to.
|
|
48
|
-
# @param root_commentable - the root commentable resource. It is optional, used for making nested comments.
|
|
58
|
+
# @param root_commentable [Object, Decidim::Comments::Comment] - the root commentable resource. It is optional, used for making nested comments.
|
|
49
59
|
#
|
|
50
60
|
# @return [Decidim::Comments::Comment]
|
|
51
61
|
def create_comment(resource, root_commentable = nil)
|
|
@@ -70,11 +80,11 @@ module Decidim
|
|
|
70
80
|
#
|
|
71
81
|
# @private
|
|
72
82
|
#
|
|
73
|
-
# @param [Decidim::Comments::Comment]
|
|
83
|
+
# @param comment [Decidim::Comments::Comment]
|
|
74
84
|
#
|
|
75
85
|
# @return nil
|
|
76
86
|
def create_votes(comment)
|
|
77
|
-
rand(0..
|
|
87
|
+
rand(0..config_value(:comments_votes_count)).times do
|
|
78
88
|
author = random_user
|
|
79
89
|
next if CommentVote.where(comment:, author:).any?
|
|
80
90
|
|
|
@@ -4,3 +4,9 @@ import "stylesheets/comments.scss"
|
|
|
4
4
|
// JavaScript
|
|
5
5
|
import "src/decidim/comments/comments"
|
|
6
6
|
import "src/decidim/comments/comments_mobile_modal"
|
|
7
|
+
|
|
8
|
+
// Stimulus controllers
|
|
9
|
+
import { definitionsFromContext } from "src/decidim/refactor/support/stimulus"
|
|
10
|
+
|
|
11
|
+
const context = require.context("src/decidim/comments/controllers", true, /controller\.js$/)
|
|
12
|
+
window.Stimulus.load(definitionsFromContext(context))
|
|
@@ -22,7 +22,6 @@ export default class CommentsComponent {
|
|
|
22
22
|
this.rootDepth = config.rootDepth;
|
|
23
23
|
this.order = config.order;
|
|
24
24
|
this.lastCommentId = config.lastCommentId;
|
|
25
|
-
this.pollingInterval = config.pollingInterval || 15000;
|
|
26
25
|
this.singleComment = config.singleComment;
|
|
27
26
|
this.toggleTranslations = config.toggleTranslations;
|
|
28
27
|
this.id = this.$element.attr("id") || this._getUID();
|
|
@@ -59,7 +58,6 @@ export default class CommentsComponent {
|
|
|
59
58
|
unmountComponent() {
|
|
60
59
|
if (this.mounted) {
|
|
61
60
|
this.mounted = false;
|
|
62
|
-
this._stopPolling();
|
|
63
61
|
this.lastCommentId = null;
|
|
64
62
|
|
|
65
63
|
$(".add-comment [data-opinion-toggle] button", this.$element).off("click.decidim-comments");
|
|
@@ -161,7 +159,6 @@ export default class CommentsComponent {
|
|
|
161
159
|
const $submit = $("button[type='submit']", $form);
|
|
162
160
|
|
|
163
161
|
$submit.attr("disabled", "disabled");
|
|
164
|
-
this._stopPolling();
|
|
165
162
|
});
|
|
166
163
|
|
|
167
164
|
const $dropdown = $add.find("[data-comments-dropdown]");
|
|
@@ -225,22 +222,6 @@ export default class CommentsComponent {
|
|
|
225
222
|
}
|
|
226
223
|
});
|
|
227
224
|
}
|
|
228
|
-
|
|
229
|
-
// Restart the polling
|
|
230
|
-
this._pollComments();
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Sets a timeout to poll new comments.
|
|
235
|
-
* @private
|
|
236
|
-
* @returns {Void} - Returns nothing
|
|
237
|
-
*/
|
|
238
|
-
_pollComments() {
|
|
239
|
-
this._stopPolling();
|
|
240
|
-
|
|
241
|
-
this.pollTimeout = setTimeout(() => {
|
|
242
|
-
this._fetchComments();
|
|
243
|
-
}, this.pollingInterval);
|
|
244
225
|
}
|
|
245
226
|
|
|
246
227
|
reloadAllComments() {
|
|
@@ -265,29 +246,16 @@ export default class CommentsComponent {
|
|
|
265
246
|
"root_depth": this.rootDepth,
|
|
266
247
|
"order": this.order,
|
|
267
248
|
// From here, the rest of properties are optional
|
|
268
|
-
...(this.toggleTranslations && { "toggle_translations": this.toggleTranslations })
|
|
269
|
-
...(this.lastCommentId && { "after": this.lastCommentId })
|
|
249
|
+
...(this.toggleTranslations && { "toggle_translations": this.toggleTranslations })
|
|
270
250
|
}),
|
|
271
251
|
success: () => {
|
|
272
252
|
if (successCallback) {
|
|
273
253
|
successCallback();
|
|
274
254
|
}
|
|
275
|
-
this._pollComments();
|
|
276
255
|
}
|
|
277
256
|
});
|
|
278
257
|
}
|
|
279
258
|
|
|
280
|
-
/**
|
|
281
|
-
* Stops polling for new comments.
|
|
282
|
-
* @private
|
|
283
|
-
* @returns {Void} - Returns nothing
|
|
284
|
-
*/
|
|
285
|
-
_stopPolling() {
|
|
286
|
-
if (this.pollTimeout) {
|
|
287
|
-
clearTimeout(this.pollTimeout);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
259
|
/**
|
|
292
260
|
* Sets the loading comments element visible in the view.
|
|
293
261
|
* @private
|
|
@@ -299,16 +267,6 @@ export default class CommentsComponent {
|
|
|
299
267
|
$("> .loading-comments", $container).removeClass("hidden");
|
|
300
268
|
}
|
|
301
269
|
|
|
302
|
-
/**
|
|
303
|
-
* Event listener for the ordering links.
|
|
304
|
-
* @private
|
|
305
|
-
* @returns {Void} - Returns nothing
|
|
306
|
-
*/
|
|
307
|
-
_onInitOrder() {
|
|
308
|
-
this._stopPolling();
|
|
309
|
-
this._setLoading();
|
|
310
|
-
}
|
|
311
|
-
|
|
312
270
|
/**
|
|
313
271
|
* Updates the state of the submit button based on input text and opinion selection.
|
|
314
272
|
*
|