decidim-comments 0.21.0 → 0.23.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/comments/bundle.js +67 -67
  3. data/app/assets/javascripts/decidim/comments/bundle.js.map +1 -1
  4. data/app/cells/decidim/comments/comment_activity_cell.rb +2 -22
  5. data/app/cells/decidim/comments/comment_cell.rb +22 -0
  6. data/app/cells/decidim/comments/comment_m/footer.erb +5 -0
  7. data/app/cells/decidim/comments/comment_m/top.erb +7 -0
  8. data/app/cells/decidim/comments/comment_m_cell.rb +29 -0
  9. data/app/commands/decidim/comments/create_comment.rb +8 -8
  10. data/app/events/decidim/comments/comment_by_followed_user_group_event.rb +9 -0
  11. data/app/events/decidim/comments/comment_event.rb +14 -9
  12. data/app/events/decidim/comments/user_group_mentioned_event.rb +10 -0
  13. data/app/forms/decidim/comments/comment_form.rb +17 -1
  14. data/app/frontend/application/icon.component.tsx +16 -4
  15. data/app/frontend/comments/add_comment_form.component.test.tsx +31 -29
  16. data/app/frontend/comments/add_comment_form.component.tsx +34 -18
  17. data/app/frontend/comments/comment.component.test.tsx +36 -5
  18. data/app/frontend/comments/comment.component.tsx +218 -88
  19. data/app/frontend/comments/comment_order_selector.component.tsx +26 -7
  20. data/app/frontend/comments/comment_thread.component.test.tsx +9 -8
  21. data/app/frontend/comments/comment_thread.component.tsx +3 -1
  22. data/app/frontend/comments/comments.component.test.tsx +17 -14
  23. data/app/frontend/comments/comments.component.tsx +28 -4
  24. data/app/frontend/comments/down_vote_button.component.tsx +27 -9
  25. data/app/frontend/comments/up_vote_button.component.tsx +27 -9
  26. data/app/frontend/comments/vote_button.component.tsx +4 -0
  27. data/app/frontend/comments/vote_button_component.test.tsx +14 -8
  28. data/app/frontend/mutations/add_comment.mutation.graphql +2 -2
  29. data/app/frontend/mutations/down_vote.mutation.graphql +2 -2
  30. data/app/frontend/mutations/up_vote.mutation.graphql +2 -2
  31. data/app/frontend/queries/comments.query.graphql +2 -2
  32. data/app/frontend/support/schema.ts +1060 -735
  33. data/app/helpers/decidim/comments/comment_cells_helper.rb +33 -0
  34. data/app/models/decidim/comments/comment.rb +81 -22
  35. data/app/models/decidim/comments/seed.rb +1 -1
  36. data/app/queries/decidim/comments/metrics/comments_metric_manage.rb +1 -6
  37. data/app/services/decidim/comments/new_comment_notification_creator.rb +28 -3
  38. data/app/types/decidim/comments/commentable_interface.rb +1 -1
  39. data/app/types/decidim/comments/commentable_mutation_type.rb +6 -3
  40. data/config/locales/am-ET.yml +1 -0
  41. data/config/locales/ar.yml +4 -1
  42. data/config/locales/bg-BG.yml +6 -0
  43. data/config/locales/bg.yml +6 -0
  44. data/config/locales/ca.yml +19 -2
  45. data/config/locales/cs.yml +31 -14
  46. data/config/locales/da-DK.yml +1 -0
  47. data/config/locales/da.yml +1 -0
  48. data/config/locales/de.yml +47 -24
  49. data/config/locales/el.yml +121 -0
  50. data/config/locales/en.yml +18 -1
  51. data/config/locales/eo.yml +1 -0
  52. data/config/locales/es-MX.yml +18 -1
  53. data/config/locales/es-PY.yml +18 -1
  54. data/config/locales/es.yml +18 -1
  55. data/config/locales/et-EE.yml +1 -0
  56. data/config/locales/et.yml +1 -0
  57. data/config/locales/eu.yml +4 -1
  58. data/config/locales/fi-plain.yml +18 -1
  59. data/config/locales/fi.yml +25 -8
  60. data/config/locales/fr-CA.yml +123 -0
  61. data/config/locales/fr.yml +25 -2
  62. data/config/locales/ga-IE.yml +1 -0
  63. data/config/locales/gl.yml +17 -1
  64. data/config/locales/hr-HR.yml +1 -0
  65. data/config/locales/hr.yml +1 -0
  66. data/config/locales/hu.yml +12 -2
  67. data/config/locales/id-ID.yml +4 -1
  68. data/config/locales/is-IS.yml +3 -3
  69. data/config/locales/is.yml +76 -0
  70. data/config/locales/it.yml +21 -1
  71. data/config/locales/ja-JP.yml +120 -0
  72. data/config/locales/ja.yml +121 -0
  73. data/config/locales/ko-KR.yml +1 -0
  74. data/config/locales/ko.yml +1 -0
  75. data/config/locales/lt-LT.yml +1 -0
  76. data/config/locales/lt.yml +1 -0
  77. data/config/locales/lv.yml +118 -0
  78. data/config/locales/mt-MT.yml +1 -0
  79. data/config/locales/mt.yml +1 -0
  80. data/config/locales/nl.yml +27 -8
  81. data/config/locales/no.yml +18 -2
  82. data/config/locales/om-ET.yml +1 -0
  83. data/config/locales/pl.yml +63 -40
  84. data/config/locales/pt-BR.yml +5 -2
  85. data/config/locales/pt.yml +47 -25
  86. data/config/locales/ro-RO.yml +124 -0
  87. data/config/locales/ru.yml +4 -1
  88. data/config/locales/si-LK.yml +1 -0
  89. data/config/locales/sk-SK.yml +116 -0
  90. data/config/locales/sk.yml +120 -0
  91. data/config/locales/sl.yml +4 -0
  92. data/config/locales/so-SO.yml +1 -0
  93. data/config/locales/sr-CS.yml +20 -0
  94. data/config/locales/sv.yml +26 -3
  95. data/config/locales/sw-KE.yml +1 -0
  96. data/config/locales/ti-ER.yml +1 -0
  97. data/config/locales/tr-TR.yml +54 -31
  98. data/config/locales/uk.yml +4 -2
  99. data/config/locales/vi-VN.yml +1 -0
  100. data/config/locales/vi.yml +1 -0
  101. data/config/locales/zh-CN.yml +121 -0
  102. data/config/locales/zh-TW.yml +1 -0
  103. data/db/migrate/20200320105911_index_foreign_keys_in_decidim_comments_comments.rb +7 -0
  104. data/db/migrate/20200706123136_make_comments_handle_i18n.rb +41 -0
  105. data/db/migrate/20200828101910_add_commentable_counter_cache_to_comments.rb +9 -0
  106. data/lib/decidim/comments/api/comment_type.rb +5 -1
  107. data/lib/decidim/comments/comment_serializer.rb +7 -2
  108. data/lib/decidim/comments/comment_vote_serializer.rb +5 -1
  109. data/lib/decidim/comments/commentable.rb +11 -0
  110. data/lib/decidim/comments/comments_helper.rb +28 -4
  111. data/lib/decidim/comments/engine.rb +13 -0
  112. data/lib/decidim/comments/mutation_extensions.rb +8 -0
  113. data/lib/decidim/comments/query_extensions.rb +4 -0
  114. data/lib/decidim/comments/test/factories.rb +10 -1
  115. data/lib/decidim/comments/test/shared_examples/comment_event.rb +12 -2
  116. data/lib/decidim/comments/test/shared_examples/create_comment_context.rb +3 -2
  117. data/lib/decidim/comments/version.rb +1 -1
  118. metadata +59 -13
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Comments
5
+ # Custom helpers for comments cells.
6
+ #
7
+ module CommentCellsHelper
8
+ def renderable?
9
+ comment.present? && root_commentable.present?
10
+ end
11
+
12
+ def resource_link_text
13
+ comment.formatted_body
14
+ end
15
+
16
+ def resource_link_path
17
+ return root_commentable.polymorphic_resource_path(url_params) if root_commentable&.respond_to?(:polymorphic_resource_path)
18
+
19
+ resource_locator(root_commentable).path(url_params)
20
+ end
21
+
22
+ delegate :root_commentable, to: :comment
23
+
24
+ def root_commentable_title
25
+ decidim_html_escape(translated_attribute(root_commentable.title))
26
+ end
27
+
28
+ def url_params
29
+ { commentId: comment.id }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -13,6 +13,9 @@ module Decidim
13
13
  include Decidim::DataPortability
14
14
  include Decidim::Traceable
15
15
  include Decidim::Loggable
16
+ include Decidim::Searchable
17
+ include Decidim::TranslatableResource
18
+ include Decidim::TranslatableAttributes
16
19
 
17
20
  # Limit the max depth of a comment tree. If C is a comment and R is a reply:
18
21
  # C (depth 0)
@@ -22,23 +25,42 @@ module Decidim
22
25
  # |--R (depth 3)
23
26
  MAX_DEPTH = 3
24
27
 
28
+ translatable_fields :body
29
+
25
30
  belongs_to :commentable, foreign_key: "decidim_commentable_id", foreign_type: "decidim_commentable_type", polymorphic: true
26
- belongs_to :root_commentable, foreign_key: "decidim_root_commentable_id", foreign_type: "decidim_root_commentable_type", polymorphic: true
31
+ belongs_to :root_commentable, foreign_key: "decidim_root_commentable_id", foreign_type: "decidim_root_commentable_type", polymorphic: true, touch: true
27
32
  has_many :up_votes, -> { where(weight: 1) }, foreign_key: "decidim_comment_id", class_name: "CommentVote", dependent: :destroy
28
33
  has_many :down_votes, -> { where(weight: -1) }, foreign_key: "decidim_comment_id", class_name: "CommentVote", dependent: :destroy
29
34
 
30
- validates :body, presence: true
31
- validates :depth, numericality: { greater_than_or_equal_to: 0 }
32
- validates :alignment, inclusion: { in: [0, 1, -1] }
35
+ # Updates the counter caches for the root_commentable when a comment is
36
+ # created or updated.
37
+ after_save :update_counter
33
38
 
34
- validates :body, length: { maximum: 1000 }
39
+ # Updates the counter caches for the root_commentable when a comment is
40
+ # deleted.
41
+ after_destroy :update_counter
35
42
 
36
- validate :commentable_can_have_comments
43
+ # Updates the counter caches for the root_commentable when a comment is
44
+ # touched, which happens when a comment was reported and its moderation
45
+ # is accepted and sets the comment as hidden.
46
+ after_touch :update_counter
37
47
 
38
- before_save :compute_depth
48
+ before_validation :compute_depth
49
+ validates :body, presence: true
50
+ validates :depth, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: MAX_DEPTH }
51
+ validates :alignment, inclusion: { in: [0, 1, -1] }
52
+ validate :body_length
53
+ validate :commentable_can_have_comments
39
54
 
40
55
  delegate :organization, to: :commentable
41
56
 
57
+ translatable_fields :body
58
+ searchable_fields(
59
+ participatory_space: :itself,
60
+ A: :body,
61
+ datetime: :created_at
62
+ )
63
+
42
64
  def self.positive
43
65
  where(alignment: 1)
44
66
  end
@@ -99,23 +121,30 @@ module Decidim
99
121
 
100
122
  # Public: Overrides the `reported_content_url` Reportable concern method.
101
123
  def reported_content_url
102
- ResourceLocatorPresenter.new(root_commentable).url(anchor: "comment_#{id}")
103
- end
124
+ url_params = { anchor: "comment_#{id}" }
104
125
 
105
- # Public: Returns the comment message ready to display (it is expected to include HTML)
106
- def formatted_body
107
- @formatted_body ||= Decidim::ContentProcessor.render(sanitized_body, "div")
126
+ if root_commentable&.respond_to?(:polymorphic_resource_url)
127
+ root_commentable.polymorphic_resource_url(url_params)
128
+ else
129
+ ResourceLocatorPresenter.new(root_commentable).url(url_params)
130
+ end
108
131
  end
109
132
 
110
133
  def self.export_serializer
111
134
  Decidim::Comments::CommentSerializer
112
135
  end
113
136
 
114
- def self.newsletter_participant_ids(space)
115
- Decidim::Comments::Comment.includes(:root_commentable).not_hidden
116
- .where("decidim_comments_comments.decidim_author_id IN (?)", Decidim::User.where(organization: space.organization).pluck(:id))
117
- .where("decidim_comments_comments.decidim_author_type IN (?)", "Decidim::UserBaseEntity")
118
- .map(&:author).pluck(:id).flatten.compact.uniq
137
+ # Public: Returns the list of author IDs of type `UserBaseEntity` that commented in one of the +resources+.
138
+ # Expects all +resources+ to be of the same "commentable_type".
139
+ # If the result is not `Decidim::Comments::Commentable` returns `nil`.
140
+ def self.user_commentators_ids_in(resources)
141
+ if resources.first&.kind_of?(Decidim::Comments::Commentable)
142
+ commentable_type = resources.first.class.name
143
+ Decidim::Comments::Comment.select("DISTINCT decidim_author_id").not_hidden
144
+ .where(decidim_commentable_id: resources.pluck(:id))
145
+ .where(decidim_commentable_type: commentable_type)
146
+ .where("decidim_author_type" => "Decidim::UserBaseEntity").pluck(:decidim_author_id)
147
+ end
119
148
  end
120
149
 
121
150
  def can_participate?(user)
@@ -124,8 +153,35 @@ module Decidim
124
153
  root_commentable.can_participate?(user)
125
154
  end
126
155
 
156
+ def formatted_body
157
+ Decidim::ContentProcessor.render(sanitize_content(render_markdown(translated_body)), "div")
158
+ end
159
+
160
+ def translated_body
161
+ @translated_body ||= translated_attribute(body, organization)
162
+ end
163
+
127
164
  private
128
165
 
166
+ def body_length
167
+ language = (body.keys - ["machine_translations"]).first
168
+ errors.add(:body, :too_long, count: comment_maximum_length) unless body[language].length <= comment_maximum_length
169
+ end
170
+
171
+ def comment_maximum_length
172
+ return unless commentable.commentable?
173
+ return component.settings.comments_max_length if component_settings_comments_max_length?
174
+ return organization.comments_max_length if organization.comments_max_length.positive?
175
+
176
+ 1000
177
+ end
178
+
179
+ def component_settings_comments_max_length?
180
+ return unless component&.settings.respond_to?(:comments_max_length)
181
+
182
+ component.settings.comments_max_length.positive?
183
+ end
184
+
129
185
  # Private: Check if commentable can have comments and if not adds
130
186
  # a validation error to the model
131
187
  def commentable_can_have_comments
@@ -138,11 +194,8 @@ module Decidim
138
194
  end
139
195
 
140
196
  # Private: Returns the comment body sanitized, sanitizing HTML tags
141
- def sanitized_body
142
- Rails::Html::WhiteListSanitizer.new.sanitize(
143
- render_markdown(body),
144
- scrubber: Decidim::Comments::UserInputScrubber.new
145
- ).try(:html_safe)
197
+ def sanitize_content(content)
198
+ Decidim::ContentProcessor.sanitize(content)
146
199
  end
147
200
 
148
201
  # Private: Initializes the Markdown parser
@@ -154,6 +207,12 @@ module Decidim
154
207
  def render_markdown(string)
155
208
  markdown.render(string)
156
209
  end
210
+
211
+ def update_counter
212
+ return unless root_commentable
213
+
214
+ root_commentable.update_comments_count
215
+ end
157
216
  end
158
217
  end
159
218
  end
@@ -25,7 +25,7 @@ module Decidim
25
25
  params = {
26
26
  commentable: resource,
27
27
  root_commentable: resource,
28
- body: ::Faker::Lorem.sentence(50),
28
+ body: { en: ::Faker::Lorem.sentence(50) },
29
29
  author: author,
30
30
  user_group: user_group
31
31
  }
@@ -9,9 +9,6 @@ module Decidim
9
9
  end
10
10
 
11
11
  def save
12
- return @registry if @registry
13
-
14
- @registry = []
15
12
  query.each do |key, results|
16
13
  cumulative_value = results[:cumulative]
17
14
  next if cumulative_value.zero?
@@ -23,10 +20,8 @@ module Decidim
23
20
  organization: @organization, decidim_category_id: category_id,
24
21
  related_object_type: related_object_type, related_object_id: related_object_id)
25
22
  record.assign_attributes(cumulative: cumulative_value, quantity: quantity_value)
26
- @registry << record
23
+ record.save!
27
24
  end
28
- @registry.each(&:save!)
29
- @registry
30
25
  end
31
26
 
32
27
  private
@@ -17,9 +17,12 @@ module Decidim
17
17
  # comment - the Comment from which to generate notifications.
18
18
  # mentioned_users - An ActiveRecord::Relation of the users that have been
19
19
  # mentioned
20
- def initialize(comment, mentioned_users)
20
+ # mentioned_groups - And ActiveRecord::Relation of the user_groups that have
21
+ # been mentioned
22
+ def initialize(comment, mentioned_users, mentioned_groups = nil)
21
23
  @comment = comment
22
24
  @mentioned_users = mentioned_users
25
+ @mentioned_groups = mentioned_groups
23
26
  @already_notified_users = [comment.author]
24
27
  end
25
28
 
@@ -28,14 +31,16 @@ module Decidim
28
31
  # Returns nothing.
29
32
  def create
30
33
  notify_mentioned_users
34
+ notify_mentioned_groups
31
35
  notify_parent_comment_author
32
36
  notify_author_followers
37
+ notify_user_group_followers
33
38
  notify_commentable_recipients
34
39
  end
35
40
 
36
41
  private
37
42
 
38
- attr_reader :comment, :mentioned_users, :already_notified_users
43
+ attr_reader :comment, :mentioned_users, :mentioned_groups, :already_notified_users
39
44
 
40
45
  def notify_mentioned_users
41
46
  affected_users = mentioned_users - already_notified_users
@@ -44,6 +49,17 @@ module Decidim
44
49
  notify(:user_mentioned, affected_users: affected_users)
45
50
  end
46
51
 
52
+ def notify_mentioned_groups
53
+ return unless mentioned_groups
54
+
55
+ mentioned_groups.each do |group|
56
+ affected_users = group.accepted_users - already_notified_users
57
+ @already_notified_users += affected_users
58
+
59
+ notify(:user_group_mentioned, affected_users: affected_users, extra: { group: group })
60
+ end
61
+ end
62
+
47
63
  # Notifies the author of a comment that their comment has been replied.
48
64
  # Only applies if the comment is a reply.
49
65
  def notify_parent_comment_author
@@ -62,6 +78,15 @@ module Decidim
62
78
  notify(:comment_by_followed_user, followers: followers)
63
79
  end
64
80
 
81
+ def notify_user_group_followers
82
+ return if comment.user_group.blank?
83
+
84
+ followers = comment.user_group.followers - already_notified_users
85
+ @already_notified_users += followers
86
+
87
+ notify(:comment_by_followed_user_group, followers: followers)
88
+ end
89
+
65
90
  # Notifies the users the `comment.commentable` resource implements as necessary.
66
91
  def notify_commentable_recipients
67
92
  followers = comment.commentable.users_to_notify_on_comment_created - already_notified_users
@@ -90,7 +115,7 @@ module Decidim
90
115
  extra: {
91
116
  comment_id: comment.id
92
117
  }
93
- }.merge(users)
118
+ }.deep_merge(users)
94
119
 
95
120
  Decidim::EventsManager.publish(data)
96
121
  end
@@ -41,7 +41,7 @@ module Decidim
41
41
  description "The number of comments in all levels this resource holds"
42
42
 
43
43
  resolve lambda { |obj, _args, _ctx|
44
- obj.comments.count
44
+ obj.comments_count
45
45
  }
46
46
  end
47
47
 
@@ -16,9 +16,12 @@ module Decidim
16
16
  argument :userGroupId, types.ID, "The comment's user group id. Replaces the author."
17
17
 
18
18
  resolve lambda { |obj, args, ctx|
19
- params = { "comment" => { "body" => args[:body], "alignment" => args[:alignment], "user_group_id" => args[:userGroupId] } }
20
- form = Decidim::Comments::CommentForm.from_params(params).with_context(current_organization: ctx[:current_organization])
21
- Decidim::Comments::CreateComment.call(form, ctx[:current_user], obj) do
19
+ params = { "comment" => { "body" => args[:body], "alignment" => args[:alignment], "user_group_id" => args[:userGroupId], "commentable" => obj } }
20
+ form = Decidim::Comments::CommentForm.from_params(params).with_context(
21
+ current_organization: ctx[:current_organization],
22
+ current_component: obj.component
23
+ )
24
+ Decidim::Comments::CreateComment.call(form, ctx[:current_user]) do
22
25
  on(:ok) do |comment|
23
26
  return comment
24
27
  end
@@ -0,0 +1 @@
1
+ am:
@@ -4,6 +4,7 @@ ar:
4
4
  decidim/comments/comment_by_followed_user_event: تعليق
5
5
  decidim/comments/comment_created_event: تعليق
6
6
  decidim/comments/reply_created_event: تعليق الرد
7
+ decidim/comments/user_group_mentioned_event: أشير
7
8
  decidim/comments/user_mentioned_event: أشير
8
9
  activerecord:
9
10
  models:
@@ -62,7 +63,6 @@ ar:
62
63
  does_not_belong: يحتوي على نشاط غير قانوني أو تهديدات انتحارية أو معلومات شخصية أو أي شيء آخر تعتقد أنه لا ينتمي إلى %{organization_name}.
63
64
  offensive: يحتوي على العنصرية والتمييز الجنسي والتشهير والهجمات الشخصية والتهديدات بالقتل أو طلبات الانتحار أو أي شكل من أشكال خطاب الكراهية.
64
65
  spam: يحتوي على clickbait أو الإعلان أو الخدع أو روبوت البرامج النصية.
65
- title: الإبلاغ عن مشكلة
66
66
  show_replies: اظهر الردود الـ %{replies_count}
67
67
  single_comment_link_title: الحصول على رابط نحو تعليق واحد
68
68
  comment_order_selector:
@@ -89,6 +89,9 @@ ar:
89
89
  email_outro: لقد تلقيت هذا الإشعار لأنك تتابع %{author_name}. يمكنك إلغاء تتبع هذا المستخدم من صفحة ملفه الشخصي.
90
90
  email_subject: هناك تعليق جديد مِن %{author_name} على %{resource_title}
91
91
  notification_title: هناك تعليق جديد مِن <a href="%{author_path}">%{author_name} %{author_nickname}</a> على <a href="%{resource_path}">%{resource_title}</a>.
92
+ comment_by_followed_user_group:
93
+ email_subject: هناك تعليق جديد مِن %{author_name} على %{resource_title}
94
+ notification_title: هناك تعليق جديد مِن <a href="%{author_path}">%{author_name} %{author_nickname}</a> على <a href="%{resource_path}">%{resource_title}</a>.
92
95
  comment_created:
93
96
  email_intro: "%{resource_title} تم التعليق. يمكنك قراءة التعليق في هذه الصفحة:"
94
97
  email_outro: لقد تلقيت هذا الإشعار لأنك تتابع "%{resource_title}" أو مؤلفه. يمكنك إلغاء تتبعه من الرابط السابق.
@@ -0,0 +1,6 @@
1
+ bg:
2
+ activemodel:
3
+ models:
4
+ decidim/comments/comment_by_followed_user_event: Коментар
5
+ decidim/comments/comment_created_event: Коментар
6
+ decidim/comments/reply_created_event: Отговор на коментар
@@ -0,0 +1,6 @@
1
+ bg:
2
+ activemodel:
3
+ models:
4
+ decidim/comments/comment_by_followed_user_event: Коментар
5
+ decidim/comments/comment_created_event: Коментар
6
+ decidim/comments/reply_created_event: Отговор на коментар
@@ -4,6 +4,7 @@ ca:
4
4
  decidim/comments/comment_by_followed_user_event: Comentari
5
5
  decidim/comments/comment_created_event: Comentari
6
6
  decidim/comments/reply_created_event: Resposta al comentari
7
+ decidim/comments/user_group_mentioned_event: Mencionar
7
8
  decidim/comments/user_mentioned_event: Mencionar
8
9
  activerecord:
9
10
  models:
@@ -16,8 +17,10 @@ ca:
16
17
  decidim:
17
18
  comments:
18
19
  comments: Comentaris
20
+ comments_count: Número de comentaris
19
21
  last_activity:
20
22
  new_comment_at_html: "<span>Nou comentari a %{link}</span>"
23
+ view: Mostrar
21
24
  votes:
22
25
  create:
23
26
  error: S'ha produït un error en votar el comentari.
@@ -54,7 +57,7 @@ ca:
54
57
  does_not_belong: Conté activitat il·legal, amenaces de suïcidi, informació personal, o qualsevol altra cosa que creguis que no pertany a %{organization_name}.
55
58
  offensive: Conté racisme, sexisme, insults, atacs personals, amenaces de mort, peticions de suïcidi o qualsevol forma de discurs d'odi.
56
59
  spam: Conté "clickbait", publicitat o estafes.
57
- title: Denúncia un problema
60
+ title: Notificar contingut inapropiat
58
61
  show_replies: Mostra %{replies_count} respostes
59
62
  single_comment_link_title: Aconsegueix l'enllaç al comentari
60
63
  comment_order_selector:
@@ -71,9 +74,13 @@ ca:
71
74
  blocked_comments_warning: Els comentaris estan desactivats en aquest moment, però pots llegir els anteriors.
72
75
  comment_details_title: Detalls del comentari
73
76
  loading: Carregant els comentaris ...
74
- single_comment_warning: 'Pots revisar la resta de comentaris a: <a href="%{url}">here</a>.'
77
+ single_comment_warning: Pots revisar la resta de comentaris <a href="%{url}">aquí</a>.
75
78
  single_comment_warning_title: Estàs veient un sol comentari
76
79
  title: "%{count} comentaris"
80
+ down_vote_button:
81
+ text: No estic d'acord amb aquest comentari
82
+ up_vote_button:
83
+ text: Estic d'acord amb aquest comentari
77
84
  events:
78
85
  comments:
79
86
  comment_by_followed_user:
@@ -81,6 +88,11 @@ ca:
81
88
  email_outro: Has rebut aquesta notificació perquè estàs seguint %{author_name}. Pots deixar de seguir a aquesta participant des de la seva pàgina de perfil.
82
89
  email_subject: Hi ha un nou comentari de %{author_name} en %{resource_title}
83
90
  notification_title: Hi ha un nou comentari per <a href="%{author_path}">%{author_name} %{author_nickname}</a> a <a href="%{resource_path}">%{resource_title}</a>.
91
+ comment_by_followed_user_group:
92
+ email_intro: '%{author_name} ha deixat un comentari a%{resource_title}. Pots llegir-lo en aquesta pàgina:'
93
+ email_outro: Reps aquesta notificació perquè segueixes a %{author_name}. Pots deixar de seguir aquest grup des de la seva pàgina de perfil.
94
+ email_subject: Hi ha un nou comentari de %{author_name} en %{resource_title}
95
+ notification_title: Hi ha un nou comentari per <a href="%{author_path}">%{author_name} %{author_nickname}</a> a <a href="%{resource_path}">%{resource_title}</a>.
84
96
  comment_created:
85
97
  email_intro: "S'ha comentat %{resource_title}. Pots llegir el comentari d'aquesta pàgina:"
86
98
  email_outro: Has rebut aquesta notificació perquè estàs seguint "%{resource_title}" o la seva autora. Pots deixar de seguir-la des de l'enllaç anterior.
@@ -91,6 +103,11 @@ ca:
91
103
  email_outro: Has rebut aquesta notificació perquè s'ha respost el teu comentari.
92
104
  email_subject: "%{author_name} ha respost el teu comentari a %{resource_title}"
93
105
  notification_title: <a href="%{author_path}">%{author_name} %{author_nickname}</a> ha respost el teu comentari a <a href="%{resource_path}">%{resource_title}</a>
106
+ user_group_mentioned:
107
+ email_intro: Un grup al qual pertanys ha estat esmentat
108
+ email_outro: Has rebut aquesta notificació perquè formes part del grup %{group_name} que ha estat esmentat a %{resource_title}.
109
+ email_subject: T'han esmentat a %{resource_title} com a membre de %{group_name}
110
+ notification_title: <a href="%{author_path}">%{author_name} %{author_nickname}</a> t'ha esmentat com a membre de <a href="%{group_path}">%{group_name} %{group_nickname}</a> a <a href="%{resource_path}">%{resource_title}</a>
94
111
  user_mentioned:
95
112
  email_intro: Has estat esmentada
96
113
  email_outro: Has rebut aquesta notificació perquè has estat esmentada a %{resource_title}.
@@ -4,7 +4,8 @@ cs:
4
4
  decidim/comments/comment_by_followed_user_event: Komentář
5
5
  decidim/comments/comment_created_event: Komentář
6
6
  decidim/comments/reply_created_event: Odpověď na komentář
7
- decidim/comments/user_mentioned_event: Zmínit se
7
+ decidim/comments/user_group_mentioned_event: Zmínka
8
+ decidim/comments/user_mentioned_event: Zmínka
8
9
  activerecord:
9
10
  models:
10
11
  decidim/comments/comment:
@@ -13,71 +14,77 @@ cs:
13
14
  many: Komentáře
14
15
  other: Komentáře
15
16
  decidim/comments/comment_vote:
16
- one: Hlasování
17
+ one: Hlasovat
17
18
  few: Hlasy
18
19
  many: Hlasy
19
20
  other: Hlasy
20
21
  decidim:
21
22
  comments:
22
23
  comments: Komentáře
24
+ comments_count: Počet komentářů
23
25
  last_activity:
24
26
  new_comment_at_html: "<span>Nový komentář v %{link}</span>"
27
+ view: Zobrazit
25
28
  votes:
26
29
  create:
27
- error: Při hlasování se vyskytly chyby.
30
+ error: Při hlasování o komentáři došlo k chybě.
28
31
  components:
29
32
  add_comment_form:
30
- account_message: <a href="%{sign_in_url}">Přihlaste se svým účtem</a> nebo <a href="%{sign_up_url}">přihlaste se</a> a přidejte svůj komentář.
33
+ account_message: <a href="%{sign_in_url}">Přihlaste se pomocí svého účtu</a> nebo se <a href="%{sign_up_url}">zaregistrujte</a> a přidejte svůj komentář.
31
34
  form:
32
35
  body:
33
36
  label: Komentář
34
37
  placeholder: Co si o tom myslíš?
35
38
  form_error: Text je povinný a nesmí být delší než %{length} znaků.
36
- submit: Poslat
39
+ submit: Odeslat
37
40
  user_group_id:
38
41
  label: Komentovat jako
39
42
  opinion:
40
43
  neutral: Neutrální
41
44
  remaining_characters: "Zbývá %{count} znaků"
42
- remaining_characters_1: "Zbývá %{count} znaků"
45
+ remaining_characters_1: "Zbývá %{count} znak"
43
46
  title: Přidejte svůj komentář
44
47
  comment:
45
48
  alignment:
46
49
  against: Proti
47
50
  in_favor: Ve prospěch
48
- deleted_user: Vymazaný uživatel
51
+ deleted_user: Vymazaný účastník
49
52
  hide_replies: Skrýt odpovědi
50
53
  reply: Odpověď
51
54
  report:
52
55
  action: Zpráva
53
- already_reported: Tento obsah je již nahlášen a bude kontrolován administrátorem.
56
+ already_reported: Tento obsah je již nahlášen a bude přezkoumán administrátorem.
54
57
  close: Zavřít
55
58
  description: Je tento obsah nevhodný?
56
59
  details: Další komentáře
57
60
  reasons:
58
61
  does_not_belong: Obsahuje nezákonnou činnost, sebevražedné hrozby, osobní informace nebo něco jiného, o kterém si myslíte, že nepatří na %{organization_name}.
59
62
  offensive: Obsahuje rasismus, sexismus, podvody, osobní útoky, hrozby smrti, žádosti o sebevraždu nebo jakoukoli formu projevy nenávisti.
60
- spam: Obsahuje clickbait, reklama, podvody nebo skripty.
61
- title: Nahlásit problém
63
+ spam: Obsahuje clickbait, reklamu, podvody nebo škodlivé skripty.
64
+ title: Nahlásit nevhodný obsah
62
65
  show_replies: Zobrazit %{replies_count} odpovědí
63
66
  single_comment_link_title: Získat odkaz na jeden komentář
64
67
  comment_order_selector:
65
68
  order:
66
69
  best_rated: Nejlépe hodnocené
67
- most_discussed: Nejdiskutovanější
70
+ most_discussed: Nejvíce diskutované
68
71
  older: Starší
69
- recent: Nedávno
72
+ recent: Nedávné
70
73
  title: 'Seřadit podle:'
71
74
  comment_thread:
72
75
  title: Konverzace s číslem %{authorName}
73
76
  comments:
74
- blocked_comments_for_user_warning: V tuto chvíli nemůžete komentovat, ale můžete si přečíst předchozí.
75
- blocked_comments_warning: Komentáře jsou v tuto chvíli zakázány, ale můžete si přečíst předchozí.
77
+ blocked_comments_for_user_warning: Momentálně nemůžete komentovat, ale můžete si přečíst ty předchozí.
78
+ blocked_comments_warning: Komentáře jsou momentálně zakázány, ale můžete si přečíst ty předchozí.
76
79
  comment_details_title: Podrobnosti komentáře
77
80
  loading: Načítání komentářů ...
78
81
  single_comment_warning: Můžete zkontrolovat zbytek komentářů <a href="%{url}">zde</a>.
79
82
  single_comment_warning_title: Vidíte jeden komentář
80
83
  title: "%{count} komentářů"
84
+ down_vote_button:
85
+ text: Nesouhlasím s tímto komentářem
86
+ up_vote_button:
87
+ text: Souhlasím s tímto komentářem
81
88
  events:
82
89
  comments:
83
90
  comment_by_followed_user:
@@ -85,6 +92,11 @@ cs:
85
92
  email_outro: Toto oznámení jste obdrželi, protože jste sledovali %{author_name}. Tento uživatel můžete zrušit ze své profilové stránky.
86
93
  email_subject: K dispozici je nový komentář %{author_name} v %{resource_title}
87
94
  notification_title: K dispozici je nový komentář <a href="%{author_path}">%{author_name} %{author_nickname}</a> v <a href="%{resource_path}">%{resource_title}</a>.
95
+ comment_by_followed_user_group:
96
+ email_intro: 'Skupina %{author_name} zanechala komentář v %{resource_title}. Můžete si jej přečíst na této stránce:'
97
+ email_outro: Obdrželi jste toto oznámení, protože sledujete %{author_name}. Můžete zrušit sledování této skupiny na její profilové stránce.
98
+ email_subject: K dispozici je nový komentář %{author_name} v %{resource_title}
99
+ notification_title: K dispozici je nový komentář <a href="%{author_path}">%{author_name} %{author_nickname}</a> v <a href="%{resource_path}">%{resource_title}</a>.
88
100
  comment_created:
89
101
  email_intro: "%{resource_title} bylo komentováno. Můžete si přečíst komentář na této stránce:"
90
102
  email_outro: Toto oznámení jste obdrželi, protože jste sledovali "%{resource_title}" nebo jeho autora. Můžete jej odhlásit od předchozího odkazu.
@@ -95,6 +107,11 @@ cs:
95
107
  email_outro: Toto oznámení jste obdrželi, protože váš komentář byl zodpovězen.
96
108
  email_subject: "%{author_name} odpověděl váš komentář v %{resource_title}"
97
109
  notification_title: <a href="%{author_path}">%{author_name} %{author_nickname}</a> odpověděl / a svůj komentář v <a href="%{resource_path}">%{resource_title}</a>
110
+ user_group_mentioned:
111
+ email_intro: Byla zmíněna skupina, do které patříte
112
+ email_outro: Obdrželi jste toto oznámení, protože jste členem skupiny %{group_name}, která byla zmíněna v %{resource_title}.
113
+ email_subject: Byl jste zmíněn v %{resource_title} jako člen %{group_name}
114
+ notification_title: Byli jste zmíněni v <a href="%{resource_path}">%{resource_title}</a> od <a href="%{author_path}">%{author_name} %{author_nickname}</a> jako člen <a href="%{group_path}">%{group_name} %{group_nickname}</a>
98
115
  user_mentioned:
99
116
  email_intro: Byl jste zmíněn
100
117
  email_outro: Toto oznámení jste obdrželi, protože jste byli uvedeni v %{resource_title}.