mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Notifications: Cleaned up mails, added debounce for updates
- Updated mail notification design to be a bit prettier, and extracted text to new lang file for translation. - Added debounce logic for page update notifications. - Fixed watch options not being filtered to current user.
This commit is contained in:
parent
371779205a
commit
615741af9d
@ -5,6 +5,7 @@ namespace BookStack\Activity\Models;
|
|||||||
use BookStack\App\Model;
|
use BookStack\App\Model;
|
||||||
use BookStack\Users\Models\HasCreatorAndUpdater;
|
use BookStack\Users\Models\HasCreatorAndUpdater;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,7 +36,7 @@ class Comment extends Model implements Loggable
|
|||||||
/**
|
/**
|
||||||
* Get the parent comment this is in reply to (if existing).
|
* Get the parent comment this is in reply to (if existing).
|
||||||
*/
|
*/
|
||||||
public function parent()
|
public function parent(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Comment::class);
|
return $this->belongsTo(Comment::class);
|
||||||
}
|
}
|
||||||
@ -50,20 +51,16 @@ class Comment extends Model implements Loggable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get created date as a relative diff.
|
* Get created date as a relative diff.
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public function getCreatedAttribute()
|
public function getCreatedAttribute(): string
|
||||||
{
|
{
|
||||||
return $this->created_at->diffForHumans();
|
return $this->created_at->diffForHumans();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get updated date as a relative diff.
|
* Get updated date as a relative diff.
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public function getUpdatedAttribute()
|
public function getUpdatedAttribute(): string
|
||||||
{
|
{
|
||||||
return $this->updated_at->diffForHumans();
|
return $this->updated_at->diffForHumans();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Activity\Notifications\Handlers;
|
namespace BookStack\Activity\Notifications\Handlers;
|
||||||
|
|
||||||
|
use BookStack\Activity\Models\Loggable;
|
||||||
use BookStack\Activity\Notifications\Messages\BaseActivityNotification;
|
use BookStack\Activity\Notifications\Messages\BaseActivityNotification;
|
||||||
use BookStack\Entities\Models\Entity;
|
use BookStack\Entities\Models\Entity;
|
||||||
use BookStack\Permissions\PermissionApplicator;
|
use BookStack\Permissions\PermissionApplicator;
|
||||||
@ -18,7 +19,7 @@ abstract class BaseNotificationHandler implements NotificationHandler
|
|||||||
* @param class-string<BaseActivityNotification> $notification
|
* @param class-string<BaseActivityNotification> $notification
|
||||||
* @param int[] $userIds
|
* @param int[] $userIds
|
||||||
*/
|
*/
|
||||||
protected function sendNotificationToUserIds(string $notification, array $userIds, User $initiator, Entity $relatedModel): void
|
protected function sendNotificationToUserIds(string $notification, array $userIds, User $initiator, string|Loggable $detail, Entity $relatedModel): void
|
||||||
{
|
{
|
||||||
$users = User::query()->whereIn('id', array_unique($userIds))->get();
|
$users = User::query()->whereIn('id', array_unique($userIds))->get();
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ abstract class BaseNotificationHandler implements NotificationHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send the notification
|
// Send the notification
|
||||||
$user->notify(new $notification($relatedModel, $initiator));
|
$user->notify(new $notification($detail, $initiator));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Activity\Notifications\Handlers;
|
namespace BookStack\Activity\Notifications\Handlers;
|
||||||
|
|
||||||
|
use BookStack\Activity\Models\Activity;
|
||||||
use BookStack\Activity\Models\Comment;
|
use BookStack\Activity\Models\Comment;
|
||||||
use BookStack\Activity\Models\Loggable;
|
use BookStack\Activity\Models\Loggable;
|
||||||
use BookStack\Activity\Notifications\Messages\CommentCreationNotification;
|
use BookStack\Activity\Notifications\Messages\CommentCreationNotification;
|
||||||
@ -12,7 +13,7 @@ use BookStack\Users\Models\User;
|
|||||||
|
|
||||||
class CommentCreationNotificationHandler extends BaseNotificationHandler
|
class CommentCreationNotificationHandler extends BaseNotificationHandler
|
||||||
{
|
{
|
||||||
public function handle(string $activityType, Loggable|string $detail, User $user): void
|
public function handle(Activity $activity, Loggable|string $detail, User $user): void
|
||||||
{
|
{
|
||||||
if (!($detail instanceof Comment)) {
|
if (!($detail instanceof Comment)) {
|
||||||
throw new \InvalidArgumentException("Detail for comment creation notifications must be a comment");
|
throw new \InvalidArgumentException("Detail for comment creation notifications must be a comment");
|
||||||
@ -24,10 +25,10 @@ class CommentCreationNotificationHandler extends BaseNotificationHandler
|
|||||||
$watcherIds = $watchers->getWatcherUserIds();
|
$watcherIds = $watchers->getWatcherUserIds();
|
||||||
|
|
||||||
// Page owner if user preferences allow
|
// Page owner if user preferences allow
|
||||||
if (!$watchers->isUserIgnoring($detail->owned_by) && $detail->ownedBy) {
|
if (!$watchers->isUserIgnoring($detail->created_by) && $detail->createdBy) {
|
||||||
$userNotificationPrefs = new UserNotificationPreferences($detail->ownedBy);
|
$userNotificationPrefs = new UserNotificationPreferences($detail->createdBy);
|
||||||
if ($userNotificationPrefs->notifyOnOwnPageComments()) {
|
if ($userNotificationPrefs->notifyOnOwnPageComments()) {
|
||||||
$watcherIds[] = $detail->owned_by;
|
$watcherIds[] = $detail->created_by;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +41,6 @@ class CommentCreationNotificationHandler extends BaseNotificationHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sendNotificationToUserIds(CommentCreationNotification::class, $watcherIds, $user, $page);
|
$this->sendNotificationToUserIds(CommentCreationNotification::class, $watcherIds, $user, $detail, $page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Activity\Notifications\Handlers;
|
namespace BookStack\Activity\Notifications\Handlers;
|
||||||
|
|
||||||
|
use BookStack\Activity\Models\Activity;
|
||||||
use BookStack\Activity\Models\Loggable;
|
use BookStack\Activity\Models\Loggable;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
|
|
||||||
@ -9,8 +10,8 @@ interface NotificationHandler
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Run this handler.
|
* Run this handler.
|
||||||
* Provides the activity type, related activity detail/model
|
* Provides the activity, related activity detail/model
|
||||||
* along with the user that triggered the activity.
|
* along with the user that triggered the activity.
|
||||||
*/
|
*/
|
||||||
public function handle(string $activityType, string|Loggable $detail, User $user): void;
|
public function handle(Activity $activity, string|Loggable $detail, User $user): void;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Activity\Notifications\Handlers;
|
namespace BookStack\Activity\Notifications\Handlers;
|
||||||
|
|
||||||
|
use BookStack\Activity\Models\Activity;
|
||||||
use BookStack\Activity\Models\Loggable;
|
use BookStack\Activity\Models\Loggable;
|
||||||
use BookStack\Activity\Notifications\Messages\PageCreationNotification;
|
use BookStack\Activity\Notifications\Messages\PageCreationNotification;
|
||||||
use BookStack\Activity\Tools\EntityWatchers;
|
use BookStack\Activity\Tools\EntityWatchers;
|
||||||
@ -11,13 +12,13 @@ use BookStack\Users\Models\User;
|
|||||||
|
|
||||||
class PageCreationNotificationHandler extends BaseNotificationHandler
|
class PageCreationNotificationHandler extends BaseNotificationHandler
|
||||||
{
|
{
|
||||||
public function handle(string $activityType, Loggable|string $detail, User $user): void
|
public function handle(Activity $activity, Loggable|string $detail, User $user): void
|
||||||
{
|
{
|
||||||
if (!($detail instanceof Page)) {
|
if (!($detail instanceof Page)) {
|
||||||
throw new \InvalidArgumentException("Detail for page create notifications must be a page");
|
throw new \InvalidArgumentException("Detail for page create notifications must be a page");
|
||||||
}
|
}
|
||||||
|
|
||||||
$watchers = new EntityWatchers($detail, WatchLevels::NEW);
|
$watchers = new EntityWatchers($detail, WatchLevels::NEW);
|
||||||
$this->sendNotificationToUserIds(PageCreationNotification::class, $watchers->getWatcherUserIds(), $user, $detail);
|
$this->sendNotificationToUserIds(PageCreationNotification::class, $watchers->getWatcherUserIds(), $user, $detail, $detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace BookStack\Activity\Notifications\Handlers;
|
namespace BookStack\Activity\Notifications\Handlers;
|
||||||
|
|
||||||
|
use BookStack\Activity\ActivityType;
|
||||||
|
use BookStack\Activity\Models\Activity;
|
||||||
use BookStack\Activity\Models\Loggable;
|
use BookStack\Activity\Models\Loggable;
|
||||||
use BookStack\Activity\Notifications\Messages\PageUpdateNotification;
|
use BookStack\Activity\Notifications\Messages\PageUpdateNotification;
|
||||||
use BookStack\Activity\Tools\EntityWatchers;
|
use BookStack\Activity\Tools\EntityWatchers;
|
||||||
@ -12,15 +14,31 @@ use BookStack\Users\Models\User;
|
|||||||
|
|
||||||
class PageUpdateNotificationHandler extends BaseNotificationHandler
|
class PageUpdateNotificationHandler extends BaseNotificationHandler
|
||||||
{
|
{
|
||||||
public function handle(string $activityType, Loggable|string $detail, User $user): void
|
public function handle(Activity $activity, Loggable|string $detail, User $user): void
|
||||||
{
|
{
|
||||||
if (!($detail instanceof Page)) {
|
if (!($detail instanceof Page)) {
|
||||||
throw new \InvalidArgumentException("Detail for page update notifications must be a page");
|
throw new \InvalidArgumentException("Detail for page update notifications must be a page");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get last update from activity
|
||||||
|
$lastUpdate = $detail->activity()
|
||||||
|
->where('type', '=', ActivityType::PAGE_UPDATE)
|
||||||
|
->where('id', '!=', $activity->id)
|
||||||
|
->latest('created_at')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// Return if the same user has already updated the page in the last 15 mins
|
||||||
|
if ($lastUpdate && $lastUpdate->user_id === $user->id) {
|
||||||
|
if ($lastUpdate->created_at->gt(now()->subMinutes(15))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get active watchers
|
||||||
$watchers = new EntityWatchers($detail, WatchLevels::UPDATES);
|
$watchers = new EntityWatchers($detail, WatchLevels::UPDATES);
|
||||||
$watcherIds = $watchers->getWatcherUserIds();
|
$watcherIds = $watchers->getWatcherUserIds();
|
||||||
|
|
||||||
|
// Add page owner if preferences allow
|
||||||
if (!$watchers->isUserIgnoring($detail->owned_by) && $detail->ownedBy) {
|
if (!$watchers->isUserIgnoring($detail->owned_by) && $detail->ownedBy) {
|
||||||
$userNotificationPrefs = new UserNotificationPreferences($detail->ownedBy);
|
$userNotificationPrefs = new UserNotificationPreferences($detail->ownedBy);
|
||||||
if ($userNotificationPrefs->notifyOnOwnPageChanges()) {
|
if ($userNotificationPrefs->notifyOnOwnPageChanges()) {
|
||||||
@ -28,6 +46,6 @@ class PageUpdateNotificationHandler extends BaseNotificationHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sendNotificationToUserIds(PageUpdateNotification::class, $watcherIds, $user, $detail);
|
$this->sendNotificationToUserIds(PageUpdateNotification::class, $watcherIds, $user, $detail, $detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace BookStack\Activity\Notifications;
|
namespace BookStack\Activity\Notifications\MessageParts;
|
||||||
|
|
||||||
use Illuminate\Contracts\Support\Htmlable;
|
use Illuminate\Contracts\Support\Htmlable;
|
||||||
|
|
26
app/Activity/Notifications/MessageParts/ListMessageLine.php
Normal file
26
app/Activity/Notifications/MessageParts/ListMessageLine.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\Activity\Notifications\MessageParts;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Support\Htmlable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bullet point list of content, where the keys of the given list array
|
||||||
|
* are bolded header elements, and the values follow.
|
||||||
|
*/
|
||||||
|
class ListMessageLine implements Htmlable
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected array $list
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toHtml(): string
|
||||||
|
{
|
||||||
|
$list = [];
|
||||||
|
foreach ($this->list as $header => $content) {
|
||||||
|
$list[] = '<strong>' . e($header) . '</strong> ' . e($content);
|
||||||
|
}
|
||||||
|
return implode("<br>\n", $list);
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace BookStack\Activity\Notifications\Messages;
|
namespace BookStack\Activity\Notifications\Messages;
|
||||||
|
|
||||||
use BookStack\Activity\Models\Loggable;
|
use BookStack\Activity\Models\Loggable;
|
||||||
|
use BookStack\Activity\Notifications\MessageParts\LinkedMailMessageLine;
|
||||||
use BookStack\Users\Models\User;
|
use BookStack\Users\Models\User;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
@ -47,4 +48,16 @@ abstract class BaseActivityNotification extends Notification
|
|||||||
'activity_creator' => $this->user,
|
'activity_creator' => $this->user,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the common reason footer line used in mail messages.
|
||||||
|
*/
|
||||||
|
protected function buildReasonFooterLine(): LinkedMailMessageLine
|
||||||
|
{
|
||||||
|
return new LinkedMailMessageLine(
|
||||||
|
url('/preferences/notifications'),
|
||||||
|
trans('notifications.footer_reason'),
|
||||||
|
trans('notifications.footer_reason_link'),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace BookStack\Activity\Notifications\Messages;
|
namespace BookStack\Activity\Notifications\Messages;
|
||||||
|
|
||||||
use BookStack\Activity\Models\Comment;
|
use BookStack\Activity\Models\Comment;
|
||||||
use BookStack\Activity\Notifications\LinkedMailMessageLine;
|
use BookStack\Activity\Notifications\MessageParts\ListMessageLine;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
|
||||||
@ -17,16 +17,14 @@ class CommentCreationNotification extends BaseActivityNotification
|
|||||||
$page = $comment->entity;
|
$page = $comment->entity;
|
||||||
|
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->subject("New Comment on Page: " . $page->getShortName())
|
->subject(trans('notifications.new_comment_subject', ['pageName' => $page->getShortName()]))
|
||||||
->line("A user has commented on a page in " . setting('app-name') . ':')
|
->line(trans('notifications.new_comment_intro', ['appName' => setting('app-name')]))
|
||||||
->line("Page Name: " . $page->name)
|
->line(new ListMessageLine([
|
||||||
->line("Commenter: " . $this->user->name)
|
trans('notifications.detail_page_name') => $page->name,
|
||||||
->line("Comment: " . strip_tags($comment->html))
|
trans('notifications.detail_commenter') => $this->user->name,
|
||||||
->action('View Comment', $page->getUrl('#comment' . $comment->local_id))
|
trans('notifications.detail_comment') => strip_tags($comment->html),
|
||||||
->line(new LinkedMailMessageLine(
|
]))
|
||||||
url('/preferences/notifications'),
|
->action(trans('notifications.action_view_comment'), $page->getUrl('#comment' . $comment->local_id))
|
||||||
'This notification was sent to you because :link cover this type of activity for this item.',
|
->line($this->buildReasonFooterLine());
|
||||||
'your notification preferences',
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Activity\Notifications\Messages;
|
namespace BookStack\Activity\Notifications\Messages;
|
||||||
|
|
||||||
use BookStack\Activity\Notifications\LinkedMailMessageLine;
|
use BookStack\Activity\Notifications\MessageParts\ListMessageLine;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
|
||||||
@ -14,15 +14,13 @@ class PageCreationNotification extends BaseActivityNotification
|
|||||||
$page = $this->detail;
|
$page = $this->detail;
|
||||||
|
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->subject("New Page: " . $page->getShortName())
|
->subject(trans('notifications.new_page_subject', ['pageName' => $page->getShortName()]))
|
||||||
->line("A new page has been created in " . setting('app-name') . ':')
|
->line(trans('notifications.new_page_intro', ['appName' => setting('app-name')]))
|
||||||
->line("Page Name: " . $page->name)
|
->line(new ListMessageLine([
|
||||||
->line("Created By: " . $this->user->name)
|
trans('notifications.detail_page_name') => $page->name,
|
||||||
->action('View Page', $page->getUrl())
|
trans('notifications.detail_created_by') => $this->user->name,
|
||||||
->line(new LinkedMailMessageLine(
|
]))
|
||||||
url('/preferences/notifications'),
|
->action(trans('notifications.action_view_page'), $page->getUrl())
|
||||||
'This notification was sent to you because :link cover this type of activity for this item.',
|
->line($this->buildReasonFooterLine());
|
||||||
'your notification preferences',
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Activity\Notifications\Messages;
|
namespace BookStack\Activity\Notifications\Messages;
|
||||||
|
|
||||||
use BookStack\Activity\Notifications\LinkedMailMessageLine;
|
use BookStack\Activity\Notifications\MessageParts\ListMessageLine;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
|
||||||
@ -14,16 +14,14 @@ class PageUpdateNotification extends BaseActivityNotification
|
|||||||
$page = $this->detail;
|
$page = $this->detail;
|
||||||
|
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->subject("Updated Page: " . $page->getShortName())
|
->subject(trans('notifications.updated_page_subject', ['pageName' => $page->getShortName()]))
|
||||||
->line("A page has been updated in " . setting('app-name') . ':')
|
->line(trans('notifications.updated_page_intro', ['appName' => setting('app-name')]))
|
||||||
->line("Page Name: " . $page->name)
|
->line(new ListMessageLine([
|
||||||
->line("Updated By: " . $this->user->name)
|
trans('notifications.detail_page_name') => $page->name,
|
||||||
->line("To prevent a mass of notifications, for a while you won't be sent notifications for further edits to this page by the same editor.")
|
trans('notifications.detail_updated_by') => $this->user->name,
|
||||||
->action('View Page', $page->getUrl())
|
]))
|
||||||
->line(new LinkedMailMessageLine(
|
->line(trans('notifications.updated_page_debounce'))
|
||||||
url('/preferences/notifications'),
|
->action(trans('notifications.action_view_page'), $page->getUrl())
|
||||||
'This notification was sent to you because :link cover this type of activity for this item.',
|
->line($this->buildReasonFooterLine());
|
||||||
'your notification preferences',
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace BookStack\Activity\Notifications;
|
namespace BookStack\Activity\Notifications;
|
||||||
|
|
||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
|
use BookStack\Activity\Models\Activity;
|
||||||
use BookStack\Activity\Models\Loggable;
|
use BookStack\Activity\Models\Loggable;
|
||||||
use BookStack\Activity\Notifications\Handlers\CommentCreationNotificationHandler;
|
use BookStack\Activity\Notifications\Handlers\CommentCreationNotificationHandler;
|
||||||
use BookStack\Activity\Notifications\Handlers\NotificationHandler;
|
use BookStack\Activity\Notifications\Handlers\NotificationHandler;
|
||||||
@ -17,13 +18,14 @@ class NotificationManager
|
|||||||
*/
|
*/
|
||||||
protected array $handlers = [];
|
protected array $handlers = [];
|
||||||
|
|
||||||
public function handle(string $activityType, string|Loggable $detail, User $user): void
|
public function handle(Activity $activity, string|Loggable $detail, User $user): void
|
||||||
{
|
{
|
||||||
|
$activityType = $activity->type;
|
||||||
$handlersToRun = $this->handlers[$activityType] ?? [];
|
$handlersToRun = $this->handlers[$activityType] ?? [];
|
||||||
foreach ($handlersToRun as $handlerClass) {
|
foreach ($handlersToRun as $handlerClass) {
|
||||||
/** @var NotificationHandler $handler */
|
/** @var NotificationHandler $handler */
|
||||||
$handler = app()->make($handlerClass);
|
$handler = app()->make($handlerClass);
|
||||||
$handler->handle($activityType, $detail, $user);
|
$handler->handle($activity, $detail, $user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class ActivityLogger
|
|||||||
|
|
||||||
$this->setNotification($type);
|
$this->setNotification($type);
|
||||||
$this->dispatchWebhooks($type, $detail);
|
$this->dispatchWebhooks($type, $detail);
|
||||||
$this->notifications->handle($type, $detail, user());
|
$this->notifications->handle($activity, $detail, user());
|
||||||
Theme::dispatch(ThemeEvents::ACTIVITY_LOGGED, $type, $detail);
|
Theme::dispatch(ThemeEvents::ACTIVITY_LOGGED, $type, $detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,14 +76,16 @@ class UserEntityWatchOptions
|
|||||||
$entities[] = $this->entity->chapter;
|
$entities[] = $this->entity->chapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = Watch::query()->where(function (Builder $subQuery) use ($entities) {
|
$query = Watch::query()
|
||||||
foreach ($entities as $entity) {
|
->where('user_id', '=', $this->user->id)
|
||||||
$subQuery->orWhere(function (Builder $whereQuery) use ($entity) {
|
->where(function (Builder $subQuery) use ($entities) {
|
||||||
$whereQuery->where('watchable_type', '=', $entity->getMorphClass())
|
foreach ($entities as $entity) {
|
||||||
|
$subQuery->orWhere(function (Builder $whereQuery) use ($entity) {
|
||||||
|
$whereQuery->where('watchable_type', '=', $entity->getMorphClass())
|
||||||
->where('watchable_id', '=', $entity->id);
|
->where('watchable_id', '=', $entity->id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->watchMap = $query->get(['watchable_type', 'level'])
|
$this->watchMap = $query->get(['watchable_type', 'level'])
|
||||||
->pluck('level', 'watchable_type')
|
->pluck('level', 'watchable_type')
|
||||||
|
26
lang/en/notifications.php
Normal file
26
lang/en/notifications.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Text used for activity-based notifications.
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
|
||||||
|
'new_comment_subject' => 'New comment on page: :pageName',
|
||||||
|
'new_comment_intro' => 'A user has commented on a page in :appName:',
|
||||||
|
'new_page_subject' => 'New page: :pageName',
|
||||||
|
'new_page_intro' => 'A new page has been created in :appName:',
|
||||||
|
'updated_page_subject' => 'Updated page: :pageName',
|
||||||
|
'updated_page_intro' => 'A page has been updated in :appName:',
|
||||||
|
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
|
||||||
|
|
||||||
|
'detail_page_name' => 'Page Name:',
|
||||||
|
'detail_commenter' => 'Commenter:',
|
||||||
|
'detail_comment' => 'Comment:',
|
||||||
|
'detail_created_by' => 'Created By:',
|
||||||
|
'detail_updated_by' => 'Updated By:',
|
||||||
|
|
||||||
|
'action_view_comment' => 'View Comment',
|
||||||
|
'action_view_page' => 'View Page',
|
||||||
|
|
||||||
|
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
|
||||||
|
'footer_reason_link' => 'your notification preferences',
|
||||||
|
];
|
@ -30,7 +30,7 @@
|
|||||||
$style = [
|
$style = [
|
||||||
/* Layout ------------------------------ */
|
/* Layout ------------------------------ */
|
||||||
|
|
||||||
'body' => 'margin: 0; padding: 0; width: 100%; background-color: #F2F4F6;',
|
'body' => 'margin: 0; padding: 0; width: 100%; background-color: #F2F4F6;color:#444444;',
|
||||||
'email-wrapper' => 'width: 100%; margin: 0; padding: 0; background-color: #F2F4F6;',
|
'email-wrapper' => 'width: 100%; margin: 0; padding: 0; background-color: #F2F4F6;',
|
||||||
|
|
||||||
/* Masthead ----------------------- */
|
/* Masthead ----------------------- */
|
||||||
@ -54,8 +54,8 @@ $style = [
|
|||||||
|
|
||||||
'anchor' => 'color: '.setting('app-color').';overflow-wrap: break-word;word-wrap: break-word;word-break: break-all;word-break:break-word;',
|
'anchor' => 'color: '.setting('app-color').';overflow-wrap: break-word;word-wrap: break-word;word-break: break-all;word-break:break-word;',
|
||||||
'header-1' => 'margin-top: 0; color: #2F3133; font-size: 19px; font-weight: bold; text-align: left;',
|
'header-1' => 'margin-top: 0; color: #2F3133; font-size: 19px; font-weight: bold; text-align: left;',
|
||||||
'paragraph' => 'margin-top: 0; color: #74787E; font-size: 16px; line-height: 1.5em;',
|
'paragraph' => 'margin-top: 0; color: #444444; font-size: 16px; line-height: 1.5em;',
|
||||||
'paragraph-sub' => 'margin-top: 0; color: #74787E; font-size: 12px; line-height: 1.5em;',
|
'paragraph-sub' => 'margin-top: 0; color: #444444; font-size: 12px; line-height: 1.5em;',
|
||||||
'paragraph-center' => 'text-align: center;',
|
'paragraph-center' => 'text-align: center;',
|
||||||
|
|
||||||
/* Buttons ------------------------------ */
|
/* Buttons ------------------------------ */
|
||||||
@ -147,7 +147,7 @@ $style = [
|
|||||||
|
|
||||||
<!-- Outro -->
|
<!-- Outro -->
|
||||||
@foreach ($outroLines as $line)
|
@foreach ($outroLines as $line)
|
||||||
<p style="{{ $style['paragraph'] }}">
|
<p style="{{ $style['paragraph-sub'] }}">
|
||||||
{{ $line }}
|
{{ $line }}
|
||||||
</p>
|
</p>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
Loading…
Reference in New Issue
Block a user