614 Commits

Author SHA1 Message Date
Tom Wheeler 4a101503a8 fix(overlays): show export button in XS and S grid sizes
fix #574
2026-04-24 02:30:20 +12:00
Tom Wheeler 5618671286 fix(letterboxd): fall back to TMDB ID scraping if more than one exact title + year search result
fix #581
2026-04-24 02:13:16 +12:00
bitr8 b109ef513d fix: refresh Plex shared-server cache at start of user filter batches (#579)
Pass forceRefresh=true to getAllPlexUserIds() from the four batch entry
points so each run reads the user's current Plex sharing settings rather
than a snapshot left by the previous run.

Fixes #577

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-04-22 18:35:37 +12:00
RedRubble 0886d9eaa8 feat(overlays): Refresh overlay of a single item (#561)
* feat: refresh overlay of a single item

* fix(overlay): add single item overlay refresh to frontend (in test item search feature)

---------

Co-authored-by: Tom Wheeler <thomas.wheeler.tcw@gmail.com>
2026-04-22 15:38:54 +12:00
Weblate (bot) 9fed643189 Translations update from Hosted Weblate (#507)
* Translated using Weblate (French)

Currently translated at 99.3% (1423 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Hungarian)

Currently translated at 99.8% (1430 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/hu/

* Translated using Weblate (French)

Currently translated at 99.4% (1424 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.4% (1424 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Swedish)

Currently translated at 26.3% (377 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/sv/

* Translated using Weblate (French)

Currently translated at 99.6% (1427 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.8% (1430 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Hungarian)

Currently translated at 99.9% (1431 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/hu/

* Translated using Weblate (French)

Currently translated at 84.5% (1340 of 1585 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 85.2% (1360 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 91.5% (1460 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 97.3% (1553 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1595 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (German)

Currently translated at 17.1% (273 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/de/

* Translated using Weblate (French)

Currently translated at 87.1% (1434 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 95.3% (1569 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 98.6% (1623 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1646 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (German)

Currently translated at 16.9% (279 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/de/

* Translated using Weblate (French)

Currently translated at 100.0% (1685 of 1685 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 97.9% (1713 of 1748 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1748 of 1748 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1748 of 1748 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

---------

Co-authored-by: Sulli <susu.leduc@gmail.com>
Co-authored-by: Koch Norbert <kochnorbert@icloud.com>
Co-authored-by: Hannes Brolin Lagerstedt <mainhannes@gmail.com>
Co-authored-by: Sarge527 <Maximiliannelles@mail.de>
Co-authored-by: U.B. <hex0x@mail.de>
2026-04-22 14:59:11 +12:00
Tom Wheeler 480de07d07 chore(i18n): add Chinese, Japanese, and Ukrainian (translate via Weblate) 2026-04-22 14:45:39 +12:00
Tom Wheeler adf8b0a99b fix(seerr): fix Seerr user collection ordering and visibility
Store rating keys for per-user Seerr collections to enable home screen ordering, and fix visibility
form to hide unavailable options for user and server owner collections
2026-04-22 14:45:17 +12:00
bitr8 cae827f9fc fix: accept Plex webhook thumb field to prevent MulterError (#567)
Plex webhooks are multipart/form-data with a `payload` text field
and a `thumb` JPEG file. `upload.none()` rejects file fields,
throwing `MulterError: Unexpected field` on every webhook that
includes a thumbnail.

Switch to `upload.single('thumb')` so multer accepts the image
(discarded after the request, only `payload` is used).

Fixes #565

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-04-22 12:49:31 +12:00
bitr8 9593560ad0 fix(placeholders): match legacy edition tags in orphan file cleanup (#578)
The orphan file scanner only matched {edition-Trailer}, but
removePlaceholder accepts {edition-Placeholder} and {edition-Coming Soon}
too (legacy formats from before the Dec 2025 rename). Legacy files were
never garbage-collected and accumulated in the placeholder root.

Fixes #575

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-04-22 12:49:06 +12:00
timelordx 6c9f9d837c fix: use /api/collections/overlay-data endpoint (#569)
Maintainerr >= 3.4.0 changed GET /api/collections to return only 2 preview items per collection. T
he new /api/collections/overlay-data endpoint returns the full media list.
Falls back to the legacy endpoint for Maintainerr <= 3.3.x compatibility.

Co-authored-by: timelordx <timelordx@users.noreply.github.com>
2026-04-21 18:52:03 +12:00
Ryan Brothers 6c307e3a58 fix: add NOT operator to TMDB Advanced Custom Filters (#539) 2026-04-21 18:09:29 +12:00
Tom Wheeler 5ca4511e70 fix(titles): add Seerr displayName as variable
fix #542
2026-04-04 14:14:06 +13:00
Tom Wheeler b4c808f433 fix(overlays): use TMDb title for RT lookup and decouple from IMDb ID gate
fix #532
2026-04-04 13:34:31 +13:00
bitr8 2bff7617f7 fix: back off on IMDb Top 250 cache refresh failure (#547)
When refreshTop250Cache() fails (e.g. WAF timeout), lastRefresh was
never set, so needsRefresh() returned true on every subsequent call.
This caused a ~30s WAF timeout per item across the entire library.

Set lastRefresh on failure with a 5-minute backoff so it retries once
per window instead of per item.

Fixes #546

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-04-04 13:28:13 +13:00
bitr8 2cd410771a fix: remove date-based overlays when content is downloaded (#556)
Coming Soon, Countdown, Far Future Release Date, and Releasing Tomorrow
overlays persisted after content was grabbed before its official release
date. Added downloaded == false to all affected preset template conditions.

Returning Soon templates intentionally excluded — they track future
seasons on shows that already have downloaded content.

Ref: agregarr/agregarr#554

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-04-04 13:27:28 +13:00
bitr8 5ed40a3832 fix: path traversal in overlay template export (#513)
The overlay template export endpoints resolve asset paths with a
fallback to path.join(cwd, assetPath), allowing arbitrary file reads
via crafted asset paths.

- Remove unrestricted cwd fallback from both export endpoints
- Restrict resolution to config/uploads/ and config/posters/
- Add path.resolve() containment check

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-03-17 21:03:13 +13:00
Tom Wheeler 67b813988e perf(letterboxd): reduce Playwright usage and parallelise TMDB resolution
searches TMDB API first, if no exact match found then grabs TMDB ID from individual page with
playwright
2026-03-17 21:00:33 +13:00
Tom Wheeler 06e962c7ce fix(multi-source): reset stale title template when changing from single to multi source
fix #521
2026-03-17 20:13:54 +13:00
Tom Wheeler 199841f3ae fix(placeholders): placeholder filters blocking creation when grab missing items was not enabled
fix #509
2026-03-17 19:43:59 +13:00
Tom Wheeler c2f11799cf fix(imdb-letterboxd): use Playwright clients in random list and title validation for IMDb/Letterboxd
fix #475
2026-03-17 19:35:50 +13:00
Tom Wheeler cd14951bbc fix(security): validate filenames in icon and poster thumbnail routes to prevent path traversal 2026-03-17 16:19:54 +13:00
bitr8 ef873b7fe6 Sanitize SVG content on icon upload (#514)
SVG files uploaded as icons are saved without sanitisation. Embedded
script tags, event handlers, foreignObject elements, and javascript:
URIs in SVG content enable stored XSS.

Adds sanitizeSvg() that strips dangerous elements and attributes
before saving. Applied via uploadIcon() so template imports are
also covered.

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-03-17 10:06:38 +13:00
bitr8 404e7c865e fix: TV placeholders leaking into filtered hubs (#503)
PlaceholderDiscovery re-verified TV items via isPlaceholderItem() which
returns false during library-level scans (no Children metadata in Plex
response). The marker file on disk already proves it's an Agregarr-created
placeholder, so trust that instead of re-checking a broken API path.

Also: find S00E00 by episode index not array position, and use async
placeholder detection in the orphan scan for definitive TV identification.

Ref #414

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-03-17 10:03:53 +13:00
bitr8 c1de3be561 Remove unused vm2 dependency (#515)
vm2 is listed as a dependency but never imported anywhere in the
codebase. It has been deprecated and has multiple sandbox escape
CVEs. Removing it.

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-03-17 09:51:48 +13:00
Tom Wheeler 9d2d211ef5 chore(i18n): extract strings 2026-03-17 09:40:13 +13:00
Tom Wheeler 95f77d64a4 fix(seerr): enable Home/Recommended visibility options for Seerr Individual Requests collections
Longstanding Plex bug not respecting label restrictions for Collections on Home/Recommended has been
fixed in PMS Beta 1.43.1.10540, confirmed working with Agregarr. Also removes previous easter egg
which enabled the option (intended for use when the project was going to be a PR for Overseerr,
allowing use of the option without waiting for an update)

fix #112
2026-03-17 09:26:16 +13:00
Tom Wheeler 07f0a14ef0 fix(placeholders): add Plex Webhook support to mark placeholders as unwatched 2026-03-15 23:42:12 +13:00
Weblate (bot) c46046fc08 Translations update from Hosted Weblate (#463)
* Translated using Weblate (French)

Currently translated at 99.3% (1423 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Hungarian)

Currently translated at 99.8% (1430 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/hu/

* Translated using Weblate (French)

Currently translated at 99.4% (1424 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.4% (1424 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Swedish)

Currently translated at 26.3% (377 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/sv/

* Translated using Weblate (French)

Currently translated at 99.6% (1427 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.8% (1430 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Hungarian)

Currently translated at 99.9% (1431 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/hu/

* Translated using Weblate (French)

Currently translated at 84.5% (1340 of 1585 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 85.2% (1360 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 91.5% (1460 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 97.3% (1553 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1595 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (German)

Currently translated at 17.1% (273 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/de/

* Translated using Weblate (French)

Currently translated at 87.1% (1434 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 95.3% (1569 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 98.6% (1623 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1646 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (German)

Currently translated at 16.9% (279 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/de/

* Translated using Weblate (French)

Currently translated at 100.0% (1685 of 1685 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 97.9% (1713 of 1748 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1748 of 1748 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1748 of 1748 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1758 of 1758 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

---------

Co-authored-by: Sulli <susu.leduc@gmail.com>
Co-authored-by: Koch Norbert <kochnorbert@icloud.com>
Co-authored-by: Hannes Brolin Lagerstedt <mainhannes@gmail.com>
Co-authored-by: Sarge527 <Maximiliannelles@mail.de>
Co-authored-by: U.B. <hex0x@mail.de>
2026-03-05 19:06:08 +13:00
Tom Wheeler 501d6b68d7 chore(overlays): revert order of imdb and rt overlays 2026-03-05 19:04:49 +13:00
Tom Wheeler 78842cd050 fix(tmdb-collections): respect language setting for TMDB franchise collections
fix #487
2026-03-03 23:51:32 +13:00
bitr8 8d850322b9 fix(overlays): support Maintainerr v3 API (mediaServerId rename) (#504)
Maintainerr v3 renamed `plexId` (number) to `mediaServerId` (string)
in their API response. The overlay context builder compared against the
old field, silently failing to match any media items so daysUntilAction
never populated.

Read `mediaServerId` with fallback to `plexId`, compare as strings.
Supports both Maintainerr v2 and v3.

Fixes #501

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-03-03 00:18:43 +13:00
Ruben 207a1ed905 fix(overlays): correct air date today logic for next episode and season (#496)
* fix(overlays): correct air date today logic for next episode

* fix(overlays): correct air date today logic for next season
2026-03-03 00:16:56 +13:00
bitr8 d8655cad41 fix(placeholders): handle Plex returning TV seasons as Children.Directory (#491)
Plex returns seasons as Children.Directory (not Children.Metadata)
when using ?includeChildren=1. All placeholder detection code only
checked Children.Metadata, so isPlaceholderItem() always returned
false for TV shows — skipping title fixes and triggering false
cleanup of valid placeholders.

Added Metadata || Directory fallback across all detection paths,
type casts, and getChildrenMetadata() API helper.

Fixes #414

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-03-03 00:15:31 +13:00
bitr8 68d832a2bd fix: guard splice in arrangeCollectionItemsInOrder (#481)
When an item isn't yet visible in Plex, indexOf returns -1 and
splice(-1, 1) removes the last element of the tracking array,
corrupting all subsequent move decisions.

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-03-03 00:14:13 +13:00
Rust84 4f11ad1260 fix(local-posters): fix pagination and library filtering for local poster folders (#477)
Add pagination loop to process all library items instead of only the first 50. Use
plexApi.getLibraries() instead of OverlayLibraryConfig so libraries without overlays are included.

#433
2026-03-03 00:13:43 +13:00
Douw Jacobs 898c300d2a fix(overlays): fix days since season premiere logic (#473) 2026-03-03 00:10:36 +13:00
Tom Wheeler f563170053 chore(overlay-test): correct typing 2026-03-03 00:06:49 +13:00
Tom Wheeler 843d314984 fix(connections): correctly handle CSRF cookie name 2026-03-03 00:05:41 +13:00
Tom Wheeler d91d040c1e chore(dependencies): remove unused openpgp, minor patch bumps 2026-03-03 00:03:50 +13:00
Tom Wheeler aba123fcc5 fix(uploads): add authentication to poster export/import, trakt, and anime routes 2026-03-02 23:59:02 +13:00
bitr8 5134db5b9f fix(overlays): parallelise collection membership check in overlay test (#483)
The overlay test endpoint checks every collection for item membership
sequentially. With ~150 collections at ~250ms each, the request takes
~37 seconds and the frontend times out.

Batched the getCollectionItems() calls with Promise.all at concurrency
10, matching the pattern in OverlayLibraryService. Brings the check
down to ~4 seconds for 150 collections.

Fixes #468

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-02-25 17:30:26 +13:00
bitr8 831ccaba98 fix(collections): index MAL IDs for constant-time lookups (#482)
lookupByMal() iterates all ~25k anime ID rows to find a MAL ID match.
MAL sources can fetch thousands of items, each calling lookupByMal(),
so preview requests time out before returning results.

Added a _byMal Map index built during loadAnimeIds(), matching the
existing _byAniDB pattern. Lookups are now O(1) instead of O(n).

Fixes #480

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-02-23 10:54:24 +13:00
Ryan Brothers 863d9974be fix(TMDB): Multiple custom advanced filter fixes (#476)
* FIX: ADD-OR dropdown was not letting you change it to OR

* FIX: make it so that TMDB cast,crew,people filters show the name with the ID

* FIX: add name when adding person on TMDB as an ID number

* FIX: TMDB custom collection now saves settings on update

* FIX: after deleting a TMDB custom collection, you could not make a new one with the same name

* FIX: hydration was not working on large groups of IDs
2026-02-23 10:01:25 +13:00
Sean Bingham 4a4e1d85c1 fix(cleanup): prevent auto-franchise collections from being deleted when custom sync is enabled (#470)
Updated 'CollectionCleanupService' so deletion checks look at all Agregarr labels on a collection, instead of only the first one.
2026-02-23 09:58:22 +13:00
Anthony Hoivik cb12822872 fix(overlays): move IMDb rating position out of conflict with top banner tiles (#408)
* fix: move IMDb rating position out of conflict with top banner tiles

* fix: move dolby vision, hdr position down to prevent conflict with new imdb position
2026-02-21 19:42:07 +13:00
Sean Bingham 069e58c174 fix(coming-soon): makes hideIndividualItems work for Coming Soon collections (#469)
* - Updated `hideIndividualItems` description in settings to clarify support for both Coming Soon and TMDB auto_franchise collections.
- Improved `ComingSoonCollectionSync` to filter items based on media type and apply collection exclusions.
- Added logic to set collection mode when `hideIndividualItems` is enabled, ensuring individual items are hidden in the library tab.
- Adjusted UI components to reflect changes in collection mode options for TMDB and Coming Soon collections.

* fix(comingsoon): guard missingItems before quick-sync storage
2026-02-20 13:25:41 +13:00
bitr8 77c5a91139 fix(Placeholders): Scan all placeholder-enabled libraries, not just the first (#467)
.find() only returned the first TV/movie library with placeholders
enabled, silently skipping any additional libraries. Replace with
.filter() + Set to discover and process placeholders across all
libraries.

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
2026-02-20 13:24:37 +13:00
bitr8 63b8851a1a fix(Placeholders): Separate placeholder filters independent of auto-request filters (#456)
* feat: separate placeholder filters independent of auto-request filters

Add placeholderMinimumYear, placeholderMinimumImdbRating,
placeholderMinimumRottenTomatoesRating,
placeholderMinimumRottenTomatoesAudienceRating, and
placeholderFilterSettings to CollectionConfig and
MultiSourceCollectionConfig.

buildPlaceholderFilterConfig() helper swaps placeholder values into
standard filter fields so MissingItemFilterService works unchanged.
Updated BaseCollectionSync and MultiSourceOrchestrator call sites.

Collapsible "Placeholder Filters" section in collection edit form
reuses FilterWithMode/KeywordFilterWithMode. Auto-expands when
editing configs with existing values.

Fixed pre-existing gap: keywords missing from
MultiSourceCollectionConfig.filterSettings type.

---------

Co-authored-by: bitr8 <bitr8@users.noreply.github.com>
Co-authored-by: Tom Wheeler <thomas.wheeler.tcw@gmail.com>
2026-02-20 13:22:44 +13:00
Tom Wheeler 266a6057e0 docs(seerr): overseerr has been updated to Seerr across the frontend
fix #142
2026-02-20 12:08:07 +13:00
Weblate (bot) df26046348 Translations update from Hosted Weblate (#439)
* Translated using Weblate (French)

Currently translated at 99.3% (1423 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Hungarian)

Currently translated at 99.8% (1430 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/hu/

* Translated using Weblate (French)

Currently translated at 99.4% (1424 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.4% (1424 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Swedish)

Currently translated at 26.3% (377 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/sv/

* Translated using Weblate (French)

Currently translated at 99.6% (1427 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.8% (1430 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (Hungarian)

Currently translated at 99.9% (1431 of 1432 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/hu/

* Translated using Weblate (French)

Currently translated at 84.5% (1340 of 1585 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 85.2% (1360 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 91.5% (1460 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 97.3% (1553 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1595 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (German)

Currently translated at 17.1% (273 of 1595 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/de/

* Translated using Weblate (French)

Currently translated at 87.1% (1434 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 95.3% (1569 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 98.6% (1623 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (1646 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (German)

Currently translated at 16.9% (279 of 1646 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/de/

* Translated using Weblate (French)

Currently translated at 100.0% (1685 of 1685 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

* Translated using Weblate (French)

Currently translated at 97.9% (1713 of 1748 strings)

Translation: agregarr/Agregarr Frontend
Translate-URL: https://hosted.weblate.org/projects/agregarr/agregarr-frontend/fr/

---------

Co-authored-by: Sulli <susu.leduc@gmail.com>
Co-authored-by: Koch Norbert <kochnorbert@icloud.com>
Co-authored-by: Hannes Brolin Lagerstedt <mainhannes@gmail.com>
Co-authored-by: Sarge527 <Maximiliannelles@mail.de>
Co-authored-by: U.B. <hex0x@mail.de>
2026-02-14 11:49:12 +13:00