Add initial ios push notifications to server (#1207)

* Add initial push notification logic for iOS

* Adjust notification form css

* Clean up schema.rb

* Add mark-all-as-read functionality for ios notifications

* Update app/models/notification.rb

Fix `find` to `find_by`

Co-Authored-By: benhalpern <bendhalpern@gmail.com>
This commit is contained in:
Ben Halpern 2018-11-27 17:40:43 -05:00 committed by GitHub
parent 13280c24ef
commit db6232adf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 77 additions and 7 deletions

View file

@ -108,6 +108,8 @@ variable :PUSHER_APP_ID, :String, default: "Optional"
variable :PUSHER_CLUSTER, :String, default: "Optional"
variable :PUSHER_KEY, :String, default: "Optional"
variable :PUSHER_SECRET, :String, default: "Optional"
variable :PUSHER_BEAMS_ID, :String, default: "Optional"
variable :PUSHER_BEAMS_KEY, :String, default: "Optional"
# Google recaptcha
variable :RECAPTCHA_SECRET, :String, default: "Optional"

View file

@ -68,6 +68,7 @@ gem "puma", "~> 3.12"
gem "puma_worker_killer", "~> 0.1"
gem "pundit", "~> 2.0"
gem "pusher", "~> 1.3"
gem "pusher-push-notifications", "~> 1.0"
gem "rack-host-redirect", "~> 1.3"
gem "rack-timeout", "~> 0.5"
gem "rails", "~> 5.1"

View file

@ -187,6 +187,8 @@ GEM
activesupport (>= 3.2.0)
carrierwave
fastimage
caze (0.2.2)
activesupport (>= 3)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
chromedriver-helper (2.1.0)
@ -638,6 +640,9 @@ GEM
httpclient (~> 2.7)
multi_json (~> 1.0)
pusher-signature (~> 0.1.8)
pusher-push-notifications (1.0.0)
caze
rest-client
pusher-signature (0.1.8)
rack (2.0.6)
rack-host-redirect (1.3.0)
@ -980,6 +985,7 @@ DEPENDENCIES
pundit (~> 2.0)
pundit-matchers (~> 1.6)
pusher (~> 1.3)
pusher-push-notifications (~> 1.0)
rack-host-redirect (~> 1.3)
rack-timeout (~> 0.5)
rails (~> 5.1)

View file

@ -240,13 +240,13 @@ a.header-link{
transition: height 0.3s ease;
cursor:text;
&.embiggened{
height:calc(13vw + 15px);
height:calc(2vw + 115px);
}
&.embiggened-more{
height:calc(20vw + 18px);
height:calc(5vw + 118px);
}
&.embiggened-max{
height:calc(30vw + 18px);
height:calc(10vw + 118px);
}
&.preview-loading{
background: white url(image_path('loading-ellipsis.svg')) no-repeat center center;

View file

@ -306,7 +306,7 @@
font-size:16px;
padding:6px;
transition: height 0.3s ease;
height:calc(4vw + 68px);
height:calc(2vw + 120px);
}
input[type="submit"]{
margin-right:15px;

View file

@ -22,13 +22,13 @@ class Notification < ApplicationRecord
notification.notified_at = Time.current
notification.read = is_read
notification.save!
end
end
end
handle_asynchronously :send_new_follower_notification
def send_to_followers(notifiable, action = nil)
# followers is an array and not an activerecord object
notifiable.user.followers.sort_by(&:updated_at).reverse[0..2500].each do |follower|
notifiable.user.followers.sort_by(&:updated_at).reverse[0..10000].each do |follower|
json_data = {
user: user_data(notifiable.user),
article: article_data(notifiable)
@ -59,6 +59,10 @@ class Notification < ApplicationRecord
action: nil,
json_data: json_data,
)
# Be careful with this basic first implementation of push notification. Has dependency of Pusher/iPhone sort of tough to test reliably.
if User.find_by(id: user_id)&.mobile_comment_notifications
send_push_notifications(user_id, "@#{notifiable.user.username} replied to you:", notifiable.title, "/notifications/comments")
end
end
end
handle_asynchronously :send_new_comment_notifications
@ -257,6 +261,24 @@ class Notification < ApplicationRecord
updated_at: article.updated_at
}
end
def send_push_notifications(user_id, title, body, path)
return unless ApplicationConfig["PUSHER_BEAMS_KEY"] && ApplicationConfig["PUSHER_BEAMS_KEY"].size == 64
payload = {
apns: {
aps: {
alert: {
title: title,
body: body.strip!
}
},
data: {
url: "https://dev.to" + path
}
}
}
Pusher::PushNotifications.publish(interests: ["user-notifications-#{user_id}"], payload: payload)
end
end
# instance methods

View file

@ -69,6 +69,7 @@ class UserPolicy < ApplicationPolicy
email_public
editor_version
email_unread_notifications
mobile_comment_notifications
employer_name
employer_url
employment_title

View file

@ -5,6 +5,25 @@ class ReadNotificationsService
def mark_as_read
NotificationCounter.new(@user).set_to_zero
remove_notifications(@user.id)
"read"
end
def remove_notifications(user_id)
return unless ApplicationConfig["PUSHER_BEAMS_KEY"] && ApplicationConfig["PUSHER_BEAMS_KEY"].size == 64
payload = {
apns: {
aps: {
alert: {
title: "DEV Notifications",
body: "Marking as read 🙂"
}
},
data: {
url: "REMOVE_NOTIFICATIONS"
}
}
}
Pusher::PushNotifications.publish(interests: ["user-notifications-#{user_id}"], payload: payload)
end
end

View file

@ -40,6 +40,14 @@
<%= f.label :email_unread_notifications, "Send me occasional reminders that I have unread notifications on dev.to" %>
</div>
</div>
<h3>Mobile Notification Settings (Beta)</h3>
<p><em>iOS only for now. Additional settings and platforms will be rolled out as new notification features are made available.</em></p>
<div class="checkbox-field">
<div class="sub-field">
<%= f.check_box :mobile_comment_notifications %>
<%= f.label :mobile_comment_notifications, "Notify me when someone replies to me in a comment thread" %>
</div>
</div>
<div class="field">
<label></label>
<%= f.hidden_field :tab, value: @tab %>

View file

@ -6,3 +6,8 @@ Pusher.secret = ApplicationConfig["PUSHER_SECRET"]
Pusher.cluster = ApplicationConfig["PUSHER_CLUSTER"]
Pusher.logger = Rails.logger
Pusher.encrypted = true
Pusher::PushNotifications.configure do |config|
config.instance_id = ApplicationConfig["PUSHER_BEAMS_ID"]
config.secret_key = ApplicationConfig["PUSHER_BEAMS_KEY"]
end

View file

@ -0,0 +1,5 @@
class AddMobileCommentNotificationsToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :mobile_comment_notifications, :boolean, default: true
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20181120170350) do
ActiveRecord::Schema.define(version: 20181127173004) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -739,6 +739,7 @@ ActiveRecord::Schema.define(version: 20181120170350) do
t.datetime "mentee_form_updated_at"
t.text "mentor_description"
t.datetime "mentor_form_updated_at"
t.boolean "mobile_comment_notifications", default: true
t.integer "monthly_dues", default: 0
t.string "mostly_work_with"
t.string "name"