decidim-comments 0.29.1 → 0.30.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/comments/comment/actions.erb +0 -8
  3. data/app/cells/decidim/comments/comment/show.erb +41 -5
  4. data/app/cells/decidim/comments/comment_cell.rb +44 -0
  5. data/app/cells/decidim/comments/comment_form/comment_as.erb +24 -6
  6. data/app/cells/decidim/comments/comment_form/opinion.erb +0 -4
  7. data/app/cells/decidim/comments/comment_form/show.erb +31 -29
  8. data/app/cells/decidim/comments/comment_form_cell.rb +7 -2
  9. data/app/cells/decidim/comments/comment_thread/show.erb +1 -1
  10. data/app/cells/decidim/comments/comments/add_comment.erb +12 -14
  11. data/app/cells/decidim/comments/comments/comments_in_single_column.erb +6 -0
  12. data/app/cells/decidim/comments/comments/order_control.erb +32 -9
  13. data/app/cells/decidim/comments/comments/show.erb +7 -7
  14. data/app/cells/decidim/comments/comments_cell.rb +56 -12
  15. data/app/cells/decidim/comments/two_columns_comments/column.erb +20 -0
  16. data/app/cells/decidim/comments/two_columns_comments/show.erb +11 -0
  17. data/app/cells/decidim/comments/two_columns_comments_cell.rb +86 -0
  18. data/app/forms/decidim/comments/comment_form.rb +14 -0
  19. data/app/models/decidim/comments/comment.rb +9 -7
  20. data/app/packs/entrypoints/decidim_comments.js +1 -0
  21. data/app/packs/src/decidim/comments/comments.component.js +151 -24
  22. data/app/packs/src/decidim/comments/comments.component.test.js +2 -1
  23. data/app/packs/src/decidim/comments/comments.js +95 -12
  24. data/app/packs/src/decidim/comments/comments_dropdown.js +57 -0
  25. data/app/packs/src/decidim/comments/comments_mobile_modal.js +46 -0
  26. data/app/packs/stylesheets/comments.scss +203 -50
  27. data/app/queries/decidim/comments/metrics/comment_participants_metric_measure.rb +1 -1
  28. data/app/queries/decidim/comments/metrics/comments_metric_manage.rb +22 -17
  29. data/app/views/decidim/comments/comments/create.js.erb +9 -1
  30. data/app/views/decidim/comments/comments/update.js.erb +6 -0
  31. data/config/locales/ar.yml +0 -1
  32. data/config/locales/bg.yml +0 -1
  33. data/config/locales/bn-BD.yml +1 -0
  34. data/config/locales/bs-BA.yml +15 -0
  35. data/config/locales/ca.yml +36 -3
  36. data/config/locales/cs.yml +37 -2
  37. data/config/locales/de.yml +36 -3
  38. data/config/locales/el.yml +0 -1
  39. data/config/locales/en.yml +35 -2
  40. data/config/locales/es-MX.yml +35 -2
  41. data/config/locales/es-PY.yml +35 -2
  42. data/config/locales/es.yml +36 -3
  43. data/config/locales/eu.yml +55 -19
  44. data/config/locales/fi-plain.yml +35 -2
  45. data/config/locales/fi.yml +39 -6
  46. data/config/locales/fr-CA.yml +8 -2
  47. data/config/locales/fr.yml +8 -2
  48. data/config/locales/gl.yml +0 -1
  49. data/config/locales/hu.yml +0 -1
  50. data/config/locales/id-ID.yml +0 -1
  51. data/config/locales/is-IS.yml +0 -1
  52. data/config/locales/it.yml +1 -1
  53. data/config/locales/ja.yml +34 -2
  54. data/config/locales/lb.yml +0 -1
  55. data/config/locales/lt.yml +0 -1
  56. data/config/locales/lv.yml +0 -1
  57. data/config/locales/nl.yml +0 -1
  58. data/config/locales/no.yml +0 -1
  59. data/config/locales/pl.yml +0 -2
  60. data/config/locales/pt-BR.yml +0 -1
  61. data/config/locales/pt.yml +0 -1
  62. data/config/locales/ro-RO.yml +1 -2
  63. data/config/locales/ru.yml +0 -1
  64. data/config/locales/sk.yml +0 -1
  65. data/config/locales/sv.yml +19 -2
  66. data/config/locales/tr-TR.yml +0 -1
  67. data/config/locales/uk.yml +0 -1
  68. data/config/locales/zh-CN.yml +0 -1
  69. data/config/locales/zh-TW.yml +0 -1
  70. data/decidim-comments.gemspec +2 -2
  71. data/lib/decidim/api/comment_mutation_type.rb +2 -2
  72. data/lib/decidim/api/comment_type.rb +25 -45
  73. data/lib/decidim/api/commentable_interface.rb +10 -16
  74. data/lib/decidim/api/commentable_mutation_type.rb +2 -3
  75. data/lib/decidim/comments/commentable.rb +11 -0
  76. data/lib/decidim/comments/commentable_with_component.rb +3 -1
  77. data/lib/decidim/comments/engine.rb +7 -1
  78. data/lib/decidim/comments/query_extensions.rb +1 -1
  79. data/lib/decidim/comments/test/factories.rb +9 -1
  80. data/lib/decidim/comments/test/shared_examples/comment_event.rb +1 -1
  81. data/lib/decidim/comments/test/shared_examples/comment_voted_event.rb +2 -2
  82. data/lib/decidim/comments/test/shared_examples/create_comment_context.rb +1 -1
  83. data/lib/decidim/comments/test/shared_examples/translatable_comment.rb +2 -2
  84. data/lib/decidim/comments/version.rb +1 -1
  85. metadata +19 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51d04842ce82296e0d8bd4a7146abc0f4c40f7097d349895fba37706bfb6a358
4
- data.tar.gz: a79cb56faacd55d250a965a8373de198758a58b9dc83e3f37f01828728c99094
3
+ metadata.gz: ab9e4d5d3fbe47d002562511e0714a8006064ae68d8db6a575d217e1ff4ff094
4
+ data.tar.gz: 484efc915fc431bd0e638a0d8e746d2e577dfdb4f9b36a31cb211469bb65bc5a
5
5
  SHA512:
6
- metadata.gz: 56945ff77b2ca01a53e3e8f637a08038cd806f9cb9002d36b59235ba9a130a5b1321cd304cac8661ea5084b31cb0917d5638ef9801be31668ef971871b5734b1
7
- data.tar.gz: ee75b0ea226b00e66607726ba344baa0f66d89345c26422415b3bd833b84831463bb16170a4608a267e5ca165e3388466866aeeba2badfc7cea14be61d5914a7
6
+ metadata.gz: 0b49a6ae8203a07ffb10f8b85cde3619cb0891a94372ec699e0a8686589d4c11fa98615d958ee091033d8f55cb88bd011d051ac22ec17ea595bed822f5a34b06
7
+ data.tar.gz: d940aa2380a2a88e8c46833de885ffefd92a5d35a54e5388012fbc6183cc84732e3b92f0cc7afc07824efac41607d3e7761cd97faab25355ffe537b8dc80501f
@@ -1,12 +1,4 @@
1
1
  <div class="comment__actions">
2
- <% if depth.zero? && has_replies_in_children? %>
3
- <button class="button button__sm button__text-secondary" data-comment-hide data-controls="comment-<%= model.id %>-replies" data-open="true" id="comment-<%= model.id %>-replies-trigger">
4
- <%= icon "arrow-down-s-line" %>
5
- <span data-show-comment-reply class="font-normal"><%= t("decidim.components.comment.show_replies", count: replies.size) %></span>
6
- <%= icon "arrow-up-s-line" %>
7
- <span data-hide-comment-reply class="font-normal"><%= t("decidim.components.comment.hide_replies", count: replies.size) %></span>
8
- </button>
9
- <% end %>
10
2
  <% if can_reply? %>
11
3
  <button class="button button__sm button__text-secondary" data-controls="panel-<%= reply_id %>" id="panel-<%= reply_id %>-trigger">
12
4
  <%= icon "chat-1-line" %>
@@ -1,9 +1,20 @@
1
- <%= content_tag :div, id: "comment_#{model.id}", class: "comment relative", role: "comment", data: { comment_id: model.id, parent: parent_element_id } do %>
1
+ <%= content_tag :div,
2
+ id: "comment_#{model.id}",
3
+ class: ["comment", "relative", ("top-comment" if top_comment_label.present?)].compact,
4
+ role: "comment",
5
+ data: { comment_id: model.id, parent: parent_element_id } do %>
2
6
  <% if model.hidden? %>
3
7
  <%= render :moderation_data %>
4
8
  <% elsif model.deleted? %>
5
9
  <%= render :deletion_data %>
6
10
  <% else %>
11
+ <% if top_comment_label.present? %>
12
+ <div class="most-upvoted-label label">
13
+ <span><%= icon "star-s-line" %></span>
14
+ <span><%= top_comment_label %></span>
15
+ </div>
16
+ <% end %>
17
+
7
18
  <div class="comment__header">
8
19
  <div class="sr-only"><%= comment_label %></div>
9
20
 
@@ -21,7 +32,9 @@
21
32
 
22
33
  <div class="relative ml-auto">
23
34
  <button id="dropdown-trigger-<%= context_menu_id %>" data-component="dropdown" data-target="dropdown-menu-<%= context_menu_id %>" aria-label="<%= t("decidim.components.comment.controls_label") %>">
24
- &#8230;
35
+ <%# NOTE: having two times the icon call is intentional, as that is how the `dropdown` CSS code is done %>
36
+ <%= icon "more-fill" %>
37
+ <%= icon "more-fill" %>
25
38
  </button>
26
39
 
27
40
  <div id="dropdown-menu-<%= context_menu_id %>" aria-hidden="true">
@@ -51,6 +64,13 @@
51
64
  <% end %>
52
65
  </li>
53
66
  <% end %>
67
+ <% if (extra_actions) %>
68
+ <% extra_actions.each do |action| %>
69
+ <li>
70
+ <%= link_to(*action) %>
71
+ </li>
72
+ <% end %>
73
+ <% end %>
54
74
  </ul>
55
75
  </div>
56
76
  </div>
@@ -63,10 +83,26 @@
63
83
  </div>
64
84
  </div>
65
85
 
66
- <div data-comment-footer data-component="accordion" id="accordion-<%= model.id %>">
86
+ <div data-comment-footer data-component="accordion" id="accordion-<%= model.id %>" class="relative">
67
87
  <div class="comment__footer-grid">
68
- <%= render :actions %>
69
- <%= votes %>
88
+ <div class="comment__votes-actions">
89
+ <%= render :actions %>
90
+ <%= votes %>
91
+ </div>
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 %>
70
106
  </div>
71
107
  <% if can_reply? %>
72
108
  <div id="panel-<%= reply_id %>" class="add-comment" data-additional-reply>
@@ -5,6 +5,7 @@ module Decidim
5
5
  # A cell to display a single comment.
6
6
  class CommentCell < Decidim::ViewModel
7
7
  include Decidim::ResourceHelper
8
+ include Decidim::UserRoleChecker
8
9
  include Cell::ViewModel::Partial
9
10
 
10
11
  delegate :current_user, :user_signed_in?, to: :controller
@@ -43,6 +44,12 @@ module Decidim
43
44
  "comment_#{model.decidim_commentable_id}"
44
45
  end
45
46
 
47
+ def top_comment_label
48
+ return unless options[:top_comment]
49
+
50
+ I18n.t("decidim.components.comments.top_comment_label")
51
+ end
52
+
46
53
  def comment_label
47
54
  if reply?
48
55
  t("decidim.components.comment.comment_label_reply", comment_id: model.id, parent_comment_id: model.decidim_commentable_id)
@@ -67,6 +74,7 @@ module Decidim
67
74
  hash.push(model.down_votes_count)
68
75
  hash.push(model.cache_key_with_version)
69
76
  hash.push(model.author.cache_key_with_version)
77
+ hash.push(extra_actions.to_s)
70
78
  @hash = hash.join(Decidim.cache_key_separator)
71
79
  end
72
80
 
@@ -86,6 +94,27 @@ module Decidim
86
94
  options[:order] || "older"
87
95
  end
88
96
 
97
+ def extra_actions
98
+ return @extra_actions if defined?(@extra_actions) && @extra_actions.present?
99
+
100
+ @extra_actions = model.extra_actions_for(current_user)
101
+ return unless @extra_actions
102
+
103
+ @extra_actions.map! do |action|
104
+ [
105
+ "#{icon(action[:icon]) if action[:icon].present?}#{action[:label]}",
106
+ action[:url],
107
+ {
108
+ class: "dropdown__item"
109
+ }
110
+ ].tap do |link|
111
+ link[2][:method] = action[:method] if action[:method].present?
112
+ link[2][:remote] = action[:remote] if action[:remote].present?
113
+ link[2][:data] = action[:data] if action[:data].present?
114
+ end
115
+ end
116
+ end
117
+
89
118
  def reply_id
90
119
  "comment#{model.id}-reply"
91
120
  end
@@ -95,10 +124,17 @@ module Decidim
95
124
  end
96
125
 
97
126
  def can_reply?
127
+ return false if two_columns_layout?
128
+ return true if current_participatory_space && user_has_any_role?(current_user, current_participatory_space)
129
+
98
130
  user_signed_in? && accepts_new_comments? &&
99
131
  root_commentable.user_allowed_to_comment?(current_user)
100
132
  end
101
133
 
134
+ def two_columns_layout?
135
+ root_commentable.respond_to?(:two_columns_layout?) && root_commentable.two_columns_layout?
136
+ end
137
+
102
138
  def author_presenter
103
139
  if model.author.respond_to?(:official?) && model.author.official?
104
140
  Decidim::Core::OfficialAuthorPresenter.new
@@ -207,6 +243,10 @@ module Decidim
207
243
  root_commentable.try(:component)
208
244
  end
209
245
 
246
+ def current_participatory_space
247
+ current_component&.participatory_space
248
+ end
249
+
210
250
  def vote_button_to(path, params, &)
211
251
  # actions are linked to objects belonging to a component
212
252
  # To apply :comment permission, the modal authorizer should be refactored to allow participatory spaces-level comments
@@ -214,6 +254,10 @@ module Decidim
214
254
 
215
255
  action_authorized_button_to(:vote_comment, path, params.merge(resource: root_commentable), &)
216
256
  end
257
+
258
+ def decidim_verifications
259
+ Decidim::Verifications::Engine.routes.url_helpers
260
+ end
217
261
  end
218
262
  end
219
263
  end
@@ -1,10 +1,28 @@
1
1
  <div class="comment__as">
2
- <label class="mr-2 inline-block" for="<%= comment_as_id %>">
3
- <%= t("decidim.components.add_comment_form.form.user_group_id.label") %>
4
- </label>
5
- <select class="p-2" id="<%= comment_as_id %>" name="comment[user_group_id]">
2
+ <button id="dropdown-trigger-<%= comment_as_id %>" data-component="dropdown" data-target="dropdown-menu-<%= comment_as_id %>" data-comments-dropdown>
3
+ <div class="comment__as-author-selected">
4
+ <label class="ml-10 text-left text-xs" for="<%= comment_as_id %>">
5
+ <%= t("decidim.components.add_comment_form.form.user_group_id.your_profile") %>
6
+ </label>
7
+ <span class="flex items-center gap-2"></span>
8
+ </div>
9
+ <%= icon "arrow-down-s-line" %>
10
+ <%= icon "arrow-up-s-line" %>
11
+ </button>
12
+
13
+ <ul id="dropdown-menu-<%= comment_as_id %>" class="gap-4">
6
14
  <% comment_as_options.each do |option| %>
7
- <option value="<%= option[1] %>"><%= option[0] %></option>
15
+ <li class="comment__as-author-container">
16
+ <div class="comment__as-author-info">
17
+ <div class="author__avatar-container border border-white">
18
+ <%= image_tag option[0].avatar_url(:thumb), alt: t("decidim.author.avatar", name: option[0].name), class: "author__avatar" %>
19
+ </div>
20
+
21
+ <p class="comment__as-author-name"><%= option[0].name %></p>
22
+ </div>
23
+
24
+ <input type="radio" name="comment[user_group_id]" class="w-5 h-4" value="<%= option[1] %>">
25
+ </li>
8
26
  <% end %>
9
- </select>
27
+ </ul>
10
28
  </div>
@@ -5,10 +5,6 @@
5
5
  <span><%= t("decidim.components.comment.alignment.in_favor") %></span>
6
6
  <%= icon "thumb-up-line" %>
7
7
  </button>
8
- <button type="button" aria-pressed="true" class="is-active" data-toggle-meh="true" data-selected-label="<%= t("decidim.components.add_comment_form.opinion.neutral_selected") %>">
9
- <span><%= t("decidim.components.add_comment_form.opinion.neutral") %></span>
10
- <%= icon "loader-3-line" %>
11
- </button>
12
8
  <button type="button" aria-pressed="false" data-toggle-ko="true" data-selected-label="<%= t("decidim.components.add_comment_form.opinion.negative_selected") %>">
13
9
  <span><%= t("decidim.components.comment.alignment.against") %></span>
14
10
  <%= icon "thumb-down-line" %>
@@ -1,41 +1,43 @@
1
1
  <%= form_for(form_object, url: decidim_comments.comments_path(order:), method: :post, remote: true, html: { id: form_id }) do |form| %>
2
+ <% unless reply? %>
3
+ <div class="comment__form-mobile-banner">
4
+ <p class="font-semibold text-2xl"><%= t("decidim.components.add_comment_form.add_comment") %></p>
5
+ <button type="button" class="close-button close-add-comment-fullscreen">
6
+ <%= icon "close-line" %>
7
+ </button>
8
+ </div>
9
+ <% end %>
2
10
  <%= form.hidden_field :commentable_gid, id: nil %>
3
11
  <%= form.hidden_field :alignment, id: nil, class: "alignment-input" %>
4
12
  <%= comment_as_for(form) %>
5
13
 
6
- <div class="flex justify-between items-end mb-4">
7
- <label class="comment__form-label" for="<%= add_comment_id %>">
8
- <%= t("decidim.components.add_comment_form.form.body.label") %>
9
- </label>
10
-
11
- <span id="<%= add_comment_id %>-remaining-characters" class="remaining-character-count"></span>
14
+ <div class="px-4 md:p-0">
15
+ <%= form.text_area(
16
+ :body,
17
+ id: add_comment_id,
18
+ class: "w-full min-h-[160px]",
19
+ maxlength: comments_max_length,
20
+ required: true,
21
+ placeholder: t("decidim.components.add_comment_form.form.body.placeholder"),
22
+ label: false,
23
+ data: { remaining_characters: "##{add_comment_id}-remaining-characters", input_emoji: true }
24
+ ) %>
12
25
  </div>
13
-
14
- <%= form.text_area(
15
- :body,
16
- id: add_comment_id,
17
- class: "w-full min-h-[160px]",
18
- maxlength: comments_max_length,
19
- required: true,
20
- placeholder: t("decidim.components.add_comment_form.form.body.placeholder"),
21
- label: false,
22
- data: { remaining_characters: "##{add_comment_id}-remaining-characters", input_emoji: true }
23
- ) %>
26
+ <span id="<%= add_comment_id %>-remaining-characters" class="remaining-character-count"></span>
24
27
 
25
28
  <div class="comment__form-submit">
26
- <% if alignment_enabled? %>
29
+ <% if two_columns_layout? && alignment_enabled? %>
27
30
  <%= render :opinion %>
28
31
  <% end %>
29
-
30
- <button type="submit" class="button button__sm button__secondary" disabled="disabled">
31
- <span>
32
- <% if reply? %>
33
- <%= t("decidim.components.add_comment_form.form.submit_reply") %>
34
- <% else %>
35
- <%= t("decidim.components.add_comment_form.form.submit_root_comment") %>
36
- <% end %>
37
- </span>
38
- <%= icon "chat-1-line" %>
39
- </button>
32
+ <div class="<%= reply? ? "" : "publish-comment-button" %>">
33
+ <button type="submit"
34
+ class="button button__sm button__secondary <%= reply? ? "w-full" : "h-9 close-comment-fullscreen" %>"
35
+ disabled="disabled">
36
+ <span>
37
+ <%= reply? ? t("decidim.components.add_comment_form.form.submit_reply") : t("decidim.components.add_comment_form.form.submit_root_comment") %>
38
+ </span>
39
+ <%= icon "chat-1-line" %>
40
+ </button>
41
+ </div>
40
42
  </div>
41
43
  <% end %>
@@ -13,6 +13,10 @@ module Decidim
13
13
  render view: :comment_as, locals: { form: }
14
14
  end
15
15
 
16
+ def two_columns_layout?
17
+ model.respond_to?(:two_columns_layout?) && model.two_columns_layout?
18
+ end
19
+
16
20
  private
17
21
 
18
22
  def cache_hash
@@ -21,6 +25,7 @@ module Decidim
21
25
  hash.push(model.cache_key)
22
26
  hash.push(order)
23
27
  hash.push(current_user.try(:id))
28
+ hash.push(options)
24
29
  hash.join(Decidim.cache_key_separator)
25
30
  end
26
31
 
@@ -74,8 +79,8 @@ module Decidim
74
79
  end
75
80
 
76
81
  def comment_as_options
77
- [[current_user.name, ""]] + verified_user_groups.map do |group|
78
- [group.name, group.id]
82
+ [[UserPresenter.new(current_user), ""]] + verified_user_groups.map do |group|
83
+ [UserGroupPresenter.new(group), group.id]
79
84
  end
80
85
  end
81
86
 
@@ -1,3 +1,3 @@
1
1
  <div class="comment-thread" role="region">
2
- <%= cell("decidim/comments/comment", model, root_depth: model.depth, order:) %>
2
+ <%= cell("decidim/comments/comment", model, root_depth: model.depth, order:, top_comment: options[:top_comment]) %>
3
3
  </div>
@@ -1,15 +1,13 @@
1
- <div class="add-comment">
2
- <% if user_signed_in? %>
1
+ <% if user_signed_in? %>
2
+ <div class="add-comment hidden md:flex" id="add-comment-anchor">
3
3
  <%== cell("decidim/comments/comment_form", model, root_depth:) %>
4
- <% else %>
5
- <p>
6
- <span>
7
- <%== t(
8
- "decidim.components.add_comment_form.account_message",
9
- sign_in_url: decidim.new_user_session_path,
10
- sign_up_url: decidim.new_user_registration_path
11
- ) %>
12
- </span>
13
- </p>
14
- <% end %>
15
- </div>
4
+ </div>
5
+ <% else %>
6
+ <p>
7
+ <div class="flash flex-col warning">
8
+ <div class="flash__message">
9
+ <%= action_authorized_link_to("comment", t("decidim.components.add_comment_form.account_message"), "#", **onboarding_action_params) %>
10
+ </div>
11
+ </div>
12
+ </p>
13
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <div class="comment-threads" id="<%= threads_node_id %>" aria-live="polite">
2
+ <%= comments_loading %>
3
+ <% comments.each do |comment| %>
4
+ <%= cell("decidim/comments/comment_thread", comment, order:) %>
5
+ <% end %>
6
+ </div>
@@ -1,13 +1,36 @@
1
1
  <div class="comment-order-by">
2
- <% available_orders.each do | order_value| %>
3
- <div class="text-center">
4
- <%= link_to(
5
- t("decidim.components.comment_order_selector.order.#{order_value}"),
6
- decidim_comments.comments_path(commentable_gid: model.to_signed_global_id.to_s, order: order_value, reload: 1),
7
- class: "button button__sm button__text-secondary only:m-auto comment-order-by__item inline-block #{order_value == order ? "underline font-bold" : ""}",
8
- remote: true,
9
- aria: { controls: threads_node_id }
10
- ) %>
2
+ <%= form_with url: "#" do %>
3
+ <div class="md:hidden">
4
+ <select id="order-mobile" aria-label="<%= t("decidim.components.comment.sort_by") %>" data-mobile-order-comment-select="true">
5
+ <option class="input-hidden" value="" <%= "disabled selected hidden" %>> <%= t("decidim.components.comment.sort_by") %> </option>
6
+ <% available_orders.each do |order_value| %>
7
+ <option
8
+ value="<%= order_value %>"
9
+ <%= "selected" if order_value == order %>
10
+ <% if order == nil && order_value == "older" || order_value == order %>
11
+ class="selected"
12
+ <% end %>
13
+ data-order-comment-url="<%= decidim_comments.comments_path(commentable_gid: model.to_signed_global_id.to_s, order: order_value || "older", reload: 1) %>">
14
+ <%= t("decidim.components.comment_order_selector.order.#{order_value}") %>
15
+ </option>
16
+ <% end %>
17
+ </select>
18
+ </div>
19
+ <div class="hidden md:block">
20
+ <label for="order" class="comments-label-dropdown"><%= t("decidim.components.comment.sort_by") %></label>
21
+ <select id="order" aria-label="<%= t("decidim.components.comment.sort_by") %>" data-desktop-order-comment-select="true">
22
+ <% available_orders.each do |order_value| %>
23
+ <option
24
+ value="<%= order_value %>"
25
+ <%= "selected" if order_value == order %>
26
+ <% if order == nil && order_value == "older" || order_value == order %>
27
+ class="selected"
28
+ <% end %>
29
+ data-order-comment-url="<%= decidim_comments.comments_path(commentable_gid: model.to_signed_global_id.to_s, order: order_value || "older", reload: 1) %>">
30
+ <%= t("decidim.components.comment_order_selector.order.#{order_value}") %>
31
+ </option>
32
+ <% end %>
33
+ </select>
11
34
  </div>
12
35
  <% end %>
13
36
  </div>
@@ -12,16 +12,16 @@
12
12
  </span>
13
13
  <% end %>
14
14
  </h2>
15
- <%= render :order_control %>
15
+ <%= render :order_control unless two_columns_layout? %>
16
16
  </div>
17
17
  <%= single_comment_warning %>
18
18
  <%= blocked_comments_warning %>
19
- <div class="comment-threads" id="<%= threads_node_id %>" aria-live="polite">
20
- <%= comments_loading %>
21
- <% comments.each do |comment| %>
22
- <%= cell("decidim/comments/comment_thread", comment, order:) %>
23
- <% end %>
24
- </div>
19
+ <%= render_comments %>
20
+ <% if user_signed_in? %>
21
+ <button class="button button__lg button__secondary flex md:hidden w-full h-9 text-sm add-comment-mobile">
22
+ <%= t("add_comment", scope: "decidim.components.add_comment_form") %>
23
+ </button>
24
+ <% end %>
25
25
  <%= add_comment %>
26
26
  <%= user_comments_blocked_warning %>
27
27
  </div>
@@ -4,13 +4,17 @@ module Decidim
4
4
  module Comments
5
5
  # A cell to display a comments section for a commentable object.
6
6
  class CommentsCell < Decidim::ViewModel
7
+ include UserRoleChecker
7
8
  delegate :user_signed_in?, to: :controller
8
- def add_comment
9
- return if single_comment?
10
- return if comments_blocked?
11
- return if user_comments_blocked?
12
9
 
13
- render :add_comment
10
+ def render_comments
11
+ return render_single_comment if single_comment?
12
+
13
+ two_columns_layout? ? render_comments_in_two_columns : render(:comments_in_single_column)
14
+ end
15
+
16
+ def add_comment
17
+ render :add_comment if can_add_comments?
14
18
  end
15
19
 
16
20
  def single_comment_warning
@@ -19,6 +23,10 @@ module Decidim
19
23
  render :single_comment_warning
20
24
  end
21
25
 
26
+ def reply?
27
+ model.is_a?(Decidim::Comments::Comment)
28
+ end
29
+
22
30
  def comments_loading
23
31
  return if single_comment?
24
32
 
@@ -41,6 +49,28 @@ module Decidim
41
49
 
42
50
  private
43
51
 
52
+ def two_columns_layout?
53
+ model.try(:two_columns_layout?)
54
+ end
55
+
56
+ def render_single_comment
57
+ @sorted_comments_in_favor = [single_comment]
58
+ render :comments_in_single_column
59
+ end
60
+
61
+ def render_comments_in_two_columns
62
+ cell(TwoColumnsCommentsCell, model).call
63
+ end
64
+
65
+ def can_add_comments?
66
+ return true if current_participatory_space && user_has_any_role?(current_user, current_participatory_space)
67
+ return if single_comment?
68
+ return if comments_blocked?
69
+ return if user_comments_blocked?
70
+
71
+ true
72
+ end
73
+
44
74
  def decidim_comments
45
75
  Decidim::Comments::Engine.routes.url_helpers
46
76
  end
@@ -74,7 +104,7 @@ module Decidim
74
104
  end
75
105
 
76
106
  def order
77
- options[:order] || "older"
107
+ options[:order]
78
108
  end
79
109
 
80
110
  def decidim
@@ -139,16 +169,30 @@ module Decidim
139
169
  model.try(:component)
140
170
  end
141
171
 
172
+ def current_participatory_space
173
+ model.try(:participatory_space)
174
+ end
175
+
176
+ def onboarding_action_params
177
+ params = if model.try(:component).present? || current_component.present?
178
+ { resource: model }
179
+ else
180
+ { resource: model, permissions_holder: model }
181
+ end
182
+ return params if ResourceLocatorPresenter.new(model).url
183
+ rescue NoMethodError
184
+ params.merge!(data: { onboarding_redirect_path: request.path })
185
+ end
186
+
142
187
  def blocked_comments_for_unauthorized_user_warning_link
143
- options = if current_component.present?
144
- { resource: model }
145
- else
146
- { resource: model, permissions_holder: model }
147
- end
148
- action_authorized_link_to(:comment, commentable_path, options) do
188
+ action_authorized_link_to(:comment, commentable_path, onboarding_action_params) do
149
189
  t("decidim.components.comments.blocked_comments_for_unauthorized_user_warning")
150
190
  end
151
191
  end
192
+
193
+ def decidim_verifications
194
+ Decidim::Verifications::Engine.routes.url_helpers
195
+ end
152
196
  end
153
197
  end
154
198
  end
@@ -0,0 +1,20 @@
1
+ <div class="comments-section__<%= @title.parameterize %>">
2
+ <div class="comments-section__header">
3
+ <%= icon @icon_name, class: "icon" %>
4
+ <span class="comments-section__title"><%= @title %></span>
5
+ </div>
6
+
7
+ <% if @top_comment.present? %>
8
+ <div class="top-comment">
9
+ <%= cell("decidim/comments/comment_thread", @top_comment, order:, top_comment: true) %>
10
+ </div>
11
+ <% end %>
12
+
13
+ <% if @comments.any? %>
14
+ <% @comments.each do |comment| %>
15
+ <%= cell("decidim/comments/comment_thread", comment, order:) %>
16
+ <% end %>
17
+ <% else %>
18
+ <p class="comments-section__no-comments"><%= @no_comments_message %></p>
19
+ <% end %>
20
+ </div>
@@ -0,0 +1,11 @@
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")) %>
4
+ </div>
5
+
6
+ <div id="mobileContainer" class="comment-threads block md:hidden" aria-live="polite">
7
+ <%= comments_loading %>
8
+ <% @interleaved_comments.each do |comment| %>
9
+ <%= cell("decidim/comments/comment_thread", comment, order:, top_comment: (comment == @top_comment_in_favor || comment == @top_comment_against)) %>
10
+ <% end %>
11
+ </div>