Skip to content

Commit 02f9f15

Browse files
authored
Send email notifications for replies (#62)
2 parents 416da74 + 18ba4e3 commit 02f9f15

23 files changed

+501
-396
lines changed

.rubocop.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
AllCops:
22
TargetRubyVersion: 2.3
3+
Style/AsciiComments:
4+
Enabled: false
35
Security/YAMLLoad:
46
Enabled: false

app/assets/stylesheets/forms.sass

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ select, input, textarea, button
1616
font-family: $sansFont
1717

1818
.edit_reader, .new_reader
19-
label
19+
label:not(.notification)
2020
font: 600 80% $sansFont
2121
text-transform: uppercase
2222
letter-spacing: 0.05em
@@ -34,7 +34,7 @@ select, input, textarea, button
3434
.pt-checkbox
3535
margin: 5px 0 0 0
3636

37-
.pt-control
37+
.pt-control:not(.notification)
3838
text-transform: uppercase
3939

4040
.actions

app/controllers/readers_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def reader_params
8585
@reader_can_set_password = @reader && !@reader.created_password
8686
end
8787

88-
permitted = %i[name initials email locale]
88+
permitted = %i[name initials email locale send_reply_notifications]
8989
permitted << :password if @reader_can_set_password
9090

9191
params.require(:reader).permit(*permitted)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
module CommentThreadsHelper
4+
def comment_thread_url(locale, comment_thread)
5+
"#{case_url(locale, comment_thread.card.case.slug)}" \
6+
"/#{comment_thread.card.element.case_element.position}" \
7+
"/cards/#{comment_thread.card_id}/comments"
8+
end
9+
end

app/jobs/notification_broadcast_job.rb renamed to app/jobs/reply_notification_broadcast_job.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# frozen_string_literal: true
22

3-
class NotificationBroadcastJob < ActiveJob::Base
3+
class ReplyNotificationBroadcastJob < ActiveJob::Base
44
queue_as :default
55

66
def perform(notification)
@@ -12,7 +12,6 @@ def perform(notification)
1212
private
1313

1414
def render_notification(notification)
15-
ApplicationController.renderer.render partial: 'notifications/notification',
16-
locals: { notification: notification }
15+
ApplicationController.renderer.render notification
1716
end
1817
end

app/mailers/application_mailer.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
class ApplicationMailer < ActionMailer::Base
44
helper :application
5-
default from: 'Michigan Sustainability Cases <[email protected]>'
5+
6+
FROM_ADDRESS = '[email protected]'
7+
default from: "Michigan Sustainability Cases <#{FROM_ADDRESS}>"
68

79
layout 'mailer'
810
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
class ReplyNotificationMailer < ApplicationMailer
4+
helper :cases
5+
helper :comment_threads
6+
7+
def notify(notification)
8+
@notification = notification
9+
reader = @notification.reader
10+
return unless reader.send_reply_notifications
11+
12+
mail(to: reader.name_and_email,
13+
from: from_header,
14+
subject: subject_header) do |format|
15+
format.text
16+
format.html
17+
end
18+
end
19+
20+
private
21+
22+
# Build the from header. We’re setting the from name to the name of the
23+
# reader whose comment triggered the notification, but the from address
24+
# remains our notification address so as not to trip spam filters
25+
def from_header
26+
"#{@notification.notifier.name} <#{ApplicationMailer::FROM_ADDRESS}>"
27+
end
28+
29+
# Build the email subject as follows
30+
# RE: [National Adaptation] “I understand that Ethiopia would be a...” (# 46)
31+
#
32+
# Every notification of a reply to the same original comment will have the
33+
# same subject so that they can be threaded
34+
def subject_header
35+
comment_thread = @notification.comment_thread
36+
"RE: [#{@notification.case.kicker}] " \
37+
"“#{comment_thread.comments.first.content.truncate(40)}” " \
38+
"(##{comment_thread.id})"
39+
end
40+
end

app/models/comment.rb

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Comment < ApplicationRecord
66

77
translates :content
88

9-
acts_as_list scope: :comment_thread
9+
default_scope { order :created_at }
1010

1111
validates :content, presence: :true
1212

@@ -20,18 +20,17 @@ def timestamp
2020

2121
private
2222

23-
def notification_data
24-
{ notifier_id: reader.id,
25-
comment_thread_id: comment_thread.id,
26-
card_id: comment_thread.card.id,
27-
case_id: comment_thread.card.case.id,
28-
page_id: comment_thread.card.element.id }
29-
end
30-
3123
def send_notifications_of_reply
32-
(comment_thread.collocutors - [reader]).each do |r|
33-
Notification.create reader: r, category: :reply_to_thread,
34-
data: notification_data
24+
card = comment_thread.card
25+
comment_thread.collocutors.each do |other_reader|
26+
next if other_reader == reader
27+
ReplyNotification.create reader: other_reader,
28+
notifier: reader,
29+
comment: self,
30+
comment_thread: comment_thread,
31+
card: card,
32+
case: card.case,
33+
page: card.element
3534
end
3635
end
3736
end

app/models/comment_thread.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ class CommentThread < ApplicationRecord
66
belongs_to :reader
77
belongs_to :group
88
belongs_to :card
9-
belongs_to :case
109
has_many :comments, dependent: :restrict_with_error
1110

1211
def collocutors

app/models/notification.rb

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)