530 Commits
Author SHA1 Message Date
Inverle b182fb94e8 Fix desync between favicon and title unread counters (#9262)
Closes #8237
Regression from https://github.com/FreshRSS/FreshRSS/commit/80e7e15e3f619408db1752a3899ff708bc7bcc93, https://github.com/FreshRSS/FreshRSS/commit/d289c5340f3b21f1561e57390e89b0b5c7881d17

The function for updating the favicon count would only get called if there were articles newly marked as unread, so if there were only articles newly marked as read, the separate counters would display different values.

Behavior is now the same as for updating the title - always updating the favicon counter, without requiring any conditions to be true.
2026-09-06 21:35:15 +02:00
Inverle 0a44b7d017 Follow-up #9169 remove form IDs everywhere (#9205)
* Follow-up #9169 remove form IDs everywhere

* Add some `<form name>` alongside `class`
2026-08-29 23:21:39 +02:00
InverleandAlexandre Alapetite a84c0a8bc2 Fix all broken links in the entire repository (#9207)
* Fix all broken links in the entire repository

* Update docs/CHANGELOG-old2.md

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

* Update config.default.php

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

* Update README.md

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

* Update docs/i18n/freshrss.fr.po

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

* Update docs/i18n/templates/freshrss.pot

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

* Update README.md

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

* Update docs/fr/users/01_Installation.md

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

* Update docs/fr/users/01_Installation.md

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

* Update docs/en/internationalization.md

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

* Manual fixes, preferences
* Prefer canonical when known, prefer shorter, prefer roots, prefer URLs with content negotation (e.g. language preference)
* Keep 302, 307 unchanged
* Use only `.example`, `example.net` or similarly reserved domains for URL examples

* Fix language negotiation for developer.mozilla.org

* Restore a Stackoverflow 302

* Fix some example.com

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-08-19 16:19:21 +02:00
Inverle 48ece4200f Improve aside keyboard navigation (#9202)
* Allow jumping from category to feed with keyboard shortcuts

* It's now possible to jump from categories to feeds (press shift+j when focused on a category)
   * Similarly, it's possible to jump from a feed to the current category by using alt+k
* If the very first feed is focused and the user presses shift+k, there is no jump to the last unread feed in that category anymore, instead nothing happens.
   * Same if the very last is focused and the user presses shift+j (no jump to the first unread feed in that category)
* Alt+home/end (first/last category) now jumps regardless if the first/last category is read or unread
   * In addition, shift+home/end does not jump between unread feeds anymore, now it jumps between the first visible feed in the category and the last visible feed in the category 
* Alt+h (jump to next unread category) now fall backs to the same behavior as alt+j (jump to next category) if there are no more unread categories after

* Remove dead `jump_to_unread` code in `prev_feed`

* Jump to first/last categories even if they're not unread

* Ensure jump is only to visible items

* Focus current category if jumping from feed

* `delayedClick(null)` will now throw an error
2026-08-17 20:41:26 +02:00
24039afb10 Remove stale dynamic favicon links (#9127)
* Remove stale dynamic favicon links

- remove every previous dynamic favicon link before appending the updated unread-count icon
- prevent stale duplicate favicon links from being preferred by browsers

Fixes #8237.

* Replace dynamic favicon in place

---------

Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
Co-authored-by: Inverle <inverle@proton.me>
2026-08-15 00:08:07 +02:00
Inverle 1146d05bdd Allow modifiers for open website shortcut (#9186)
Minimal changes borrowed from https://github.com/FreshRSS/FreshRSS/pull/8990

Allows usage of <kbd>Ctrl/Shift</kbd> keys with the open website shortcut, so that you can open an article either in a new background tab or a new window.

Doesn't work in Chromium browsers, the website opens normally in a new tab there instead. (Firefox only)
2026-08-09 20:58:40 +02:00
Alexandre Alapetite cb482dd836 Bump globals and @eslint/js (#9181)
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/9178
2026-08-07 10:27:15 +02:00
Alexandre Alapetite 324c1e3978 Bump neostandard and blocked eslint (#9178)
https://github.com/neostandard/neostandard/issues/350
https://github.com/neostandard/neostandard/releases/tag/v0.14.0-next

Replaces https://github.com/FreshRSS/FreshRSS/pull/8751
2026-08-07 09:41:22 +02:00
Inverle 0cf8815de1 Fix HTML injection via decoded website attribute in feed menu (#9170)
To reproduce:
1. Add a feed e.g. `https://github.com/FreshRSS/FreshRSS/releases.atom`
2. Change its website URL to `https://github.com/FreshRSS/FreshRSS/releases.atom?"><marquee>test</marquee><?x`
3. Open the feed's menu from the sidebar after saving the settings

Follow-up of https://github.com/FreshRSS/FreshRSS/pull/9146 (same issue but in a different menu)
2026-08-03 00:02:04 +02:00
Gerard Alvear Porras 2a42d79cda Fix sharing menu conflicts with extensions (#9074)
Detect only the share menu that belongs directly to the share dropdown.
An extension can add an unrelated nested `.dropdown-menu`. The previous descendant selector then skipped share-menu creation, leaving share URL placeholders unreplaced.
Fixes #7820.
Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
2026-07-30 12:22:51 +02:00
Alexandre Alapetite 1b7178a18b Security: apply encodeURIComponent to share template (#9146)
For instance if an article title is `<title>XSS &quot;&gt;&lt;img src=x&gt; END</title>`

Reported by @meifukun
2026-07-28 11:47:07 +02:00
1460e75730 Fix auto-share shortcut on first use (#9072)
* Fix auto-share shortcut on first use


- Re-read the share actions after creating the lazy-loaded share menu.
- Restore the documented one-key share behavior when exactly one action is configured.

## Why

The shortcut checked the action count before it built the menu. On first use it therefore found no action and required a second press.

Fixes #7299.

* Slight variable scope adjustment

---------

Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-24 19:17:14 +02:00
46f5e13019 Refresh only feeds in the current view (#9060)
* Refresh only feeds in the current view

Closes #8025. Passes the current feed or category selection to the refresh endpoint and limits the batch accordingly. 

* Fix case of Dynamic OPML, and keep feed order

---------

Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-21 17:46:55 +02:00
Gerard Alvear PorrasandGerard Alvear 9e92ace6f2 Fix extension settings cancel action (#9053)
Closes #3662. Closes the extension settings slider when its reset/cancel control is used while preserving unsaved-change confirmation.

---------

Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
2026-07-21 17:45:36 +02:00
c5fc194624 Detect JSON feeds from .json URLs (#9058)
* Detect JSON feeds from .json URLs

Closes #7574. Detects .json feed URLs while adding a subscription and selects the JSON Feed source type automatically. 

* Auto open details

* Broaden JSON feed URL detection

---------

Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-20 18:01:41 +02:00
CronandAlexandre Alapetite 94ff6e4366 Stop the unread-count poller after the session ends (#9065)
* fix: stop the unread poller after the session ends

refreshUnreads() polls nbUnreadsPerFeed every 2 minutes and never checks
the response status, so once the session ends it keeps polling a dead
session indefinitely. Each request is a 401 (auth proxy / OIDC image) or
403 (stock); behind fail2ban the repeated failures ban the client IP.

Handle it like the other badAjax(status == 403) call sites: on a 401/403,
reload to re-authenticate instead of retrying.

* Enlarge HTTP 4xx status range

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-18 22:26:32 +02:00
28bc73afed Dispatch a JS event when an entry finishes being marked read/unread (#9031)
* Dispatch a JS event when an entry finishes being marked read/unread

Extensions that render their own read/unread indicator outside of the
main article list (e.g. a custom reading pane) had no way to know when
a mark read/unread AJAX request completed, so their own UI could get
stuck (e.g. a spinner never reset).

Dispatch a `freshrss:entryStateChange` event on `document` with the
entry id and new state once the toggle has been applied, following the
existing `freshrss:*` JavaScript event convention used elsewhere in
main.js.

Fixes #8862

* Minor preferences

---------

Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-12 23:04:12 +02:00
TowyTowyandClaude Fable 5 8aa8655cda fix(js): use Event() constructor instead of deprecated initEvent() (#9035)
`document.createEvent('Event')` followed by `Event.initEvent()` is
deprecated (https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent).
Replace the two remaining usages in `main.js` with the standard
`new Event(name, { bubbles, cancelable })` constructor, matching the
pattern already used in `extra.js`. The `bubbles` and `cancelable`
flags are kept identical (both `true`) so dispatch behaviour is
unchanged.

Fixes #5152

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 22:51:15 +02:00
Frans de JongeandAlexandre Alapetite 612ac4f117 Notifications: pluralize the "new articles" count message (#8988)
* Generate new articles notification string in PHP

Closes #6470

Changes proposed in this pull request:

- Generate notifications string  in PHP
- Use plurals support

* New articles notification: switch to plural forms

* README status

* fix paramInt invocation

* i18n

* make fix-all

* Apply suggestion from @Frenzie

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-07-06 11:16:29 +02:00
Inverle 13c2b68806 Keep scroll position of slider after form submit (#8974)
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/8612#issuecomment-4078560064

Depends on https://github.com/FreshRSS/FreshRSS/pull/8973
2026-07-04 13:32:52 +02:00
Inverle 9b43639c88 Fix slider not reinitializing after form submit (#8973)
"Follow-up" of https://github.com/FreshRSS/FreshRSS/pull/8612 (not fixing a regression, just a bug)

Some features like URL observers and custom favicon JS (e.g. *Reset to default* button) wouldn't work, due to `extra.js` not being loaded properly on pages where the slider content was already included in the HTML.
2026-07-04 12:14:05 +02:00
Inverle 6984c22b5c Fix feed dropdown bugs due to hash desync (#8949)
Fixes regression caused by https://github.com/FreshRSS/FreshRSS/pull/8335
To reproduce it, open any dropdown in the aside, reload the page, and try to open the same dropdown - it will disappear

To explain the issue more clearly, the dropdown menu wouldn't show because earlier its opacity is set to 0%, and after clicking the same dropdown after a page reload, the hashchange event wouldn't trigger to restore the previous opacity, and also the second listener would trigger to remove the dropdown if you opened it again.

Maybe https://github.com/FreshRSS/FreshRSS/issues/6156 is relevant here

Also a CSS change to stop showing the dropdown toggle icon of the previously opened dropdown after a page reload while the dropdown was open.
2026-06-28 21:38:37 +02:00
Frans de Jonge aaae9ee388 Always jump article to top when header is offscreen, also when 'Stick the article to the top when opened' is disabled (#8870)
* Always jump article to top when header is offscreen

Closes #4069.

How to test the feature manually:

1. Disable 'Stick the article to the top when opened'
2. Open a very long article
3. No scrolling will occur if you close it again while the header is still onscreen
4. If the header left the screen, opening another article will scroll to it to top 
5. Same for collapsing the current article, but then it'll put the current header at the top

* Compensate for layout shift

* Fix going back to previous article above viewport

* clarify variable name: header_off_screen → header_above_viewport
2026-06-05 15:31:42 +02:00
Alexandre Alapetite 3a696929b7 Fix click mark as read (#8817)
Fix https://github.com/FreshRSS/FreshRSS/issues/8806
Regression from https://github.com/FreshRSS/FreshRSS/pull/8553
Apply same logic to onmouseup than onauxclick.
2026-05-14 13:00:45 +02:00
polybjornandBjørn A. Andersen c43930cfd1 fix(js): stop sidebar auto-reopening on page navigation (#8773)
After #8747 the sidebar would re-open on its own when navigating
(e.g. clicking the logo) on sessions where sessionStorage said
the sidebar should be closed.

init_nav_menu() ran toggle_aside_click() to honour the stored
state, then gated a follow-up `.visible` re-add on
`getComputedStyle(aside).display !== 'none'`. Before #8747 that
gate worked because the close path set `aside.style.display =
'none'` inline; #8747 replaced that with an `is-hidden` class
applied only at wide viewports, so at narrow viewports the
computed display stays `table-cell` after closing and the gate
wrongly re-adds `.visible`, sliding the drawer open.

Gate on the toggle button's `.active` state instead. It's the
real source of truth for "should the sidebar be open" and is
already used elsewhere in the same function.

Fixes #8771

Co-authored-by: Bjørn A. Andersen <polybjorn@users.noreply.github.com>
2026-05-03 14:16:33 +02:00
polybjornandBjørn A. Andersen 3c61c84abf fix(themes): restore sidebar slide animation at narrow viewports (#8747)
The `transition: width 200ms linear` rule on `.aside` in the narrow
`@media` block stopped firing after #8201 added inline `display: none`
toggling. Browsers don't interpolate width when an element flips to or
from `display: none`, so width snaps on open and the close transition
gets cut off before any frame renders.

Replace the inline `display` toggle with an `is-hidden` class, applied
only at wide viewports. At narrow viewports the existing `width: 0;
position: fixed; overflow: hidden` already hides the element, so
`display: none` is redundant there and was the only thing blocking the
transition.

Co-authored-by: Bjørn A. Andersen <polybjorn@users.noreply.github.com>
2026-05-02 21:21:49 +02:00
e416117591 Disable unread counter in tab title and favicon (refresh of #6590) (#8728)
Closes FreshRSS/FreshRSS#6522.

Refresh of FreshRSS/FreshRSS#6590 by @sgzmd, which has been stalled with merge
conflicts since 2024. All original commits are preserved as-is in the history
(authorship intact); this PR adds a merge with current `edge` plus minor fixes.

## Summary

Adds a user setting `show_title_unread` (default `true`, so existing behavior
is preserved) that hides the unread article counter from both the tab title
and the favicon overlay. A single toggle controls both, matching the request
in #6522.

## Screenshots

Toggle in display settings:

<img width="320" height="127" alt="Display settings with new toggle" src="https://github.com/user-attachments/assets/fc78f825-161d-4b47-9b85-08e39554a4b1" />

Tab title and favicon when **enabled** (current behavior):

<img width="253" height="42" alt="Tab title and favicon with unread counter" src="https://github.com/user-attachments/assets/57387600-72e0-4b22-b059-04b5bfea673a" />

Tab title and favicon when **disabled** (new behavior):

<img width="254" height="40" alt="Tab title and favicon without unread counter" src="https://github.com/user-attachments/assets/93ac7997-dd4e-49bc-ab4a-74e4f0d2db1b" />

## Changes on top of #6590

- Resolved merge conflicts with current `edge` (controllers, model, view,
  `config.default.php`, ~25 i18n files, plus the `zh-tw` -> `zh-TW` rename).
- Replaced Czech text mistakenly placed in `de/conf.php` with an English
  `// TODO` marker so a German speaker can translate later.
- Renamed JS context key `show_unread_favicon` -> `show_title_unread` to
  match the backend property and avoid a confusing dual-name for one setting.
- Removed an unused duplicate of `show_title_unread` from `config.default.php`
  (the setting is read via `userConf()`, never `systemConf()`).
- Gated the dynamic title rewrite in `incUnreadsFeed` (`p/scripts/main.js`)
  on the setting. Without this, marking an article read while the setting
  was off would re-add the `(N)` prefix to the tab title.
- Escaped a stray apostrophe in the Occitan translation that broke parsing.
- `make fix-all` re-sorted i18n keys and added `// TODO` placeholders for
  `fi`, `pt-PT`, `uk` (untranslated by the original PR).

## Test plan

- [x] `make test-all` passes (620/620 PHPUnit, phpstan, phpcs, eslint,
      stylelint, markdownlint clean; `bin/typos` failed locally with a binary
      arch mismatch on macOS arm64 - unrelated to this change).
- [x] Manually tested on a real instance: default behavior unchanged;
      toggling the setting hides both the tab title `(N) ` prefix and the
      favicon overlay; toggling back restores both; marking articles read
      while the setting is off does not bring the counter back; opening and
      closing an article preserves the user's choice.

* Make showing the number of unread items in the title configurable.

* Proposed approach to passing show_unread_favicon setting down to client-side code

* Fixes and refactoring

* Updating default config for the user.

When user's config wasn't initialised we are copying it from `config-user.default.php` - if `show_title_unread` is not there, it is assumed to be false, whereas in `config.default.php` it's true by default. This results in inconsistency until user changes the field for the first time in Config->Display.

* Adding translations.

* fix: gate JS title rewrite + drop dead system config entry

The original PR added show_title_unread to both config-user.default.php
(read by userConf, the right place) and config.default.php (read by
systemConf, never used here). Drop the system-level entry.

Also: incUnreadsFeed dynamically rewrites document.title when articles
are marked read/unread. That code path was not gated by the setting, so
toggling the setting off and then marking an article read would re-add
the (N) prefix to the tab title. Skip the document.title / prevTitle
write when context.show_title_unread is false.

* fix: drop README pollution from local make fix-all

`make fix-all` regenerated the README translation tables on macOS, where the
case-insensitive filesystem and an untracked local `app/i18n/nb/` directory
caused the generator to emit `zh-tw` (lowercase) and an `nb` entry. Reset
both README files to upstream/edge so CI can regenerate them cleanly.

* fix: restore zh-TW/conf.php from edge (case-insensitive FS damage)

The macOS case-insensitive filesystem caused the merge to overwrite
upstream/edge's properly-translated zh-TW/conf.php with the older
zh-tw/conf.php content from the PR side, regressing translation
coverage from 94% to 71%. Reset the file to edge's content and re-add
the show_title_unread Traditional Chinese translation.

---------

Co-authored-by: sgzmd <sigizmund@gmail.com>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Bjørn A. Andersen <polybjorn@users.noreply.github.com>
2026-04-29 21:35:31 +02:00
Alexandre Alapetite 62b7dc37fe Allow extension configurations to use select-input-changer (#8721)
Useful for https://github.com/FreshRSS/Extensions/pull/456
2026-04-28 09:14:09 +02:00
Inverle cc64991c16 Implement setting for iframe referrer allowlist (#8672)
* Implement setting for iframe referrer allowlist

* Improve config label
2026-04-07 18:29:27 +02:00
InverleandFrans de Jonge 57471eda19 Don't mark as read if middle click is outside of article link (#8553)
* Don't mark as read if middle click is outside of article link

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

https://developer.mozilla.org/en-US/docs/Web/API/Element/auxclick_event

> The auxclick event is fired at an [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) when a non-primary pointing device button (any mouse button other than the primary—usually leftmost—button) has been pressed and released both within the same element.

> auxclick is fired after the [mousedown](https://developer.mozilla.org/en-US/docs/Web/API/Element/mousedown_event) and [mouseup](https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseup_event) events have been fired, in that order.

* Split up `onmouseup` and `onauxclick` logic

Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>

---------

Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
2026-04-03 22:32:19 +02: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
Inverle a4bcdf1a80 Create dynamic favicons from SVG instead of PNG canvas (#8577) 2026-03-08 10:46:38 +01:00
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
Inverle b249b9d026 Fix JS error when Navigation API is not present (#8524)
Closes https://github.com/FreshRSS/FreshRSS/issues/8511
2026-02-22 23:30:39 +01:00
Inverle 6b5304b825 Fix slider behavior when using navigate back button (#8496)
Closes https://github.com/FreshRSS/FreshRSS/issues/8488

* Ensure leave confirmation is shown by preventing navigation using the [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API)
* Prevent scroll lock by removing it on `hashchange` instead of `onclick` on the close buttons
2026-02-08 20:42:20 +01:00
rupak b59a2101b4 Add option to enable notifications (#8458)
Closes https://github.com/FreshRSS/FreshRSS/issues/7330

- Default behavior is same
- Added FreshRSS_Context::userConf()->html5_disable_notif so that, it determines weather user wants notification. (will not show any even it has permission) (i want default false so disable, so old configs get proper default values)
- Added button such that checking it makes it request permission too 
<img width="707" height="119" alt="image" src="https://github.com/user-attachments/assets/a0fdbc4d-9f15-4644-8753-f0e6c979677f" />

- test notification actually happening (how can i trigger it, do i have to wait it), this code fixes permissions.
2026-01-29 21:34:35 +01:00
Alexandre Alapetite ac0bf3c170 Fix shortcut next unread article (#8466)
fix https://github.com/FreshRSS/FreshRSS/issues/8426
regression from https://github.com/FreshRSS/FreshRSS/pull/8057
2026-01-25 13:57:20 +01:00
Tsung-Han Yu 84604e0c64 fix validator url update (#8436)
Closes https://github.com/FreshRSS/FreshRSS/issues/8435

Changes proposed in this pull request:
- update validator links to use the same open-url handler with prefix + encoding
- ensure the validator link reflects the current #url field value before opening
- keep existing open-url behavior for other links unchanged

How to test the feature manually:
1. Open feed edit (or add feed) form.
2. Change the feed URL in the URL field.
3. Click “Check the validity of the feed” and verify it opens the validator with the updated URL.
2026-01-20 20:00:39 +01:00
2cbb5f8db1 Update documentation in regards to CSP warnings (#8439)
* Add a reference to the check where the warning is triggered

Note:
This is the place where the admin sees the browser pointing to.
Adding this information here allows the admin to find the matching
documentation entry.

* Update Content-Security-Policy section of english ServerConfig documentation

Note:
This fixes some minor formating/typping issues and adds some clarity to
the fact that this warning is also triggered on correctly configured
hosts, simply due to the nature of how correctness of CSP rules are checked.

* Move CSP infor source-code comment into console.info

Note:
Improve visibility of why this is happening.

* Point towards static website documentation instead of git

This URL should also remain more fixed even accross new branches/releases.

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

* Minor fixes

* Remove overwrite part

---------

Co-authored-by: Inverle <inverle@proton.me>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2026-01-17 22:28:56 +01:00
Inverle 672411ca70 Fix dropdown menus in sidebar going under the navigation bar (#8336)
Missed in #8335 because I was testing without having the navigation bar enabled.

<img width="674" height="198" alt="image" src="https://github.com/user-attachments/assets/a1db7f95-f1d9-47e5-a572-20892e6c7abc" />
2025-12-21 15:37:23 +01:00
Inverle f387abe2c4 Display sidebar dropdowns above if no space below (#8335)
Closes https://github.com/FreshRSS/FreshRSS/issues/7801
2025-12-21 14:02:27 +01:00
Alexandre Alapetite 476e57b046 Reverse hash and nonce (#8320)
Safer password evaluation
2025-12-15 22:06:05 +01:00
Inverle 36118117f0 Improve scrolling into filter in sidebar (#8307)
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/8281

todo:
* [x] Include labels (prefix `t_`) too
* [x] Keep sidebar scrollTop when using the nav menu
* [ ] ~~Make this work in the reader view's sidebar too~~ for separate PR
* [x] Prevent whole page from scrolling on `scrollIntoView()` call, just scroll in the sidebar (probably related: https://github.com/FreshRSS/FreshRSS/pull/8306#issuecomment-3647414618)

This TODO will be done in a separate PR since it requires optimizing the sidebar toggle code.
edit: it does work on Chrome already though, but only if `#stream` isn't too large / breaks randomly (Firefox is slower it seems)
2025-12-15 15:12:12 +01:00
Inverle 7dd04b00cf Scroll into filtered feed/category on page load (#8281)
Previously if you were to go to for example *Subscription management* and filter a feed, the feed wouldn't be visible in a sidebar with lots of feeds, since you'd have to scroll to it first. Now, this is no longer the case.
Note that if the navigation comes from the sidebar itself, the original behavior remains. (scroll into previous `scrollTop` value of sidebar)
Also improves experience of using shift+j/k (see https://github.com/FreshRSS/FreshRSS/pull/8057)
2025-12-11 18:33:39 +01:00
Inverle e85d805351 Keep scroll state of page when closing the slider with JS shortcut (#8301)
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/8295
2025-12-09 17:05:05 +01:00
Inverle bb9089aa99 Fix chart resize regression due to chart.js v4 update (#8298)
* Fix chart resize regression due to chart.js v4 update

* Update to chart.js v4.5.1 + add .map file for easier debugging

https://github.com/chartjs/Chart.js/releases/tag/v4.5.1

* Delete .map file
2025-12-09 00:59:10 +01:00
Alexandre Alapetite 78e40c6fe3 Scaling of user statistics (#8277)
Fix https://github.com/FreshRSS/FreshRSS/issues/8268
To better support user management on FreshRSS instance with many users.

SQL speed improved. On a reduced test with 5 users, including some large accounts (PostgreSQL on a very tiny and slow server), improving from ~2.3s to ~1.8s, which gives ~20% speed improvement.

Then tested with 1000 users, with only the default feed (on my old desktop computer):

```sh
for i in {1..1000}; do ./cli/create-user.php --user=freshrss$i --password=freshrss; done
app/actualize_script.php
cli/access-permissions.sh
```

SQLite:

```console
$ time cli/user-info.php | wc -l
1001

real    0m1.366s
user    0m0.908s
sys     0m0.475s
```

PostgreSQL:

```console
$ time cli/user-info.php | wc -l
1001

real    0m28.498s
user    0m12.137s
sys     0m2.217s
```

MariaDB:

```console
# time ./cli/user-info.php | wc -l
1001

real    0m49.485s
user    0m1.276s
sys     0m2.258s
```

Yes, SQLite is much faster - not a surprise for such use-cases, where the TCP connection is not re-used.

I have added some CLI options to disable some statistics:

```sh
cli/user-info.php --no-db-size --no-db-counts
```

For the Web UI, I have disabled detailed user statistics if it takes too long, and retrieve missing user statistics asynchronously via JavaScript. Lazy loading of the user details based on IntersectionObserver, with maximum 10 requests in parallel.
Web UI tested on 1000 users as well. Checked with SeaMonkey.
2025-12-04 19:11:31 +01:00
InverleandAlexandre Alapetite d55f017ccd Implement button for toggling sidebar on all views (#8201)
* Implement button for toggling sidebar on all views

Closes https://github.com/FreshRSS/FreshRSS/issues/7673, https://github.com/FreshRSS/FreshRSS/issues/7100, https://github.com/FreshRSS/FreshRSS/issues/6119, https://github.com/FreshRSS/FreshRSS/issues/5338, https://github.com/FreshRSS/FreshRSS/issues/2792, https://github.com/FreshRSS/FreshRSS/issues/4224, https://github.com/FreshRSS/FreshRSS/issues/4136

https://github.com/user-attachments/assets/0629e465-6450-440e-b38b-430e9ff73ef9

Keyboard shortcut for doing the same: <kbd>t</kbd>

* Partially fix other views

Repartition page looks broken on Swage

* Correction

`close-aside` wasn't meant to be removed

* i18n(conf): fr

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

* make fix-all

* Fix settings slider not opening in reader view

* make readme

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-12-04 08:48:03 +01:00
Inverle 8cb2158a39 Replace arrow navigation in theme switcher with <select> (#8190)
Follow-up (or replacement) of https://github.com/FreshRSS/FreshRSS/pull/8167

![gif](https://github.com/user-attachments/assets/96cdeaff-36bc-4d0b-9b75-97bd7ff78ba1)
2025-11-06 20:45:44 +01:00
Tommaso FerrariandAlexandre Alapetite 63fe743878 Fix 7307 - Scroll after load (#7962)
* Fix 7307 - Scroll after load

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

- Wrap the body of `loadDynamicTags()` into a Promise
- inside `mylabels()`, wait for the promise to complete, then scroll
- when `loadDynamicTags()` is not being called, return a self-resolving promise

How to test the feature manually:

1. Click on an long article
2. press keyboard shortcut `l` to go to "My labels"
3. page should scroll down
4. the `My labels` popup should be fully visible

* Rewritten as async/await
* Explicit HTTP Accept application/json

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-11-05 11:51:33 +01:00