Skip to content

fix(ui): stabilize library switching and add media sorting#2586

Merged
enoch85 merged 9 commits into
developmentfrom
fix/ui-library-switching
Apr 2, 2026
Merged

fix(ui): stabilize library switching and add media sorting#2586
enoch85 merged 9 commits into
developmentfrom
fix/ui-library-switching

Conversation

@enoch85

@enoch85 enoch85 commented Apr 1, 2026

Copy link
Copy Markdown
Collaborator

Description

Stabilizes library switching, adds media sorting, tightens the first-run navigation flow, and aligns metadata settings with the Arr-style card layout.

Library switching — The library selector now receives its resolved libraries and selected value from the owning page instead of each screen independently re-fetching. This keeps the selector mounted during reloads and prevents accidental refetches on query revalidation.

Sorting — Shared sort field/order types and comparison helpers in @maintainerr/contracts, validated sort/sortOrder query params on server endpoints, and Plex/Jellyfin adapter translation. Overview, Collection Media, and Collection Exclusions expose reusable sort controls. Metadata-backed sort keys (title, rating, air date, watch count) hydrate all matching rows before pagination since those values aren't stored locally. Delete Soonest stays DB-backed (maps to add-date ordering).

Media server setup guard — Non-settings routes redirect to /settings/main when no media server is configured. Blocked nav entries are disabled with a toast.

Metadata settings — Reworked metadata provider settings into Arr-style cards with inline feedback, reserved status space, provider-level primary switching, and focused UI regression coverage.

Shared infinite scroll hook — Extracted duplicated pagination/scroll logic into useInfinitePaginatedList with a shared scroll threshold constant.

Smaller cleanups:

  • Centralize DATA_DIR / database path resolution (dataDir.ts)
  • Shared getAudienceRating helper
  • Null-safe isAbsoluteUrl

Related issue

N/A

Checklist

  • I have read the CONTRIBUTING.md document.
  • I understand the code I am submitting and can explain how it works
  • I have performed a self-review of my code
  • I have linted and formatted my code
  • My changes generate no new warnings
  • New and existing unit tests pass locally with my changes

How to test

  1. Setup guard: Start without a configured media server. Confirm Overview/Rules/Collections/Docs redirect to /settings/main with a toast, and blocked nav entries are disabled.
  2. Library switching: Configure Plex or Jellyfin, open Overview, switch libraries. Confirm the selector stays visible during reloads and library-query revalidation doesn't cause duplicate fetches.
  3. Sorting: Change the sort dropdown in Overview and verify title, air date, rating, and watch-count sorts work (including with search results). Repeat on Collection Media and Collection Exclusions. Verify Delete Soonest appears when deleteAfterDays is set.
  4. Infinite scroll: Scroll to the bottom of Overview, Collection Media, and Collection Exclusions after switching sort options — confirm paging continues correctly.

@enoch85 enoch85 marked this pull request as ready for review April 2, 2026 03:18
@enoch85 enoch85 merged commit 196d496 into development Apr 2, 2026
13 checks passed
@enoch85 enoch85 deleted the fix/ui-library-switching branch April 2, 2026 03:25
maintainerr-automation Bot added a commit that referenced this pull request Apr 3, 2026
* fix(server): Use shared watch state for isWatched and Plex viewCount (#2570)

* Metadata provider abstraction layer with TVDB support (#2573)

* fix: register tvdb cache in CacheManager

* build(deps-dev): bump the nestjs group with 2 updates (#2575)

Bumps the nestjs group with 2 updates: [@nestjs/cli](https://github.com/nestjs/nest-cli) and [@nestjs/schematics](https://github.com/nestjs/schematics).


Updates `@nestjs/cli` from 11.0.16 to 11.0.17
- [Release notes](https://github.com/nestjs/nest-cli/releases)
- [Commits](nestjs/nest-cli@11.0.16...11.0.17)

Updates `@nestjs/schematics` from 11.0.9 to 11.0.10
- [Release notes](https://github.com/nestjs/schematics/releases)
- [Commits](nestjs/schematics@11.0.9...11.0.10)

---
updated-dependencies:
- dependency-name: "@nestjs/cli"
  dependency-version: 11.0.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/schematics"
  dependency-version: 11.0.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nestjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump axios from 1.13.6 to 1.14.0 (#2576)

Bumps [axios](https://github.com/axios/axios) from 1.13.6 to 1.14.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](axios/axios@v1.13.6...v1.14.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump knip from 6.0.6 to 6.1.1 (#2578)

Bumps [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) from 6.0.6 to 6.1.1.
- [Release notes](https://github.com/webpro-nl/knip/releases)
- [Commits](https://github.com/webpro-nl/knip/commits/knip@6.1.1/packages/knip)

---
updated-dependencies:
- dependency-name: knip
  dependency-version: 6.1.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump @tanstack/eslint-plugin-query (#2579)

Bumps [@tanstack/eslint-plugin-query](https://github.com/TanStack/query/tree/HEAD/packages/eslint-plugin-query) from 5.91.4 to 5.96.0.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/eslint-plugin-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/eslint-plugin-query@5.96.0/packages/eslint-plugin-query)

---
updated-dependencies:
- dependency-name: "@tanstack/eslint-plugin-query"
  dependency-version: 5.96.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix(ui): smooth settings refresh and stream warnings + tune flickering and loadingspinner (#2574)

* build(deps): bump react-router-dom from 7.13.1 to 7.13.2 (#2584)

Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 7.13.1 to 7.13.2.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.13.2/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-version: 7.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump ts-jest from 29.4.6 to 29.4.9 (#2583)

Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.4.6 to 29.4.9.
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](kulshekhar/ts-jest@v29.4.6...v29.4.9)

---
updated-dependencies:
- dependency-name: ts-jest
  dependency-version: 29.4.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump @typescript-eslint/eslint-plugin (#2585)

Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.57.2 to 8.58.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix(ui): stabilize library switching and add media sorting (#2586)

* build(deps): bump lodash-es from 4.17.23 to 4.18.1 (#2587)

Bumps [lodash-es](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](lodash/lodash@4.17.23...4.18.1)

---
updated-dependencies:
- dependency-name: lodash-es
  dependency-version: 4.18.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat(metadata): add per-provider metadata refresh action

Adds a "Refresh metadata" button to each provider card in Metadata
Settings. Clicking it:
1. Tests the provider connection as a safety net before touching cache
2. Flushes only that provider's local NodeCache
3. Fires batched refreshItemMetadata calls to Plex/Jellyfin for all
   collection items linked to that provider (fire-and-forget)

Button label is context-aware ("Save to refresh", "Configure to
refresh") and disabled while unsaved changes are pending. Inline
feedback reuses the shared useSettingsFeedback pattern. A server-side
in-progress guard prevents concurrent refreshes of the same provider.

* fix(ui): make overview title sort explicit (#2589)

* build(deps): bump @tanstack/react-query from 5.91.3 to 5.96.1 (#2590)

Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.91.3 to 5.96.1.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.96.1/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.96.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump @tanstack/eslint-plugin-query (#2591)

Bumps [@tanstack/eslint-plugin-query](https://github.com/TanStack/query/tree/HEAD/packages/eslint-plugin-query) from 5.96.0 to 5.96.1.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/eslint-plugin-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/eslint-plugin-query@5.96.1/packages/eslint-plugin-query)

---
updated-dependencies:
- dependency-name: "@tanstack/eslint-plugin-query"
  dependency-version: 5.96.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump lodash from 4.17.23 to 4.18.1 (#2592)

Bumps [lodash](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](lodash/lodash@4.17.23...4.18.1)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.18.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat(metadata): add ID validation and retry path for metadata refresh (#2594)

Introduces media-server-id.utils with heuristic ID classification to
skip foreign-server IDs (e.g. Jellyfin UUIDs stored against a Plex
instance) before queuing metadata refresh requests. Adds a GET-on-failure
retry path in MetadataSettingsService for manual refreshes: on first
failure, looks up the item to get a verified (possibly corrected) ID and
retries once, covering Jellyfin 'Guid can't be empty' corruption scenarios.

* fix: stabilize metadata sourcing and settings feedback flows (#2595)

* fix(ui): use active metadata provider in media modal

* chore(server): clean metadata lint warnings

* change tvdb link

* fix: align settings feedback and persist github cache

* fix(ui): align metadata test button text

* Update API key link in Metadata component

* fix: delete Tautulli config on media server switch to Jellyfin (#2597)

* build(deps): bump the nestjs group with 5 updates (#2598)

Bumps the nestjs group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) | `11.1.17` | `11.1.18` |
| [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) | `11.1.17` | `11.1.18` |
| [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) | `11.1.17` | `11.1.18` |
| [@nestjs/typeorm](https://github.com/nestjs/typeorm) | `11.0.0` | `11.0.1` |
| [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) | `11.1.17` | `11.1.18` |


Updates `@nestjs/common` from 11.1.17 to 11.1.18
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.18/packages/common)

Updates `@nestjs/core` from 11.1.17 to 11.1.18
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.18/packages/core)

Updates `@nestjs/platform-express` from 11.1.17 to 11.1.18
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.18/packages/platform-express)

Updates `@nestjs/typeorm` from 11.0.0 to 11.0.1
- [Release notes](https://github.com/nestjs/typeorm/releases)
- [Commits](nestjs/typeorm@11.0.0...11.0.1)

Updates `@nestjs/testing` from 11.1.17 to 11.1.18
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.18/packages/testing)

---
updated-dependencies:
- dependency-name: "@nestjs/common"
  dependency-version: 11.1.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/core"
  dependency-version: 11.1.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/platform-express"
  dependency-version: 11.1.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/typeorm"
  dependency-version: 11.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/testing"
  dependency-version: 11.1.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nestjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump react-hook-form from 7.72.0 to 7.72.1 (#2599)

Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.72.0 to 7.72.1.
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](react-hook-form/react-hook-form@v7.72.0...v7.72.1)

---
updated-dependencies:
- dependency-name: react-hook-form
  dependency-version: 7.72.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump @tanstack/react-query from 5.96.1 to 5.96.2 (#2600)

Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.96.1 to 5.96.2.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.96.2/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.96.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump @tanstack/eslint-plugin-query (#2601)

Bumps [@tanstack/eslint-plugin-query](https://github.com/TanStack/query/tree/HEAD/packages/eslint-plugin-query) from 5.96.1 to 5.96.2.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/eslint-plugin-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/eslint-plugin-query@5.96.2/packages/eslint-plugin-query)

---
updated-dependencies:
- dependency-name: "@tanstack/eslint-plugin-query"
  dependency-version: 5.96.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: wortmanb <744697+wortmanb@users.noreply.github.com>
Co-authored-by: enoch85 <mailto@danielhansson.nu>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Javiink <43996484+Javiink@users.noreply.github.com>
@maintainerr-automation

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.4.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant