Commit Graph

7070 Commits

Author SHA1 Message Date
Bowen
ae2d0d7fe8 feat(favicon): Use feed-provided icon URL (<image><url>, Atom icon/logo, JSON Feed icon) (#8633)
* prefer feed.icon
Closes #5518

Changes proposed in this pull request:

- When a feed provides an icon URL (<image><url> in RSS 2.0/1.0, <atom:icon>/<atom:logo> in Atom, icon/favicon fields in JSON Feed), that URL is stored as a feedIconUrl attribute on the feed and used as the primary source for favicon downloads, instead of scraping the feed's website for <link rel="icon"> tags.
- If the feed-provided icon URL fails to return a valid image, the existing fallback chain (website HTML favicon search → /favicon.ico) is preserved.
Custom favicons uploaded by users always take priority and are never overridden.

How to test the feature manually:

1. Add an RSS feed that includes a <image><url> element (e.g. an RSSHub feed: `https://rsshub.app/youtube/channel/UC2cRwTuSWxxEtrRnT4lrlQA`). After actualization, confirm the feed's favicon matches the avatar image from the feed, not the Bilibili site favicon.
2. Add an Atom feed containing <atom:icon> or <atom:logo> Confirm the feed icon is used.
3. Add a JSON Feed (spec: icon field). Confirm icon is preferred over favicon when both are present.
4. Temporarily point a feed's <image><url> to a broken URL. Confirm FreshRSS falls back to the website favicon silently.
5. Upload a custom favicon for a feed, then actualize it. Confirm the custom favicon is not replaced.

<img width="470" height="317" alt="image" src="https://github.com/user-attachments/assets/17445154-d94c-44d6-b7e7-019bf24c5767" />

* fix(favicon): use htmlspecialchars_decode for feed image URL

* Decode quotes as well

* New function in our SimplePie fork
https://github.com/FreshRSS/simplepie/pull/73

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-31 09:57:06 +02:00
Michael
61f3151f7f Convert feed view into grid where appropriate (#8631)
* Convert feed view into grid where appropriate
This makes the feed view prettier on mobile, if thumbnails and summary are shown, as discussed in https://github.com/FreshRSS/FreshRSS/discussions/8629

**Changes proposed in this pull request:**

- Converts Feed Item list into multiple lines
- But only if both thumbnails and summaries are shown

The code is quite different from what I had done in my own hack: There I had used `display: flex` and then counted items, but that only works for my own hack: here we don't know how many items a given user may have, so we use `display:grid` instead with name grid areas.

**How to test the feature manually:**

1. Ensure you enable both thumbnails and summaries
2. Check out the feed view on mobile
3. Play around with enabling and disabling bookmarks, share button, etc.

**Pull request checklist:**

- [x] clear commit messages
- [x] code manually tested
- [ ] unit tests written (optional if too hard)
- [ ] documentation updated

**Screenshots:**

<img width="458" height="1173" alt="SCR-20260324-jnte" src="https://github.com/user-attachments/assets/1d5c1615-961a-4953-8157-f9f8a5470545" />
<img width="459" height="1172" alt="SCR-20260324-jnwf" src="https://github.com/user-attachments/assets/96ffcea3-384f-4de9-9c50-3366022713d8" />


* remove gap

* fix lint errors

* fix style errors

* remove whitespaces

* Reduce use of slow `:has()` CSS selector

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-31 09:53:09 +02:00
zanivann
160c579737 Translate sorting criteria to Portuguese (#8649)
* Translate sorting criteria to Portuguese

* make fix-all

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-30 10:13:41 +02:00
Alexandre Alapetite
3171107628 Add legacy rules PHPCS 3 (#8645)
Some tools are not yet supporting PHPCS 4 such as:
https://github.com/valeryan/vscode-phpsab/issues/168
451cfdb306/README.md (L15-L17)
2026-03-29 18:35:37 +02:00
Alexandre Alapetite
eba59a8c7c Fix for PHPStan 2.1.44 (#8644)
https://github.com/phpstan/phpstan/releases/tag/2.1.44
2026-03-29 14:34:45 +02:00
Alexandre Alapetite
37c8f1f466 CSSXPath 1.5.0 (#8642)
https://github.com/phpgt/CssXPath/releases/tag/v1.5.0
2026-03-29 11:39:52 +02:00
Alexandre Alapetite
71c26f5512 Fix duplicates in the user labels when sorting randomly (#8626)
DISTINCT does not work in this case, so use GROUP BY instead
2026-03-28 13:06:36 +01:00
Alexandre Alapetite
72b72f8d28 Docker / CLI: allow chown/chmod to fail with warning (#8635)
Docker / CLI: allow chown/chmod to fail with warning
fix https://github.com/FreshRSS/FreshRSS/issues/8632
Seems needed for some NFS share
2026-03-27 13:56:21 +01:00
dependabot[bot]
45c156cf6b Bump picomatch (#8638)
Bumps  and [picomatch](https://github.com/micromatch/picomatch). These dependencies needed to be updated together.

Updates `picomatch` from 4.0.3 to 4.0.4
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)

Updates `picomatch` from 2.3.1 to 2.3.2
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 4.0.4
  dependency-type: indirect
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-25 23:06:30 +01:00
Alexandre Alapetite
04c750defd SimplePie: Fix Undefined array key "" in get_thumbnail() (#8634)
https://github.com/simplepie/simplepie/pull/970
https://github.com/FreshRSS/simplepie/pull/72
fix https://github.com/FreshRSS/FreshRSS/issues/8614

Solve warning in the case of `<media:thumbnail />`
2026-03-25 10:04:48 +01:00
Alexandre Alapetite
ed18aba733 SimplePie bump upstream (#8628)
https://github.com/FreshRSS/simplepie/pull/71
2026-03-24 08:36:53 +01:00
Alexandre Alapetite
1f614e5b46 Fixes for PHPStan 2.1.42 (#8627) 2026-03-24 08:27:41 +01:00
Inverle
ebaac787e0 Fix wrong error redirect in subscription management (#8625)
Was supposed to show feeds with errors on redirect, only if they were being shown before, not when you modify a feed with an error.
2026-03-23 11:29:57 +01:00
maTh
1ed2c38c3f do not show dot, if no unread number is shown (#8624)
* do not show dot, if no unread number is shown

* Update app/Controllers/indexController.php

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-21 23:01:55 +01:00
Alexandre Alapetite
25ee11fd66 Changelog 2026-03-21 17:32:55 +01:00
Alexandre Alapetite
1b90c40fd6 New automatic feed visibility/priority during search (#8609)
When the search query includes some feed IDs or category IDs, adjust feed visibility/priority filter to include at minimum feed or category visibility.
Fix: https://github.com/FreshRSS/FreshRSS/issues/8602
2026-03-21 17:15:07 +01:00
dependabot[bot]
b19060aa1f Bump flatted from 3.3.3 to 3.4.2 (#8621)
Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.3 to 3.4.2.
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.2)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-21 00:16:33 +01:00
Alexandre Alapetite
0257ba9051 Fix CSS padding of .content pre code (#8620)
fix https://github.com/FreshRSS/FreshRSS/discussions/8618
And also duplicated `.box .box-content .item.feed`
2026-03-20 23:04:20 +01:00
dependabot[bot]
94b2a66f7e Bump json in /docs in the bundler group across 1 directory (#8617)
Bumps the bundler group with 1 update in the /docs directory: [json](https://github.com/ruby/json).


Updates `json` from 2.18.1 to 2.19.2
- [Release notes](https://github.com/ruby/json/releases)
- [Changelog](https://github.com/ruby/json/blob/master/CHANGES.md)
- [Commits](https://github.com/ruby/json/compare/v2.18.1...v2.19.2)

---
updated-dependencies:
- dependency-name: json
  dependency-version: 2.19.2
  dependency-type: indirect
  dependency-group: bundler
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-19 14:25:12 +01:00
Inverle
815b97017b Improve consistency of slider behavior after submitting form (#8612)
Closes https://github.com/FreshRSS/FreshRSS/issues/8529

* Preserve `error` parameter after submitting form in subscription management
2026-03-18 00:10:53 +01:00
Alexandre Alapetite
aeb55693e4 SQL improve PHP syntax uniformity (#8604)
* New SQL wrapper function `fetchInt()`
* Favour use of `fetchAssoc()`, `fetchInt()`, `fetchColumn()`
* Favour Nowdoc / Heredoc syntax for SQL
    * Update indenting to PHP 8.1+ convention
* Favour `bindValue()` instead of position `?` when possible
* Favour `bindValue()` over `bindParam()`
* More uniform and robust syntax when using `bindValue()`, checking return code
2026-03-15 14:44:39 +01:00
Inverle
5ef8756e49 Update user modify date when changing UserJS/UserCSS (#8607)
UserCSS textarea wasn't being updated after changing the CSS until clearing cache
(while using Chromium with a normal browser window)
2026-03-15 13:52:57 +01:00
Inverle
a05546526d Fix wrong navigation buttons layout on Chromium (#8606)
* Fix wrong navigation buttons layout on Chromium

* Replace another `display: table`

* `justify-content` not needed

* Replace hardcoded width with `flex: 1`
2026-03-15 13:26:03 +01:00
Alexandre Alapetite
69c48df049 Fix keyset pagination when sorting by category name (#8597)
There was a typo with a `=` too much
2026-03-14 23:16:47 +01:00
Inverle
858bc0eace Follow-up #8599 switch fallthrough (#8603)
https://github.com/FreshRSS/FreshRSS/pull/8599
2026-03-14 22:58:48 +01:00
Inverle
033e73a446 Allow passing Minz_HookType as hook name in registerHook() (#8600)
* Allow passing `Minz_HookType` as hook name in `registerHook()`

* Add missing `Minz_HookType::EntriesFavorite` documentation

* More corrections

* PHPDoc sync with signature
2026-03-14 22:33:24 +01:00
Inverle
3bb16b0a53 Add new hook: Minz_HookType::ActionExecute (#8599)
* Add new hook: `Minz_HookType::ActionExecute`

* Move down `ActionExecute`
2026-03-14 18:20:57 +01:00
Alexandre Alapetite
36e1c59d8d More robust JS (#8595)
Avoid JS errors:
* Following an SQL / paging issue
* When using a limited view such as `&ajax=1`
2026-03-14 11:08:29 +01:00
Alexandre Alapetite
bae0919f28 Fix SQLite paging when sorting by article length (#8594)
In the case of SQLite, there was a PDO type problem resulting in paging when sorting by article length to be buggy.
The problem was located in `LENGTH(e.content) < ?`
Change to explicit typed binding.
2026-03-14 11:07:57 +01:00
Alexandre Alapetite
a7dfd3c34b Fix loading spin regression when no article (#8588)
Fix https://github.com/FreshRSS/FreshRSS/issues/8586
Regression from https://github.com/FreshRSS/FreshRSS/pull/8577
2026-03-12 13:27:12 +01:00
Kachelkaiser
e9199fcce9 German translation updates (#8557)
* German Translation updates

* Fix German translations in admin.php

* Fix capitalization in encoding support warning

* Update German translations in admin.php

* Fix capitalization in encoding support warning

* Update German Translation of conf.php

* Update German translations for feedback messages

* Update German translations in index.php

* Update German translations in install.php

* Update German translations in sub.php

* Fix German translations for email validation messages

* make fix-all

* Update ZIP extension message in German translation

* make fix-all

* Update app/i18n/de/conf.php

Co-authored-by: maTh <1645099+math-GH@users.noreply.github.com>

* Update app/i18n/de/admin.php

Co-authored-by: maTh <1645099+math-GH@users.noreply.github.com>

* Update app/i18n/de/conf.php

Co-authored-by: maTh <1645099+math-GH@users.noreply.github.com>

* Global replace of Twitter → X (Twitter)

* Also ignore Twitter in German

* Update sensitive parameter description in German

* Ungelesene Artikel

* fix typo

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: maTh <1645099+math-GH@users.noreply.github.com>
Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
2026-03-11 17:52:44 +01:00
Gabbi
ae041d8389 Update database title translation to Italian (#8566)
* Update database title translation to Italian

* Update app/i18n/it/install.php

* make fix-all

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-09 10:35:49 +01:00
Inverle
77372239b0 Fix email validation and allow error page for unverified email users (#8582)
Closes https://github.com/FreshRSS/FreshRSS/issues/8581

Regression caused by commit 26c1102567 (v1.28.1), `$username` variable was empty and changes that were made to the `FreshRSS_UserDAO::exists()` function revealed this issue.

Additionally users that have unverified emails can properly access error redirects now, so an infinite redirect loop doesn't happen.
2026-03-09 09:40:56 +01:00
Inverle
a4bcdf1a80 Create dynamic favicons from SVG instead of PNG canvas (#8577) 2026-03-08 10:46:38 +01:00
Alexandre Alapetite
2d437f99dd Changelog 2026-03-07 14:22:41 +01:00
Alexandre Alapetite
1c6c3deda2 Fix SQL IF NOT EXISTS for MySQL (#8576)
fix https://github.com/FreshRSS/FreshRSS/issues/8570
As opposed to MariaDB, MySQL still does not support `IF NOT EXISTS`...
* https://dev.mysql.com/doc/refman/9.6/en/alter-table.html
* https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-table
2026-03-07 13:27:55 +01:00
Daniel
366a5d0a15 i18n: complete Spanish translation (100%) (#8572)
* i18n: complete Spanish translation (100%)

* make fix-all

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-06 16:38:36 +01:00
Gabbi
ff8c269a3f Add Gabriele Biggio to CREDITS.md (#8568)
Changes proposed in this pull request:
- Added my user to CREDITS.md for Italian translations to this great project!
2026-03-04 15:59:01 +01:00
Gabbi
cf625bcf1c Translate 'Server Modification Date' to Italian (#8555)
* Translate 'Server Modification Date' to Italian

* Update Italian translation for date_modified

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-03 16:41:20 +01:00
Gabbi
989910f8e0 Translate database connection messages to Italian (#8554)
* Translate database connection messages to Italian

Added missing Italian translations to FreshRSS/app/i18n/it/install.php

* make fix-all

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-03 15:42:20 +01:00
Gabbi
1dba465fbb Translate sidebar hidden message to Italian (#8556) 2026-03-03 15:25:12 +01:00
Inverle
4a2c93c9e7 Fix redirect to wrong view after mark as read (#8552)
fix https://github.com/FreshRSS/FreshRSS/issues/6509
A wrong redirect (to normal view) happened in case of both the big mark as read button on the bottom and the navbar 
one, for reader and global views.
2026-03-02 21:45:38 +01:00
rid3r45
3e4d5bb041 Add option to hide sidebar by default (#8515) (#8528)
* Add option to hide sidebar by default (#8515)

Closes https://github.com/FreshRSS/FreshRSS/issues/8515

Changes proposed in this pull request:

- Add `sidebar_hidden_by_default` user preference (default: `false`)
- Add a checkbox in the Display settings page to toggle this preference
- Hide the sidebar on page load in `normal` and `reader` views when the preference is enabled and no session state exists
- Add English translation key; mark all other languages as `TODO` for translators

How to test the feature manually:

1. Go to Settings → Display, tick "Hide sidebar by default", save
2. Go back to the main view (normal or reader): the sidebar should be hidden on load
3. Toggle the sidebar manually — it should open/stay open for the rest of the session
4. Open a new tab: the sidebar should be hidden again
5. Go to Settings → Display, untick the option, save: the sidebar should now be visible on load as usual
6. Check that the sidebar is always visible on Settings pages regardless of the preference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: PR comment

* Update app/i18n/pl/conf.php

* i18n: fr

* make fix-all

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Inverle <inverle@proton.me>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-02 13:32:10 +01:00
Christian Weiske
e29459f010 Add cweiske to credits file (#8550)
See https://github.com/FreshRSS/FreshRSS/pull/8510#issuecomment-3983883790
2026-03-02 13:17:18 +01:00
Christian Weiske
560b772e43 Re-add database status in installation check (#8510)
* Re-add database status in installation check

It got disabled in 2014 to get a beta out.
Time to re-enable it.

Tested on SQLite.

"checkTable" now only verifies that at least the expected columns
exist, but does not fail on additional columns provided by
e.g. extensions.

Related: https://github.com/FreshRSS/FreshRSS/issues/678

* make fix-all

* i18n

* Simpler and more correct content_bin

* Fix PostgreSQL

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-02 12:43:35 +01:00
Inverle
63c8fe1285 docs: Fix broken or dead links (#8548)
* docs: Fix broken or dead links
Used the following commands to find broken links:
1. `lychee -E --dump https://freshrss.github.io/FreshRSS/en/ --include freshrss.github.io --output links.txt`
2. `lychee -v --suggest --archive wayback --timeout 5 -u "Mozilla/5.0 (X11; Linux x86_64; rv:148.0) Gecko/20100101 Firefox/148.0" --files-from links.txt --output output.txt`
3. `cat output.txt`

Then did the same for https://freshrss.github.io/FreshRSS/fr/

We could look into using lychee in CI:
https://github.com/lycheeverse/lychee?tab=readme-ov-file#github-action-usage

* Replace PostgreSQL 16 link with current version

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

* Remove paragraph about bug message format

* Update README with official app website links

* Replace broken French images with English versions

* Fix broken Fever API docs link in French docs

* Replace GNU Social link with new one in `shares.php`

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-03-02 08:21:23 +01:00
Alexandre Alapetite
b68b80e5de Fix user query parsing (#8543)
* Fix user query parsing
Fix https://github.com/FreshRSS/FreshRSS/issues/8531
We used to take some shortcuts in the code, but now that the logic has complexified, we need to parse those user queries more properly.

* More fixes
2026-03-01 21:45:24 +01:00
Alexandre Alapetite
cf631b6f87 Implement filter on last modified date by server (#8131)
* Implement filter on last modified date by server
Especially relevant for API, to get the modified changes: the API will now return the articles that are new or which content has been modified since `ot`:

fix https://github.com/FreshRSS/FreshRSS/issues/7304
fix https://github.com/FreshRSS/FreshRSS/issues/2566
https://github.com/jocmp/capyreader/discussions/533#discussioncomment-11341808

New corresponding search operator `mdate:` and new UI:

<img width="650" height="627" alt="image" src="https://github.com/user-attachments/assets/8ba02937-abc7-44bf-b718-cf269cc37caf" />

* Migration from existing id column

* Fix auto-update

* Index after update for performance

* Minor comment

* Minor whitespace

* Fix regex

* Minor .gitignore

* Changelog and warning

* Update app/i18n/pl/gen.php

Co-authored-by: Inverle <inverle@proton.me>

* make fix-all

* Optimise SQL auto-update
For speed and resilience

* Minor SQLite change of sequence

* Changelog

* Speed optimisation: No DEFAULT 0

* Better migration

* Revert small bug

* Prepare filtering on multiple dates for API

* make fix-all

* Update tests

* Remaining manual merge

* Update versions

* Remove warnings no longer relevant in changelog

* Implement in API, and COALESCE

* No lastModified when adding new article

* Rework logic

* Sort IS NOT NULL

* Remove forgotten lastModified

---------

Co-authored-by: Inverle <inverle@proton.me>
2026-03-01 21:43:03 +01:00
Inverle
9f0a8deb6f Only display scrollbar everywhere if there's an overflow (#8542)
Replaces all instances of `overflow-{x,y}: scroll` with `overflow-{x,y}: auto`

Empty scrollbars may appear due to usage of `scroll` instead of `auto` on Chromium, even when there is no overflow. As far as I know this does not happen with Firefox.

<img width="1461" height="405" alt="2026-03-01_14-29" src="https://github.com/user-attachments/assets/0a246823-8ea5-4d50-a1e8-aac33e73df0e" />
<img width="753" height="806" alt="2026-03-01_14-30" src="https://github.com/user-attachments/assets/631b06a5-5008-4ede-a216-bccac4898f85" />
2026-03-01 21:25:16 +01:00
Inverle
b98aa6b00c Improve pagination styling in logs page (#8541)
Before:

<img width="819" height="82" alt="2026-03-01_13-47" src="https://github.com/user-attachments/assets/96262bd2-25de-42b2-a19a-275b81f300cb" />

After:

<img width="842" height="77" alt="2026-03-01_13-48" src="https://github.com/user-attachments/assets/895f2db8-74ef-4aa6-ade4-b8b0794fc287" />

---


* Made button text actually centered
* Removed italic font
* Added `overflow-x: auto` so page doesn't overflow if there's too many pagination buttons displayed on a small screen
2026-03-01 21:08:41 +01:00