diff options
| author | 2025-12-13 11:38:33 +0100 | |
|---|---|---|
| committer | 2025-12-13 11:38:33 +0100 | |
| commit | 4b6127ee04229ac64d74076933e800601df884c0 (patch) | |
| tree | 1e2d61e2881bf6d1c2377ea0c9f6979b10166279 | |
| parent | a8a544a2a205b42d2009b5c52d8939e8bc36263c (diff) | |
New links in transitions and jump to next transition (#8294)
Easier to explain graphically:
<img width="408" height="266" alt="image" src="https://github.com/user-attachments/assets/0e3724a1-155b-4a87-89b3-cfe8a18cb100" />
The jump to next section ⏭ works when the sorting criterion is a date.
Need https://github.com/FreshRSS/FreshRSS/pull/8293
| -rw-r--r-- | app/Controllers/indexController.php | 37 | ||||
| -rw-r--r-- | app/views/index/normal.phtml | 7 | ||||
| -rw-r--r-- | lib/Minz/Request.php | 1 | ||||
| -rw-r--r-- | p/themes/base-theme/frss.css | 9 | ||||
| -rw-r--r-- | p/themes/base-theme/frss.rtl.css | 9 |
5 files changed, 58 insertions, 5 deletions
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 3961a3fcd..c51dd6662 100644 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -52,10 +52,9 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { /** * Content for displaying a transition between entries when sorting by specific criteria. - * @param 'id'|'c.name'|'date'|'f.name'|'link'|'title'|'rand'|'lastUserModified'|'length' $sort */ - public static function transition(FreshRSS_Entry $entry, string $sort): string { - return match ($sort) { + public static function transition(FreshRSS_Entry $entry): string { + return match (FreshRSS_Context::$sort) { 'id' => _t('index.feed.received' . self::dayRelative($entry->dateAdded(raw: true), mayBeFuture: false)) . ' — ' . timestamptodate($entry->dateAdded(raw: true), hour: false), 'date' => _t('index.feed.published' . self::dayRelative($entry->date(raw: true), mayBeFuture: true)) . @@ -69,6 +68,38 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { } /** + * Produce a hyperlink to the next transition of entries. + */ + public static function transitionLink(FreshRSS_Entry $entry, int $offset = 0): string { + if (in_array(FreshRSS_Context::$sort, ['c.name', 'f.name'], true)) { + return Minz_Url::display(Minz_Request::modifiedCurrentRequest([ + 'get' => match (FreshRSS_Context::$sort) { + 'c.name' => 'c_' . ($entry->feed()?->category()?->id() ?? '0'), + 'f.name' => 'f_' . ($entry->feed()?->id() ?? '0'), + }, + ])); + } + $operator = match (FreshRSS_Context::$sort) { + 'id' => 'date', + 'date' => 'pubdate', + 'lastUserModified' => 'userdate', + default => throw new InvalidArgumentException('Unsupported sort criterion for transition: ' . FreshRSS_Context::$sort), + }; + $offset = FreshRSS_Context::$order === 'ASC' ? $offset : -$offset; + $timestamp = match (FreshRSS_Context::$sort) { + 'id' => $entry->dateAdded(raw: true), + 'date' => $entry->date(raw: true), + 'lastUserModified' => $entry->lastUserModified(), + default => throw new InvalidArgumentException('Unsupported sort criterion for transition: ' . FreshRSS_Context::$sort), + }; + $searchString = $operator . ':' . ($offset < 0 ? '/' : '') . date('Y-m-d', $timestamp + ($offset * 86400)) . ($offset > 0 ? '/' : ''); + return Minz_Url::display(Minz_Request::modifiedCurrentRequest([ + 'search' => FreshRSS_Context::$search->getRawInput() === '' ? $searchString : + FreshRSS_Context::$search->enforce(new FreshRSS_Search($searchString))->__toString(), + ])); + } + + /** * This action displays the normal view of FreshRSS. */ public function normalAction(): void { diff --git a/app/views/index/normal.phtml b/app/views/index/normal.phtml index 2eb512f2e..dd15f9b0e 100644 --- a/app/views/index/normal.phtml +++ b/app/views/index/normal.phtml @@ -59,14 +59,17 @@ $today = @strtotime('today'); $this->entry->feed() ?? FreshRSS_Feed::default(); $this->entry->_feed($this->feed); - if ($last_transition !== ($transition = FreshRSS_index_Controller::transition($this->entry, FreshRSS_Context::$sort))) { + if ($last_transition !== ($transition = FreshRSS_index_Controller::transition($this->entry))) { $last_transition = $transition; ?><div class="transition"> <span class="transition-value"> <?php if (FreshRSS_Context::$sort === 'f.name' && FreshRSS_Context::userConf()->show_favicons): ?> <img class="favicon" src="<?= $this->feed->favicon() ?>" alt="✇" loading="lazy" /> <?php endif;?> - <?= $transition ?> + <a href="<?= FreshRSS_index_Controller::transitionLink($this->entry) ?>"><?= $transition ?></a> + <?php if (in_array(FreshRSS_Context::$sort, ['id', 'date', 'lastUserModified'], true)): ?> + <a class="transition-next" href="<?= FreshRSS_index_Controller::transitionLink($this->entry, offset: 1) ?>">⏭</a> + <?php endif; ?> </span> <span class="name"><?= FreshRSS_Context::$name ?></span> </div><?php diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 0e8dc28d0..8667c6442 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -214,6 +214,7 @@ class Minz_Request { if (null !== $extraParams) { $currentRequest['params'] = array_merge($currentRequest['params'], $extraParams); } + unset($currentRequest['params']['rid']); return $currentRequest; } diff --git a/p/themes/base-theme/frss.css b/p/themes/base-theme/frss.css index 9d27c936b..b02ba9305 100644 --- a/p/themes/base-theme/frss.css +++ b/p/themes/base-theme/frss.css @@ -1418,6 +1418,10 @@ input[type="search"] { background: inherit; } +.transition a, .transition a:hover { + color: inherit; +} + .transition .name { position: absolute; right: 0; @@ -1427,6 +1431,11 @@ input[type="search"] { text-overflow: ellipsis; } +.transition-next { + margin-left: .5em; + opacity: 0.5; +} + /*=== Feed article header and footer */ .flux_header { background: inherit; diff --git a/p/themes/base-theme/frss.rtl.css b/p/themes/base-theme/frss.rtl.css index 8a4d4da37..2a386588c 100644 --- a/p/themes/base-theme/frss.rtl.css +++ b/p/themes/base-theme/frss.rtl.css @@ -1418,6 +1418,10 @@ input[type="search"] { background: inherit; } +.transition a, .transition a:hover { + color: inherit; +} + .transition .name { position: absolute; left: 0; @@ -1427,6 +1431,11 @@ input[type="search"] { text-overflow: ellipsis; } +.transition-next { + margin-right: .5em; + opacity: 0.5; +} + /*=== Feed article header and footer */ .flux_header { background: inherit; |
