Skip to content

Releases: IbbyLabs/XRDB

v1.22.0

17 Apr 04:35
16bd6d4

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Added

  • support original language artwork selection (FR-85)

    • add original as a first class language option in the configurator and supported language defaults
    • keep request state cache identity distinct for lang=original without breaking fixed locale callers
    • resolve TMDB artwork bundles, certification lookups, and localized badge data through the title's original language
    • document lang=original usage and cover it with request state, prepared media, and configurator regression tests

Fixed

  • resolve BUG-111 badge border scaling

    Replace fixed badge border stroke widths with height relative stroke calculations so rating and genre badges keep proportional borders at large poster scales.

    Scale outer and inner badge strokes from badge height with clamps to preserve current normal size rendering while fixing thin borders on 4K and oversized poster outputs.

    Add direct SVG regression tests for rating badge glass borders and genre badge glass borders so future changes cannot silently reintroduce under scaled outlines.

  • resolve BUG-110 logo quality badge flow

    Remove the duplicated logo quality controls from the configurator and wire logo quality badges through the full image route pipeline.

    Parse logo quality badge params, enable the media feature pipeline for logo requests, preserve logo quality settings in the render seed, size the logo badge band for rating and quality rows, and render logo quality rows in the final output.

    Add regression coverage for logo request state parsing, logo quality only layout, renderer output in the logo badge band, and render cache busting for logo quality changes.

Documentation

  • refresh static doc assets

v1.21.2

16 Apr 23:08
8c736a5

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Fixed

  • invalidate proxied manifests when source config changes

    Make proxy manifest identity depend on the effective source manifest payload and proxy seed so stable source URLs do not keep a stale addon identity after configuration changes.

    Add explicit no store cache headers to proxy manifest and proxy ref responses and cover the behavior with focused proxy regression tests.

  • BUG-101 BUG-105 preserve proxy age rating placement and clean genre sizing

    Keep the genre badge size slider available when the clean text genre style is active so the configurator still exposes badge scaling in that mode.

    Forward ageRatingBadgePosition through shared proxy image query keys and cover the rewrite with a regression test so poster proxy manifests preserve custom age rating placement.

Documentation

  • refresh static doc assets

  • align freshness guidance and refresh doc assets

    Clarify that the Generated manifest flow uses a stable UUID backed install URL that refreshes when the source addon manifest changes instead of implying a rotated install link is required.

    Update proxy page and reference copy to describe server managed TMDB and MDBList coverage, record the recent proxy and configurator fixes in the unreleased changelog, and refresh the tracked README preview metadata plus static documentation captures.

v1.21.1

16 Apr 21:46
992da72

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Fixed

  • keep personal provider keys server side

    Move personal provider credentials into an opaque server held session and resolve them through session aware configurator routes instead of browser visible params.

    Add server fallback behavior for TMDB, Fanart, and Simkl requests, strip provider keys from previews and saved workspace exports, and show masked previews for saved personal keys in the advanced access keys modal.

  • harden server managed credential handling

    Prefer server side TMDB bearer auth when a read access token is configured while keeping explicit per request overrides intact.

    Redact sensitive credential query params from observer URLs and replay storage, hash MDBList cache keys, and omit xrdbKey from masked exports.

    Update docs, templates, and tests for the new credential handling and masked export behavior.

  • BUG-109 restore full language options

    Move configurator language loading behind a server route so provider keys stay out of the browser while TMDB backed language options still load. Also keep the language dropdown aligned inside the viewport and cover both regressions with focused tests.

  • prefer IMDb reverse mapping for anime episode fallback

    Use season aware reverse mapping for AniList episode thumbnail fallback instead of always routing through the TMDB show id.

    The previous fallback path could resolve sequel anime entries to the wrong AniList work and reuse the same episode thumbnail across seasons, which is what caused the JJK S02E01 and S03E01 collision.

    Prefer explicit anime mapping ids and resolved IMDb ids before falling back to TMDB, and keep the regression covered with a focused artwork selection test for the season 3 episode fallback path.

  • sanitize poster warm replay requests

    Default poster warm renders to a lean imdb,tmdb profile and strip replay only params, provider credentials, config ids, and MDBList backed providers before replay.

    Share the MDBList backed provider set and add focused regressions for sanitized replay storage and warm request parameter normalization.

  • BUG-108 shorten cache for transient MDBList failures

    Detect transient MDBList failures during provider resolution and carry a short lived TTL through prepared media into final image cache control.

    Add focused regressions for MDBList failure handling, provider resolution propagation, prepared media state, and final image TTL calculation.

Documentation

  • refresh static doc assets

v1.21.0

16 Apr 05:54
925a548

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Added

  • harden stream cache

    Implement stream cache hardening controls for Torrentio with feature gated behavior and a global hardening kill switch.

    Add negative caching, stale while revalidate serving, circuit breaker thresholds and cooldowns, provider request budgets, prewarm popularity ranking with snapshot restore, and observe only auto tune telemetry paths.

    Document activation and rollback controls in README and env template, extend config and metadata plumbing for hardening controls, and add targeted hardening tests that validate gating, rollback behavior, SWR, circuit, budgets, and prewarm recovery flows.

  • add adaptive stream cache ttl policy

    Introduce adaptive Torrentio stream cache TTL selection using recency buckets (fresh, warm, stable) instead of relying only on a fixed TTL.

    Add operator configurable adaptive window and TTL environment variables, document them in README and env template, and wire prepared media cache TTL calls through the adaptive helper.

    Add targeted tests for recency classification boundaries, fallback behavior for missing or invalid dates, and deterministic TTL jitter behavior.

Fixed

  • BUG-106 restore full provider resolution

    • switch MDBList fetch from legacy mdblist.com/api query format to api.mdblist.com path format

    • pass resolved media type through provider rating fetch so movie/show endpoints are targeted correctly

    • map MDBList popcorn source aliases to tomatoesaudience so RT audience ratings render

    • update MDB fetch tests to assert exact endpoint URLs and add popcorn alias coverage

  • replace s<=30 season cap with TMDB number_of_seasons bound

    Fetch the show detail endpoint to read number_of_seasons and use that
    as the upper bound for the consolidated remap season walk. Falls back
    to 100 if the endpoint fails. Eliminates the hard coded 30 season cap
    that would silently return null for long running consolidated series.

    Updated resolveTmdbConsolidatedSeasonEpisode tests to mock the
    tmdb:tv:{id} show detail key in all three test cases.

  • BUG-102 BUG-103 TMDB episode ID mode and anime S2 consolidated remap

    BUG-103: add tmdb episode ID mode with tmdb:{tmdb_id} URL pattern.
    Wired tmdb to EpisodeIdMode union, EPISODE_ID_MODE_SET,
    buildEpisodePatternBaseId, and applyEpisodeIdModeToXrdbId.
    Added TMDB selector to export view and configuratorPageOptions.
    export view now imports EPISODE_ID_MODE_OPTIONS from
    configuratorPageOptions so option descriptions render inline
    below the selector pills.

    BUG-102: anime S2+ thumbnails now resolve unique stills via
    resolveTmdbConsolidatedSeasonEpisode. Applied in the generic
    IMDb else path and as TVDB fallback when thetvdb.com scrape
    returns null (no hard 404).

    README: document tmdb:{tmdb_id} in episode base ID formats.

    Verified: lint clean, 841/841 tests pass, production build
    clean. Manual checks: tmdb:1399/S01E01 200, anime S1/S2 stills
    differ, tvdb:81189/S99E99 200 fallback, tt0468569 poster 200,
    TVDB description visible in export options.

  • constrain Tailwind source scanning to app and components (#3)

    Co authored by: IbbyLabs 40578997+IbbyLabs@users.noreply.github.com

Documentation

  • refresh static doc assets
  • add minimal self host template

Other Changes

  • reuse known TMDB season counts in remap helper

    Reuse TMDB show season counts that are already loaded in image route
    resolution when calling resolveTmdbConsolidatedSeasonEpisode. This
    avoids an extra /tv/{id} fetch in thumbnail remap paths while keeping
    the existing fallback fetch when the season count is not already known.

    Verified with focused thumbnail tests, full lint + test, and a fresh
    manual pass of the export and thumbnail checks on a clean dev server.

  • consolidate season fetch loop into single pass

    Replace the separate targetSeason early check fetch and priorCount loop
    with a single pass from s=1 to targetSeason. Tracks priorCount and
    targetSeasonEpisodeCount in one loop, eliminating the duplicate fetch
    of targetSeason that previously occurred when episodes exceeded the
    season count. All fetches after the first are still cache hits.

    Updated test mocks to reflect the new fetch sequence.

  • add color scheme dark meta tag (#2)

v1.20.1

16 Apr 01:29
a2fd94a

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Fixed

  • BUG-100 stabilize saved profile revert and sync diffs

    Route saved profile revert through the canonical snapshot apply path so imported workspace changes clear dirty state correctly after revert.

    Compare saved profile and cross type sync params with allow missing server managed provider key options so dirty checks and sync diffs still work when TMDB and MDBList keys are only configured on the server.

    Add regression coverage for provider keyless dirty detection and sync to all diffs.

Documentation

  • refresh static doc assets

v1.20.0

15 Apr 23:10
25277d3

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Added

  • expand poster warm sources with TMDB multi endpoint, IMDb baseline, recent ring

    • TMDB: fetch 6 endpoints per pass (movie/popular p1+p2, movie/now_playing p1,
    tv/popular p1+p2, tv/on_the_air p1) instead of 2; up to ~120 raw ids before cap
    • MDBList: raise default limit from 100 to 200
    • IMDb: new optional source reads local title.ratings.tsv.gz, sorts by vote count,
    merges top N ids; no network required, falls back cleanly when file is absent
    • Recent ring: bounded in memory ring buffer (default 500) records each inbound
    poster request with its full search params (auth stripped); scheduler replays
    exact request signatures so warm hits land in per config cache slots
    • Wire recordRecentPosterRequest into imageRouteHandler for poster requests
    • New env vars: XRDB_POSTER_WARM_IMDB_ENABLED/LIMIT, XRDB_POSTER_WARM_RECENT_ENABLED/LIMIT
    • Update XRDB_POSTER_WARM_MDBLIST_LIMIT default in docs and env.template to 200
    • 9 new tests covering TMDB 6 endpoint mapping, IMDb sort/cap/missing file,
    ring dedup/eviction/auth strip/limit; all existing tests updated for new fields
    • 834/834 tests pass, lint clean, build clean

  • FR-80 FR-55 speed up poster cold loads

    • default poster stream badges to off for new configs

    • add non blocking posterStreamBadges=auto behavior with deferred warming

    • add Torrentio timeout, fallback host, and proxy bypass controls

    • add scheduled poster cache warming with source parsing and overlap protection

    • enforce metadata cache pruning bounds and add stream warm observability

    • update docs, env template, and tests for new behavior

Fixed

  • track poster warm target seed file
  • include poster warm targets in docker build context

Documentation

  • refresh static doc assets

Other Changes

  • bake poster warm targets.txt into image

v1.19.1

15 Apr 05:02
475f185

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Fixed

  • BUG-97 apply stored episode config profile when thumbnail URL has no explicit badge params

    The /thumbnail//S01E01.jpg route is a thin wrapper that parses the
    episode token into season and episode numbers, then constructs an internal
    backdrop URL (/backdrop/::.jpg?thumbnail=1) and
    delegates rendering to the shared image handler.

    XRDB_EPISODE_CONFIG_PROFILE_ID is a server side env var intended to apply
    a default config profile to all episode thumbnail requests, so Plex,
    Jellyfin, and similar callers that send bare URLs with no query params
    receive the operator configured badge and rating settings. The feature was
    completely inert due to two separate gaps in the route:

    1. configId was read only from the ?config= search param of the incoming
      URL. The env var was never consulted, so bare thumbnail URLs always
      rendered with no profile applied.

    2. The route constructs a fresh internal URL for the backdrop handler. The
      original search params are copied over but ?config= was never explicitly
      set on the internal URL. Even if configId had been populated, the
      backdrop renderer would have received no config param and skipped the
      profile lookup entirely.

    Fix reads XRDB_EPISODE_CONFIG_PROFILE_ID as a fallback when no ?config=
    is present on the incoming request. When configId resolves from the env
    var rather than the caller URL, it is injected into the internal backdrop
    URL as ?config= before forwarding. The guard on !requestUrl.searchParams
    .has('config') ensures the env var is strictly a fallback: an explicit
    ?config= from the caller always takes precedence.

  • BUG-98 fix quality badge column centering when clean genre badge reserves bottom space

    When a poster renders Pill Glass quality badges alongside a clean style
    genre badge, the renderer reserves a block of space at the bottom of the
    poster for the genre badge via cleanPosterReservedBottomHeight. That value
    is folded into effectiveBadgeBottomOffset so layout bounds are correct
    throughout the renderer.

    The quality badge column centering step did not use effectiveBadgeBottomOffset
    as the lower boundary. Instead it divided the full output height by two,
    treating the center of the entire image as the target midpoint. The result
    was that the quality column drifted into the space reserved for the genre
    badge and appeared off center relative to the usable area above it.

    The fix computes availableCenter as:
    (badgeTopOffset + outputHeight, effectiveBadgeBottomOffset) / 2

    This bounds the center calculation to the region between the top badge
    offset and the effective bottom offset, so the column centers correctly
    within the available space regardless of how much bottom space the clean
    genre badge reserves.

  • BUG-99 apply configured value color to ring score text across all accent modes

    aggregateValueColor was fully resolved in the display state pipeline but
    was never passed to buildPosterCompactRingOverlay. The ring builder had
    the score text fill hardcoded to #f8fafc regardless of what color was
    configured. As a result, any value set via aggregateValueColor was silently
    ignored whenever the compact ring presentation was active.

    The fix adds an optional valueColor param to buildPosterCompactRingOverlay
    and threads it through to the SVG fill attribute using valueColor ?? '#f8fafc'
    so the hardcoded default is preserved when no color is configured.

    On the display state side, compactRingValueColor is derived before the
    ring builder call: when the primary badge is an aggregate kind, the color
    follows the aggregate value color resolver; for provider badges, it falls
    back to the aggregateValueColor input. This keeps behavior consistent
    across all four accent modes (source, genre, custom, dynamic).

    Tests added for all four accent modes to confirm the configured color
    appears in the rendered SVG and that the default white is preserved when
    no color is set.

Documentation

  • refresh static doc assets

v1.19.0

15 Apr 02:39
1f47e85

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Added

  • shift to server managed provider keys

    Remove provider key entry fields from configurator access keys and surface server credential status in the UI.

    Use server TMDB and MDBList fallbacks across search, preview, proxy, and export payload generation while keeping optional per request overrides.

    Update docs and env template for XRDB_TMDB_API_KEY support and add regression coverage for credential omission and server key detection.

Fixed

  • BUG-96 fallback to server MDBList keys

    Retry provider rating resolution with the server MDBList key pool when a manual MDBList key returns no data.

    Add regression coverage for manual key failure so preview badges keep rendering from fallback data.

  • BUG-95 genre badge respects selected position in blockbuster mode

    In blockbuster poster mode, the collision avoidance loop was pushing the
    genre badge away from all blockbuster overlay elements (score tiles,
    callout tiles, rating badges, strip), ignoring the user's chosen position
    entirely. The badge could end up halfway down the poster regardless of
    what genreBadgePosition was set to.

    Fix: pass empty collisionRects for blockbuster poster mode in
    imageRouteRenderer so the collision loop exits immediately and the badge
    renders at the user selected offset. Non blockbuster posters and
    backdrops continue to use full collision avoidance as before.

    Also refreshed doc static assets and README capture date.

  • BUG-92 accept all config profile ID formats in link import

    Configurator link import validated config IDs with a UUID only pattern, which caused encrypted xrc_ IDs and legacy xr_ IDs to be rejected during parse. When those URLs were imported, configProfileId was dropped and the saved profile binding was silently lost.

    This commit replaces the UUID only matcher with a unified CONFIG_PROFILE_ID_RE that accepts all supported profile ID families: UUID v4, xrc_<16 hex>, and xr_<8 hex>. The parsing path now preserves profile IDs consistently across import flows without changing merge precedence behavior.

    Regression coverage includes explicit xrc_ and xr_ parser tests plus request state tests validating UUID profile resolution, explicit URL parameter precedence over saved profile parameters, and parity between generated inline URLs and ?config URLs across poster, backdrop, logo, and thumbnail routes.

  • BUG-89 skip clean style scrim when background opacity is 0

    Clean genre badge rendering still produced the clean style scrim when background opacity was explicitly set to 0, which made fully transparent clean badges impossible and caused a mismatch between requested opacity and rendered output.

    This commit updates the clean style rendering path so the scrim/background layer is skipped when effective clean background opacity resolves to zero, while preserving existing clean text treatment, shadow behavior, and non zero opacity rendering.

    The change keeps clean style visuals deterministic across inline URLs and saved profile URLs where genreBadgeBackgroundOpacity is set to 0.

  • BUG-88 enforce clean text only constraints

    Clean style behavior drifted across configurator state, URL generation, and runtime normalization. Icon and both modes could leak into clean style and non bottom center positions could persist, which produced inconsistent output between saved settings, generated links, and rendered images.

    This commit centralizes clean style coercion through shared helpers so clean style resolves to text mode and bottom center placement unless genre badge mode is explicitly off. The coercion is applied across configurator props normalization, output query generation, runtime request state parsing, and renderer badge building to keep behavior consistent on poster, backdrop, thumbnail, and logo routes.

    Regression coverage was expanded in genre badge, request state, image route badge, and ui config suites to lock clean style mode and placement coercion and ensure clean output remains text only across parsing and rendering paths.

  • BUG-87 prevent clean genre title overlap

    Clean genre badges could overlap the poster title area on some output sizes because clean mode placement short circuited before collision avoidance and because the renderer did not reserve space using the actual clean badge footprint.

    This commit removes the clean mode early return in genre placement so collision rect solving always runs, clamps placement using dynamic min inset, computes clean poster reserved bottom height from the rendered clean badge SVG height, and tracks the clean overlay collision rectangle so later overlays cannot collide into it.

    Coverage was added with a multi size poster placement regression test to verify clean genre badges do not overlap the title region across normal, large, and 4k poster outputs.

  • BUG-86 keep poster genre and clean logo scaling proportional

    Adjust poster genre badge auto scaling to keep normalized visual proportions more stable across normal, large, and 4K outputs while preserving user scale compounding behavior.

    Update poster clean overlay logo sizing so small source logos can upscale proportionally for higher resolution poster renders, preventing undersized 4K logo output.

    Add focused regression coverage for poster genre normalized ratio consistency and 4K clean logo upscale behavior across rendering paths.

  • BUG-80 harden AIOMetadata TV poster target resolution

    Harden AIOMetadata TV export target resolution so poster URLs consistently resolve the correct media target and avoid ambiguous poster selection behavior.

    Align export view and config profile client state handling with the normalized media target path so generated patterns and saved state stay consistent.

    Add targeted regression tests for config profile client state, media target normalization, and UI config serialization to lock the BUG-80 behavior in place.

  • stabilize side placement and grouped age rating behavior

    Allow grouped age rating placement to participate correctly on supported poster side layouts while preserving the intended quality badge side behavior.

    Update poster display preference resolution and quality badge placement controls so grouped certification output does not overlap or drift when side positions are selected.

    Refresh supporting docs and visual reference assets, and add regression coverage for display preference resolution, age rating extraction behavior, quality badge control normalization, and UI config payload handling.

Documentation

  • refresh static doc assets

v1.18.2

13 Apr 06:17
e3fa68b

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Fixed

  • BUG-91 prevent server key exposure and allow tmdb only profile save with server mdb fallback

    Hide server side Fanart, MDBList, and Simkl credential values from configurator env access responses while keeping non sensitive availability flags.

    Decouple profile save gating from config string generation so profile create/update/migrate only require TMDB when server MDBList is configured.

    Add legacy MDBLIST_KEY alias support for server availability checks and update regression tests.

Documentation

  • refresh static doc assets

v1.18.1

13 Apr 04:40
6e99ed0

Choose a tag to compare

Tip

Changelog: read the matching entry or browse the full compare.

Fixed

  • BUG-90 prevent login overwrite of unsaved config

    Add login conflict handling so profile reveal does not silently replace active local configurator edits.

    Introduce explicit conflict resolution actions for loading profile values or keeping web changes.

    Add and update config profile client state tests for conflict detection behavior.

    Verification: pnpm run lint && pnpm run test && pnpm run build

Documentation

  • refresh static doc assets