From f83a22d8cde1e02741a8721fb8b72501ab37ffa4 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 25 Mar 2024 15:13:22 +0100 Subject: [PATCH] imp: Group news and read links by dates --- locales/fr_FR/LC_MESSAGES/main.mo | Bin 57923 -> 57959 bytes locales/fr_FR/LC_MESSAGES/main.po | 46 +++++++++++---------- src/controllers/News.php | 8 +++- src/controllers/Read.php | 19 +++++---- src/utils/LinksTimeline.php | 52 ++++++++++++++++++++++++ src/utils/LinksTimeline/DateGroup.php | 28 +++++++++++++ src/views/news/index.phtml | 48 ++++++++++++++-------- src/views/read/index.phtml | 50 ++++++++++++++--------- tests/utils/LinksTimelineTest.php | 55 ++++++++++++++++++++++++++ 9 files changed, 240 insertions(+), 66 deletions(-) create mode 100644 src/utils/LinksTimeline.php create mode 100644 src/utils/LinksTimeline/DateGroup.php create mode 100644 tests/utils/LinksTimelineTest.php diff --git a/locales/fr_FR/LC_MESSAGES/main.mo b/locales/fr_FR/LC_MESSAGES/main.mo index 04afd8ff08b357aee84bf47f5e27c7716c22abda..6465f6759c5dd816ba3f93faf8a77c235249b8f2 100644 GIT binary patch delta 10435 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 delta 10417 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 RcEJnwgMAqr&+VHY`TxIQ1+oAD diff --git a/locales/fr_FR/LC_MESSAGES/main.po b/locales/fr_FR/LC_MESSAGES/main.po index 51df75ca..44d9f317 100644 --- a/locales/fr_FR/LC_MESSAGES/main.po +++ b/locales/fr_FR/LC_MESSAGES/main.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: flusio\n" -"POT-Creation-Date: 2024-03-24 20:14+0100\n" -"PO-Revision-Date: 2024-03-24 20:14+0100\n" +"POT-Creation-Date: 2024-03-25 15:13+0100\n" +"PO-Revision-Date: 2024-03-25 15:13+0100\n" "Last-Translator: Marien Fressinaud \n" "Language-Team: \n" "Language: fr_FR\n" @@ -50,7 +50,7 @@ msgstr "Afficher" #: controllers/Feeds.php:107 controllers/Groups.php:90 #: controllers/Links.php:270 controllers/Links.php:442 #: controllers/Mastodon.php:211 controllers/Mastodon.php:297 -#: controllers/News.php:75 controllers/Passwords.php:89 +#: controllers/News.php:79 controllers/Passwords.php:89 #: controllers/Passwords.php:192 controllers/Registrations.php:103 #: controllers/Sessions.php:85 controllers/Support.php:70 #: controllers/collections/Filters.php:105 @@ -455,20 +455,20 @@ msgstr "plateforme inconnue" msgid "%s on %s" msgstr "%s sur %s" -#: utils/view_helpers.php:102 +#: utils/view_helpers.php:81 msgid "< 1 min" msgstr "< 1 min" -#: utils/view_helpers.php:104 +#: utils/view_helpers.php:83 #, php-format msgid "%s min" msgstr "%s min" -#: utils/view_helpers.php:222 +#: utils/view_helpers.php:201 msgid "There are no relevant links to suggest at this time." msgstr "Il n'y a aucun lien pertinent à vous proposer pour le moment." -#: utils/view_helpers.php:224 +#: utils/view_helpers.php:203 #, php-format msgid "" "You can add links to your bookmarks to read them later." @@ -476,7 +476,7 @@ msgstr "" "Vous pouvez placer des liens dans vos signets pour les " "lire plus tard." -#: utils/view_helpers.php:254 views/links/show.phtml:73 +#: utils/view_helpers.php:233 views/links/show.phtml:73 msgid "you" msgstr "vous" @@ -1143,7 +1143,7 @@ msgstr "Régler pour le journal" msgid "Copy the link" msgstr "Copier le lien" -#: views/collections/show_public.phtml:165 views/news/index.phtml:52 +#: views/collections/show_public.phtml:165 views/news/index.phtml:68 msgid "Mark all as read" msgstr "Tout marquer comme lu" @@ -2110,15 +2110,19 @@ msgstr "Toujours rien ? Avez-vous vérifié votre spam ?" msgid "Didn’t receive the email? Resend it" msgstr "Courriel non reçu ? Renvoyer" -#: views/news/index.phtml:41 +#: views/news/index.phtml:21 views/read/index.phtml:38 +msgid "Today" +msgstr "Aujourd’hui" + +#: views/news/index.phtml:57 msgid "Empty the news" msgstr "Vider le journal" -#: views/news/index.phtml:62 +#: views/news/index.phtml:78 msgid "Read the links later" msgstr "Lire les liens plus tard" -#: views/news/index.phtml:71 +#: views/news/index.phtml:87 msgid "" "You’ll remove all the news links, this action cannot be canceled. Are you " "sure?" @@ -2126,41 +2130,41 @@ msgstr "" "Vous allez retirer tous les liens du journal, cette action ne peut pas être " "annulée. Confirmez-vous ?" -#: views/news/index.phtml:79 +#: views/news/index.phtml:95 msgid "Never see the links again" msgstr "Ne plus revoir les liens" -#: views/news/index.phtml:87 +#: views/news/index.phtml:103 msgid "" "Fill your news feed with the content published by the feeds that you follow." msgstr "" "Remplissez votre journal avec le contenu publié par les flux que vous suivez." -#: views/news/index.phtml:101 +#: views/news/index.phtml:117 msgid "Refresh the news" msgstr "Rafraichir le journal" -#: views/news/index.phtml:106 +#: views/news/index.phtml:122 msgid "Fill the news with…" msgstr "Remplissez votre journal avec…" -#: views/news/index.phtml:129 +#: views/news/index.phtml:145 msgid "the latest publications" msgstr "les dernières publications" -#: views/news/index.phtml:130 +#: views/news/index.phtml:146 msgid "from your followed feeds" msgstr "depuis vos flux suivis" -#: views/news/index.phtml:145 +#: views/news/index.phtml:161 msgid "3 links of -10 minutes" msgstr "3 liens de -10 minutes" -#: views/news/index.phtml:146 views/news/index.phtml:162 +#: views/news/index.phtml:162 views/news/index.phtml:178 msgid "from your bookmarks" msgstr "depuis vos signets" -#: views/news/index.phtml:161 +#: views/news/index.phtml:177 msgid "1 link of +10 minutes" msgstr "1 lien de +10 minutes" diff --git a/src/controllers/News.php b/src/controllers/News.php index 4ea68765..ca4ce0c2 100644 --- a/src/controllers/News.php +++ b/src/controllers/News.php @@ -7,6 +7,7 @@ use flusio\auth; use flusio\models; use flusio\services; +use flusio\utils; /** * Handle the requests related to the news. @@ -33,9 +34,12 @@ public function index(): Response } $news = $user->news(); + $links = $news->links(['published_at', 'number_comments']); + $links_timeline = new utils\LinksTimeline($links); + return Response::ok('news/index.phtml', [ 'news' => $news, - 'links' => $news->links(['published_at', 'number_comments']), + 'links_timeline' => $links_timeline, 'no_news' => \Minz\Flash::pop('no_news'), ]); } @@ -70,7 +74,7 @@ public function create(Request $request): Response if (!\Minz\Csrf::validate($csrf)) { return Response::badRequest('news/index.phtml', [ 'news' => $news, - 'links' => [], + 'links_timeline' => new utils\LinksTimeline([]), 'no_news' => false, 'error' => _('A security verification failed: you should retry to submit the form.'), ]); diff --git a/src/controllers/Read.php b/src/controllers/Read.php index 2432e534..2d0c581d 100644 --- a/src/controllers/Read.php +++ b/src/controllers/Read.php @@ -45,16 +45,19 @@ public function index(Request $request): Response ]); } + $links = $read_list->links( + ['published_at', 'number_comments'], + [ + 'offset' => $pagination->currentOffset(), + 'limit' => $pagination->numberPerPage(), + 'context_user_id' => $user->id, + ] + ); + $links_timeline = new utils\LinksTimeline($links); + return Response::ok('read/index.phtml', [ 'collection' => $read_list, - 'links' => $read_list->links( - ['published_at', 'number_comments'], - [ - 'offset' => $pagination->currentOffset(), - 'limit' => $pagination->numberPerPage(), - 'context_user_id' => $user->id, - ] - ), + 'links_timeline' => $links_timeline, 'pagination' => $pagination, ]); } diff --git a/src/utils/LinksTimeline.php b/src/utils/LinksTimeline.php new file mode 100644 index 00000000..063f10f0 --- /dev/null +++ b/src/utils/LinksTimeline.php @@ -0,0 +1,52 @@ + + * @license http://www.gnu.org/licenses/agpl-3.0.en.html AGPL + */ +class LinksTimeline +{ + /** @var array */ + private array $dates_groups = []; + + /** + * @param models\Link[] $links + */ + public function __construct(array $links) + { + foreach ($links as $link) { + if (!$link->published_at) { + continue; + } + + $date_key = $link->published_at->format('Y-m-d'); + if (isset($this->dates_groups[$date_key])) { + $date_group = $this->dates_groups[$date_key]; + } else { + $date_group = new LinksTimeline\DateGroup($link->published_at); + $this->dates_groups[$date_key] = $date_group; + } + + $date_group->links[] = $link; + } + } + + /** + * @return array + */ + public function datesGroups(): array + { + return $this->dates_groups; + } + + public function empty(): bool + { + return empty($this->dates_groups); + } +} diff --git a/src/utils/LinksTimeline/DateGroup.php b/src/utils/LinksTimeline/DateGroup.php new file mode 100644 index 00000000..727dc8d5 --- /dev/null +++ b/src/utils/LinksTimeline/DateGroup.php @@ -0,0 +1,28 @@ + + * @license http://www.gnu.org/licenses/agpl-3.0.en.html AGPL + */ +class DateGroup +{ + public \DateTimeImmutable $date; + + /** @var models\Link[] */ + public array $links = []; + + public function __construct(\DateTimeImmutable $date) + { + $this->date = $date; + } + + public function isToday(): bool + { + $today = \Minz\Time::now(); + return $this->date->format('Y-m-d') === $today->format('Y-m-d'); + } +} diff --git a/src/views/news/index.phtml b/src/views/news/index.phtml index 18263d0a..900d30eb 100644 --- a/src/views/news/index.phtml +++ b/src/views/news/index.phtml @@ -12,22 +12,38 @@

- -
- - include('links/_link.phtml', [ - 'link' => $link, - 'from' => \Minz\Url::for('news'), - 'display_edit' => true, - 'display_repair' => true, - 'display_via' => true, - 'display_read_later' => true, - 'display_mark_as_read' => true, - 'display_never' => true, - 'storing_must_mark_as_read' => true, - ]); ?> - -
+empty()): ?> + datesGroups() as $date_group): ?> +
+
+

+ isToday()): ?> + ⋅ + + + date, 'dd MMMM') ?> +

+ +
+
+ +
+ links as $link): ?> + include('links/_link.phtml', [ + 'link' => $link, + 'from' => \Minz\Url::for('news'), + 'display_edit' => true, + 'display_repair' => true, + 'display_via' => true, + 'display_read_later' => true, + 'display_mark_as_read' => true, + 'display_never' => true, + 'storing_must_mark_as_read' => true, + ]); ?> + +
+
+
-
- - include('links/_link.phtml', [ - 'link' => $link, - 'from' => \Minz\Url::for('read list', $current_url_params), - 'display_via' => $link->via_type !== 'bookmarks', - 'display_comments' => true, - 'display_edit' => true, - 'display_repair' => true, - 'display_delete' => true, - 'display_read_later' => 'auto', - 'display_mark_as_unread' => true, - ]); ?> - - - -
- -
+datesGroups() as $date_group): ?> +
+
+

+ isToday()): ?> + ⋅ + + + date, 'dd MMMM') ?> +

+ +
+
+ +
+ links as $link): ?> + include('links/_link.phtml', [ + 'link' => $link, + 'from' => \Minz\Url::for('read list', $current_url_params), + 'display_via' => $link->via_type !== 'bookmarks', + 'display_comments' => true, + 'display_edit' => true, + 'display_repair' => true, + 'display_delete' => true, + 'display_read_later' => 'auto', + 'display_mark_as_unread' => true, + ]); ?> + +
+
+ include('_pagination.phtml', ['pagination' => $pagination, 'url' => url('read list')]) ?> diff --git a/tests/utils/LinksTimelineTest.php b/tests/utils/LinksTimelineTest.php new file mode 100644 index 00000000..28faf348 --- /dev/null +++ b/tests/utils/LinksTimelineTest.php @@ -0,0 +1,55 @@ +published_at = new \DateTimeImmutable('2024-03-20 18:00'); + $link2 = LinkFactory::create(); + $link2->published_at = new \DateTimeImmutable('2024-03-22 12:00'); + $link3 = LinkFactory::create(); + $link3->published_at = new \DateTimeImmutable('2024-03-20 12:00'); + $links = [$link1, $link2, $link3]; + + $timeline = new LinksTimeline($links); + + $this->assertFalse($timeline->empty()); + $dates_groups = $timeline->datesGroups(); + $this->assertSame(2, count($dates_groups)); + $group1 = $dates_groups['2024-03-20']; + $group2 = $dates_groups['2024-03-22']; + $this->assertEquals($link1->published_at, $group1->date); + $this->assertSame(2, count($group1->links)); + $this->assertSame($link1->id, $group1->links[0]->id); + $this->assertSame($link3->id, $group1->links[1]->id); + $this->assertEquals($link2->published_at, $group2->date); + $this->assertSame(1, count($group2->links)); + $this->assertSame($link2->id, $group2->links[0]->id); + } + + public function testEmptyReturnsTrue(): void + { + $links = []; + + $timeline = new LinksTimeline($links); + + $this->assertTrue($timeline->empty()); + } + + public function testConstructIgnoresLinksWithoutPublishedAt(): void + { + $link = LinkFactory::create(); + $links = [$link]; + + $timeline = new LinksTimeline($links); + + $this->assertTrue($timeline->empty()); + } +}