diff --git a/Envfile b/Envfile index 3e792dd9a..51b3a5199 100644 --- a/Envfile +++ b/Envfile @@ -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" diff --git a/Gemfile b/Gemfile index f225378e9..e66eaf2b5 100644 --- a/Gemfile +++ b/Gemfile @@ -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" diff --git a/Gemfile.lock b/Gemfile.lock index 9adeeee14..9acd6a0ab 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/app/assets/stylesheets/comments.scss b/app/assets/stylesheets/comments.scss index 5b1a6f1e5..706e3c6c6 100644 --- a/app/assets/stylesheets/comments.scss +++ b/app/assets/stylesheets/comments.scss @@ -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; diff --git a/app/assets/stylesheets/notifications.scss b/app/assets/stylesheets/notifications.scss index 7228fb0ca..530d79960 100644 --- a/app/assets/stylesheets/notifications.scss +++ b/app/assets/stylesheets/notifications.scss @@ -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; diff --git a/app/models/notification.rb b/app/models/notification.rb index f39956e1e..4d539ed56 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -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 diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index b7d72f89b..12d9650bc 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -69,6 +69,7 @@ class UserPolicy < ApplicationPolicy email_public editor_version email_unread_notifications + mobile_comment_notifications employer_name employer_url employment_title diff --git a/app/services/read_notifications_service.rb b/app/services/read_notifications_service.rb index b731b0ac1..a6dd93ef3 100644 --- a/app/services/read_notifications_service.rb +++ b/app/services/read_notifications_service.rb @@ -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 diff --git a/app/views/users/_notifications.html.erb b/app/views/users/_notifications.html.erb index b563c3c38..9c5b6cd9c 100644 --- a/app/views/users/_notifications.html.erb +++ b/app/views/users/_notifications.html.erb @@ -40,6 +40,14 @@ <%= f.label :email_unread_notifications, "Send me occasional reminders that I have unread notifications on dev.to" %> +
iOS only for now. Additional settings and platforms will be rolled out as new notification features are made available.
+