From b7088ccfb71b00370bac147fbe07daac728342c2 Mon Sep 17 00:00:00 2001 From: Peter Deltchev Date: Wed, 28 Dec 2016 07:07:28 -0800 Subject: [PATCH] #25: Built out email unsubscription UI and further tweaked the email template. --- .../Controllers/NotificationsController.php | 19 ++++++- app/Mail/BaseNotification.php | 6 ++- app/Models/User.php | 5 ++ public/templates/account/settings.html | 4 ++ public/templates/home/email-unsubscribed.html | 3 ++ resources/assets/scripts/app/app.coffee | 6 ++- .../app/controllers/account-settings.coffee | 5 +- .../notifications-email-unsubscribed.coffee | 24 +++++++++ .../app/services/activity-types.coffee | 50 +++++++++++++++++++ resources/emails/src/layouts/notification.hbs | 4 +- routes/web.php | 3 +- 11 files changed, 120 insertions(+), 9 deletions(-) create mode 100644 public/templates/home/email-unsubscribed.html create mode 100644 resources/assets/scripts/app/controllers/notifications-email-unsubscribed.coffee create mode 100644 resources/assets/scripts/app/services/activity-types.coffee diff --git a/app/Http/Controllers/NotificationsController.php b/app/Http/Controllers/NotificationsController.php index 633ad653..edfb118c 100644 --- a/app/Http/Controllers/NotificationsController.php +++ b/app/Http/Controllers/NotificationsController.php @@ -21,9 +21,11 @@ namespace Poniverse\Ponyfm\Http\Controllers; use App; +use Auth; use DB; use Poniverse\Ponyfm\Models\Email; use Poniverse\Ponyfm\Models\EmailSubscription; +use View; class NotificationsController extends Controller { @@ -45,9 +47,24 @@ class NotificationsController extends Controller { } public function getEmailUnsubscribe($subscriptionKey) { + /** @var EmailSubscription $subscription */ $subscription = EmailSubscription::findOrFail($subscriptionKey); $subscription->delete(); - return 'Unsubscribed!'; + if (Auth::check() && $subscription->user->id === Auth::user()->id) { + return redirect(route('account:settings', [ + 'slug' => $subscription->user->slug, + 'unsubscribedMessageKey' => $subscription->activity_type + ]), 303); + } else { + return redirect(route('email:confirm-unsubscribed', [ + 'unsubscribedUser' => $subscription->user->display_name, + 'unsubscribedMessageKey' => $subscription->activity_type + ]), 303); + } + } + + public function getEmailUnsubscribePage() { + return View::make('shared.null'); } } diff --git a/app/Mail/BaseNotification.php b/app/Mail/BaseNotification.php index 0180a7df..cb6786bf 100644 --- a/app/Mail/BaseNotification.php +++ b/app/Mail/BaseNotification.php @@ -127,8 +127,10 @@ abstract class BaseNotification extends Mailable { ->text("emails.plaintext.notifications.{$templateName}") ->with(array_merge($extraVariables, [ 'notificationUrl' => $this->generateNotificationUrl(), - 'unsubscribeUrl' => $this->generateUnsubscribeUrl(), - 'thumbnailUrl' => $this->activityRecord->thumbnail_url + 'unsubscribeUrl' => $this->generateUnsubscribeUrl(), + 'thumbnailUrl' => $this->activityRecord->thumbnail_url, + 'recipientName' => $this->emailRecord->getUser()->display_name, + 'accountSettingsUrl' => $this->emailRecord->getUser()->getSettingsUrl(), ])); } } diff --git a/app/Models/User.php b/app/Models/User.php index 8b1febd2..360e3d3a 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -338,6 +338,11 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon return Gravatar::getUrl($email, Image::$ImageTypes[$type]['width']); } + public function getSettingsUrl() + { + return route('account:settings', ['slug' => $this->slug]); + } + /** * Get the token value for the "remember me" session. * diff --git a/public/templates/account/settings.html b/public/templates/account/settings.html index 4618a743..8a78956a 100644 --- a/public/templates/account/settings.html +++ b/public/templates/account/settings.html @@ -44,6 +44,10 @@
+
+

{{ ::unsubscribeMessage }}

+
+

Notification settings

On-site notifications are always on. That way, you can always see what you've missed whenever you log on to Pony.fm!

diff --git a/public/templates/home/email-unsubscribed.html b/public/templates/home/email-unsubscribed.html new file mode 100644 index 00000000..fdfc990b --- /dev/null +++ b/public/templates/home/email-unsubscribed.html @@ -0,0 +1,3 @@ +
+

{{ ::unsubscribeMessage }}

+
diff --git a/resources/assets/scripts/app/app.coffee b/resources/assets/scripts/app/app.coffee index 9b75395a..48f1369a 100644 --- a/resources/assets/scripts/app/app.coffee +++ b/resources/assets/scripts/app/app.coffee @@ -307,8 +307,12 @@ ponyfm.config [ templateUrl: '/templates/admin/announcement-show.html' controller: 'admin-announcement-edit' - # Homepage + state.state 'notifications-email-unsubscribed', + url: '/notifications/email/unsubscribed', + controller: 'notifications-email-unsubscribed', + templateUrl: '/templates/home/email-unsubscribed.html' + # Homepage if window.pfm.auth.isLogged state.state 'home', url: '/' diff --git a/resources/assets/scripts/app/controllers/account-settings.coffee b/resources/assets/scripts/app/controllers/account-settings.coffee index 7049c59f..6ca62b76 100644 --- a/resources/assets/scripts/app/controllers/account-settings.coffee +++ b/resources/assets/scripts/app/controllers/account-settings.coffee @@ -15,11 +15,12 @@ # along with this program. If not, see . module.exports = angular.module('ponyfm').controller "account-settings", [ - '$scope', 'auth', '$state' - ($scope, auth, $state) -> + '$scope', 'auth', '$state', 'activity-types', + ($scope, auth, $state, activityTypes) -> $scope.settings = {} $scope.errors = {} $scope.isDirty = false + $scope.unsubscribeMessage = activityTypes.getUnsubscribeMessage() $scope.touchModel = () -> $scope.isDirty = true diff --git a/resources/assets/scripts/app/controllers/notifications-email-unsubscribed.coffee b/resources/assets/scripts/app/controllers/notifications-email-unsubscribed.coffee new file mode 100644 index 00000000..ad84741b --- /dev/null +++ b/resources/assets/scripts/app/controllers/notifications-email-unsubscribed.coffee @@ -0,0 +1,24 @@ +# Pony.fm - A community for pony fan music. +# Copyright (C) 2016 Peter Deltchev +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +module.exports = angular.module('ponyfm').controller "notifications-email-unsubscribed", [ + '$scope', 'activity-types', + ($scope, activityTypes) -> + console.log("boom") + + $scope.unsubscribeMessage = activityTypes.getUnsubscribeMessage() + +] diff --git a/resources/assets/scripts/app/services/activity-types.coffee b/resources/assets/scripts/app/services/activity-types.coffee new file mode 100644 index 00000000..8b889856 --- /dev/null +++ b/resources/assets/scripts/app/services/activity-types.coffee @@ -0,0 +1,50 @@ +# Pony.fm - A community for pony fan music. +# Copyright (C) 2016 Peter Deltchev +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +module.exports = angular.module('ponyfm').factory('activity-types', [ + '$location', + ($location) -> + self = + getUnsubscribeMessage: () -> + if $location.search().unsubscribedMessageKey? + if $location.search().unsubscribedUser? + return self.generateUnsubscribeMessage( + $location.search().unsubscribedMessageKey, + $location.search().unsubscribedUser, + ) + else + return self.generateUnsubscribeMessage($location.search().unsubscribedMessageKey) + else + return null + + generateUnsubscribeMessage: (activityType, displayName = null) -> + # TODO: get these messages from the backend + switch parseInt(activityType) + when 1 then activityString = 'updates from the Pony.fm team' + when 2 then activityString = 'new tracks by users you follow' + when 3 then activityString = 'new albums by users you follow' + when 4 then activityString = 'new playlists by users you follow' + when 5 then activityString = 'when you get new followers' + when 6 then activityString = 'when someone leaves you a comment' + when 7 then activityString = 'when something of yours is favourited' + else throw "#{activityType} is an invalid activity type!" + + if displayName + return "#{displayName} - you've been unsubscribed from email notifications for #{activityString}. You can re-enable them by logging in and going to your account settings." + else + return "You successfully unsubscribed from email notifications for #{activityString}. If you want, you can re-subscribe below." + return self +]) diff --git a/resources/emails/src/layouts/notification.hbs b/resources/emails/src/layouts/notification.hbs index 0f24e001..9e854e0b 100644 --- a/resources/emails/src/layouts/notification.hbs +++ b/resources/emails/src/layouts/notification.hbs @@ -24,13 +24,13 @@
What's this?
-

Pony.fm can now send you notifications via email! You can control what you get email notifications for in your account settings.

+

Pony.fm can now send you notifications via email! You can control what you get email notifications for in your account settings.

Unsubscribe from this kind of email


- Sent with ♥
+ Sent with ♥ to \{{ $recipientName }}

Poniverse
248-1641 Lonsdale Avenue
diff --git a/routes/web.php b/routes/web.php index 5b3fe5ed..0deb5137 100644 --- a/routes/web.php +++ b/routes/web.php @@ -80,6 +80,7 @@ Route::get('notifications', 'AccountController@getNotifications'); Route::group(['prefix' => 'notifications/email'], function() { Route::get('/unsubscribe/{subscriptionKey}', 'NotificationsController@getEmailUnsubscribe')->name('email:unsubscribe'); + Route::get('/unsubscribed', 'NotificationsController@getEmailUnsubscribePage')->name('email:confirm-unsubscribed'); Route::get('/click/{emailKey}', 'NotificationsController@getEmailClick')->name('email:click'); }); @@ -246,7 +247,7 @@ Route::group(['prefix' => '{slug}'], function () { Route::get('/uploader', 'UploaderController@getIndex'); - Route::get('/', 'AccountController@getIndex'); + Route::get('/', 'AccountController@getIndex')->name('account:settings'); }); });