decidim-comments 0.22.0 → 0.23.0

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/comments/bundle.js +53 -53
  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 +1 -1
  10. data/app/forms/decidim/comments/comment_form.rb +8 -1
  11. data/app/frontend/comments/add_comment_form.component.test.tsx +30 -28
  12. data/app/frontend/comments/add_comment_form.component.tsx +32 -16
  13. data/app/frontend/comments/comment.component.test.tsx +35 -4
  14. data/app/frontend/comments/comment.component.tsx +24 -15
  15. data/app/frontend/comments/comment_thread.component.test.tsx +9 -8
  16. data/app/frontend/comments/comment_thread.component.tsx +3 -1
  17. data/app/frontend/comments/comments.component.test.tsx +17 -14
  18. data/app/frontend/comments/comments.component.tsx +28 -4
  19. data/app/frontend/comments/down_vote_button.component.tsx +24 -9
  20. data/app/frontend/comments/up_vote_button.component.tsx +24 -9
  21. data/app/frontend/mutations/add_comment.mutation.graphql +2 -2
  22. data/app/frontend/mutations/down_vote.mutation.graphql +2 -2
  23. data/app/frontend/mutations/up_vote.mutation.graphql +2 -2
  24. data/app/frontend/queries/comments.query.graphql +2 -2
  25. data/app/frontend/support/schema.ts +1060 -735
  26. data/app/helpers/decidim/comments/comment_cells_helper.rb +33 -0
  27. data/app/models/decidim/comments/comment.rb +73 -20
  28. data/app/models/decidim/comments/seed.rb +1 -1
  29. data/app/types/decidim/comments/commentable_interface.rb +1 -1
  30. data/app/types/decidim/comments/commentable_mutation_type.rb +4 -1
  31. data/config/locales/am-ET.yml +1 -0
  32. data/config/locales/bg.yml +6 -0
  33. data/config/locales/ca.yml +1 -0
  34. data/config/locales/cs.yml +1 -0
  35. data/config/locales/da.yml +1 -0
  36. data/config/locales/en.yml +1 -0
  37. data/config/locales/eo.yml +1 -0
  38. data/config/locales/es-MX.yml +1 -0
  39. data/config/locales/es-PY.yml +1 -0
  40. data/config/locales/es.yml +3 -2
  41. data/config/locales/et.yml +1 -0
  42. data/config/locales/fi-plain.yml +1 -0
  43. data/config/locales/fi.yml +2 -1
  44. data/config/locales/fr-CA.yml +2 -1
  45. data/config/locales/fr.yml +2 -1
  46. data/config/locales/hr.yml +1 -0
  47. data/config/locales/hu.yml +1 -1
  48. data/config/locales/is-IS.yml +0 -2
  49. data/config/locales/is.yml +76 -0
  50. data/config/locales/ja-JP.yml +2 -2
  51. data/config/locales/ja.yml +121 -0
  52. data/config/locales/ko-KR.yml +1 -0
  53. data/config/locales/ko.yml +1 -0
  54. data/config/locales/lt.yml +1 -0
  55. data/config/locales/{lv-LV.yml → lv.yml} +0 -0
  56. data/config/locales/mt.yml +1 -0
  57. data/config/locales/nl.yml +3 -2
  58. data/config/locales/om-ET.yml +1 -0
  59. data/config/locales/pl.yml +5 -5
  60. data/config/locales/so-SO.yml +1 -0
  61. data/config/locales/sv.yml +1 -0
  62. data/config/locales/ti-ER.yml +1 -0
  63. data/config/locales/uk.yml +0 -1
  64. data/config/locales/vi-VN.yml +1 -0
  65. data/config/locales/vi.yml +1 -0
  66. data/config/locales/zh-CN.yml +121 -0
  67. data/config/locales/zh-TW.yml +1 -0
  68. data/db/migrate/20200706123136_make_comments_handle_i18n.rb +41 -0
  69. data/db/migrate/20200828101910_add_commentable_counter_cache_to_comments.rb +9 -0
  70. data/lib/decidim/comments/api/comment_type.rb +5 -1
  71. data/lib/decidim/comments/comment_serializer.rb +7 -2
  72. data/lib/decidim/comments/comment_vote_serializer.rb +5 -1
  73. data/lib/decidim/comments/commentable.rb +11 -0
  74. data/lib/decidim/comments/comments_helper.rb +28 -4
  75. data/lib/decidim/comments/engine.rb +13 -0
  76. data/lib/decidim/comments/mutation_extensions.rb +8 -0
  77. data/lib/decidim/comments/query_extensions.rb +4 -0
  78. data/lib/decidim/comments/test/factories.rb +10 -1
  79. data/lib/decidim/comments/test/shared_examples/comment_event.rb +1 -1
  80. data/lib/decidim/comments/version.rb +1 -1
  81. metadata +37 -11
@@ -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: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: MAX_DEPTH }
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
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,12 +121,13 @@ 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
@@ -112,10 +135,10 @@ module Decidim
112
135
  end
113
136
 
114
137
  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
138
+ authors_sql = Decidim::Comments::Comment.select("DISTINCT decidim_comments_comments.decidim_author_id").not_hidden
139
+ .where("decidim_comments_comments.decidim_author_type" => "Decidim::UserBaseEntity").to_sql
140
+
141
+ Decidim::User.where(organization: space.organization).where("id IN (#{authors_sql})").pluck(:id)
119
142
  end
120
143
 
121
144
  def can_participate?(user)
@@ -124,8 +147,35 @@ module Decidim
124
147
  root_commentable.can_participate?(user)
125
148
  end
126
149
 
150
+ def formatted_body
151
+ Decidim::ContentProcessor.render(sanitize_content(render_markdown(translated_body)), "div")
152
+ end
153
+
154
+ def translated_body
155
+ @translated_body ||= translated_attribute(body, organization)
156
+ end
157
+
127
158
  private
128
159
 
160
+ def body_length
161
+ language = (body.keys - ["machine_translations"]).first
162
+ errors.add(:body, :too_long, count: comment_maximum_length) unless body[language].length <= comment_maximum_length
163
+ end
164
+
165
+ def comment_maximum_length
166
+ return unless commentable.commentable?
167
+ return component.settings.comments_max_length if component_settings_comments_max_length?
168
+ return organization.comments_max_length if organization.comments_max_length.positive?
169
+
170
+ 1000
171
+ end
172
+
173
+ def component_settings_comments_max_length?
174
+ return unless component&.settings.respond_to?(:comments_max_length)
175
+
176
+ component.settings.comments_max_length.positive?
177
+ end
178
+
129
179
  # Private: Check if commentable can have comments and if not adds
130
180
  # a validation error to the model
131
181
  def commentable_can_have_comments
@@ -138,11 +188,8 @@ module Decidim
138
188
  end
139
189
 
140
190
  # 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)
191
+ def sanitize_content(content)
192
+ Decidim::ContentProcessor.sanitize(content)
146
193
  end
147
194
 
148
195
  # Private: Initializes the Markdown parser
@@ -154,6 +201,12 @@ module Decidim
154
201
  def render_markdown(string)
155
202
  markdown.render(string)
156
203
  end
204
+
205
+ def update_counter
206
+ return unless root_commentable
207
+
208
+ root_commentable.update_comments_count
209
+ end
157
210
  end
158
211
  end
159
212
  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
  }
@@ -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
 
@@ -17,7 +17,10 @@ module Decidim
17
17
 
18
18
  resolve lambda { |obj, args, ctx|
19
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(current_organization: ctx[:current_organization])
20
+ form = Decidim::Comments::CommentForm.from_params(params).with_context(
21
+ current_organization: ctx[:current_organization],
22
+ current_component: obj.component
23
+ )
21
24
  Decidim::Comments::CreateComment.call(form, ctx[:current_user]) do
22
25
  on(:ok) do |comment|
23
26
  return comment
@@ -0,0 +1 @@
1
+ am:
@@ -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: Отговор на коментар
@@ -20,6 +20,7 @@ ca:
20
20
  comments_count: Número de comentaris
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Nou comentari a %{link}</span>"
23
+ view: Mostrar
23
24
  votes:
24
25
  create:
25
26
  error: S'ha produït un error en votar el comentari.
@@ -24,6 +24,7 @@ cs:
24
24
  comments_count: Počet komentářů
25
25
  last_activity:
26
26
  new_comment_at_html: "<span>Nový komentář v %{link}</span>"
27
+ view: Zobrazit
27
28
  votes:
28
29
  create:
29
30
  error: Při hlasování o komentáři došlo k chybě.
@@ -0,0 +1 @@
1
+ da:
@@ -21,6 +21,7 @@ en:
21
21
  comments_count: Comments count
22
22
  last_activity:
23
23
  new_comment_at_html: "<span>New comment at %{link}</span>"
24
+ view: View
24
25
  votes:
25
26
  create:
26
27
  error: There was a problem voting the comment.
@@ -0,0 +1 @@
1
+ eo:
@@ -20,6 +20,7 @@ es-MX:
20
20
  comments_count: Número de comentarios
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Nuevo comentario en %{link}</span>"
23
+ view: Ver
23
24
  votes:
24
25
  create:
25
26
  error: Ha habido errores al votar el comentario.
@@ -20,6 +20,7 @@ es-PY:
20
20
  comments_count: Número de comentarios
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Nuevo comentario en %{link}</span>"
23
+ view: Ver
23
24
  votes:
24
25
  create:
25
26
  error: Ha habido errores al votar el comentario.
@@ -20,6 +20,7 @@ es:
20
20
  comments_count: Número de comentarios
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Nuevo comentario en %{link}</span>"
23
+ view: Ver
23
24
  votes:
24
25
  create:
25
26
  error: Se ha producido un error al votar el comentario.
@@ -88,8 +89,8 @@ es:
88
89
  email_subject: Hay un nuevo comentario de %{author_name} en %{resource_title}
89
90
  notification_title: Hay un nuevo comentario de <a href="%{author_path}">%{author_name} %{author_nickname}</a> en <a href="%{resource_path}">%{resource_title}</a>.
90
91
  comment_by_followed_user_group:
91
- email_intro: '%{author_name} ha dejado un comentario en %{resource_title}. Puede leerlo en esta página:'
92
- email_outro: Recibes esta notificación porque sigues a %{author_name}. Puedes dejar de seguir a este grupo des de su página de perfil.
92
+ email_intro: '%{author_name} ha dejado un comentario en %{resource_title}. Puedes leerlo en esta página:'
93
+ email_outro: Recibes esta notificación porque sigues a %{author_name}. Puedes dejar de seguir a este grupo desde su página de perfil.
93
94
  email_subject: Hay un nuevo comentario de %{author_name} en %{resource_title}
94
95
  notification_title: Hay un nuevo comentario de <a href="%{author_path}">%{author_name} %{author_nickname}</a> en <a href="%{resource_path}">%{resource_title}</a>.
95
96
  comment_created:
@@ -0,0 +1 @@
1
+ et:
@@ -20,6 +20,7 @@ fi-pl:
20
20
  comments_count: Kommenttien määrä
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Uusi kommentti osoitteessa %{link}</span>"
23
+ view: Näytä
23
24
  votes:
24
25
  create:
25
26
  error: Äänestettäessä kommenttia tapahtui virhe.
@@ -20,6 +20,7 @@ fi:
20
20
  comments_count: Kommenttien määrä
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Uusi kommentti osoitteessa %{link}</span>"
23
+ view: Näytä
23
24
  votes:
24
25
  create:
25
26
  error: Kommentin äänestys epäonnistui.
@@ -109,7 +110,7 @@ fi:
109
110
  notification_title: Käyttäjä <a href="%{author_path}">%{author_name}%{author_nickname}</a> on maininnut sinut kohteessa <a href="%{resource_path}">%{resource_title}</a> ryhmän <a href="%{group_path}">%{group_name} %{group_nickname}</a> jäsenenä
110
111
  user_mentioned:
111
112
  email_intro: Sinut on mainittu
112
- email_outro: Tämä ilmoitus on lähetetty sinulle, koska sinut on mainittu kohdssa %{resource_title}.
113
+ email_outro: Tämä ilmoitus on lähetetty sinulle, koska sinut on mainittu kohteessa %{resource_title}.
113
114
  email_subject: Sinut on mainittu kohdassa %{resource_title}
114
115
  notification_title: <a href="%{author_path}">%{author_name} %{author_nickname}</a> on maininnut sinut kohdassa <a href="%{resource_path}">%{resource_title}</a>
115
116
  metrics:
@@ -16,10 +16,11 @@ fr-CA:
16
16
  other: Votes
17
17
  decidim:
18
18
  comments:
19
- comments: Commentaires
19
+ comments: commentaires
20
20
  comments_count: Nombre de commentaires
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Nouveau commentaire à %{link}</span>"
23
+ view: Voir
23
24
  votes:
24
25
  create:
25
26
  error: Une erreur s'est produite lors du vote sur le commentaire.
@@ -16,10 +16,11 @@ fr:
16
16
  other: Votes
17
17
  decidim:
18
18
  comments:
19
- comments: Commentaires
19
+ comments: commentaires
20
20
  comments_count: Nombre de commentaires
21
21
  last_activity:
22
22
  new_comment_at_html: "<span>Nouveau commentaire à %{link}</span>"
23
+ view: Voir
23
24
  votes:
24
25
  create:
25
26
  error: Une erreur s'est produite lors du vote sur le commentaire.
@@ -0,0 +1 @@
1
+ hr:
@@ -16,7 +16,7 @@ hu:
16
16
  other: Szavazatok
17
17
  decidim:
18
18
  comments:
19
- comments: Megjegyzések
19
+ comments: Hozzászólások
20
20
  last_activity:
21
21
  new_comment_at_html: "<span>Új megjegyzés: %{link}</span>"
22
22
  votes:
@@ -1,7 +1,5 @@
1
1
  is-IS:
2
2
  decidim:
3
- comments:
4
- comments: Athugasemdir
5
3
  components:
6
4
  add_comment_form:
7
5
  account_message: <a href="%{sign_in_url}">Skráðu þig inn með reikningnum þínum</a> eða <a href="%{sign_up_url}">skráðu þig</a> til að bæta við ummælum þínum.
@@ -0,0 +1,76 @@
1
+ is:
2
+ decidim:
3
+ comments:
4
+ comments: Athugasemdir
5
+ components:
6
+ add_comment_form:
7
+ account_message: <a href="%{sign_in_url}">Skráðu þig inn með reikningnum þínum</a> eða <a href="%{sign_up_url}">skráðu þig</a> til að bæta við ummælum þínum.
8
+ form:
9
+ body:
10
+ label: Athugasemd
11
+ placeholder: Hvað finnst þér um þetta?
12
+ form_error: Textinn er krafist og það má ekki vera lengri en %{length} stafir.
13
+ submit: Senda
14
+ user_group_id:
15
+ label: Athugasemd sem
16
+ opinion:
17
+ neutral: Hlutlaus
18
+ remaining_characters: "%{count} stafir eftir"
19
+ remaining_characters_1: "%{count} stafur eftir"
20
+ title: Bæta við athugasemd þinni
21
+ comment:
22
+ alignment:
23
+ against: Gegn
24
+ in_favor: Í hag
25
+ reply: Svara
26
+ report:
27
+ action: Skýrsla
28
+ already_reported: Þetta efni er þegar tilkynnt og það verður endurskoðað af stjórnanda.
29
+ close: Loka
30
+ description: Er þetta efni óviðeigandi?
31
+ details: Önnur athugasemdir
32
+ reasons:
33
+ does_not_belong: Inniheldur ólöglega starfsemi, sjálfsvígshugmyndir, persónulegar upplýsingar eða eitthvað sem þér finnst ekki tilheyra %{organization_name}.
34
+ offensive: Inniheldur kynþáttafordóma, kynhneigð, slurðir, persónulegar árásir, dauðarefsárásir, sjálfsvígstilraunir eða hvers konar hatursmál.
35
+ spam: Inniheldur clickbait, auglýsingar, óþekktarangi eða handritabots.
36
+ comment_order_selector:
37
+ order:
38
+ best_rated: Bestu einkunnir
39
+ most_discussed: Mest rætt
40
+ older: Eldri
41
+ recent: Nýleg
42
+ title: 'Raða eftir:'
43
+ comment_thread:
44
+ title: Samtal við %{authorName}
45
+ comments:
46
+ blocked_comments_warning: Athugasemdir eru gerðar óvirkar á þessum tíma, en þú getur lesið þau fyrri.
47
+ loading: Hleð inn athugasemdir ...
48
+ title: "%{count} athugasemdir"
49
+ events:
50
+ comments:
51
+ comment_by_followed_user:
52
+ email_intro: "%{author_name} hefur skilið eftir athugasemd í %{resource_title}. Þú getur lesið það á þessari síðu:"
53
+ email_outro: Þú hefur fengið þessa tilkynningu vegna þess að þú fylgist með %{author_name}. Þú getur sleppt þessari notanda frá prófílssíðunni sinni.
54
+ email_subject: Það er nýtt ummæli um %{author_name} í %{resource_title}
55
+ notification_title: Það er nýtt ummæli við <a href="%{author_path}">%{author_name} %{author_nickname}</a> í <a href="%{resource_path}">%{resource_title}</a>.
56
+ comment_by_followed_user_group:
57
+ email_subject: Það er nýtt ummæli um %{author_name} í %{resource_title}
58
+ notification_title: Það er nýtt ummæli við <a href="%{author_path}">%{author_name} %{author_nickname}</a> í <a href="%{resource_path}">%{resource_title}</a>.
59
+ comment_created:
60
+ email_intro: "%{resource_title} hefur verið skrifað ummæli. Þú getur lesið athugasemdina á þessari síðu:"
61
+ email_outro: Þú hefur fengið þessa tilkynningu vegna þess að þú fylgist með "%{resource_title}" eða höfundinum. Þú getur sleppt því frá fyrri tengilinn.
62
+ email_subject: Það er nýtt ummæli frá %{author_name} í %{resource_title}
63
+ notification_title: Það er nýtt ummæli frá <a href="%{author_path}">%{author_name} %{author_nickname}</a> í <a href="%{resource_path}">%{resource_title}</a>
64
+ reply_created:
65
+ email_intro: "%{author_name} hefur svarað ummæli þín í %{resource_title}. Þú getur lesið það á þessari síðu:"
66
+ email_outro: Þú hefur fengið þessa tilkynningu vegna þess að ummæli þín voru svarað.
67
+ email_subject: "%{author_name} hefur svarað ummæli þín í %{resource_title}"
68
+ notification_title: <a href="%{author_path}">%{author_name} %{author_nickname}</a> hefur svarað athugasemd þinni í <a href="%{resource_path}">%{resource_title}</a>
69
+ user_mentioned:
70
+ email_intro: Þú hefur verið nefndur
71
+ email_outro: Þú hefur fengið þessa tilkynningu vegna þess að þú hefur verið nefndur í %{resource_title}.
72
+ email_subject: Þú hefur verið nefndur í %{resource_title}
73
+ notification_title: Þú hefur verið nefndur í <a href="%{resource_path}">%{resource_title}</a> af <a href="%{author_path}">%{author_name} %{author_nickname}</a>
74
+ errors:
75
+ messages:
76
+ cannot_have_comments: getur ekki haft athugasemdir