decidim-comments 0.23.6 → 0.24.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/comments/bundle.js.map +1 -1
  3. data/app/assets/javascripts/decidim/comments/comments.component.js.es6 +292 -0
  4. data/app/assets/javascripts/decidim/comments/comments.component.test.js +581 -0
  5. data/app/assets/javascripts/decidim/comments/comments.js.erb +1 -1
  6. data/app/cells/decidim/comments/comment/actions.erb +7 -0
  7. data/app/cells/decidim/comments/comment/alignment_badge.erb +4 -0
  8. data/app/cells/decidim/comments/comment/author.erb +1 -0
  9. data/app/cells/decidim/comments/comment/show.erb +40 -0
  10. data/app/cells/decidim/comments/comment/utilities.erb +13 -0
  11. data/app/cells/decidim/comments/comment/votes.erb +25 -0
  12. data/app/cells/decidim/comments/comment_card_cell.rb +22 -0
  13. data/app/cells/decidim/comments/comment_cell.rb +142 -8
  14. data/app/cells/decidim/comments/comment_form/comment_as.erb +10 -0
  15. data/app/cells/decidim/comments/comment_form/show.erb +24 -0
  16. data/app/cells/decidim/comments/comment_form_cell.rb +94 -0
  17. data/app/cells/decidim/comments/comment_m/top.erb +1 -1
  18. data/app/cells/decidim/comments/comment_thread/show.erb +6 -0
  19. data/app/cells/decidim/comments/comment_thread/title.erb +3 -0
  20. data/app/cells/decidim/comments/comment_thread_cell.rb +30 -0
  21. data/app/cells/decidim/comments/comments/add_comment.erb +30 -0
  22. data/app/cells/decidim/comments/comments/blocked_comments_warning.erb +3 -0
  23. data/app/cells/decidim/comments/comments/order_control.erb +37 -0
  24. data/app/cells/decidim/comments/comments/show.erb +32 -0
  25. data/app/cells/decidim/comments/comments/single_comment_warning.erb +9 -0
  26. data/app/cells/decidim/comments/comments/user_comments_blocked_warning.erb +3 -0
  27. data/app/cells/decidim/comments/comments_cell.rb +134 -0
  28. data/app/commands/decidim/comments/vote_comment.rb +34 -10
  29. data/app/controllers/decidim/comments/application_controller.rb +16 -0
  30. data/app/controllers/decidim/comments/comments_controller.rb +122 -0
  31. data/app/controllers/decidim/comments/votes_controller.rb +41 -0
  32. data/app/events/decidim/comments/comment_created_event.rb +1 -1
  33. data/app/events/decidim/comments/comment_downvoted_event.rb +8 -0
  34. data/app/events/decidim/comments/comment_upvoted_event.rb +8 -0
  35. data/app/events/decidim/comments/comment_voted_event.rb +26 -0
  36. data/app/forms/decidim/comments/comment_form.rb +6 -2
  37. data/app/models/decidim/comments/comment.rb +22 -8
  38. data/app/models/decidim/comments/seed.rb +1 -1
  39. data/app/permissions/decidim/comments/permissions.rb +59 -0
  40. data/app/queries/decidim/comments/metrics/comment_participants_metric_measure.rb +2 -2
  41. data/app/queries/decidim/comments/metrics/comments_metric_manage.rb +5 -6
  42. data/app/queries/decidim/comments/sorted_comments.rb +18 -14
  43. data/app/views/decidim/comments/comments/_comment.html.erb +5 -0
  44. data/app/views/decidim/comments/comments/_comments.html.erb +1 -0
  45. data/app/views/decidim/comments/comments/create.js.erb +16 -0
  46. data/app/views/decidim/comments/comments/error.js.erb +1 -0
  47. data/app/views/decidim/comments/comments/index.js.erb +24 -0
  48. data/app/views/decidim/comments/comments/reload.js.erb +21 -0
  49. data/app/views/decidim/comments/votes/create.js.erb +23 -0
  50. data/app/views/decidim/comments/votes/error.js.erb +1 -0
  51. data/config/locales/ar.yml +0 -2
  52. data/config/locales/ca.yml +7 -2
  53. data/config/locales/cs.yml +24 -7
  54. data/config/locales/de.yml +17 -2
  55. data/config/locales/el.yml +0 -2
  56. data/config/locales/en.yml +17 -2
  57. data/config/locales/es-MX.yml +7 -2
  58. data/config/locales/es-PY.yml +7 -2
  59. data/config/locales/es.yml +7 -2
  60. data/config/locales/eu.yml +0 -2
  61. data/config/locales/fi-plain.yml +17 -2
  62. data/config/locales/fi.yml +17 -2
  63. data/config/locales/fr-CA.yml +17 -2
  64. data/config/locales/fr.yml +17 -2
  65. data/config/locales/gl.yml +7 -2
  66. data/config/locales/hu.yml +0 -2
  67. data/config/locales/id-ID.yml +0 -2
  68. data/config/locales/is-IS.yml +0 -1
  69. data/config/locales/it.yml +4 -2
  70. data/config/locales/ja.yml +8 -4
  71. data/config/locales/lv.yml +0 -2
  72. data/config/locales/nl.yml +0 -2
  73. data/config/locales/no.yml +0 -2
  74. data/config/locales/pl.yml +19 -2
  75. data/config/locales/pt-BR.yml +0 -2
  76. data/config/locales/pt.yml +0 -2
  77. data/config/locales/ro-RO.yml +0 -3
  78. data/config/locales/ru.yml +0 -2
  79. data/config/locales/sk.yml +0 -2
  80. data/config/locales/sv.yml +7 -2
  81. data/config/locales/tr-TR.yml +7 -2
  82. data/config/locales/uk.yml +0 -1
  83. data/config/locales/zh-CN.yml +0 -2
  84. data/lib/decidim/api/add_comment_type.rb +13 -0
  85. data/lib/decidim/api/comment_mutation_type.rb +22 -0
  86. data/lib/decidim/api/comment_type.rb +89 -0
  87. data/lib/decidim/api/commentable_interface.rb +50 -0
  88. data/lib/decidim/api/commentable_mutation_type.rb +30 -0
  89. data/{app/types/decidim/comments → lib/decidim/api}/commentable_type.rb +2 -5
  90. data/lib/decidim/comments/api.rb +12 -0
  91. data/lib/decidim/comments/comments_helper.rb +10 -52
  92. data/lib/decidim/comments/engine.rb +9 -7
  93. data/lib/decidim/comments/mutation_extensions.rb +22 -22
  94. data/lib/decidim/comments/query_extensions.rb +12 -14
  95. data/lib/decidim/comments/test/shared_examples/comment_voted_event.rb +65 -0
  96. data/lib/decidim/comments/test.rb +1 -0
  97. data/lib/decidim/comments/version.rb +1 -1
  98. data/lib/decidim/comments.rb +1 -3
  99. metadata +67 -66
  100. data/app/assets/javascripts/decidim/comments/bundle.js +0 -268
  101. data/app/frontend/application/apollo_client.ts +0 -12
  102. data/app/frontend/application/application.component.test.tsx +0 -23
  103. data/app/frontend/application/application.component.tsx +0 -35
  104. data/app/frontend/application/icon.component.test.tsx +0 -38
  105. data/app/frontend/application/icon.component.tsx +0 -46
  106. data/app/frontend/comments/add_comment_form.component.test.tsx +0 -265
  107. data/app/frontend/comments/add_comment_form.component.tsx +0 -482
  108. data/app/frontend/comments/comment.component.test.tsx +0 -490
  109. data/app/frontend/comments/comment.component.tsx +0 -677
  110. data/app/frontend/comments/comment_order_selector.component.test.tsx +0 -29
  111. data/app/frontend/comments/comment_order_selector.component.tsx +0 -106
  112. data/app/frontend/comments/comment_thread.component.test.tsx +0 -82
  113. data/app/frontend/comments/comment_thread.component.tsx +0 -81
  114. data/app/frontend/comments/comments.component.test.tsx +0 -150
  115. data/app/frontend/comments/comments.component.tsx +0 -289
  116. data/app/frontend/comments/down_vote_button.component.test.tsx +0 -59
  117. data/app/frontend/comments/down_vote_button.component.tsx +0 -133
  118. data/app/frontend/comments/up_vote_button.component.test.tsx +0 -59
  119. data/app/frontend/comments/up_vote_button.component.tsx +0 -133
  120. data/app/frontend/comments/vote_button.component.tsx +0 -50
  121. data/app/frontend/comments/vote_button_component.test.tsx +0 -64
  122. data/app/frontend/entry.ts +0 -38
  123. data/app/frontend/entry_test.ts +0 -6
  124. data/app/frontend/fragments/add_comment_form_commentable.fragment.graphql +0 -4
  125. data/app/frontend/fragments/add_comment_form_session.fragment.graphql +0 -6
  126. data/app/frontend/fragments/comment.fragment.graphql +0 -14
  127. data/app/frontend/fragments/comment_data.fragment.graphql +0 -27
  128. data/app/frontend/fragments/comment_thread.fragment.graphql +0 -6
  129. data/app/frontend/fragments/down_vote_button.fragment.graphql +0 -6
  130. data/app/frontend/fragments/up_vote_button.fragment.graphql +0 -6
  131. data/app/frontend/mutations/add_comment.mutation.graphql +0 -9
  132. data/app/frontend/mutations/down_vote.mutation.graphql +0 -9
  133. data/app/frontend/mutations/up_vote.mutation.graphql +0 -9
  134. data/app/frontend/queries/comments.query.graphql +0 -26
  135. data/app/frontend/support/asset_url.ts +0 -11
  136. data/app/frontend/support/generate_comments_data.ts +0 -49
  137. data/app/frontend/support/generate_user_data.ts +0 -14
  138. data/app/frontend/support/generate_user_group_data.ts +0 -14
  139. data/app/frontend/support/graphql_transformer.js +0 -32
  140. data/app/frontend/support/load_translations.ts +0 -48
  141. data/app/frontend/support/require_all.ts +0 -10
  142. data/app/frontend/support/resolve_graphql_query.ts +0 -37
  143. data/app/frontend/support/schema.ts +0 -2026
  144. data/app/types/decidim/comments/commentable_interface.rb +0 -61
  145. data/app/types/decidim/comments/commentable_mutation_type.rb +0 -33
  146. data/lib/decidim/comments/api/add_comment_type.rb +0 -13
  147. data/lib/decidim/comments/api/comment_mutation_type.rb +0 -20
  148. data/lib/decidim/comments/api/comment_type.rb +0 -89
@@ -0,0 +1,292 @@
1
+ /**
2
+ * A plain Javascript component that handles the comments.
3
+ *
4
+ * @class
5
+ * @augments Component
6
+ */
7
+ ((exports) => {
8
+ const $ = exports.$; // eslint-disable-line
9
+
10
+ class CommentsComponent {
11
+ constructor($element, config) {
12
+ this.$element = $element;
13
+ this.commentableGid = config.commentableGid;
14
+ this.commentsUrl = config.commentsUrl;
15
+ this.rootDepth = config.rootDepth;
16
+ this.order = config.order;
17
+ this.lastCommentId = config.lastCommentId;
18
+ this.pollingInterval = config.pollingInterval || 15000;
19
+ this.id = this.$element.attr("id") || this._getUID();
20
+ this.mounted = false;
21
+ }
22
+
23
+ /**
24
+ * Handles the logic for mounting the component
25
+ * @public
26
+ * @returns {Void} - Returns nothing
27
+ */
28
+ mountComponent() {
29
+ if (this.$element.length > 0 && !this.mounted) {
30
+ this.mounted = true;
31
+ this._initializeComments(this.$element);
32
+
33
+ $(".order-by__dropdown .is-submenu-item a", this.$element).on(
34
+ "click.decidim-comments",
35
+ () => {
36
+ this._onInitOrder();
37
+ }
38
+ );
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Handles the logic for unmounting the component
44
+ * @public
45
+ * @returns {Void} - Returns nothing
46
+ */
47
+ unmountComponent() {
48
+ if (this.mounted) {
49
+ this.mounted = false;
50
+ this._stopPolling();
51
+
52
+ $(".add-comment .opinion-toggle .button", this.$element).off("click.decidim-comments");
53
+ $(".add-comment textarea", this.$element).off("input.decidim-comments");
54
+ $(".order-by__dropdown .is-submenu-item a", this.$element).off("click.decidim-comments");
55
+ $(".add-comment form", this.$element).off("submit.decidim-comments");
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Adds a new thread to the comments section.
61
+ * @public
62
+ * @param {String} threadHtml - The HTML content for the thread.
63
+ * @returns {Void} - Returns nothing
64
+ */
65
+ addThread(threadHtml) {
66
+ const $parent = $(".comments:first", this.$element);
67
+ const $comment = $(threadHtml);
68
+ const $threads = $(".comment-threads", this.$element);
69
+ this._addComment($threads, $comment);
70
+ this._finalizeCommentCreation($parent);
71
+ }
72
+
73
+ /**
74
+ * Adds a new reply to an existing comment.
75
+ * @public
76
+ * @param {Number} commentId - The ID of the comment for which to add the
77
+ * reply to.
78
+ * @param {String} replyHtml - The HTML content for the reply.
79
+ * @returns {Void} - Returns nothing
80
+ */
81
+ addReply(commentId, replyHtml) {
82
+ const $parent = $(`#comment_${commentId}`);
83
+ const $comment = $(replyHtml);
84
+ const $replies = $(`#comment-${commentId}-replies`);
85
+ this._addComment($replies, $comment);
86
+ $replies.siblings(".comment__additionalreply").removeClass("hide");
87
+ this._finalizeCommentCreation($parent);
88
+ }
89
+
90
+ /**
91
+ * Generates a unique identifier for the form.
92
+ * @private
93
+ * @returns {String} - Returns a unique identifier
94
+ */
95
+ _getUID() {
96
+ return `comments-${new Date().setUTCMilliseconds()}-${Math.floor(Math.random() * 10000000)}`;
97
+ }
98
+
99
+ /**
100
+ * Initializes the comments for the given parent element.
101
+ * @private
102
+ * @param {jQuery} $parent The parent element to initialize.
103
+ * @returns {Void} - Returns nothing
104
+ */
105
+ _initializeComments($parent) {
106
+ $(".add-comment", $parent).each((_i, el) => {
107
+ const $add = $(el);
108
+ const $form = $("form", $add);
109
+ const $opinionButtons = $(".opinion-toggle .button", $add);
110
+ const $text = $("textarea", $form);
111
+
112
+ $opinionButtons.on("click.decidim-comments", this._onToggleOpinion);
113
+ $text.on("input.decidim-comments", this._onTextInput);
114
+
115
+ $(document).trigger("attach-mentions-element", [$text.get(0)]);
116
+
117
+ $form.on("submit.decidim-comments", () => {
118
+ const $submit = $("button[type='submit']", $form);
119
+
120
+ $submit.attr("disabled", "disabled");
121
+ this._stopPolling();
122
+ });
123
+ });
124
+
125
+ this._pollComments();
126
+ }
127
+
128
+ /**
129
+ * Adds the given comment element to the given target element and
130
+ * initializes it.
131
+ * @private
132
+ * @param {jQuery} $target - The target element to add the comment to.
133
+ * @param {jQuery} $container - The comment container element to add.
134
+ * @returns {Void} - Returns nothing
135
+ */
136
+ _addComment($target, $container) {
137
+ let $comment = $(".comment", $container);
138
+ if ($comment.length < 1) {
139
+ // In case of a reply
140
+ $comment = $container;
141
+ }
142
+ this.lastCommentId = parseInt($comment.data("comment-id"), 10);
143
+
144
+ $target.append($container);
145
+ $container.foundation();
146
+ this._initializeComments($container);
147
+ if (exports.Decidim.createCharacterCounter) {
148
+ exports.Decidim.createCharacterCounter($(".add-comment textarea", $container));
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Finalizes the new comment creation after the comment adding finishes
154
+ * successfully.
155
+ * @private
156
+ * @param {jQuery} $parent - The parent comment element to finalize.
157
+ * @returns {Void} - Returns nothing
158
+ */
159
+ _finalizeCommentCreation($parent) {
160
+ const $add = $("> .add-comment", $parent);
161
+ const $text = $("textarea", $add);
162
+ const characterCounter = $text.data("remaining-characters-counter");
163
+ $text.val("");
164
+ if (characterCounter) {
165
+ characterCounter.updateStatus();
166
+ }
167
+ if (!$add.parent().is(".comments")) {
168
+ $add.addClass("hide");
169
+ }
170
+
171
+ // Restart the polling
172
+ this._pollComments();
173
+ }
174
+
175
+ /**
176
+ * Sets a timeout to poll new comments.
177
+ * @private
178
+ * @returns {Void} - Returns nothing
179
+ */
180
+ _pollComments() {
181
+ this._stopPolling();
182
+
183
+ this.pollTimeout = setTimeout(() => {
184
+ $.ajax({
185
+ url: this.commentsUrl,
186
+ method: "GET",
187
+ contentType: "application/javascript",
188
+ data: {
189
+ "commentable_gid": this.commentableGid,
190
+ "root_depth": this.rootDepth,
191
+ order: this.order,
192
+ after: this.lastCommentId
193
+ }
194
+ }).done(() => {
195
+ this._pollComments();
196
+ });
197
+ }, this.pollingInterval);
198
+ }
199
+
200
+ /**
201
+ * Stops polling for new comments.
202
+ * @private
203
+ * @returns {Void} - Returns nothing
204
+ */
205
+ _stopPolling() {
206
+ if (this.pollTimeout) {
207
+ clearTimeout(this.pollTimeout);
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Sets the loading comments element visible in the view.
213
+ * @private
214
+ * @returns {Void} - Returns nothing
215
+ */
216
+ _setLoading() {
217
+ const $container = $("> .comments-container", this.$element);
218
+ $("> .comments", $container).addClass("hide");
219
+ $("> .loading-comments", $container).removeClass("hide");
220
+ }
221
+
222
+ /**
223
+ * Event listener for the ordering links.
224
+ * @private
225
+ * @returns {Void} - Returns nothing
226
+ */
227
+ _onInitOrder() {
228
+ this._stopPolling();
229
+ this._setLoading();
230
+ }
231
+
232
+ /**
233
+ * Event listener for the opinion toggle buttons.
234
+ * @private
235
+ * @param {Event} ev - The event object.
236
+ * @returns {Void} - Returns nothing
237
+ */
238
+ _onToggleOpinion(ev) {
239
+ let $btn = $(ev.target);
240
+ if (!$btn.is(".button")) {
241
+ $btn = $btn.parents(".button");
242
+ }
243
+
244
+ const $add = $btn.closest(".add-comment");
245
+ const $form = $("form", $add);
246
+ const $opinionButtons = $(".opinion-toggle .button", $add);
247
+ const $alignment = $(".alignment-input", $form);
248
+
249
+ $opinionButtons.removeClass("is-active");
250
+ $btn.addClass("is-active");
251
+
252
+ if ($btn.is(".opinion-toggle--ok")) {
253
+ $alignment.val(1);
254
+ } else if ($btn.is(".opinion-toggle--meh")) {
255
+ $alignment.val(0);
256
+ } else if ($btn.is(".opinion-toggle--ko")) {
257
+ $alignment.val(-1);
258
+ }
259
+ }
260
+
261
+ /**
262
+ * Event listener for the comment field text input.
263
+ * @private
264
+ * @param {Event} ev - The event object.
265
+ * @returns {Void} - Returns nothing
266
+ */
267
+ _onTextInput(ev) {
268
+ const $text = $(ev.target);
269
+ const $add = $text.closest(".add-comment");
270
+ const $form = $("form", $add);
271
+ const $submit = $("button[type='submit']", $form);
272
+
273
+ if ($text.val().length > 0) {
274
+ $submit.removeAttr("disabled");
275
+ } else {
276
+ $submit.attr("disabled", "disabled");
277
+ }
278
+ }
279
+ }
280
+
281
+ exports.Decidim = exports.Decidim || {};
282
+ exports.Decidim.CommentsComponent = CommentsComponent;
283
+
284
+ $(() => {
285
+ $("[data-decidim-comments]").each((_i, el) => {
286
+ const $el = $(el);
287
+ const comments = new CommentsComponent($el, $el.data("decidim-comments"));
288
+ comments.mountComponent();
289
+ $(el).data("comments", comments);
290
+ });
291
+ });
292
+ })(window);