From 995d4bde54223cb5d625276fc5514d32aafe4e4f Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 12 Oct 2023 02:19:57 +0300 Subject: [PATCH] implement events pagination --- .env | 2 + config/services.yaml | 1 + public/asset/default/css/framework.css | 20 +++- src/Controller/TorrentController.php | 28 +++++- src/Controller/UserController.php | 63 ++++++++++-- src/Repository/ActivityRepository.php | 61 ++++++++++++ src/Service/ActivityService.php | 110 ++++++++++++++++++++- templates/default/torrent/info.html.twig | 48 ++++++++- templates/default/user/dashboard.html.twig | 37 ++++++- templates/default/user/info.html.twig | 40 +++++++- 10 files changed, 388 insertions(+), 22 deletions(-) diff --git a/.env b/.env index be151e5..28edf71 100644 --- a/.env +++ b/.env @@ -52,6 +52,8 @@ APP_NAME=YGGtracker APP_LOCALE=en APP_LOCALES=en|cs|eo|fr|ka|de|he|it|lv|pl|pt|ru|es|uk +APP_PAGINATION=10 + APP_THEME=default APP_THEMES=default diff --git a/config/services.yaml b/config/services.yaml index 65372d7..45ceb5b 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -6,6 +6,7 @@ parameters: app.version: '%env(APP_VERSION)%' app.name: '%env(APP_NAME)%' + app.pagination: '%env(APP_PAGINATION)%' app.trackers: '%env(APP_TRACKERS)%' app.locales: '%env(APP_LOCALES)%' app.themes: '%env(APP_THEMES)%' diff --git a/public/asset/default/css/framework.css b/public/asset/default/css/framework.css index 7349b72..3b63c64 100644 --- a/public/asset/default/css/framework.css +++ b/public/asset/default/css/framework.css @@ -103,13 +103,25 @@ a.label-green:hover { background-color: #65916d; } -.button { - border: transparent 1px solid; +.button, +a.button, +a.button:active, +a.button:visited, +a.button:hover { + background: #5d627d; + border: #5d627d 1px solid; + color: #ccc; + padding: 6px 8px; border-radius: 3px; - padding: 8px; + opacity: .96; + display: inline-block; } -.button-green { +.button-green, +a.button-green, +a.button-green:active, +a.button-green:visited, +a.button-green:hover { color: #fff; background-color: #65916d; border: #65916d 1px solid; diff --git a/src/Controller/TorrentController.php b/src/Controller/TorrentController.php index db3a941..f038b70 100644 --- a/src/Controller/TorrentController.php +++ b/src/Controller/TorrentController.php @@ -17,11 +17,16 @@ class TorrentController extends AbstractController { // Torrent #[Route( - '/{_locale}/torrent/{torrentId}', + '/{_locale}/torrent/{torrentId}/{page}', name: 'torrent_info', requirements: [ - 'torrentId' => '\d+' + 'torrentId' => '\d+', + 'page' => '\d+', + ], + defaults: + [ + 'page' => 1, ], methods: [ @@ -29,6 +34,7 @@ class TorrentController extends AbstractController ] )] public function info( + int $page, Request $request, TranslatorInterface $translator, UserService $userService, @@ -82,6 +88,12 @@ class TorrentController extends AbstractController ); } + // Get total activities + $total = $activityService->findActivitiesTotalByTorrentId( + $torrent->getId(), + $user->getEvents() + ); + // Render template return $this->render('default/torrent/info.html.twig', [ 'torrent' => @@ -166,6 +178,18 @@ class TorrentController extends AbstractController // 'magnet' => $file->getMagnetLink() ], 'trackers' => explode('|', $this->getParameter('app.trackers')), + 'activities' => $activityService->findLastActivitiesByTorrentId( + $torrent->getId(), + $user->getEvents(), + $this->getParameter('app.pagination'), + ($page - 1) * $this->getParameter('app.pagination') + ), + 'pagination' => + [ + 'page' => $page, + 'pages' => ceil($total / $this->getParameter('app.pagination')), + 'total' => $total + ] ]); } diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index cf7078f..5eeae8a 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -39,10 +39,23 @@ class UserController extends AbstractController } #[Route( - '/{_locale}', - name: 'user_dashboard' + '/{_locale}/{page}', + name: 'user_dashboard', + requirements: + [ + 'page' => '\d+', + ], + defaults: + [ + 'page' => 1, + ], + methods: + [ + 'GET' + ] )] public function index( + int $page, Request $request, UserService $userService, ActivityService $activityService @@ -54,12 +67,24 @@ class UserController extends AbstractController $activityService ); + $total = $activityService->findActivitiesTotal( + $user->getEvents() + ); + return $this->render( 'default/user/dashboard.html.twig', [ 'activities' => $activityService->findLastActivities( - $user->getEvents() - ) + $user->getEvents(), + $this->getParameter('app.pagination'), + ($page - 1) * $this->getParameter('app.pagination') + ), + 'pagination' => + [ + 'page' => $page, + 'pages' => ceil($total / $this->getParameter('app.pagination')), + 'total' => $total + ] ] ); } @@ -181,18 +206,22 @@ class UserController extends AbstractController } #[Route( - '/{_locale}/profile/{userId}', + '/{_locale}/profile/{userId}/{page}', name: 'user_info', defaults: [ '_locale' => '%app.locale%', - 'userId' => null + 'userId' => 0, + 'page' => 1, ], requirements: [ '_locale' => '%app.locales%', - 'userId' => '\d+', + 'userId' => '\d+', + 'page' => '\d+', ], )] public function info( + int $userId, + int $page, Request $request, TranslatorInterface $translator, UserService $userService, @@ -216,12 +245,18 @@ class UserController extends AbstractController // Init target user if (!$userTarget = $userService->getUser( - $request->get('userId') ? $request->get('userId') : $user->getId() + $userId ? $userId : $user->getId() )) { throw $this->createNotFoundException(); } + // Get total activities + $total = $activityService->findActivitiesTotalByUserId( + $userTarget->getId(), + $user->getEvents() + ); + // Render template return $this->render( 'default/user/info.html.twig', @@ -260,6 +295,18 @@ class UserController extends AbstractController ) ], 'events' => $activityService->getEventsTree(), + 'activities' => $activityService->findLastActivitiesByUserId( + $userTarget->getId(), + $user->getEvents(), + $this->getParameter('app.pagination'), + ($page - 1) * $this->getParameter('app.pagination') + ), + 'pagination' => + [ + 'page' => $page, + 'pages' => ceil($total / $this->getParameter('app.pagination')), + 'total' => $total + ] ] ); } diff --git a/src/Repository/ActivityRepository.php b/src/Repository/ActivityRepository.php index 78d420e..f87aa83 100644 --- a/src/Repository/ActivityRepository.php +++ b/src/Repository/ActivityRepository.php @@ -20,4 +20,65 @@ class ActivityRepository extends ServiceEntityRepository { parent::__construct($registry, Activity::class); } + + public function findActivitiesTotal( + array $whitelist + ): int + { + return $this->createQueryBuilder('a') + ->select('count(a.id)') + ->where('a.event IN (:event)') + ->setParameter(':event', $whitelist) + ->getQuery() + ->getSingleScalarResult() + ; + } + + public function findActivitiesTotalByUserId( + int $userId, + array $whitelist + ): int + { + return $this->createQueryBuilder('a') + ->select('count(a.id)') + ->where('a.userId = :userId') + ->andWhere('a.event IN (:event)') + ->setParameter(':userId', $userId) + ->setParameter(':event', $whitelist) + ->getQuery() + ->getSingleScalarResult() + ; + } + + public function findActivitiesTotalByTorrentId( + int $torrentId, + array $whitelist + ): int + { + return $this->createQueryBuilder('a') + ->select('count(a.id)') + ->where('a.torrentId = :torrentId') + ->andWhere('a.event IN (:event)') + ->setParameter(':torrentId', $torrentId) + ->setParameter(':event', $whitelist) + ->getQuery() + ->getSingleScalarResult() + ; + } + + public function findActivitiesTotalByArticleId( + int $articleId, + array $whitelist + ): int + { + return $this->createQueryBuilder('a') + ->select('count(a.id)') + ->where('a.articleId = :articleId') + ->andWhere('a.event IN (:event)') + ->setParameter(':articleId', $articleId) + ->setParameter(':event', $whitelist) + ->getQuery() + ->getSingleScalarResult() + ; + } } diff --git a/src/Service/ActivityService.php b/src/Service/ActivityService.php index 029d28c..5ce2897 100644 --- a/src/Service/ActivityService.php +++ b/src/Service/ActivityService.php @@ -361,7 +361,9 @@ class ActivityService } public function findLastActivities( - array $whitelist + array $whitelist, + int $limit = 10, + int $offset = 0 ): array { return $this->entityManagerInterface @@ -372,13 +374,17 @@ class ActivityService ], [ 'id' => 'DESC' - ] + ], + $limit, + $offset ); } public function findLastActivitiesByUserId( int $userId, - array $whitelist + array $whitelist, + int $limit = 10, + int $offset = 0 ): array { return $this->entityManagerInterface @@ -386,11 +392,105 @@ class ActivityService ->findBy( [ 'userId' => $userId, - 'event' => $whitelist + 'event' => $whitelist, + ], + [ + 'id' => 'DESC' + ], + $limit, + $offset + ); + } + + public function findLastActivitiesByTorrentId( + int $torrentId, + array $whitelist, + int $limit = 10, + int $offset = 0 + ): array + { + return $this->entityManagerInterface + ->getRepository(Activity::class) + ->findBy( + [ + 'torrentId' => $torrentId, + 'event' => $whitelist, ], [ 'id' => 'DESC' - ] + ], + $limit, + $offset + ); + } + + public function findLastActivitiesByArticleId( + int $articleId, + array $whitelist, + int $limit = 10, + int $offset = 0 + ): array + { + return $this->entityManagerInterface + ->getRepository(Activity::class) + ->findBy( + [ + 'articleId' => $articleId, + 'event' => $whitelist, + ], + [ + 'id' => 'DESC' + ], + $limit, + $offset + ); + } + + public function findActivitiesTotal( + array $whitelist + ): int + { + return $this->entityManagerInterface + ->getRepository(Activity::class) + ->findActivitiesTotal($whitelist); + } + + public function findActivitiesTotalByUserId( + int $userId, + array $whitelist + ): int + { + return $this->entityManagerInterface + ->getRepository(Activity::class) + ->findActivitiesTotalByUserId( + $userId, + $whitelist + ); + } + + public function findActivitiesTotalByTorrentId( + int $torrentId, + array $whitelist + ): int + { + return $this->entityManagerInterface + ->getRepository(Activity::class) + ->findActivitiesTotalByTorrentId( + $torrentId, + $whitelist + ); + } + + public function findActivitiesTotalByArticleId( + int $articleId, + array $whitelist + ): int + { + return $this->entityManagerInterface + ->getRepository(Activity::class) + ->findActivitiesTotalByArticleId( + $articleId, + $whitelist ); } diff --git a/templates/default/torrent/info.html.twig b/templates/default/torrent/info.html.twig index 4c03127..d1a823e 100644 --- a/templates/default/torrent/info.html.twig +++ b/templates/default/torrent/info.html.twig @@ -20,7 +20,7 @@ {% endmacro %} {% from _self import recursive_file_tree %} {% extends 'default/layout.html.twig' %} -{% block title %}{{ 'Torrent' | trans }} #{{ torrent.id }} - {{ name }}{% endblock %} +{% block title %}{{ 'Torrent' | trans }} #{{ torrent.id }}{% if pagination.page > 1 %} - {{ 'Page' | trans }} {{ pagination.page }}{% endif %} - {{ name }}{% endblock %} {% block main_content %}
@@ -322,4 +322,50 @@
+ {% if activities %} + + {% for activity in activities %} +
+ {{ render(controller( + 'App\\Controller\\ActivityController::event', + { activity : activity } + )) }} +
+ {% endfor %} + {% if pagination.pages > 1 %} +
+
+   + {# @TODO + + + + + + #} +
+
+ {% if pagination.pages > 1 %} + {{ 'Page' | trans | lower }} {{ pagination.page }} / {{ pagination.pages }} + {% if pagination.page > 1 %} + {% if pagination.page == 2 %} + + {{ 'Back' | trans | lower }} + + {% else %} + + {{ 'Back' | trans | lower }} + + {% endif %} + {% endif %} + {% if pagination.page < pagination.pages %} + + {{ 'Next' | trans | lower }} + + {% endif %} + {% endif %} +
+
+ {% endif %} + {% endif %} {% endblock %} \ No newline at end of file diff --git a/templates/default/user/dashboard.html.twig b/templates/default/user/dashboard.html.twig index 655b728..2d93192 100644 --- a/templates/default/user/dashboard.html.twig +++ b/templates/default/user/dashboard.html.twig @@ -1,5 +1,5 @@ {% extends 'default/layout.html.twig' %} -{% block title %}{{ 'Activity' | trans }} - {{ name }}{% endblock %} +{% block title %}{{ 'Activity' | trans }}{% if pagination.page > 1 %} - {{ 'Page' | trans }} {{ pagination.page }}{% endif %} - {{ name }}{% endblock %} {% block main_content %} {% for activity in activities %}
@@ -9,4 +9,39 @@ )) }}
{% endfor %} + {% if pagination.pages > 1 %} +
+
+   + {# @TODO + + + + + + #} +
+
+ {% if pagination.pages > 1 %} + {{ 'Page' | trans | lower }} {{ pagination.page }} / {{ pagination.pages }} + {% if pagination.page > 1 %} + {% if pagination.page == 2 %} + + {{ 'Back' | trans | lower }} + + {% else %} + + {{ 'Back' | trans | lower }} + + {% endif %} + {% endif %} + {% if pagination.page < pagination.pages %} + + {{ 'Next' | trans | lower }} + + {% endif %} + {% endif %} +
+
+ {% endif %} {% endblock %} \ No newline at end of file diff --git a/templates/default/user/info.html.twig b/templates/default/user/info.html.twig index dc2c1fe..ffc9863 100644 --- a/templates/default/user/info.html.twig +++ b/templates/default/user/info.html.twig @@ -1,5 +1,5 @@ {% extends 'default/layout.html.twig' %} -{% block title %}{{ 'User'|trans }} #{{ user.id }} - {{ name }}{% endblock %} +{% block title %}{{ 'User'|trans }} #{{ user.id }}{% if pagination.page > 1 %} - {{ 'Page' | trans }} {{ pagination.page }}{% endif %} - {{ name }}{% endblock %} {% block main_content %}
@@ -219,12 +219,15 @@
{% if user.activities %} + + {#

{{ 'Last activity' | trans }}

RSS
+ #} {% for activity in user.activities %}
{{ render(controller( @@ -233,5 +236,40 @@ )) }}
{% endfor %} + {% if pagination.pages > 1 %} +
+
+   + {# @TODO + + + + + + #} +
+
+ {% if pagination.pages > 1 %} + {{ 'Page' | trans | lower }} {{ pagination.page }} / {{ pagination.pages }} + {% if pagination.page > 1 %} + {% if pagination.page == 2 %} + + {{ 'Back' | trans | lower }} + + {% else %} + + {{ 'Back' | trans | lower }} + + {% endif %} + {% endif %} + {% if pagination.page < pagination.pages %} + + {{ 'Next' | trans | lower }} + + {% endif %} + {% endif %} +
+
+ {% endif %} {% endif %} {% endblock %} \ No newline at end of file