decidim-comments 0.29.1 → 0.30.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.
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
@@ -82,7 +82,6 @@
82
82
  comments:
83
83
  blocked_comments_for_unauthorized_user_warning: Du må verifiseres for å kommentere, men du kan lese de forrige.
84
84
  blocked_comments_for_user_warning: Du kan ikke kommentere for øyeblikket, men du kan lese de forrige.
85
- blocked_comments_warning: Kommenterer er deaktivert på dette tidspunktet, men du kan lese de forrige.
86
85
  comment_details_title: Kommenter detaljer
87
86
  loading: Laster inn kommenterer ...
88
87
  single_comment_warning: <a href="%{url}">Se alle kommentarer</a>
@@ -43,7 +43,6 @@ pl:
43
43
  error: Podczas dodawania komentarza wystąpił błąd.
44
44
  components:
45
45
  add_comment_form:
46
- account_message: <a href="%{sign_in_url}">Zaloguj się</a> lub <a href="%{sign_up_url}">utwórz konto</a>, aby dodać swój komentarz.
47
46
  form:
48
47
  body:
49
48
  label: Komentarz
@@ -107,7 +106,6 @@ pl:
107
106
  comments:
108
107
  blocked_comments_for_unauthorized_user_warning: Musisz być zweryfikowany żeby teraz komentować, ale możesz przeczytać poprzednie komentarze.
109
108
  blocked_comments_for_user_warning: Nie możesz teraz komentować, ale możesz przeczytać poprzednie komentarze.
110
- blocked_comments_warning: Komentarze są w tej chwili wyłączone, ale możesz przeczytać poprzednie.
111
109
  comment_details_title: Szczegóły komentarza
112
110
  loading: Ładowanie komentarzy ...
113
111
  single_comment_warning: <a href="%{url}">Zobacz wszystkie komentarze</a>
@@ -81,7 +81,6 @@ pt-BR:
81
81
  comments:
82
82
  blocked_comments_for_unauthorized_user_warning: Você precisa ser verificado para comentar neste momento, mas pode ler os anteriores.
83
83
  blocked_comments_for_user_warning: Você não pode comentar neste momento, mas pode ler os anteriores.
84
- blocked_comments_warning: Os comentários estão desativados neste momento, mas você pode ler os anteriores.
85
84
  comment_details_title: Detalhes do comentário
86
85
  loading: Carregando comentários ...
87
86
  single_comment_warning_title: Você está vendo um único comentário
@@ -82,7 +82,6 @@ pt:
82
82
  comments:
83
83
  blocked_comments_for_unauthorized_user_warning: Precisa de estar verificado para comentar neste momento, mas pode ler os precedentes.
84
84
  blocked_comments_for_user_warning: Não pode comentar neste momento, mas pode ler os anteriores.
85
- blocked_comments_warning: Os comentários estão desativados neste momento, mas pode ler os anteriores.
86
85
  comment_details_title: Detalhes do comentário
87
86
  loading: A carregar comentários ...
88
87
  single_comment_warning: <a href="%{url}">Ver todos os comentários</a>
@@ -41,7 +41,6 @@ ro:
41
41
  error: A apărut o problemă la votarea comentariului.
42
42
  components:
43
43
  add_comment_form:
44
- account_message: <a href="%{sign_in_url}">Autentificați-vă cu</a> sau <a href="%{sign_up_url}">creați un cont</a> pentru a adăuga comentariul dumneavoastră.
45
44
  form:
46
45
  body:
47
46
  label: Comentariu
@@ -108,7 +107,7 @@ ro:
108
107
  comments:
109
108
  blocked_comments_for_unauthorized_user_warning: Trebuie să fii verificat pentru a trimite comentarii în acest moment, dar le poți citi pe cele anterioare.
110
109
  blocked_comments_for_user_warning: Nu poți comenta în acest moment, dar le poți citi pe cele anterioare.
111
- blocked_comments_warning: Comentariile sunt dezactivate în acest moment, dar le poți citi pe cele anterioare.
110
+ blocked_comments_warning: Comentariile sunt momentan dezactivate, doar administratorii pot răspunde sau publica altele noi.
112
111
  comment_details_title: Detaliile comentariului
113
112
  loading: Se încarcă comentariile...
114
113
  single_comment_warning: <a href="%{url}">Vezi toate comentariile</a>
@@ -61,7 +61,6 @@ ru:
61
61
  title: 'Упорядочить по:'
62
62
  comments:
63
63
  blocked_comments_for_user_warning: Сейчас вам недоступно комментирование, но вы можете прочесть предыдущие комментарии.
64
- blocked_comments_warning: Комментарии сейчас отключены, но вы можете прочитать предыдущие.
65
64
  loading: Загрузка комментариев ...
66
65
  events:
67
66
  comments:
@@ -61,7 +61,6 @@ sk:
61
61
  title: 'Zoradiť podľa:'
62
62
  comments:
63
63
  blocked_comments_for_user_warning: V súčasnosti nemôžete komentovať, ale môžete si prečítať predchádzajúce komentáre.
64
- blocked_comments_warning: Komentáre nie sú v súčasnosti povolené, ale môžete si prečítať predchádzajúce komentáre.
65
64
  comment_details_title: Podrobnosti komentára
66
65
  loading: Nahrávanie komentárov...
67
66
  single_comment_warning_title: Zobrazujete jeden komentár
@@ -17,6 +17,10 @@ sv:
17
17
  one: Röst
18
18
  other: Röster
19
19
  decidim:
20
+ admin:
21
+ admin_log:
22
+ changeset:
23
+ comments: Kommentarer
20
24
  comments:
21
25
  admin:
22
26
  shared:
@@ -39,7 +43,8 @@ sv:
39
43
  error: Det gick inte att rösta om kommentaren.
40
44
  components:
41
45
  add_comment_form:
42
- account_message: <a href="%{sign_in_url}">Logga in</a> eller <a href="%{sign_up_url}">skapa ett konto</a> för kommentera.
46
+ account_message: Logga in eller skapa ett konto för kommentera.
47
+ add_comment: Kommentera
43
48
  form:
44
49
  body:
45
50
  label: Kommentera
@@ -49,6 +54,7 @@ sv:
49
54
  submit_root_comment: Publicera kommentar
50
55
  user_group_id:
51
56
  label: Kommentera som
57
+ your_profile: Din profil
52
58
  opinion:
53
59
  label: Din åsikt om frågan
54
60
  negative: Negativ
@@ -64,6 +70,9 @@ sv:
64
70
  alignment:
65
71
  against: Mot
66
72
  in_favor: För
73
+ answers:
74
+ one: "%{count} svar"
75
+ other: "%{count} svar"
67
76
  cancel_reply: Avbryt svar
68
77
  comment_label: Kommentar %{comment_id}
69
78
  comment_label_reply: Kommentar %{comment_id} (svar på kommentar %{parent_comment_id})
@@ -94,6 +103,7 @@ sv:
94
103
  one: Visa svar
95
104
  other: Visa %{count} svar
96
105
  single_comment_link_title: Hämta länk
106
+ sort_by: 'Sortera efter: '
97
107
  comment_order_selector:
98
108
  order:
99
109
  best_rated: Bästa betyg
@@ -102,16 +112,19 @@ sv:
102
112
  recent: Senaste
103
113
  title: 'Sortera efter:'
104
114
  comments:
115
+ against: Mot
105
116
  blocked_comments_for_unauthorized_user_warning: Du behöver verifiera dig för att kunna kommentera just nu, men du kan läsa tidigare kommentarer.
106
117
  blocked_comments_for_user_warning: Du kan inte kommentera just nu, men du kan läsa tidigare kommentarer.
107
- blocked_comments_warning: Kommentarer är inaktiverade just nu, men du kan läsa de föregående.
118
+ blocked_comments_warning: Kommentarer är inaktiverade, endast administratörer kan svara eller skriva nya.
108
119
  comment_details_title: Kommentarsdetaljer
120
+ in_favor: För
109
121
  loading: Laddar kommentarer...
110
122
  single_comment_warning: <a href="%{url}">Visa alla kommentarer</a>
111
123
  single_comment_warning_title: Du visar en enda kommentar
112
124
  title:
113
125
  one: "%{count} kommentar"
114
126
  other: "%{count} kommentarer"
127
+ top_comment_label: Mest stöd
115
128
  down_vote_button:
116
129
  text: Jag instämmer inte i denna kommentar
117
130
  edit_comment_modal_form:
@@ -124,6 +137,10 @@ sv:
124
137
  title: Redigera din kommentar
125
138
  up_vote_button:
126
139
  text: Jag instämmer i denna kommentar
140
+ download_your_data:
141
+ help:
142
+ comment_votes:
143
+ comment: Id för kommentaren som gillades
127
144
  events:
128
145
  comments:
129
146
  comment_by_followed_user:
@@ -64,7 +64,6 @@ tr:
64
64
  title: 'Tarafından sipariş:'
65
65
  comments:
66
66
  blocked_comments_for_user_warning: Şu anda yorum yapamıyorsunuz, ancak öncekileri okuyabilirsiniz.
67
- blocked_comments_warning: Yorumlar şu anda devre dışı, ancak öncekileri okuyabilirsiniz.
68
67
  comment_details_title: Yorum ayrıntıları
69
68
  loading: Yorumlar yükleniyor ...
70
69
  single_comment_warning_title: Tek bir yorum görüyorsunuz
@@ -60,7 +60,6 @@ uk:
60
60
  recent: Нещодавнє
61
61
  title: 'Впорядкувати за:'
62
62
  comments:
63
- blocked_comments_warning: Коментарі зараз вимкнені, але ви можете прочитати попередні.
64
63
  loading: Завантаження коментарів...
65
64
  events:
66
65
  comments:
@@ -56,7 +56,6 @@ zh-CN:
56
56
  title: '排序方式:'
57
57
  comments:
58
58
  blocked_comments_for_user_warning: 您此时无法评论,但您可以阅读前面的评论。
59
- blocked_comments_warning: 评论此时被禁用,但您可以阅读前面的评论。
60
59
  comment_details_title: 评论详情
61
60
  loading: 正在加载评论...
62
61
  single_comment_warning_title: 您正在看到一个评论
@@ -89,7 +89,6 @@ zh-TW:
89
89
  comments:
90
90
  blocked_comments_for_unauthorized_user_warning: 目前需要驗證您的身份才能發表評論,但您可以閱讀先前的評論。
91
91
  blocked_comments_for_user_warning: 目前您無法發表評論,但您可以閱讀先前的評論。
92
- blocked_comments_warning: 目前無法發表評論,但您可以閱讀先前的評論。
93
92
  comment_details_title: 評論詳細資料
94
93
  loading: 正在加載評論…
95
94
  single_comment_warning: <a href="%{url}">查看所有評論</a>
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.version = Decidim::Comments.version
11
11
  s.authors = ["Josep Jaume Rey Peroy", "Marc Riera Casals", "Oriol Gual Oliva"]
12
12
  s.email = ["josepjaume@gmail.com", "mrc2407@gmail.com", "oriolgual@gmail.com"]
13
- s.license = "AGPL-3.0"
13
+ s.license = "AGPL-3.0-or-later"
14
14
  s.homepage = "https://decidim.org"
15
15
  s.metadata = {
16
16
  "bug_tracker_uri" => "https://github.com/decidim/decidim/issues",
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  "homepage_uri" => "https://decidim.org",
20
20
  "source_code_uri" => "https://github.com/decidim/decidim"
21
21
  }
22
- s.required_ruby_version = "~> 3.2.0"
22
+ s.required_ruby_version = "~> 3.3.0"
23
23
 
24
24
  s.name = "decidim-comments"
25
25
  s.summary = "Decidim comments module"
@@ -6,14 +6,14 @@ module Decidim
6
6
  graphql_name "CommentMutation"
7
7
  description "A comment which includes its available mutations"
8
8
 
9
+ field :down_vote, Decidim::Comments::CommentType, "The comment that is downvoted", null: true
9
10
  field :id, GraphQL::Types::ID, "The Comment's unique ID", null: false
11
+ field :up_vote, Decidim::Comments::CommentType, "The comment that is upvoted", null: true
10
12
 
11
- field :up_vote, Decidim::Comments::CommentType, null: true
12
13
  def up_vote(args: {})
13
14
  VoteCommentResolver.new(weight: 1).call(object, args, context)
14
15
  end
15
16
 
16
- field :down_vote, Decidim::Comments::CommentType, null: true
17
17
  def down_vote(args: {})
18
18
  VoteCommentResolver.new(weight: -1).call(object, args, context)
19
19
  end
@@ -4,37 +4,24 @@ module Decidim
4
4
  module Comments
5
5
  # This type represents a comment on a commentable object.
6
6
  class CommentType < Decidim::Api::Types::BaseObject
7
- description "A comment"
8
-
7
+ implements Decidim::Core::TimestampsInterface
9
8
  implements Decidim::Comments::CommentableInterface
10
- field :author, Decidim::Core::AuthorInterface, "The resource author", null: false
11
-
12
- field :id, GraphQL::Types::ID, "The Comment's unique ID", null: false
13
-
14
- field :sgid, GraphQL::Types::String, "The Comment's signed global id", null: false
15
-
16
- field :body, GraphQL::Types::String, "The comment message", null: false
17
-
18
- field :formatted_body, GraphQL::Types::String, "The comment message ready to display (it is expected to include HTML)", null: false
19
-
20
- field :created_at, GraphQL::Types::String, "The creation date of the comment", null: false
21
9
 
22
- field :formatted_created_at, GraphQL::Types::String, "The creation date of the comment in relative format", null: false
10
+ description "A comment"
23
11
 
24
12
  field :alignment, GraphQL::Types::Int, "The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'", null: true
25
-
26
- field :up_votes, GraphQL::Types::Int, "The number of comment's upVotes", null: false
27
-
28
- field :up_voted, GraphQL::Types::Boolean, "Check if the current user has upvoted the comment", null: false
29
-
30
- field :down_votes, GraphQL::Types::Int, "The number of comment's downVotes", null: false
31
-
13
+ field :already_reported, GraphQL::Types::Boolean, "Check if the current user has reported the comment", null: false
14
+ field :author, Decidim::Core::AuthorInterface, "The resource author", null: false
15
+ field :body, GraphQL::Types::String, "The comment message", null: false, method: :translated_body
32
16
  field :down_voted, GraphQL::Types::Boolean, "Check if the current user has downvoted the comment", null: false
33
-
17
+ field :down_votes, GraphQL::Types::Int, "The number of comment's downVotes", null: false, method: :down_votes_count
18
+ field :formatted_body, GraphQL::Types::String, "The comment message ready to display (it is expected to include HTML)", null: false
19
+ field :formatted_created_at, GraphQL::Types::String, "The creation date of the comment in relative format", null: false, method: :friendly_created_at
34
20
  field :has_comments, GraphQL::Types::Boolean, "Check if the commentable has comments", method: :has_comments?, null: false
35
-
36
- field :already_reported, GraphQL::Types::Boolean, "Check if the current user has reported the comment", null: false
37
-
21
+ field :id, GraphQL::Types::ID, "The Comment's unique ID", null: false
22
+ field :sgid, GraphQL::Types::String, "The Comment's signed global id", null: false
23
+ field :up_voted, GraphQL::Types::Boolean, "Check if the current user has upvoted the comment", null: false
24
+ field :up_votes, GraphQL::Types::Int, "The number of comment's upVotes", null: false, method: :up_votes_count
38
25
  field :user_allowed_to_comment, GraphQL::Types::Boolean, "Check if the current user can comment", null: false
39
26
 
40
27
  def author
@@ -45,30 +32,10 @@ module Decidim
45
32
  object.to_sgid.to_s
46
33
  end
47
34
 
48
- def body
49
- object.translated_body
50
- end
51
-
52
- def created_at
53
- object.created_at.iso8601
54
- end
55
-
56
- def formatted_created_at
57
- object.friendly_created_at
58
- end
59
-
60
- def up_votes
61
- object.up_votes_count
62
- end
63
-
64
35
  def up_voted
65
36
  object.up_voted_by?(context[:current_user])
66
37
  end
67
38
 
68
- def down_votes
69
- object.down_votes_count
70
- end
71
-
72
39
  def down_voted
73
40
  object.down_voted_by?(context[:current_user])
74
41
  end
@@ -84,6 +51,19 @@ module Decidim
84
51
  def user_allowed_to_comment
85
52
  object.root_commentable.commentable? && object.root_commentable.user_allowed_to_comment?(context[:current_user])
86
53
  end
54
+
55
+ def self.authorized?(object, context)
56
+ chain = []
57
+ if object.respond_to?(:commentable) && !object.commentable.is_a?(Decidim::Comments::Comment)
58
+ chain.unshift(allowed_to?(:read, object.commentable, object.commentable,
59
+ context))
60
+ end
61
+
62
+ chain.unshift(!object.hidden?)
63
+ chain.unshift(!object.deleted?)
64
+
65
+ super && chain.all?
66
+ end
87
67
  end
88
68
  end
89
69
  end
@@ -8,43 +8,37 @@ module Decidim
8
8
  description "A commentable interface"
9
9
 
10
10
  field :id, GraphQL::Types::ID, "The commentable's ID", null: false
11
-
12
11
  field :type, GraphQL::Types::String, "The commentable's class name. i.e. `Decidim::ParticipatoryProcess`", method: :commentable_type, null: false
13
-
14
12
  field :accepts_new_comments, GraphQL::Types::Boolean, "Whether the object can have new comments or not", method: :accepts_new_comments?, null: false
15
-
16
13
  field :comments_have_alignment, GraphQL::Types::Boolean, "Whether the object comments have alignment or not", method: :comments_have_alignment?, null: false
17
-
18
14
  field :comments_have_votes, GraphQL::Types::Boolean, "Whether the object comments have votes or not", method: :comments_have_votes?, null: false
19
-
20
- field :comments, [Decidim::Comments::CommentType], null: false do
15
+ field :total_comments_count, GraphQL::Types::Int, description: "The number of comments in all levels this resource holds", method: :comments_count, null: false
16
+ field :has_comments, GraphQL::Types::Boolean, "Check if the commentable has comments", null: false
17
+ field :user_allowed_to_comment, GraphQL::Types::Boolean, "Check if the current user can comment", null: false
18
+ field :comments, [Decidim::Comments::CommentType, { null: false }], "The list of replies in this comment", null: false do
21
19
  argument :order_by, GraphQL::Types::String, "Order the comments", required: false
22
20
  argument :single_comment_id, GraphQL::Types::String, "ID of the single comment to look at", required: false
23
21
  end
24
22
 
25
- field :total_comments_count, GraphQL::Types::Int, description: "The number of comments in all levels this resource holds", null: false
26
-
27
23
  def comments(order_by: nil, single_comment_id: nil)
28
24
  SortedComments.for(object, order_by:, id: single_comment_id).not_hidden
29
25
  end
30
26
 
31
- def total_comments_count
32
- object.comments_count
33
- end
34
-
35
- field :has_comments, GraphQL::Types::Boolean, "Check if the commentable has comments", null: false
36
-
37
27
  # rubocop:disable Naming/PredicateName
38
28
  def has_comments
39
29
  object.comment_threads.not_hidden.size.positive?
40
30
  end
41
31
  # rubocop:enable Naming/PredicateName
42
32
 
43
- field :user_allowed_to_comment, GraphQL::Types::Boolean, "Check if the current user can comment", null: false
44
-
45
33
  def user_allowed_to_comment
46
34
  object.commentable? && object.user_allowed_to_comment?(context[:current_user])
47
35
  end
36
+
37
+ definition_methods do
38
+ def resolve_type(object, _context)
39
+ GraphQL::Types.const_get("#{object.class.name}Type")
40
+ end
41
+ end
48
42
  end
49
43
  end
50
44
  end
@@ -5,13 +5,12 @@ module Decidim
5
5
  class CommentableMutationType < Decidim::Api::Types::BaseObject
6
6
  description "A commentable which includes its available mutations"
7
7
 
8
- field :id, GraphQL::Types::ID, "The Commentable's unique ID", null: false
9
-
10
8
  field :add_comment, Decidim::Comments::CommentType, description: "Add a new comment to a commentable", null: true do
11
- argument :body, GraphQL::Types::String, "The comments's body", required: true
12
9
  argument :alignment, GraphQL::Types::Int, "The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'", default_value: 0, required: false
10
+ argument :body, GraphQL::Types::String, "The comments's body", required: true
13
11
  argument :user_group_id, GraphQL::Types::ID, "The comment's user group id. Replaces the author.", required: false
14
12
  end
13
+ field :id, GraphQL::Types::ID, "The Commentable's unique ID", null: false
15
14
 
16
15
  def add_comment(body:, alignment: nil, user_group_id: nil)
17
16
  params = { "comment" => { "body" => body, "alignment" => alignment, "user_group_id" => user_group_id, "commentable" => object } }
@@ -67,6 +67,17 @@ module Decidim
67
67
  update_columns(comments_count:, updated_at: Time.current)
68
68
  end
69
69
  # rubocop:enable Rails/SkipsModelValidations
70
+
71
+ # Public: Returns an array with extra actions available for a comment and a user.
72
+ # Returns an array of hashes with the following keys:
73
+ # - label: The label to be displayed in the UI.
74
+ # - url: The action to be performed when the user clicks the label.
75
+ # - method: The HTTP method to be used when performing the action (optional).
76
+ # - icon: The icon to be displayed next to the label (optional).
77
+ # - data: Any "data-*" attributes to be included in the link (optional).
78
+ def actions_for_comment(_comment, _current_user)
79
+ []
80
+ end
70
81
  end
71
82
  end
72
83
  end
@@ -9,6 +9,7 @@ module Decidim
9
9
  module CommentableWithComponent
10
10
  extend ActiveSupport::Concern
11
11
  include Decidim::Comments::Commentable
12
+ include Decidim::UserRoleChecker
12
13
 
13
14
  included do
14
15
  # Public: Overrides the `commentable?` Commentable concern method.
@@ -23,7 +24,8 @@ module Decidim
23
24
 
24
25
  # Public: Whether the object can have new comments or not.
25
26
  def user_allowed_to_comment?(user)
26
- return unless can_participate?(user)
27
+ return true if user_has_any_role?(user, component.participatory_space)
28
+ return false unless can_participate?(user)
27
29
 
28
30
  ActionAuthorizer.new(user, "comment", component, self).authorize.ok?
29
31
  end
@@ -4,7 +4,6 @@ require "rails"
4
4
  require "active_support/all"
5
5
 
6
6
  require "decidim/core"
7
- require "foundation_rails_helper"
8
7
 
9
8
  require "decidim/comments/query_extensions"
10
9
  require "decidim/comments/mutation_extensions"
@@ -21,6 +20,12 @@ module Decidim
21
20
  end
22
21
  end
23
22
 
23
+ initializer "decidim_comments.mount_routes" do
24
+ Decidim::Core::Engine.routes do
25
+ mount Decidim::Comments::Engine, at: "/", as: "decidim_comments"
26
+ end
27
+ end
28
+
24
29
  initializer "decidim_comments.query_extensions" do
25
30
  Decidim::Api::QueryType.include QueryExtensions
26
31
  end
@@ -42,6 +47,7 @@ module Decidim
42
47
 
43
48
  Decidim.icons.register(name: "Decidim::Comments::Comment", icon: "chat-1-line", description: "Comment", category: "activity", engine: :comments)
44
49
  Decidim.icons.register(name: "comments_count", icon: "wechat-line", description: "Comments Count", category: "activity", engine: :comments)
50
+ Decidim.icons.register(name: "star-s-line", icon: "star-s-line", description: "Most upvoted comment", category: "activity", engine: :comments)
45
51
 
46
52
  Decidim.icons.register(name: "thumb-up-line", icon: "thumb-up-line", description: "Upvote comment button", **common_parameters)
47
53
  Decidim.icons.register(name: "thumb-up-fill", icon: "thumb-up-fill", description: "User upvoted comment", **common_parameters)
@@ -11,7 +11,7 @@ module Decidim
11
11
  #
12
12
  # Returns nothing.
13
13
  def self.included(type)
14
- type.field :commentable, CommentableType, null: false do
14
+ type.field :commentable, Decidim::Comments::CommentableInterface do
15
15
  argument :id, GraphQL::Types::String, "The commentable's ID", required: true
16
16
  argument :type, GraphQL::Types::String, "The commentable's class name. i.e. `Decidim::ParticipatoryProcess`", required: true
17
17
  argument :locale, GraphQL::Types::String, "The locale for which to get the comments text", required: true
@@ -8,7 +8,7 @@ FactoryBot.define do
8
8
  skip_injection { false }
9
9
  end
10
10
  author { build(:user, organization: commentable.organization, skip_injection:) }
11
- commentable { build(:dummy_resource, skip_injection:) }
11
+ commentable { build(:dummy_resource, :published, skip_injection:) }
12
12
  root_commentable { commentable }
13
13
  body { Decidim::Faker::Localized.paragraph }
14
14
  participatory_space { commentable.try(:participatory_space) }
@@ -46,6 +46,14 @@ FactoryBot.define do
46
46
  create(:moderation, reportable: comment, hidden_at: 2.days.ago, skip_injection: evaluator.skip_injection)
47
47
  end
48
48
  end
49
+
50
+ trait :in_favor do
51
+ alignment { 1 }
52
+ end
53
+
54
+ trait :against do
55
+ alignment { -1 }
56
+ end
49
57
  end
50
58
 
51
59
  factory :comment_vote, class: "Decidim::Comments::CommentVote" do
@@ -10,7 +10,7 @@ shared_context "when it is a comment event" do
10
10
 
11
11
  let(:resource) { comment.commentable }
12
12
 
13
- let(:comment) { create :comment }
13
+ let(:comment) { create(:comment) }
14
14
  let(:comment_author) { comment.author }
15
15
  let(:normalized_comment_author) { comment.author }
16
16
  let(:comment_author_name) { decidim_html_escape comment.author.name }
@@ -7,8 +7,8 @@ shared_examples_for "a comment voted event" do
7
7
 
8
8
  let(:resource) { comment.commentable }
9
9
 
10
- let(:comment) { create :comment }
11
- let(:comment_vote) { create :comment_vote, comment: }
10
+ let(:comment) { create(:comment) }
11
+ let(:comment_vote) { create(:comment_vote, comment:) }
12
12
  let(:comment_vote_author) { comment_vote.author }
13
13
 
14
14
  let(:extra) { { comment_id: comment.id, author_id: comment_vote_author.id, weight:, downvotes: 100, upvotes: 999 } }
@@ -7,7 +7,7 @@ RSpec.shared_context "when creating a comment" do
7
7
  let(:user) { create(:user, organization:) }
8
8
  let(:author) { create(:user, organization:) }
9
9
  let(:current_user) { author }
10
- let(:dummy_resource) { create :dummy_resource, component: }
10
+ let(:dummy_resource) { create(:dummy_resource, component:) }
11
11
  let(:commentable) { dummy_resource }
12
12
  let(:body) { Faker::Lorem.paragraph }
13
13
  let(:alignment) { 1 }
@@ -6,10 +6,10 @@ shared_examples_for "a translated comment event" do
6
6
  describe "translated notifications" do
7
7
  let(:en_body) { "This is Sparta!" }
8
8
  let(:body) { { en: en_body, machine_translations: { ca: "C'est Sparta!" } } }
9
- let(:participatory_process) { create :participatory_process, organization: }
9
+ let(:participatory_process) { create(:participatory_process, organization:) }
10
10
  let(:component) { create(:component, participatory_space: participatory_process) }
11
11
  let(:commentable) { create(:dummy_resource, component:) }
12
- let(:comment) { create :comment, body:, commentable: }
12
+ let(:comment) { create(:comment, body:, commentable:) }
13
13
  let(:en_version) { "<div><p>#{comment.body["en"]}</p></div>" }
14
14
  let(:machine_translated) { "<div><p>#{comment.body["machine_translations"]["ca"]}</p></div>" }
15
15
 
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-comments version.
5
5
  module Comments
6
6
  def self.version
7
- "0.29.1"
7
+ "0.30.0.rc1"
8
8
  end
9
9
  end
10
10
  end