From a0805cc29b51bd77997a1ae787ec5491a390089d Mon Sep 17 00:00:00 2001 From: flashwave Date: Sat, 26 Mar 2016 17:36:58 +0100 Subject: [PATCH] more stuff --- libraries/BBcode.php | 10 +- libraries/BBcodeDefinitions/Code.php | 12 ++- libraries/Controllers/UserController.php | 42 ++++++++- libraries/Notification.php | 81 +++++++++++++++++ libraries/Router.php | 13 ++- libraries/User.php | 31 +++++++ libraries/Users.php | 86 ------------------ public/content/data/yuuno/js/yuuno.js | 29 +----- public/content/data/yuuno/js/yuuno.ts | 41 ++------- public/content/sounds/notify.mp3 | Bin 26957 -> 0 bytes public/content/sounds/notify.ogg | Bin 28034 -> 0 bytes public/settings.php | 56 ++++++------ routes.php | 60 +++++++++--- sakura.php | 2 +- templates/yuuno/global/master.twig | 6 ++ .../yuuno/settings/notifications.history.twig | 16 ++-- 16 files changed, 280 insertions(+), 205 deletions(-) create mode 100644 libraries/Notification.php delete mode 100644 public/content/sounds/notify.mp3 delete mode 100644 public/content/sounds/notify.ogg diff --git a/libraries/BBcode.php b/libraries/BBcode.php index 1a686dd..82c1c61 100644 --- a/libraries/BBcode.php +++ b/libraries/BBcode.php @@ -75,11 +75,11 @@ class BBcode ['s', '{param}'], ['spoiler', '{param}'], ['box', '
-
- Click to open
', ], - ['box', '
{option}
-
', ], +
' + . 'Click to open
'], + ['box', '
{option}
' + . '
'], ['quote', '
Quote
{param}
'], ]; diff --git a/libraries/BBcodeDefinitions/Code.php b/libraries/BBcodeDefinitions/Code.php index 73e1718..7a5737e 100644 --- a/libraries/BBcodeDefinitions/Code.php +++ b/libraries/BBcodeDefinitions/Code.php @@ -36,10 +36,12 @@ class Code extends CodeDefinition */ public function asHtml(ElementNode $el) { - return preg_replace( - "#\n*\[code\]\n*(.*?)\n*\[/code\]\n*#s", - '
\\1
', - $el->getAsBBCode() - ); + $content = ""; + + foreach ($el->getChildren() as $child) { + $content .= $child->getAsBBCode(); + } + + return "
{$content}
"; } } diff --git a/libraries/Controllers/UserController.php b/libraries/Controllers/UserController.php index f60e95a..a169aff 100644 --- a/libraries/Controllers/UserController.php +++ b/libraries/Controllers/UserController.php @@ -9,6 +9,8 @@ namespace Sakura\Controllers; use Sakura\Config; use Sakura\DB; +use Sakura\Notification; +use Sakura\Perms\Site; use Sakura\Rank; use Sakura\Router; use Sakura\Template; @@ -104,7 +106,7 @@ class UserController extends Controller global $currentUser; // Check permission - if (!$currentUser->permission(\Sakura\Perms\Site::VIEW_MEMBERLIST)) { + if (!$currentUser->permission(Site::VIEW_MEMBERLIST)) { return Template::render('global/restricted'); } @@ -136,4 +138,42 @@ class UserController extends Controller // Render the template return Template::render('main/memberlist'); } + + public function notifications() + { + // TODO: add friend on/offline messages + global $currentUser; + + // Set json content type + header('Content-Type: application/json; charset=utf-8'); + + return json_encode( + $currentUser->notifications(), + JSON_FORCE_OBJECT | JSON_NUMERIC_CHECK | JSON_BIGINT_AS_STRING + ); + } + + public function markNotification($id = 0) + { + global $currentUser; + + // Check permission + if ($currentUser->permission(Site::DEACTIVATED)) { + return '0'; + } + + // Create the notification object + $alert = new Notification($id); + + // Verify that the currently authed user is the one this alert is for + if ($alert->user !== $currentUser->id) { + return '0'; + } + + // Toggle the read status and save + $alert->toggleRead(); + $alert->save(); + + return '1'; + } } diff --git a/libraries/Notification.php b/libraries/Notification.php new file mode 100644 index 0000000..24f4ffa --- /dev/null +++ b/libraries/Notification.php @@ -0,0 +1,81 @@ + + */ +class Notification +{ + public $id = 0; + public $user = 0; + public $time = 0; + public $read = false; + public $title = "Notification"; + public $text = ""; + public $link = ""; + public $image = ""; + public $timeout = 0; + + public function __construct($id = 0) + { + // Get notification data from the database + $data = DB::table('notifications') + ->where('alert_id', $id) + ->get(); + + // Check if anything was returned and assign data + if ($data) { + $data = $data[0]; + + $this->id = $data->alert_id; + $this->user = $data->user_id; + $this->time = $data->alert_timestamp; + $this->read = intval($data->alert_read) !== 0; + $this->title = $data->alert_title; + $this->text = $data->alert_text; + $this->link = $data->alert_link; + $this->image = $data->alert_img; + $this->timeout = $data->alert_timeout; + } + } + + public function save() + { + // Create submission data, insert and update take the same format + $data = [ + 'user_id' => $this->user, + 'alert_timestamp' => $this->time, + 'alert_read' => $this->read ? 1 : 0, + 'alert_title' => $this->title, + 'alert_text' => $this->text, + 'alert_link' => $this->link, + 'alert_img' => $this->image, + 'alert_timeout' => $this->timeout, + ]; + + // Update if id isn't 0 + if ($this->id) { + DB::table('notifications') + ->where('alert_id', $this->id) + ->update($data); + } else { + $this->id = DB::table('notifications') + ->insertGetId($data); + } + } + + public function toggleRead() + { + // Set read to the negative value of itself + $this->read = !$this->read; + } +} diff --git a/libraries/Router.php b/libraries/Router.php index 7d28d6a..5da4112 100644 --- a/libraries/Router.php +++ b/libraries/Router.php @@ -136,8 +136,6 @@ class Router * * @param array $filters The filters for this group. * @param \Closure $callback The containers - * - * @return string The generated URI. */ public static function group($filters, $callback) { @@ -145,6 +143,17 @@ class Router self::$router->group($filters, $callback); } + /** + * Create filter. + * + * string $name Identifier of the filter + * \Closure $method + */ + public static function filter($name, $method) + { + self::$router->filter($name, $method); + } + /** * Handle requests. * diff --git a/libraries/User.php b/libraries/User.php index 9ece53a..179129f 100644 --- a/libraries/User.php +++ b/libraries/User.php @@ -1194,4 +1194,35 @@ class User // Return success return [1, 'SUCCESS']; } + + /** + * Get all the notifications for this user. + * + * @param int $timeDifference The timeframe of alerts that should be fetched. + * @param bool $excludeRead Whether alerts that are marked as read should be included. + * + * @return array An array with Notification objects. + */ + public function notifications($timeDifference = 0, $excludeRead = true) + { + $alertIds = DB::table('notifications') + ->where('user_id', $this->id); + + if ($timeDifference) { + $alertIds->where('alert_timestamp', '>', time() - $timeDifference); + } + + if ($excludeRead) { + $alertIds->where('alert_read', 0); + } + + $alertIds = array_column($alertIds->get(['alert_id']), 'alert_id'); + $alerts = []; + + foreach ($alertIds as $alertId) { + $alerts[$alertId] = new Notification($alertId); + } + + return $alerts; + } } diff --git a/libraries/Users.php b/libraries/Users.php index b006698..730b4d6 100644 --- a/libraries/Users.php +++ b/libraries/Users.php @@ -350,92 +350,6 @@ class Users } } - /** - * Get a user's notifications. - * - * @param int $uid The user id. - * @param int $timediff The maximum difference in time. - * @param bool $excludeRead Exclude notifications that were already read. - * @param bool $markRead Automatically mark as read. - * - * @return array The notifications. - */ - public static function getNotifications($uid = null, $timediff = 0, $excludeRead = true, $markRead = false) - { - // Prepare conditions - $uid = $uid ? $uid : self::checkLogin()[0]; - $time = $timediff ? time() - $timediff : '%'; - $read = $excludeRead ? '0' : '%'; - - // Get notifications for the database - $alerts = DB::table('notifications') - ->where('user_id', $uid) - ->where('alert_timestamp', '>', $time) - ->where('alert_read', $read) - ->get(); - - // Mark the notifications as read - if ($markRead) { - // Iterate over all entries - foreach ($alerts as $alert) { - // If the notifcation is already read skip - if ($alert->alert_read) { - continue; - } - - // Mark them as read - self::markNotificationRead($notification->alert_id); - } - } - - // Return the notifications - return $notifications; - } - - /** - * Mark a notification as read - * - * @param mixed $id The notification's ID. - * @param mixed $mode Read or unread. - */ - public static function markNotificationRead($id, $mode = true) - { - // Execute an update statement - DB::table('notifications') - ->where('alert_id', $id) - ->update([ - 'alert_read' => ($mode ? 1 : 0), - ]); - } - - /** - * Create a new notification. - * - * @param int $user The user id. - * @param string $title The notification title. - * @param string $text The rest of the text. - * @param int $timeout After how many seconds the notification should disappear. - * @param string $img The image. - * @param string $link The link. - * @param int $sound Whether it should play a noise. - */ - public static function createNotification($user, $title, $text, $timeout = 60000, $img = 'FONT:fa-info-circle', $link = '', $sound = 0) - { - // Insert it into the database - DB::table('notifications') - ->insert([ - 'user_id' => $user, - 'alert_timestamp' => time(), - 'alert_read' => 0, - 'alert_sound' => ($sound ? 1 : 0), - 'alert_title' => $title, - 'alert_text' => $text, - 'alert_link' => $link, - 'alert_img' => $img, - 'alert_timeout' => $timeout, - ]); - } - /** * Get the newest member's ID. * diff --git a/public/content/data/yuuno/js/yuuno.js b/public/content/data/yuuno/js/yuuno.js index 4ea7868..9a65a2c 100644 --- a/public/content/data/yuuno/js/yuuno.js +++ b/public/content/data/yuuno/js/yuuno.js @@ -20,18 +20,18 @@ function notifyUI(content) { alert.className = 'notification-enter'; alert.id = id; // Add the icon - if ((typeof content.img).toLowerCase() === 'undefined' || content.img == null || content.img.length < 2) { + if ((typeof content.image).toLowerCase() === 'undefined' || content.image == null || content.image.length < 2) { aIconCont = document.createElement('div'); aIconCont.className = 'font-icon fa fa-info fa-4x'; } - else if (content.img.substr(0, 5) == 'FONT:') { + else if (content.image.substr(0, 5) == 'FONT:') { aIconCont = document.createElement('div'); - aIconCont.className = 'font-icon fa ' + content.img.replace('FONT:', '') + ' fa-4x'; + aIconCont.className = 'font-icon fa ' + content.image.replace('FONT:', '') + ' fa-4x'; } else { aIconCont = document.createElement('img'); aIconCont.alt = id; - aIconCont.src = content.img; + aIconCont.src = content.image; } aIcon.appendChild(aIconCont); aIcon.className = 'notification-icon'; @@ -58,25 +58,6 @@ function notifyUI(content) { alert.appendChild(aClose); // Append the notification to the document cont.appendChild(alert); - // Play sound if request - if (content.sound) { - // Create the elements - var sound = document.createElement('audio'); - var mp3 = document.createElement('source'); - var ogg = document.createElement('source'); - // Assign attribs - mp3.type = 'audio/mp3'; - ogg.type = 'audio/ogg'; - mp3.src = sakuraVars.content + '/sounds/notify.mp3'; - ogg.src = sakuraVars.content + '/sounds/notify.ogg'; - // Append - sound.appendChild(mp3); - sound.appendChild(ogg); - // Less loud - sound.volume = 0.5; - // And play - sound.play(); - } // If keepalive is 0 keep the notification open forever if (content.timeout > 0) { // Set a timeout and close after an amount @@ -111,7 +92,7 @@ function notifyRequest(session) { } // Create AJAX object var get = new AJAX(); - get.setUrl('/settings.php?request-notifications=true&time=' + Sakura.epoch() + '&session=' + session); + get.setUrl('/notifications'); // Add callbacks get.addCallback(200, function () { // Assign the parsed JSON diff --git a/public/content/data/yuuno/js/yuuno.ts b/public/content/data/yuuno/js/yuuno.ts index 3644065..9db6f31 100644 --- a/public/content/data/yuuno/js/yuuno.ts +++ b/public/content/data/yuuno/js/yuuno.ts @@ -8,9 +8,8 @@ interface Notification { title: string; text: string; link: string; - img: string; + image: string; timeout: number; - sound: boolean; } // Spawns a notification @@ -29,22 +28,22 @@ function notifyUI(content: Notification): void { var aCIcon: HTMLDivElement = document.createElement('div'); var aClear: HTMLDivElement = document.createElement('div'); var aIconCont: any; - + // Add attributes to the main element alert.className = 'notification-enter'; alert.id = id; // Add the icon - if ((typeof content.img).toLowerCase() === 'undefined' || content.img == null || content.img.length < 2) { + if ((typeof content.image).toLowerCase() === 'undefined' || content.image == null || content.image.length < 2) { aIconCont = document.createElement('div'); aIconCont.className = 'font-icon fa fa-info fa-4x'; - } else if (content.img.substr(0, 5) == 'FONT:') { + } else if (content.image.substr(0, 5) == 'FONT:') { aIconCont = document.createElement('div'); - aIconCont.className = 'font-icon fa ' + content.img.replace('FONT:', '') + ' fa-4x'; + aIconCont.className = 'font-icon fa ' + content.image.replace('FONT:', '') + ' fa-4x'; } else { aIconCont = document.createElement('img'); aIconCont.alt = id; - aIconCont.src = content.img; + aIconCont.src = content.image; } aIcon.appendChild(aIconCont); @@ -78,30 +77,6 @@ function notifyUI(content: Notification): void { // Append the notification to the document cont.appendChild(alert); - // Play sound if request - if (content.sound) { - // Create the elements - var sound: HTMLAudioElement = document.createElement('audio'); - var mp3: HTMLSourceElement = document.createElement('source'); - var ogg: HTMLSourceElement = document.createElement('source'); - - // Assign attribs - mp3.type = 'audio/mp3'; - ogg.type = 'audio/ogg'; - mp3.src = sakuraVars.content + '/sounds/notify.mp3'; - ogg.src = sakuraVars.content + '/sounds/notify.ogg'; - - // Append - sound.appendChild(mp3); - sound.appendChild(ogg); - - // Less loud - sound.volume = 0.5; - - // And play - sound.play(); - } - // If keepalive is 0 keep the notification open forever if (content.timeout > 0) { // Set a timeout and close after an amount @@ -128,7 +103,7 @@ function notifyClose(id: string): void { // Opening an alerted link function notifyOpen(id: string): void { var sakuraHref: string = document.getElementById(id).getAttribute('sakurahref'); - + if ((typeof sakuraHref).toLowerCase() !== 'undefined') { window.location.assign(sakuraHref); } @@ -143,7 +118,7 @@ function notifyRequest(session: string): void { // Create AJAX object var get: AJAX = new AJAX(); - get.setUrl('/settings.php?request-notifications=true&time=' + Sakura.epoch() + '&session=' + session); + get.setUrl('/notifications'); // Add callbacks get.addCallback(200, () => { diff --git a/public/content/sounds/notify.mp3 b/public/content/sounds/notify.mp3 deleted file mode 100644 index 6d84cd1127f0c390b36628f509bc602bacb56572..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26957 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 diff --git a/public/settings.php b/public/settings.php index 103c89a..4963448 100644 --- a/public/settings.php +++ b/public/settings.php @@ -17,7 +17,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification // Include components require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) . 'sakura.php'; -// Notifications +// Notifications (decommissioned) if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications']) { // Create the notification container array $notifications = []; @@ -28,20 +28,23 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification && $_REQUEST['time'] > (time() - 1000) && isset($_REQUEST['session']) && $_REQUEST['session'] == session_id()) { // Get the user's notifications from the past forever but exclude read notifications - $userNotifs = Users::getNotifications(null, 0, true, true); + $alerts = $currentUser->notifications(); // Add the proper values to the array - foreach ($userNotifs as $notif) { + foreach ($alerts as $alert) { // Add the notification to the display array - $notifications[$notif['alert_timestamp']] = [ - 'read' => $notif['alert_read'], - 'title' => $notif['alert_title'], - 'text' => $notif['alert_text'], - 'link' => $notif['alert_link'], - 'img' => $notif['alert_img'], - 'timeout' => $notif['alert_timeout'], - 'sound' => $notif['alert_sound'], + $notifications[$alert->id] = [ + 'read' => $alert->read, + 'title' => $alert->title, + 'text' => $alert->text, + 'link' => $alert->link, + 'img' => $alert->image, + 'timeout' => $alert->timeout, + 'sound' => $alert->sound, ]; + + $alert->toggleRead(); + $alert->save(); } } @@ -71,7 +74,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification 'title' => $friend->username . ' is online.', 'text' => '', 'link' => '', - 'img' => '/a/' . $friend->id, + 'img' => Router::route('file.avatar', $friend->id), 'timeout' => 2000, 'sound' => false, ]; @@ -87,7 +90,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification 'title' => $friend->username . ' is offline.', 'text' => '', 'link' => '', - 'img' => '/a/' . $friend->id, + 'img' => Router::route('file.avatar', $friend->id), 'timeout' => 2000, 'sound' => false, ]; @@ -377,16 +380,20 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification if (array_key_exists($action[1], $notifStrings)) { // Get the current user's profile data $user = User::construct($currentUser->id); + $friend = User::construct($_REQUEST[(isset($_REQUEST['add']) ? 'add' : 'remove')]); - Users::createNotification( - $_REQUEST[(isset($_REQUEST['add']) ? 'add' : 'remove')], - sprintf($notifStrings[$action[1]][0], $user->username), - $notifStrings[$action[1]][1], - 60000, - Router::route('file.avatar', $user->id), - Router::route('user.profile', $user->id), - '1' - ); + $alert = new Notification; + + $alert->user = $friend->id; + $alert->time = time(); + $alert->sound = true; + $alert->title = sprintf($notifStrings[$action[1]][0], $user->username); + $alert->text = $notifStrings[$action[1]][1]; + $alert->image = Router::route('file.avatar', $user->id); + $alert->timeout = 60000; + $alert->link = Router::route('user.profile', $user->id); + + $alert->save(); } } @@ -1490,11 +1497,6 @@ if (Users::checkLogin()) { $renderData['messages'] = []; break; - // Notification history - case 'notifications.history': - $renderData['alerts'] = array_reverse(Users::getNotifications(null, 0, false, true)); - break; - // Avatar and background sizes case 'appearance.avatar': case 'appearance.background': diff --git a/routes.php b/routes.php index d59ab03..0ee16b2 100644 --- a/routes.php +++ b/routes.php @@ -6,6 +6,32 @@ // Define namespace namespace Sakura; +// Check if logged out +Router::filter('logoutCheck', function () { + global $currentUser; + + if ($currentUser->id !== 0) { + $message = "You must be logged out to do that!"; + + Template::vars(['page' => compact('message')]); + + return Template::render('global/information'); + } +}); + +// Check if logged in +Router::filter('loginCheck', function () { + global $currentUser; + + if ($currentUser->id === 0) { + $message = "You must be logged in to do that!"; + + Template::vars(['page' => compact('message')]); + + return Template::render('global/information'); + } +}); + // Meta pages Router::get('/', 'MetaController@index', 'main.index'); Router::get('/faq', 'MetaController@faq', 'main.faq'); @@ -13,16 +39,20 @@ Router::get('/search', 'MetaController@search', 'main.search'); Router::get('/p/{id}', 'MetaController@infoPage', 'main.infopage'); // Auth -Router::get('/login', 'AuthController@loginGet', 'auth.login'); -Router::post('/login', 'AuthController@loginPost', 'auth.login'); -Router::get('/logout', 'AuthController@logout', 'auth.logout'); -Router::get('/register', 'AuthController@registerGet', 'auth.register'); -Router::post('/register', 'AuthController@registerPost', 'auth.register'); -Router::get('/resetpassword', 'AuthController@resetPasswordGet', 'auth.resetpassword'); -Router::post('/resetpassword', 'AuthController@resetPasswordPost', 'auth.resetpassword'); -Router::get('/reactivate', 'AuthController@reactivateGet', 'auth.reactivate'); -Router::post('/reactivate', 'AuthController@reactivatePost', 'auth.reactivate'); -Router::get('/activate', 'AuthController@activate', 'auth.activate'); +Router::group(['before' => 'logoutCheck'], function () { + Router::get('/login', 'AuthController@loginGet', 'auth.login'); + Router::post('/login', 'AuthController@loginPost', 'auth.login'); + Router::get('/register', 'AuthController@registerGet', 'auth.register'); + Router::post('/register', 'AuthController@registerPost', 'auth.register'); + Router::get('/resetpassword', 'AuthController@resetPasswordGet', 'auth.resetpassword'); + Router::post('/resetpassword', 'AuthController@resetPasswordPost', 'auth.resetpassword'); + Router::get('/reactivate', 'AuthController@reactivateGet', 'auth.reactivate'); + Router::post('/reactivate', 'AuthController@reactivatePost', 'auth.reactivate'); + Router::get('/activate', 'AuthController@activate', 'auth.activate'); +}); +Router::group(['before' => 'loginCheck'], function () { + Router::get('/logout', 'AuthController@logout', 'auth.logout'); +}); // News Router::group(['prefix' => 'news'], function () { @@ -37,9 +67,11 @@ Router::group(['prefix' => 'forum'], function () { Router::group(['prefix' => 'post'], function () { Router::get('/{id:i}', 'ForumController@post', 'forums.post'); Router::get('/{id:i}/raw', 'ForumController@postRaw', 'forums.post.raw'); - Router::get('/{id:i}/delete', 'ForumController@deletePost', 'forums.post.delete'); - Router::post('/{id:i}/delete', 'ForumController@deletePost', 'forums.post.delete'); - Router::post('/{id:i}/edit', 'ForumController@editPost', 'forums.post.edit'); + Router::group(['before' => 'loginCheck'], function () { + Router::get('/{id:i}/delete', 'ForumController@deletePost', 'forums.post.delete'); + Router::post('/{id:i}/delete', 'ForumController@deletePost', 'forums.post.delete'); + Router::post('/{id:i}/edit', 'ForumController@editPost', 'forums.post.edit'); + }); }); // Thread @@ -66,6 +98,8 @@ Router::group(['prefix' => 'members'], function () { // User Router::get('/u/{id}', 'UserController@profile', 'user.profile'); Router::get('/u/{id}/header', 'FileController@header', 'user.header'); +Router::get('/notifications', 'UserController@notifications', 'user.notifications'); +Router::get('/notifications/{id}/mark', 'UserController@markNotification', 'user.notifications.mark'); // Files Router::get('/a/{id}', 'FileController@avatar', 'file.avatar'); diff --git a/sakura.php b/sakura.php index 8dac73a..8ef0d95 100644 --- a/sakura.php +++ b/sakura.php @@ -8,7 +8,7 @@ namespace Sakura; // Define Sakura version -define('SAKURA_VERSION', 20160325); +define('SAKURA_VERSION', 20160326); // Define Sakura Path define('ROOT', __DIR__ . '/'); diff --git a/templates/yuuno/global/master.twig b/templates/yuuno/global/master.twig index f15f22c..a2b3dab 100644 --- a/templates/yuuno/global/master.twig +++ b/templates/yuuno/global/master.twig @@ -212,6 +212,12 @@ timeElems[timeElem].innerText = Sakura.timeElapsed(Math.floor(parsed / 1000)); } } + + notifyRequest('{{ php.sessionid }}'); + + setInterval(function() { + notifyRequest('{{ php.sessionid }}'); + }, 60000); {% if sakura.dev.showChangelog and stats %} diff --git a/templates/yuuno/settings/notifications.history.twig b/templates/yuuno/settings/notifications.history.twig index fdb823e..844de4e 100644 --- a/templates/yuuno/settings/notifications.history.twig +++ b/templates/yuuno/settings/notifications.history.twig @@ -1,4 +1,4 @@ -{% set alerts = alerts|batch(10) %} +{% set alerts = user.notifications(0, false)|batch(10) %} {% set paginationPages = alerts %} {% set paginationUrl %}{{ urls.format('SETTING_MODE', ['notifications', 'history']) }}{% endset %} @@ -14,25 +14,25 @@ {% if alerts %}