decidim-comments 0.24.3 → 0.25.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -20
- data/app/assets/javascripts/decidim/comments/bundle.js.map +1 -1
- data/app/cells/decidim/comments/comment/actions.erb +1 -1
- data/app/cells/decidim/comments/comment/deletion_data.erb +1 -0
- data/app/cells/decidim/comments/comment/show.erb +30 -21
- data/app/cells/decidim/comments/comment/utilities.erb +40 -12
- data/app/cells/decidim/comments/comment/votes.erb +6 -6
- data/app/cells/decidim/comments/comment_cell.rb +29 -0
- data/app/cells/decidim/comments/comment_form/show.erb +1 -1
- data/app/cells/decidim/comments/comments/add_comment.erb +10 -6
- data/app/cells/decidim/comments/comments/order_control.erb +4 -5
- data/app/cells/decidim/comments/comments/show.erb +2 -4
- data/app/cells/decidim/comments/comments/user_comments_blocked_warning.erb +5 -1
- data/app/cells/decidim/comments/comments_cell.rb +24 -2
- data/app/cells/decidim/comments/edit_comment_modal_form/show.erb +29 -0
- data/app/cells/decidim/comments/edit_comment_modal_form_cell.rb +53 -0
- data/app/commands/decidim/comments/create_comment.rb +2 -1
- data/app/commands/decidim/comments/delete_comment.rb +46 -0
- data/app/commands/decidim/comments/update_comment.rb +62 -0
- data/app/controllers/decidim/comments/comments_controller.rb +63 -6
- data/app/events/decidim/comments/comment_voted_event.rb +9 -0
- data/app/models/decidim/comments/comment.rb +24 -1
- data/app/packs/src/decidim/comments/comments.component.js +300 -0
- data/app/{assets/javascripts → packs/src}/decidim/comments/comments.component.test.js +116 -26
- data/app/packs/src/decidim/comments/comments.component_for_testing.js +8 -0
- data/app/packs/src/decidim/comments/comments.js +1 -0
- data/app/permissions/decidim/comments/permissions.rb +10 -1
- data/app/queries/decidim/comments/metrics/comment_participants_metric_measure.rb +1 -1
- data/app/queries/decidim/comments/metrics/comments_metric_manage.rb +1 -1
- data/app/queries/decidim/comments/sorted_comments.rb +8 -6
- data/app/views/decidim/comments/comments/_delete.html.erb +5 -0
- data/app/views/decidim/comments/comments/_edited_comment.html.erb +1 -0
- data/app/views/decidim/comments/comments/create.js.erb +4 -2
- data/app/views/decidim/comments/comments/delete.js.erb +17 -0
- data/app/views/decidim/comments/comments/deletion_error.js.erb +1 -0
- data/app/views/decidim/comments/comments/reload.js.erb +2 -0
- data/app/views/decidim/comments/comments/update.js.erb +8 -0
- data/app/views/decidim/comments/comments/update_error.js.erb +1 -0
- data/config/assets.rb +5 -0
- data/config/locales/ar.yml +0 -1
- data/config/locales/ca.yml +7 -1
- data/config/locales/cs.yml +25 -1
- data/config/locales/de.yml +7 -1
- data/config/locales/el.yml +0 -1
- data/config/locales/en.yml +25 -1
- data/config/locales/es-MX.yml +7 -1
- data/config/locales/es-PY.yml +7 -1
- data/config/locales/es.yml +7 -1
- data/config/locales/fi-plain.yml +25 -1
- data/config/locales/fi.yml +25 -1
- data/config/locales/fr-CA.yml +25 -1
- data/config/locales/fr-LU.yml +162 -0
- data/config/locales/fr.yml +25 -1
- data/config/locales/gl.yml +25 -1
- data/config/locales/hu.yml +0 -1
- data/config/locales/it.yml +38 -1
- data/config/locales/ja.yml +35 -1
- data/config/locales/lb-LU.yml +1 -0
- data/config/locales/lv.yml +0 -1
- data/config/locales/nl.yml +27 -2
- data/config/locales/no.yml +0 -1
- data/config/locales/pl.yml +7 -1
- data/config/locales/pt-BR.yml +61 -0
- data/config/locales/pt.yml +0 -1
- data/config/locales/ro-RO.yml +25 -1
- data/config/locales/sk.yml +0 -1
- data/config/locales/sr-CS.yml +0 -1
- data/config/locales/sv.yml +25 -1
- data/config/locales/tr-TR.yml +0 -1
- data/config/locales/zh-CN.yml +0 -1
- data/db/migrate/20200706123136_make_comments_handle_i18n.rb +1 -1
- data/db/migrate/20210402124534_add_participatory_process_to_comments.rb +12 -0
- data/db/migrate/20210529095942_add_deleted_at_column_to_comments.rb +7 -0
- data/lib/decidim/comments/commentable.rb +6 -1
- data/lib/decidim/comments/commentable_with_component.rb +33 -0
- data/lib/decidim/comments/engine.rb +1 -9
- data/lib/decidim/comments/test/factories.rb +1 -0
- data/lib/decidim/comments/version.rb +1 -1
- data/lib/decidim/comments.rb +1 -0
- data/lib/tasks/decidim_comments.rake +15 -0
- metadata +32 -29
- data/app/assets/config/decidim_comments_manifest.js +0 -1
- data/app/assets/javascripts/decidim/comments/comments.component.js.es6 +0 -292
- data/app/assets/javascripts/decidim/comments/comments.js.erb +0 -10
- data/config/locales/ja-JP.yml +0 -120
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="comment__actions">
|
2
2
|
<% if can_reply? %>
|
3
3
|
<button class="comment__reply muted-link" aria-controls="<%= reply_id %>" data-toggle="<%= reply_id %>">
|
4
|
-
<%= icon "pencil", class: "icon--small", role: "
|
4
|
+
<%= icon "pencil", class: "icon--small", role: "img", "aria-hidden": true %> <%= t("decidim.components.comment.reply") %>
|
5
5
|
</button>
|
6
6
|
<% end %>
|
7
7
|
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render partial: "decidim/comments/comments/delete.html", locals: { comment: model } %>
|
@@ -1,36 +1,45 @@
|
|
1
1
|
<%= content_tag :div, id: "comment_#{model.id}", class: comment_classes, data: { comment_id: model.id } do %>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
<% if model.deleted? %>
|
3
|
+
<%= render :deletion_data %>
|
4
|
+
<% else %>
|
5
|
+
<div class="comment__header">
|
6
|
+
<div class="author-data">
|
7
|
+
<div class="author-data__main">
|
8
|
+
<%= render :author %>
|
9
|
+
<span>
|
10
|
+
<%= time_tag created_at, l(created_at, format: :decidim_short) %>
|
11
|
+
</span>
|
12
|
+
<% if edited? %>
|
13
|
+
<div class="author-data__extra">
|
14
|
+
<span class="comment__edited">
|
15
|
+
<%= t("decidim.components.comment.edited") %>
|
16
|
+
</span>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
19
|
+
</div>
|
12
20
|
</div>
|
21
|
+
<%= render :utilities %>
|
13
22
|
</div>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
<div class="comment__content">
|
24
|
+
<%= alignment_badge %>
|
25
|
+
<%= comment_body %>
|
26
|
+
</div>
|
27
|
+
<div class="comment__footer">
|
28
|
+
<%= render :actions %>
|
29
|
+
<%= votes %>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
23
32
|
<div id="comment-<%= model.id %>-replies">
|
24
33
|
<% if has_replies? %>
|
25
34
|
<% replies.each do |reply| %>
|
26
|
-
<%= cell("decidim/comments/comment", reply, root_depth: root_depth, order: order) %>
|
35
|
+
<%= cell("decidim/comments/comment", reply, root_depth: root_depth, order: order, reloaded: reloaded?) %>
|
27
36
|
<% end %>
|
28
37
|
<% end %>
|
29
38
|
</div>
|
30
39
|
<% if can_reply? %>
|
31
40
|
<div class="comment__additionalreply<%= " hide" unless has_replies? %>">
|
32
41
|
<button class="comment__reply muted-link" aria-controls="<%= reply_id %>" data-toggle="<%= reply_id %>">
|
33
|
-
<%= icon "pencil", class: "icon--small", role: "
|
42
|
+
<%= icon "pencil", class: "icon--small", role: "img", "aria-hidden": true %> <%= t("decidim.components.comment.reply") %>
|
34
43
|
</button>
|
35
44
|
</div>
|
36
45
|
<div class="add-comment hide" id="<%= reply_id %>" data-toggler=".hide">
|
@@ -1,13 +1,41 @@
|
|
1
|
-
<
|
2
|
-
|
3
|
-
|
4
|
-
</
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
<div class="comment__header__context-menu">
|
2
|
+
<label for="<%= context_menu_id %>" data-toggle="<%= context_menu_id %>">
|
3
|
+
<%= icon "ellipses" %>
|
4
|
+
</label>
|
5
|
+
<ul id="<%= context_menu_id %>" data-dropdown data-close-on-click="true" data-position="left" data-alignment="top" class="card dropdown-pane comment__header__context-menu__content">
|
6
|
+
<li>
|
7
|
+
<button type="button" class="link-alt comment__header__context-menu__content-item" data-open="<%= current_user.present? ? "flagModalComment#{model.id}" : "loginModal" %>" title="<%= t("decidim.components.comment.report.title") %>" aria-controls="<%= current_user.present? ? "flagModalComment#{model.id}" : "loginModal" %>" aria-haspopup="true" tabindex="0">
|
8
|
+
<%= icon "flag", class: "icon--small", aria_label: t("decidim.components.comment.report.title") %>
|
9
|
+
<span><%= t("decidim.components.comment.report.action") %></span>
|
10
|
+
</button>
|
11
|
+
</li>
|
12
|
+
<li>
|
13
|
+
<%= link_to "#{commentable_path("commentId" => model.id)}#comment_#{model.id}", target: "_blank", class: "comment__header__context-menu__content-item", title: t("decidim.components.comment.single_comment_link_title") do %>
|
14
|
+
<%= icon "link-intact", class: "icon--small", aria_label: t("decidim.components.comment.single_comment_link_title") %>
|
15
|
+
<span><%= t("decidim.components.comment.single_comment_link_title") %></span>
|
16
|
+
<% end %>
|
17
|
+
</li>
|
18
|
+
<% if model.authored_by?(current_user) %>
|
19
|
+
<li>
|
20
|
+
<button type="button" class="link-alt comment__header__context-menu__content-item" data-open="<%= "editCommentModal#{model.id}" %>" title="<%= t("decidim.components.comment.edit") %>" aria-controls="<%= "editCommentModal#{model.id}" %>" aria-haspopup="true" tabindex="0">
|
21
|
+
<%= icon "pencil", class: "icon--small", aria_label: t("decidim.components.comment.edit") %>
|
22
|
+
<span><%= t("decidim.components.comment.edit") %></span>
|
23
|
+
</button>
|
24
|
+
</li>
|
25
|
+
<li>
|
26
|
+
<%= link_to comment_path, remote: true, method: :delete, class: "comment__header__context-menu__content-item", data: { confirm: t("decidim.components.comment.confirm_destroy") } do %>
|
27
|
+
<%= icon "trash", class: "icon--small", aria_label: t("decidim.components.comment.delete") %>
|
28
|
+
<span><%= t("decidim.components.comment.delete") %></span>
|
29
|
+
<% end %>
|
30
|
+
</li>
|
31
|
+
<% end %>
|
32
|
+
</ul>
|
33
|
+
</div>
|
34
|
+
<% unless reloaded? %>
|
35
|
+
<% if current_user.present? %>
|
36
|
+
<%= cell("decidim/flag_modal", model, modal_id: "flagModalComment#{model.id}") %>
|
37
|
+
<% end %>
|
38
|
+
<% if model.authored_by?(current_user) %>
|
39
|
+
<%= cell("decidim/comments/edit_comment_modal_form", model, modal_id: "editCommentModal#{model.id}") %>
|
40
|
+
<% end %>
|
13
41
|
<% end %>
|
@@ -1,24 +1,24 @@
|
|
1
1
|
<div class="comment__votes">
|
2
2
|
<% if user_signed_in? %>
|
3
|
-
<%=
|
3
|
+
<%= vote_button_to decidim_comments.comment_votes_path(model, weight: 1), remote: true, disabled: voted_down?, class: votes_up_classes, title: t("decidim.components.up_vote_button.text") do %>
|
4
4
|
<span class="show-for-sr"><%= t("decidim.components.up_vote_button.text") %></span>
|
5
|
-
<%= icon "chevron-top", class: "icon--small", role: "
|
5
|
+
<%= icon "chevron-top", class: "icon--small", role: "img", "aria-hidden": true %>
|
6
6
|
<span class="comment__votes--count"><%= up_votes_count %></span>
|
7
7
|
<% end %>
|
8
|
-
<%=
|
8
|
+
<%= vote_button_to decidim_comments.comment_votes_path(model, weight: -1), remote: true, disabled: voted_up?, class: votes_down_classes, title: t("decidim.components.down_vote_button.text") do %>
|
9
9
|
<span class="show-for-sr"><%= t("decidim.components.down_vote_button.text") %></span>
|
10
|
-
<%= icon "chevron-bottom", class: "icon--small", role: "
|
10
|
+
<%= icon "chevron-bottom", class: "icon--small", role: "img", "aria-hidden": true %>
|
11
11
|
<span class="comment__votes--count"><%= down_votes_count %></span>
|
12
12
|
<% end %>
|
13
13
|
<% else %>
|
14
14
|
<button class="<%= votes_up_classes %> " title="<%= t("decidim.components.up_vote_button.text") %>" data-open="loginModal">
|
15
15
|
<span class="show-for-sr"><%= t("decidim.components.up_vote_button.text") %></span>
|
16
|
-
<%= icon "chevron-top", class: "icon--small", role: "
|
16
|
+
<%= icon "chevron-top", class: "icon--small", role: "img", "aria-hidden": true %>
|
17
17
|
<span class="comment__votes--count"><%= up_votes_count %></span>
|
18
18
|
</button>
|
19
19
|
<button class="<%= votes_down_classes %> " title="<%= t("decidim.components.down_vote_button.text") %>" data-open="loginModal">
|
20
20
|
<span class="show-for-sr"><%= t("decidim.components.down_vote_button.text") %></span>
|
21
|
-
<%= icon "chevron-bottom", class: "icon--small", role: "
|
21
|
+
<%= icon "chevron-bottom", class: "icon--small", role: "img", "aria-hidden": true %>
|
22
22
|
<span class="comment__votes--count"><%= down_votes_count %></span>
|
23
23
|
</button>
|
24
24
|
<% end %>
|
@@ -7,15 +7,18 @@ module Decidim
|
|
7
7
|
include ActionView::Helpers::DateHelper
|
8
8
|
include Decidim::IconHelper
|
9
9
|
include Decidim::ResourceHelper
|
10
|
+
include Cell::ViewModel::Partial
|
10
11
|
|
11
12
|
delegate :current_user, :user_signed_in?, to: :controller
|
12
13
|
|
13
14
|
property :root_commentable
|
14
15
|
property :created_at
|
16
|
+
property :deleted_at
|
15
17
|
property :alignment
|
16
18
|
property :translated_body
|
17
19
|
property :comment_threads
|
18
20
|
property :accepts_new_comments?
|
21
|
+
property :edited?
|
19
22
|
|
20
23
|
def alignment_badge
|
21
24
|
return unless [-1, 1].include?(alignment)
|
@@ -51,6 +54,10 @@ module Decidim
|
|
51
54
|
"comment#{model.id}-reply"
|
52
55
|
end
|
53
56
|
|
57
|
+
def context_menu_id
|
58
|
+
"toggle-context-menu-#{model.id}"
|
59
|
+
end
|
60
|
+
|
54
61
|
def can_reply?
|
55
62
|
user_signed_in? && accepts_new_comments? &&
|
56
63
|
root_commentable.user_allowed_to_comment?(current_user)
|
@@ -116,6 +123,10 @@ module Decidim
|
|
116
123
|
end
|
117
124
|
end
|
118
125
|
|
126
|
+
def comment_path
|
127
|
+
decidim_comments.comment_path(model)
|
128
|
+
end
|
129
|
+
|
119
130
|
def up_votes_count
|
120
131
|
model.up_votes.count
|
121
132
|
end
|
@@ -132,6 +143,10 @@ module Decidim
|
|
132
143
|
model.depth - root_depth
|
133
144
|
end
|
134
145
|
|
146
|
+
def reloaded?
|
147
|
+
options[:reloaded]
|
148
|
+
end
|
149
|
+
|
135
150
|
def voted_up?
|
136
151
|
model.up_voted_by?(current_user)
|
137
152
|
end
|
@@ -151,6 +166,20 @@ module Decidim
|
|
151
166
|
def has_replies?
|
152
167
|
model.comment_threads.any?
|
153
168
|
end
|
169
|
+
|
170
|
+
# action_authorization_button expects current_component to be available
|
171
|
+
def current_component
|
172
|
+
root_commentable.try(:component)
|
173
|
+
end
|
174
|
+
|
175
|
+
def vote_button_to(path, params, &block)
|
176
|
+
# actions are linked to objects belonging to a component
|
177
|
+
# In consultations, a question belong to a participatory_space but it has comments
|
178
|
+
# To apply :comment permission, the modal authorizer should be refactored to allow participatory spaces-level comments
|
179
|
+
return button_to(path, params, &block) unless current_component
|
180
|
+
|
181
|
+
action_authorized_button_to(:vote_comment, path, params.merge(resource: root_commentable), &block)
|
182
|
+
end
|
154
183
|
end
|
155
184
|
end
|
156
185
|
end
|
@@ -15,7 +15,7 @@
|
|
15
15
|
required: true,
|
16
16
|
placeholder: t("decidim.components.add_comment_form.form.body.placeholder"),
|
17
17
|
label: false,
|
18
|
-
data: { remaining_characters: "##{add_comment_id}-remaining-characters" }
|
18
|
+
data: { remaining_characters: "##{add_comment_id}-remaining-characters", input_emoji: true }
|
19
19
|
) %>
|
20
20
|
</div>
|
21
21
|
<button type="submit" class="button button--sc" disabled="disabled"><%= t("decidim.components.add_comment_form.form.submit") %></button>
|
@@ -1,18 +1,22 @@
|
|
1
1
|
<div class="add-comment">
|
2
|
-
<
|
2
|
+
<h5 class="section-heading"><%= t("decidim.components.add_comment_form.title") %></h5>
|
3
3
|
|
4
4
|
<% if user_signed_in? %>
|
5
5
|
<% if alignment_enabled? %>
|
6
6
|
<div class="opinion-toggle button-group">
|
7
|
-
<
|
8
|
-
|
7
|
+
<span class="show-for-sr"><%= t("decidim.components.add_comment_form.opinion.label") %></span>
|
8
|
+
<button aria-pressed="false" class="button tiny button--muted opinion-toggle--ok" data-selected-label="<%= t("decidim.components.add_comment_form.opinion.positive_selected") %>">
|
9
|
+
<%= icon "thumb-up", role: "img", "aria-hidden": true %>
|
10
|
+
<span class="show-for-sr"><%= t("decidim.components.add_comment_form.opinion.positive") %></span>
|
9
11
|
</button>
|
10
|
-
<button class="button tiny button--muted opinion-toggle--meh is-active">
|
12
|
+
<button aria-pressed="true" class="button tiny button--muted opinion-toggle--meh is-active" data-selected-label="<%= t("decidim.components.add_comment_form.opinion.neutral_selected") %>">
|
11
13
|
<%= t("decidim.components.add_comment_form.opinion.neutral") %>
|
12
14
|
</button>
|
13
|
-
<button class="button tiny button--muted opinion-toggle--ko">
|
14
|
-
<%= icon "thumb-down", role: "
|
15
|
+
<button aria-pressed="false" class="button tiny button--muted opinion-toggle--ko" data-selected-label="<%= t("decidim.components.add_comment_form.opinion.negative_selected") %>">
|
16
|
+
<%= icon "thumb-down", role: "img", "aria-hidden": true %>
|
17
|
+
<span class="show-for-sr"><%= t("decidim.components.add_comment_form.opinion.negative") %></span>
|
15
18
|
</button>
|
19
|
+
<div role="alert" aria-live="assertive" aria-atomic="true" class="selected-state show-for-sr"></div>
|
16
20
|
</div>
|
17
21
|
<% end %>
|
18
22
|
<%== cell("decidim/comments/comment_form", model, root_depth: root_depth) %>
|
@@ -1,14 +1,14 @@
|
|
1
1
|
<div class="order-by__dropdown order-by__dropdown--right">
|
2
2
|
<span class="order-by__text"><%= t("decidim.components.comment_order_selector.title") %></span>
|
3
|
-
<ul
|
3
|
+
<ul id="comments-order-menu"
|
4
|
+
class="dropdown menu"
|
4
5
|
data-dropdown-menu="data-dropdown-menu"
|
5
6
|
data-autoclose="false"
|
6
7
|
data-disable-hover="true"
|
7
8
|
data-click-open="true"
|
8
9
|
data-close-on-click="true"
|
9
|
-
tabindex="-1"
|
10
10
|
role="menubar">
|
11
|
-
<li class="is-dropdown-submenu-parent opens-right"
|
11
|
+
<li class="is-dropdown-submenu-parent opens-right" role="presentation">
|
12
12
|
<a href="#" id="comments-order-menu-control"
|
13
13
|
aria-label="<%= t("decidim.components.comment_order_selector.title") %>"
|
14
14
|
aria-controls="comments-order-menu"
|
@@ -18,10 +18,9 @@
|
|
18
18
|
id="comments-order-chooser-menu"
|
19
19
|
role="menu"
|
20
20
|
aria-labelledby="comments-order-menu-control"
|
21
|
-
tabindex="-1"
|
22
21
|
data-submenu="">
|
23
22
|
<% available_orders.each do |order_value| %>
|
24
|
-
<li role="
|
23
|
+
<li role="presentation" class="is-submenu-item is-dropdown-submenu-item">
|
25
24
|
<%= link_to(
|
26
25
|
t("decidim.components.comment_order_selector.order.#{order_value}"),
|
27
26
|
decidim_comments.comments_path(commentable_gid: model.to_signed_global_id.to_s, order: order_value, reload: 1),
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class="columns large-9 comments-container" id="comments">
|
3
3
|
<div class="comments">
|
4
4
|
<div class="row collapse order-by">
|
5
|
-
<
|
5
|
+
<h4 class="order-by__text section-heading">
|
6
6
|
<% if single_comment? %>
|
7
7
|
<%= t("decidim.components.comments.comment_details_title") %>
|
8
8
|
<% else %>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<%= t("decidim.components.comments.title", count: comments_count) %>
|
11
11
|
</span>
|
12
12
|
<% end %>
|
13
|
-
</
|
13
|
+
</h4>
|
14
14
|
<%= render :order_control %>
|
15
15
|
</div>
|
16
16
|
<%= single_comment_warning %>
|
@@ -28,5 +28,3 @@
|
|
28
28
|
</div>
|
29
29
|
</div>
|
30
30
|
<% end %>
|
31
|
-
|
32
|
-
<%= javascript_include_tag("decidim/comments/comments") %>
|
@@ -1,3 +1,7 @@
|
|
1
1
|
<div class="callout warning">
|
2
|
-
|
2
|
+
<% if comment_permissions? %>
|
3
|
+
<p><%= blocked_comments_for_unauthorized_user_warning_link %></p>
|
4
|
+
<% else %>
|
5
|
+
<p><%= t("decidim.components.comments.blocked_comments_for_user_warning") %></p>
|
6
|
+
<% end %>
|
3
7
|
</div>
|
@@ -51,7 +51,7 @@ module Decidim
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def comments_count
|
54
|
-
model.
|
54
|
+
model.comments_count
|
55
55
|
end
|
56
56
|
|
57
57
|
def root_depth
|
@@ -113,7 +113,7 @@ module Decidim
|
|
113
113
|
def single_comment
|
114
114
|
return if options[:single_comment].blank?
|
115
115
|
|
116
|
-
@single_comment ||=
|
116
|
+
@single_comment ||= SortedComments.for(model, id: options[:single_comment], order_by: order).first
|
117
117
|
end
|
118
118
|
|
119
119
|
def machine_translations_toggled?
|
@@ -129,6 +129,28 @@ module Decidim
|
|
129
129
|
|
130
130
|
!model.user_allowed_to_comment?(current_user)
|
131
131
|
end
|
132
|
+
|
133
|
+
def comment_permissions?
|
134
|
+
[model, current_component].any? do |resource|
|
135
|
+
resource.try(:permissions).try(:[], "comment")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# action_authorization_link expects current_component to be available
|
140
|
+
def current_component
|
141
|
+
model.try(:component)
|
142
|
+
end
|
143
|
+
|
144
|
+
def blocked_comments_for_unauthorized_user_warning_link
|
145
|
+
options = if current_component.present?
|
146
|
+
{ resource: model }
|
147
|
+
else
|
148
|
+
{ resource: model, permissions_holder: model }
|
149
|
+
end
|
150
|
+
action_authorized_link_to(:comment, commentable_path, options) do
|
151
|
+
t("decidim.components.comments.blocked_comments_for_unauthorized_user_warning")
|
152
|
+
end
|
153
|
+
end
|
132
154
|
end
|
133
155
|
end
|
134
156
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<div class="reveal edit-comment-modal" id="<%= "editCommentModal#{model.id}" %>" data-reveal>
|
2
|
+
<div class="reveal__header">
|
3
|
+
<h3 class="reveal__title"><%= t("decidim.components.edit_comment_modal_form.title") %></h3>
|
4
|
+
<button class="close-button" data-close aria-label="<%= t("decidim.components.edit_comment_modal_form.close") %>" type="button">
|
5
|
+
<span aria-hidden="true">×</span>
|
6
|
+
</button>
|
7
|
+
</div>
|
8
|
+
<%= form_for(form_object, url: decidim_comments.comment_path(comment), method: :put, remote: true, html: { id: form_id }) do |form| %>
|
9
|
+
<div class="field">
|
10
|
+
<label class="show-for-sr" for="<%= form_id %>">
|
11
|
+
<%= t("decidim.components.edit_comment_modal_form.form.body.label") %>
|
12
|
+
</label>
|
13
|
+
<div class="hashtags__container">
|
14
|
+
<%= form.text_area(
|
15
|
+
:body,
|
16
|
+
id: form_id,
|
17
|
+
rows: 4,
|
18
|
+
maxlength: comments_max_length,
|
19
|
+
required: true,
|
20
|
+
placeholder: t("decidim.components.edit_comment_modal_form.form.body.placeholder"),
|
21
|
+
label: false,
|
22
|
+
data: { remaining_characters: "##{form_id}-remaining-characters" }
|
23
|
+
) %>
|
24
|
+
</div>
|
25
|
+
<button type="submit" data-close class="button button--sc"><%= t("decidim.components.edit_comment_modal_form.form.submit") %></button>
|
26
|
+
<span id="<%= form_id %>-remaining-characters" class="remaining-character-count"></span>
|
27
|
+
</div>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Comments
|
5
|
+
# A cell to display a form for edditing a comment.
|
6
|
+
class EditCommentModalFormCell < Decidim::ViewModel
|
7
|
+
delegate :current_user, :user_signed_in?, to: :controller
|
8
|
+
alias comment model
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def decidim_comments
|
13
|
+
Decidim::Comments::Engine.routes.url_helpers
|
14
|
+
end
|
15
|
+
|
16
|
+
def form_id
|
17
|
+
"edit_comment_#{comment.id}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def form_object
|
21
|
+
Decidim::Comments::CommentForm.new(
|
22
|
+
body: comment.translated_body
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def comments_max_length
|
27
|
+
return 1000 unless model.respond_to?(:component)
|
28
|
+
return component_comments_max_length if component_comments_max_length
|
29
|
+
return organization_comments_max_length if organization_comments_max_length
|
30
|
+
|
31
|
+
1000
|
32
|
+
end
|
33
|
+
|
34
|
+
def component_comments_max_length
|
35
|
+
return unless model.component&.settings.respond_to?(:comments_max_length)
|
36
|
+
|
37
|
+
model.component.settings.comments_max_length if model.component.settings.comments_max_length.positive?
|
38
|
+
end
|
39
|
+
|
40
|
+
def organization_comments_max_length
|
41
|
+
return unless organization
|
42
|
+
|
43
|
+
organization.comments_max_length if organization.comments_max_length.positive?
|
44
|
+
end
|
45
|
+
|
46
|
+
def organization
|
47
|
+
return model.organization if model.respond_to?(:organization)
|
48
|
+
|
49
|
+
model.component.organization if model.component.organization.comments_max_length.positive?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -39,7 +39,8 @@ module Decidim
|
|
39
39
|
root_commentable: root_commentable(form.commentable),
|
40
40
|
body: { I18n.locale => parsed.rewrite },
|
41
41
|
alignment: form.alignment,
|
42
|
-
decidim_user_group_id: form.user_group_id
|
42
|
+
decidim_user_group_id: form.user_group_id,
|
43
|
+
participatory_space: form.current_component.try(:participatory_space)
|
43
44
|
}
|
44
45
|
|
45
46
|
@comment = Decidim.traceability.create!(
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Comments
|
5
|
+
# A command with all the business logic to delete a comment
|
6
|
+
class DeleteComment < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# comment - The comment to delete.
|
10
|
+
# current_user - The user performing the action.
|
11
|
+
def initialize(comment, current_user)
|
12
|
+
@comment = comment
|
13
|
+
@current_user = current_user
|
14
|
+
end
|
15
|
+
|
16
|
+
# Executes the command. Broadcasts these events:
|
17
|
+
#
|
18
|
+
# - :ok when everything is valid.
|
19
|
+
# - :invalid if comment isn't authored by current_user.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def call
|
23
|
+
return broadcast(:invalid) unless comment.authored_by?(current_user)
|
24
|
+
|
25
|
+
delete_comment
|
26
|
+
|
27
|
+
broadcast(:ok)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :comment, :current_user
|
33
|
+
|
34
|
+
def delete_comment
|
35
|
+
Decidim.traceability.perform_action!(
|
36
|
+
:delete,
|
37
|
+
comment,
|
38
|
+
current_user,
|
39
|
+
visibility: "public-only"
|
40
|
+
) do
|
41
|
+
comment.delete!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Comments
|
5
|
+
# A command with all the business logic to update an existing comment
|
6
|
+
class UpdateComment < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# comment - Decidim::Comments::Comment
|
10
|
+
# current_user - Decidim::User
|
11
|
+
# form - A form object with the params.
|
12
|
+
def initialize(comment, current_user, form)
|
13
|
+
@comment = comment
|
14
|
+
@current_user = current_user
|
15
|
+
@form = form
|
16
|
+
end
|
17
|
+
|
18
|
+
# Executes the command. Broadcasts these events:
|
19
|
+
#
|
20
|
+
# - :ok when everything is valid.
|
21
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
22
|
+
#
|
23
|
+
# Returns nothing.
|
24
|
+
def call
|
25
|
+
return broadcast(:invalid) if form.invalid? || !comment.authored_by?(current_user)
|
26
|
+
|
27
|
+
update_comment
|
28
|
+
|
29
|
+
broadcast(:ok)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :form, :comment, :current_user
|
35
|
+
|
36
|
+
def update_comment
|
37
|
+
parsed = Decidim::ContentProcessor.parse(form.body, current_organization: form.current_organization)
|
38
|
+
|
39
|
+
params = {
|
40
|
+
body: { I18n.locale => parsed.rewrite }
|
41
|
+
}
|
42
|
+
|
43
|
+
@comment = Decidim.traceability.update!(
|
44
|
+
comment,
|
45
|
+
current_user,
|
46
|
+
params,
|
47
|
+
visibility: "public-only",
|
48
|
+
edit: true
|
49
|
+
)
|
50
|
+
|
51
|
+
mentioned_users = parsed.metadata[:user].users
|
52
|
+
mentioned_groups = parsed.metadata[:user_group].groups
|
53
|
+
CommentCreation.publish(@comment, parsed.metadata)
|
54
|
+
send_notifications(mentioned_users, mentioned_groups)
|
55
|
+
end
|
56
|
+
|
57
|
+
def send_notifications(mentioned_users, mentioned_groups)
|
58
|
+
NewCommentNotificationCreator.new(comment, mentioned_users, mentioned_groups).create
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|