feat(web): Add persistence to unified instance filter in sidebar - #1560
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughReplaces route-encoded unified instance scope with a persisted localStorage-backed hook. Adds Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant UI as Header/Sidebar/MobileFooterNav
participant Hook as usePersistedUnifiedInstanceFilter
participant Storage as localStorage
Note over UI,Hook: User selects or applies a unified scope
User->>UI: select scope / apply
UI->>Hook: saveFilter(normalizedIds)
Hook->>Storage: write key "qui-unified-instance-filter"
Hook->>Hook: dispatch "qui-unified-instance-filter-changed"
Hook->>UI: useSyncExternalStore notifies subscribers (snapshot)
UI->>UI: recompute displayedUnifiedInstanceIds and update UI
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/layout/Sidebar.tsx`:
- Around line 152-156: Introduce a displayedUnifiedInstanceIds derived value
that returns the persistedUnifiedFilter-derived normalized IDs
(persistedNormalizedIds) when no URL scope exists, otherwise returns
effectiveUnifiedInstanceIds, and replace uses of effectiveUnifiedInstanceIds in
checkbox checked state and in toggleUnifiedScopeInstance baseline logic so the
scope menu and badge share the same source of truth; update Sidebar.tsx (and
mirror the same change in Header.tsx and MobileFooterNav.tsx) so the badge
counting, the checkbox state, and the toggleUnifiedScopeInstance function all
use displayedUnifiedInstanceIds instead of effectiveUnifiedInstanceIds.
In `@web/src/hooks/usePersistedUnifiedInstanceFilter.ts`:
- Around line 15-36: The hook usePersistedUnifiedInstanceFilter currently uses
per-component useState (persistedIds) so updates in one component don't
propagate to others; replace the local state with a shared subscription using
useSyncExternalStore: implement a getSnapshot that reads STORAGE_KEY and returns
parseUnifiedInstanceIds(localStorage.getItem(STORAGE_KEY)) (or []), implement a
subscribe function that listens to the window "storage" event and a custom
same-tab event (e.g. "unified-instance-filter-changed") and returns an
unsubscribe, then change saveFilter to write encodeUnifiedInstanceIds to
localStorage (or removeItem), and dispatch the same-tab custom event so
subscribers (via useSyncExternalStore) see immediate updates; keep
parseUnifiedInstanceIds, encodeUnifiedInstanceIds, STORAGE_KEY,
usePersistedUnifiedInstanceFilter, and saveFilter names to locate the code.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: f0946ade-73f1-42b2-a5a1-71a94200a40e
📒 Files selected for processing (4)
web/src/components/layout/Header.tsxweb/src/components/layout/MobileFooterNav.tsxweb/src/components/layout/Sidebar.tsxweb/src/hooks/usePersistedUnifiedInstanceFilter.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/src/components/layout/Header.tsx (1)
111-120: Consider extracting shared persistence logic into the hook.All three layout components (
Header,Sidebar,MobileFooterNav) duplicate the same derived state pattern:const persistedNormalizedIds = useMemo( () => normalizeUnifiedInstanceIds(persistedUnifiedFilter, activeInstanceIds), [persistedUnifiedFilter, activeInstanceIds] ) const displayedUnifiedInstanceIds = hasCustomUnifiedScope ? effectiveUnifiedInstanceIds : persistedNormalizedIds.length > 0 ? persistedNormalizedIds : effectiveUnifiedInstanceIdsThis could be encapsulated in the hook by passing
activeInstanceIdsand the URL-derived scope, returning bothpersistedIdsanddisplayedIds. However, this is a nice-to-have for future cleanup.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/layout/Header.tsx` around lines 111 - 120, The layout components (Header, Sidebar, MobileFooterNav) duplicate logic that computes persistedNormalizedIds and displayedUnifiedInstanceIds; move this derived-state into the usePersistedUnifiedInstanceFilter hook by accepting activeInstanceIds and the URL-derived scope (hasCustomUnifiedScope/effectiveUnifiedInstanceIds) and returning both persistedIds (result of normalizeUnifiedInstanceIds) and displayedIds (the conditional choosing between persistedIds and effectiveUnifiedInstanceIds). Update callers to replace local persistedNormalizedIds and displayedUnifiedInstanceIds with the hook's returned values to eliminate duplication and centralize normalization logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/hooks/usePersistedUnifiedInstanceFilter.ts`:
- Around line 43-55: The event dispatch is outside the try/catch so CHANGE_EVENT
is fired even when localStorage write/remove fails; move
window.dispatchEvent(new Event(CHANGE_EVENT)) inside the try block in the
saveFilter callback (the function named saveFilter in
usePersistedUnifiedInstanceFilter.ts) so the change event is only emitted after
successful encodeUnifiedInstanceIds and localStorage.setItem/removeItem, and
keep the catch to log the error without dispatching the event.
---
Nitpick comments:
In `@web/src/components/layout/Header.tsx`:
- Around line 111-120: The layout components (Header, Sidebar, MobileFooterNav)
duplicate logic that computes persistedNormalizedIds and
displayedUnifiedInstanceIds; move this derived-state into the
usePersistedUnifiedInstanceFilter hook by accepting activeInstanceIds and the
URL-derived scope (hasCustomUnifiedScope/effectiveUnifiedInstanceIds) and
returning both persistedIds (result of normalizeUnifiedInstanceIds) and
displayedIds (the conditional choosing between persistedIds and
effectiveUnifiedInstanceIds). Update callers to replace local
persistedNormalizedIds and displayedUnifiedInstanceIds with the hook's returned
values to eliminate duplication and centralize normalization logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 14b47286-896d-4f23-9a6a-e4de865f0a73
📒 Files selected for processing (4)
web/src/components/layout/Header.tsxweb/src/components/layout/MobileFooterNav.tsxweb/src/components/layout/Sidebar.tsxweb/src/hooks/usePersistedUnifiedInstanceFilter.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/src/components/layout/Sidebar.tsx (1)
135-165: Consider extracting the unified-scope state into a shared hook.This normalize/fallback/apply/toggle flow now lives here, in
web/src/components/layout/MobileFooterNav.tsx, and inHeader.tsx. Pulling it into one hook/helper would make future scope/badge changes land once and reduce drift between the three menus.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/layout/Sidebar.tsx` around lines 135 - 165, Extract the unified-scope logic duplicated across Sidebar.tsx, MobileFooterNav.tsx, and Header.tsx into a shared hook (e.g., useUnifiedScope) that encapsulates state and helpers: usePersistedUnifiedInstanceFilter usage, normalizeUnifiedInstanceIds fallback logic, effectiveUnifiedInstanceIds calculation, hasCustomUnifiedScope, unifiedScopeSummary, applyUnifiedScope (navigate+saveUnifiedFilter behavior) and toggleUnifiedScopeInstance; replace the in-component implementations in Sidebar (functions/variables: usePersistedUnifiedInstanceFilter, normalizeUnifiedInstanceIds, effectiveUnifiedInstanceIds, applyUnifiedScope, toggleUnifiedScopeInstance) with calls to the new hook so all three components consume the same centralized logic and reduce duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/pages/Torrents.tsx`:
- Around line 125-152: The deep-link lookup in fetchTorrentByHash is incorrectly
limited to unifiedScopeInstanceIds, causing /instances?torrent=... to fail when
the owning instance isn't in saved scope; change the logic so that when
resolving a hash (in fetchTorrentByHash / isAllInstances branch using
api.getCrossInstanceTorrents) you query across all active instances (e.g., use
activeInstanceIds or omit instanceIds to search globally) or perform a fallback
unscoped cross-instance lookup if the first scoped call returns null, and only
then clear search params; ensure to reference api.getCrossInstanceTorrents,
unifiedScopeInstanceIds, isAllInstances and the fallback to
api.getTorrents(instanceId, ...) so the code will resolve deep links regardless
of the saved unified scope.
---
Nitpick comments:
In `@web/src/components/layout/Sidebar.tsx`:
- Around line 135-165: Extract the unified-scope logic duplicated across
Sidebar.tsx, MobileFooterNav.tsx, and Header.tsx into a shared hook (e.g.,
useUnifiedScope) that encapsulates state and helpers:
usePersistedUnifiedInstanceFilter usage, normalizeUnifiedInstanceIds fallback
logic, effectiveUnifiedInstanceIds calculation, hasCustomUnifiedScope,
unifiedScopeSummary, applyUnifiedScope (navigate+saveUnifiedFilter behavior) and
toggleUnifiedScopeInstance; replace the in-component implementations in Sidebar
(functions/variables: usePersistedUnifiedInstanceFilter,
normalizeUnifiedInstanceIds, effectiveUnifiedInstanceIds, applyUnifiedScope,
toggleUnifiedScopeInstance) with calls to the new hook so all three components
consume the same centralized logic and reduce duplication.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 09da2d23-6369-4c09-91da-48138c871ff7
📒 Files selected for processing (7)
web/src/components/layout/Header.tsxweb/src/components/layout/MobileFooterNav.tsxweb/src/components/layout/Sidebar.tsxweb/src/lib/instances.tsweb/src/pages/Torrents.tsxweb/src/routes/_authenticated/instances.$instanceId.tsxweb/src/routes/_authenticated/instances.index.tsx
💤 Files with no reviewable changes (3)
- web/src/routes/_authenticated/instances.$instanceId.tsx
- web/src/lib/instances.ts
- web/src/routes/_authenticated/instances.index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- web/src/components/layout/Header.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/src/pages/Torrents.tsx (1)
53-60:⚠️ Potential issue | 🟠 MajorReset unified-view state when the persisted scope changes.
unifiedScopeInstanceIdscan now change without a route change, but this component still treatsinstanceIdas the only page identity. In/instances, switching the saved scope can keep the details panel open for a torrent whose instance is no longer in scope, and the sidebar counts stay marked as fresh until new data lands. Please treat the normalized unified scope as part of this page's identity as well, preferably with akeyor render-time exclusion instead of an Effect.As per coding guidelines, "To reset state in React, prefer a
keyor render-time adjustments instead of Effects".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/pages/Torrents.tsx` around lines 53 - 60, The page must treat the normalized unified scope as part of its identity so state resets when persistedUnifiedFilter changes: compute unifiedScopeInstanceIds (using normalizeUnifiedInstanceIds with persistedUnifiedFilter and activeInstanceIds) as you already do, then include that value in the component tree key (e.g., the root/wrapper component rendered by Torrents.tsx) so React remounts when unifiedScopeInstanceIds changes; use a stable serialization (JSON.stringify or join) of unifiedScopeInstanceIds combined with instanceId/isAllInstances to form the key and remove any Effect-based state reset logic that attempted to watch persistedUnifiedFilter.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/pages/Torrents.tsx`:
- Around line 125-140: The deep-link fetch (fetchTorrentByHash / the
cross-instance branch in the useEffect that reads search.torrent) must be gated
until useInstances has finished loading: check the isLoading flag (from
useInstances) and do not execute the cross-instance API call when isLoading is
true (or when activeInstanceIds is empty while loading); this prevents sending
instanceIds: undefined and consuming the deep link prematurely—either skip the
fetch while isLoading and let the effect re-run when instances resolve, or
retain search.torrent and explicitly retry when activeInstanceIds changes after
isLoading becomes false.
---
Outside diff comments:
In `@web/src/pages/Torrents.tsx`:
- Around line 53-60: The page must treat the normalized unified scope as part of
its identity so state resets when persistedUnifiedFilter changes: compute
unifiedScopeInstanceIds (using normalizeUnifiedInstanceIds with
persistedUnifiedFilter and activeInstanceIds) as you already do, then include
that value in the component tree key (e.g., the root/wrapper component rendered
by Torrents.tsx) so React remounts when unifiedScopeInstanceIds changes; use a
stable serialization (JSON.stringify or join) of unifiedScopeInstanceIds
combined with instanceId/isAllInstances to form the key and remove any
Effect-based state reset logic that attempted to watch persistedUnifiedFilter.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 7a762306-140c-4f19-a61a-6c5c46609973
📒 Files selected for processing (1)
web/src/pages/Torrents.tsx
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.14.1` → `v1.15.0` | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/2) for more information. --- ### Release Notes <details> <summary>autobrr/qui (ghcr.io/autobrr/qui)</summary> ### [`v1.15.0`](https://github.com/autobrr/qui/releases/tag/v1.15.0) [Compare Source](autobrr/qui@v1.14.1...v1.15.0) #### Changelog ##### Breaking change CORS is disabled by default; enable by setting QUI\_\_CORS\_ALLOWED\_ORIGINS with explicit origins (http(s)://host\[:port]). See <https://getqui.com/docs/advanced/sso-proxy-cors> ##### New Features - [`93786a2`](autobrr/qui@93786a2): feat(automations): add configurable processing priority/sorting ([#​1235](autobrr/qui#1235)) ([@​Oscariremma](https://github.com/Oscariremma)) - [`45eaf1f`](autobrr/qui@45eaf1f): feat(database): add postgres and sqlite migration CLI ([#​1530](autobrr/qui#1530)) ([@​s0up4200](https://github.com/s0up4200)) - [`430f5d1`](autobrr/qui@430f5d1): feat(torrents): mediaInfo dialog ([#​1537](autobrr/qui#1537)) ([@​s0up4200](https://github.com/s0up4200)) - [`8eb8903`](autobrr/qui@8eb8903): feat(web): Add persistence to unified instance filter in sidebar ([#​1560](autobrr/qui#1560)) ([@​drtaru](https://github.com/drtaru)) - [`7aadde7`](autobrr/qui@7aadde7): feat(web): add path autocomplete to set location dialog ([#​1432](autobrr/qui#1432)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`077f32c`](autobrr/qui@077f32c): feat: add mediainfo api endpoint ([#​1545](autobrr/qui#1545)) ([@​Audionut](https://github.com/Audionut)) - [`99cf695`](autobrr/qui@99cf695): feat: endpoint to trigger directory scans from external tools ([#​1559](autobrr/qui#1559)) ([@​s0up4200](https://github.com/s0up4200)) - [`8956f9b`](autobrr/qui@8956f9b): feat: unify bulk tag editor ([#​1571](autobrr/qui#1571)) ([@​s0up4200](https://github.com/s0up4200)) ##### Bug Fixes - [`552d617`](autobrr/qui@552d617): fix(api): align add torrent OpenAPI field ([#​1617](autobrr/qui#1617)) ([@​s0up4200](https://github.com/s0up4200)) - [`424f7a0`](autobrr/qui@424f7a0): fix(api): restrict CORS to explicit allowlist ([#​1551](autobrr/qui#1551)) ([@​s0up4200](https://github.com/s0up4200)) - [`38991d8`](autobrr/qui@38991d8): fix(auth): allow loopback health probes ([#​1621](autobrr/qui#1621)) ([@​s0up4200](https://github.com/s0up4200)) - [`4ae88c9`](autobrr/qui@4ae88c9): fix(automations): align include-cross-seeds category apply ([#​1517](autobrr/qui#1517)) ([@​s0up4200](https://github.com/s0up4200)) - [`6a127a8`](autobrr/qui@6a127a8): fix(automations): scope skipWithin to only deleted action ([#​1538](autobrr/qui#1538)) ([@​jabloink](https://github.com/jabloink)) - [`c776189`](autobrr/qui@c776189): fix(crossseed): avoid completion timeout misses on non-Gazelle torrents ([#​1536](autobrr/qui#1536)) ([@​s0up4200](https://github.com/s0up4200)) - [`b1338a7`](autobrr/qui@b1338a7): fix(crossseed): handle missing webhook collection tags ([#​1610](autobrr/qui#1610)) ([@​s0up4200](https://github.com/s0up4200)) - [`eacbb68`](autobrr/qui@eacbb68): fix(crossseed): normalize hdr aliases ([#​1572](autobrr/qui#1572)) ([@​s0up4200](https://github.com/s0up4200)) - [`537ad46`](autobrr/qui@537ad46): fix(crossseed): queue completion searches and retry rate-limit waits ([#​1523](autobrr/qui#1523)) ([@​s0up4200](https://github.com/s0up4200)) - [`4fc550f`](autobrr/qui@4fc550f): fix(crossseed): use autobrr indexer ids for webhooks ([#​1614](autobrr/qui#1614)) ([@​s0up4200](https://github.com/s0up4200)) - [`08029ad`](autobrr/qui@08029ad): fix(crossseed): valid partial matches being rejected ([#​1291](autobrr/qui#1291)) ([@​rybertm](https://github.com/rybertm)) - [`77eedd9`](autobrr/qui@77eedd9): fix(database): avoid postgres temp-table statement caching ([#​1581](autobrr/qui#1581)) ([@​s0up4200](https://github.com/s0up4200)) - [`25daa17`](autobrr/qui@25daa17): fix(dirscan): honor canceled queued webhook runs ([#​1612](autobrr/qui#1612)) ([@​s0up4200](https://github.com/s0up4200)) - [`56995f1`](autobrr/qui@56995f1): fix(dirscan): queue webhook scans and tighten age filtering ([#​1603](autobrr/qui#1603)) ([@​s0up4200](https://github.com/s0up4200)) - [`444d07b`](autobrr/qui@444d07b): fix(dirscan): select concrete hardlink base dir ([#​1606](autobrr/qui#1606)) ([@​s0up4200](https://github.com/s0up4200)) - [`c35bea0`](autobrr/qui@c35bea0): fix(instances): improve settings dialog scrolling ([#​1569](autobrr/qui#1569)) ([@​nuxencs](https://github.com/nuxencs)) - [`dc501a0`](autobrr/qui@dc501a0): fix(proxy): reauth qbit passthrough requests ([#​1582](autobrr/qui#1582)) ([@​s0up4200](https://github.com/s0up4200)) - [`7950d1d`](autobrr/qui@7950d1d): fix(proxy): search endpoint handling ([#​1524](autobrr/qui#1524)) ([@​Audionut](https://github.com/Audionut)) - [`1076eea`](autobrr/qui@1076eea): fix(qbit): prune empty managed dirs after delete\_with\_files ([#​1604](autobrr/qui#1604)) ([@​s0up4200](https://github.com/s0up4200)) - [`5a3114b`](autobrr/qui@5a3114b): fix(qbittorrent): stop reboot torrent\_completed spam ([#​1515](autobrr/qui#1515)) ([@​s0up4200](https://github.com/s0up4200)) - [`1d02e6c`](autobrr/qui@1d02e6c): fix(settings): contain settings tab scrolling ([#​1567](autobrr/qui#1567)) ([@​nuxencs](https://github.com/nuxencs)) - [`f5d69f3`](autobrr/qui@f5d69f3): fix(settings): smoother gradient ([#​1570](autobrr/qui#1570)) ([@​nuxencs](https://github.com/nuxencs)) - [`1c0c3bc`](autobrr/qui@1c0c3bc): fix(torrents): copy MediaInfo summary without brackets ([#​1540](autobrr/qui#1540)) ([@​s0up4200](https://github.com/s0up4200)) - [`3ec913a`](autobrr/qui@3ec913a): fix(web): auto-append slash on path autocomplete selection ([#​1431](autobrr/qui#1431)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`aa2f3da`](autobrr/qui@aa2f3da): fix(web): check field.state.value type in AddTorrentDialog ([#​1613](autobrr/qui#1613)) ([@​s0up4200](https://github.com/s0up4200)) - [`1abfc5e`](autobrr/qui@1abfc5e): fix(web): handle SSO proxy redirect to /index.html ([#​1600](autobrr/qui#1600)) ([@​s0up4200](https://github.com/s0up4200)) - [`1991f90`](autobrr/qui@1991f90): fix(web): warn before enabling reannounce ([#​1583](autobrr/qui#1583)) ([@​s0up4200](https://github.com/s0up4200)) ##### Other Changes - [`4069492`](autobrr/qui@4069492): chore(deps): bump the github group with 3 updates ([#​1535](autobrr/qui#1535)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`a02e9e8`](autobrr/qui@a02e9e8): chore(deps): bump the github group with 7 updates ([#​1558](autobrr/qui#1558)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`8713667`](autobrr/qui@8713667): chore(deps): bump the golang group with 15 updates ([#​1543](autobrr/qui#1543)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`420607e`](autobrr/qui@420607e): chore(go,ci): adopt go fix, bump to 1.26, and speed up PR checks ([#​1480](autobrr/qui#1480)) ([@​s0up4200](https://github.com/s0up4200)) - [`0d0df45`](autobrr/qui@0d0df45): docs: add password reset section to CLI commands ([#​1598](autobrr/qui#1598)) ([@​s0up4200](https://github.com/s0up4200)) - [`9ef56a2`](autobrr/qui@9ef56a2): refactor(makefile): windows support ([#​1546](autobrr/qui#1546)) ([@​Audionut](https://github.com/Audionut)) - [`7899cc8`](autobrr/qui@7899cc8): refactor(reflinking): add windows ReFS filesystem support ([#​1576](autobrr/qui#1576)) ([@​Audionut](https://github.com/Audionut)) - [`51d34ab`](autobrr/qui@51d34ab): refactor(releases): share hdr normalization helpers ([#​1586](autobrr/qui#1586)) ([@​s0up4200](https://github.com/s0up4200)) - [`c7f4e3d`](autobrr/qui@c7f4e3d): refactor(web): tighten unified scope navigation ([#​1618](autobrr/qui#1618)) ([@​s0up4200](https://github.com/s0up4200)) - [`4b05177`](autobrr/qui@4b05177): test(handlers): cover tag baseline field requests ([@​s0up4200](https://github.com/s0up4200)) **Full Changelog**: <autobrr/qui@v1.14.1...v1.15.0> #### Docker images - `docker pull ghcr.io/autobrr/qui:v1.15.0` - `docker pull ghcr.io/autobrr/qui:latest` #### What to do next? - Join our [Discord server](https://discord.autobrr.com/qui) Thank you for using qui! </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=--> Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4884 Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net> Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
… ) (#12) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.14.1` → `v1.19.0` | --- ### Release Notes <details> <summary>autobrr/qui (ghcr.io/autobrr/qui)</summary> ### [`v1.19.0`](https://github.com/autobrr/qui/releases/tag/v1.19.0) [Compare Source](autobrr/qui@v1.18.0...v1.19.0) ##### Changelog ##### New Features - [`e26bd6b`](autobrr/qui@e26bd6b): feat(actions): include web-dist in release artifacts ([#​1801](autobrr/qui#1801)) ([@​turtletowerz](https://github.com/turtletowerz)) - [`2fabce1`](autobrr/qui@2fabce1): feat(automations): add export to instance action ([#​1736](autobrr/qui#1736)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`3fca808`](autobrr/qui@3fca808): feat(instances): api key authentication ([#​1854](autobrr/qui#1854)) ([@​martylukyy](https://github.com/martylukyy)) - [`4ab1a75`](autobrr/qui@4ab1a75): feat(qbittorrent): show process uptime ([#​1849](autobrr/qui#1849)) ([@​s0up4200](https://github.com/s0up4200)) - [`292ef70`](autobrr/qui@292ef70): feat(torrents): hide filter icon when not active or hovering over ([#​1869](autobrr/qui#1869)) ([@​martylukyy](https://github.com/martylukyy)) - [`3c5cf3b`](autobrr/qui@3c5cf3b): feat(torrents): implement auto-fit width for columns on double-click ([#​1867](autobrr/qui#1867)) ([@​martylukyy](https://github.com/martylukyy)) - [`5a9c538`](autobrr/qui@5a9c538): feat(torrents): set comment ([#​1928](autobrr/qui#1928)) ([@​martylukyy](https://github.com/martylukyy)) - [`754f642`](autobrr/qui@754f642): feat(torrents): support new share limit parameters ([#​1872](autobrr/qui#1872)) ([@​martylukyy](https://github.com/martylukyy)) - [`06a5fb6`](autobrr/qui@06a5fb6): feat(torrents): update AddTorrent methods for qbit 5.2.x support ([#​1902](autobrr/qui#1902)) ([@​zze0s](https://github.com/zze0s)) - [`45e3adc`](autobrr/qui@45e3adc): feat: add support for monitored folders ([#​1847](autobrr/qui#1847)) ([@​martylukyy](https://github.com/martylukyy)) ##### Bug Fixes - [`77c7ae8`](autobrr/qui@77c7ae8): fix(automations): discard add torrent response ([#​1904](autobrr/qui#1904)) ([@​s0up4200](https://github.com/s0up4200)) - [`7a368f1`](autobrr/qui@7a368f1): fix(ci): repair docs and release builds ([#​1932](autobrr/qui#1932)) ([@​s0up4200](https://github.com/s0up4200)) - [`8bd114e`](autobrr/qui@8bd114e): fix(crossseed): normalize empty qbit metadata ([#​1887](autobrr/qui#1887)) ([@​s0up4200](https://github.com/s0up4200)) - [`92d66f9`](autobrr/qui@92d66f9): fix(crossseed): reuse shared string normalizer to stop goroutine leak ([#​1909](autobrr/qui#1909)) ([@​s0up4200](https://github.com/s0up4200)) - [`3c5d32a`](autobrr/qui@3c5d32a): fix(crossseed): run external programs after link-mode injection ([#​1874](autobrr/qui#1874)) ([@​s0up4200](https://github.com/s0up4200)) - [`b02d2a9`](autobrr/qui@b02d2a9): fix(qbittorrent): handle forced subcategories ([#​1863](autobrr/qui#1863)) ([@​s0up4200](https://github.com/s0up4200)) - [`83cdb01`](autobrr/qui@83cdb01): fix(qbittorrent): handle new tracker statuses ([#​1879](autobrr/qui#1879)) ([@​s0up4200](https://github.com/s0up4200)) - [`b358ab4`](autobrr/qui@b358ab4): fix(rss): mirror torrentParams to legacy flat fields for qBit < 5.0 compat ([#​1846](autobrr/qui#1846)) ([@​frrad](https://github.com/frrad)) - [`5bcf648`](autobrr/qui@5bcf648): fix(seasonpacker): windows path handling ([#​1910](autobrr/qui#1910)) ([@​Audionut](https://github.com/Audionut)) - [`7de10c4`](autobrr/qui@7de10c4): fix(torrents): clear filters in unified-view empty state ([#​1898](autobrr/qui#1898)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`38f7bd3`](autobrr/qui@38f7bd3): fix(web): Show collapsed folders when searching torrent contents ([#​1850](autobrr/qui#1850)) ([@​ewenjo](https://github.com/ewenjo)) - [`d70d0bb`](autobrr/qui@d70d0bb): fix(web): keep showing torrent column filter icons on touch devices ([#​1881](autobrr/qui#1881)) ([@​martylukyy](https://github.com/martylukyy)) - [`cecbad7`](autobrr/qui@cecbad7): fix(web): select-all bulk actions delete more torrents than visible when filters are stacked ([#​1926](autobrr/qui#1926)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`780c4aa`](autobrr/qui@780c4aa): fix(web): sidebar element collisions ([#​1876](autobrr/qui#1876)) ([@​martylukyy](https://github.com/martylukyy)) - [`b621973`](autobrr/qui@b621973): fix(web): use unique keys for duplicate search results ([#​1886](autobrr/qui#1886)) ([@​GtwoK](https://github.com/GtwoK)) ##### Other Changes - [`ffda071`](autobrr/qui@ffda071): chore(deps): bump [@​babel/plugin-transform-modules-systemjs](https://github.com/babel/plugin-transform-modules-systemjs) from 7.28.5 to 7.29.4 in /documentation ([#​1889](autobrr/qui#1889)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`89ab1c8`](autobrr/qui@89ab1c8): chore(deps): bump [@​babel/plugin-transform-modules-systemjs](https://github.com/babel/plugin-transform-modules-systemjs) from 7.29.0 to 7.29.4 in /web ([#​1888](autobrr/qui#1888)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`c420bb2`](autobrr/qui@c420bb2): chore(deps): bump follow-redirects from 1.15.11 to 1.16.0 in /documentation ([#​1903](autobrr/qui#1903)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`28e4bf9`](autobrr/qui@28e4bf9): chore(deps): bump the github group with 2 updates ([#​1894](autobrr/qui#1894)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`9b241de`](autobrr/qui@9b241de): chore(deps): bump the github group with 3 updates ([#​1861](autobrr/qui#1861)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`4872577`](autobrr/qui@4872577): chore(deps): bump webpack-dev-server from 5.2.2 to 5.2.4 in /documentation ([#​1908](autobrr/qui#1908)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`3e3ec8b`](autobrr/qui@3e3ec8b): chore(deps): bump ws from 8.18.3 to 8.20.1 in /documentation ([#​1907](autobrr/qui#1907)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`25cf511`](autobrr/qui@25cf511): chore(web): migrate to pnpm 11 ([#​1883](autobrr/qui#1883)) ([@​martylukyy](https://github.com/martylukyy)) - [`4b6dce1`](autobrr/qui@4b6dce1): docs: add shared agent instructions symlink ([#​1911](autobrr/qui#1911)) ([@​Audionut](https://github.com/Audionut)) - [`97df42c`](autobrr/qui@97df42c): other(docs): resolve 5 Dependabot security alerts on Docs Site ([#​1906](autobrr/qui#1906)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`5068a4d`](autobrr/qui@5068a4d): refactor(crossseed): gather all results for matching and refine TV based searching ([#​1871](autobrr/qui#1871)) ([@​Audionut](https://github.com/Audionut)) - [`9d3e245`](autobrr/qui@9d3e245): refactor(crossseed): improve anime/AKA handling ([#​1882](autobrr/qui#1882)) ([@​Audionut](https://github.com/Audionut)) - [`6f2b94c`](autobrr/qui@6f2b94c): refactor(torrents): drop unused rename props from TorrentContextMenu ([#​1900](autobrr/qui#1900)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`3ec0605`](autobrr/qui@3ec0605): refactor(web): clean up 180 multiline-ternary warnings repo-wide ([#​1905](autobrr/qui#1905)) ([@​nitrobass24](https://github.com/nitrobass24)) **Full Changelog**: <autobrr/qui@v1.18.0...v1.19.0> ##### Docker images - `docker pull ghcr.io/autobrr/qui:v1.19.0` - `docker pull ghcr.io/autobrr/qui:latest` ##### What to do next? - Join our [Discord server](https://discord.autobrr.com/qui) Thank you for using qui! ### [`v1.18.0`](https://github.com/autobrr/qui/releases/tag/v1.18.0) [Compare Source](autobrr/qui@v1.17.0...v1.18.0) ##### Changelog ##### New Features - [`b708bc8`](autobrr/qui@b708bc8): feat(automations): add UPLOADED\_OVER\_SIZE condition field ([#​1830](autobrr/qui#1830)) ([@​com6056](https://github.com/com6056)) - [`565731e`](autobrr/qui@565731e): feat(automations): cross-instance HARDLINK\_SCOPE\_CROSS ([#​1810](autobrr/qui#1810)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`a284860`](autobrr/qui@a284860): feat(dirscan): add webhook download client filters ([#​1751](autobrr/qui#1751)) ([@​s0up4200](https://github.com/s0up4200)) - [`fd54124`](autobrr/qui@fd54124): feat(web): Add option to copy magnet link from the context menu ([#​1835](autobrr/qui#1835)) ([@​pietrocaselani](https://github.com/pietrocaselani)) ##### Bug Fixes - [`ea33304`](autobrr/qui@ea33304): fix(crossseed): broaden TV/movie torznab categories and skip year on TV ([#​1822](autobrr/qui#1822)) ([@​imSp4rky](https://github.com/imSp4rky)) - [`3c3f944`](autobrr/qui@3c3f944): fix(license): unblock stale polar license migration ([#​1799](autobrr/qui#1799)) ([@​s0up4200](https://github.com/s0up4200)) - [`941cf42`](autobrr/qui@941cf42): fix(qbit): stop serving stale maindata to the status bar ([#​1785](autobrr/qui#1785)) ([@​Zariel](https://github.com/Zariel)) - [`ca7590a`](autobrr/qui@ca7590a): fix(rss): populate legacy assignedCategory for qBittorrent < 5.0 comp… ([#​1836](autobrr/qui#1836)) ([@​frrad](https://github.com/frrad)) - [`278441a`](autobrr/qui@278441a): fix(settings): explain disabled API keys ([#​1826](autobrr/qui#1826)) ([@​s0up4200](https://github.com/s0up4200)) - [`0f4eb52`](autobrr/qui@0f4eb52): fix(web): remove deprecated tsconfig baseUrl ([#​1840](autobrr/qui#1840)) ([@​s0up4200](https://github.com/s0up4200)) ##### Other Changes - [`c6dbf9a`](autobrr/qui@c6dbf9a): chore(deps): bump postcss from 8.5.6 to 8.5.10 in /documentation ([#​1837](autobrr/qui#1837)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`053c171`](autobrr/qui@053c171): chore(deps): bump the github group across 1 directory with 3 updates ([#​1834](autobrr/qui#1834)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`4cbedac`](autobrr/qui@4cbedac): chore(deps): bump the golang group with 15 updates ([#​1832](autobrr/qui#1832)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`dd661e8`](autobrr/qui@dd661e8): chore(deps): bump the npm group in /web with 20 updates ([#​1833](autobrr/qui#1833)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`82029d6`](autobrr/qui@82029d6): chore(deps): update go-qbittorrent for new qbt 5.2.x webAPI version ([#​1841](autobrr/qui#1841)) ([@​martylukyy](https://github.com/martylukyy)) - [`6b5b82e`](autobrr/qui@6b5b82e): refactor(time): use seconds and cleanup ([#​1823](autobrr/qui#1823)) ([@​Audionut](https://github.com/Audionut)) - [`f5cb0c1`](autobrr/qui@f5cb0c1): refactor: O(n²) cross-seed lookups in automations preview and execution paths ([#​1829](autobrr/qui#1829)) ([@​nitrobass24](https://github.com/nitrobass24)) **Full Changelog**: <autobrr/qui@v1.17.0...v1.18.0> ##### Docker images - `docker pull ghcr.io/autobrr/qui:v1.18.0` - `docker pull ghcr.io/autobrr/qui:latest` ##### What to do next? - Join our [Discord server](https://discord.autobrr.com/qui) Thank you for using qui! ### [`v1.17.0`](https://github.com/autobrr/qui/releases/tag/v1.17.0) [Compare Source](autobrr/qui@v1.16.1...v1.17.0) ##### Changelog ##### Bug Fixes - [`52c5e73`](autobrr/qui@52c5e73): fix(automations): clarify cross-seed condition labels ([#​1763](autobrr/qui#1763)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`70e0032`](autobrr/qui@70e0032): fix(crossseed): skip link-mode category path warnings ([#​1753](autobrr/qui#1753)) ([@​s0up4200](https://github.com/s0up4200)) - [`85df3e7`](autobrr/qui@85df3e7): fix(orphanscan): align content path root detection ([#​1771](autobrr/qui#1771)) ([@​s0up4200](https://github.com/s0up4200)) - [`117d617`](autobrr/qui@117d617): fix(orphanscan): ignore qBittorrent incomplete files ([#​1761](autobrr/qui#1761)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`388415e`](autobrr/qui@388415e): fix(web): fix add torrent/magnet urls ([#​1762](autobrr/qui#1762)) ([@​nitrobass24](https://github.com/nitrobass24)) ##### Other Changes - [`845599a`](autobrr/qui@845599a): chore(ci): speed up CI pipeline (9.3 min → 4.3 min for PRs) ([#​1750](autobrr/qui#1750)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`2b09cf3`](autobrr/qui@2b09cf3): chore: trim embedded web assets and Docker build context ([#​1723](autobrr/qui#1723)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`5262f7c`](autobrr/qui@5262f7c): docs: add migration PR guidance ([#​1748](autobrr/qui#1748)) ([@​s0up4200](https://github.com/s0up4200)) - [`65c7046`](autobrr/qui@65c7046): refactor(search): table & cards cleanup ([#​1768](autobrr/qui#1768)) ([@​nuxencs](https://github.com/nuxencs)) **Full Changelog**: <autobrr/qui@v1.16.1...v1.17.0> ##### Docker images - `docker pull ghcr.io/autobrr/qui:v1.17.0` - `docker pull ghcr.io/autobrr/qui:latest` ##### What to do next? - Join our [Discord server](https://discord.autobrr.com/qui) Thank you for using qui! ### [`v1.16.1`](https://github.com/autobrr/qui/releases/tag/v1.16.1) [Compare Source](autobrr/qui@v1.16.0...v1.16.1) ##### Changelog ##### Bug Fixes - [`e177ad9`](autobrr/qui@e177ad9): fix(auth): harden OIDC PKCE flow ([#​1746](autobrr/qui#1746)) ([@​s0up4200](https://github.com/s0up4200)) - [`393e2b7`](autobrr/qui@393e2b7): fix(dirscan): tighten flexible matching and improve diagnostics ([#​1742](autobrr/qui#1742)) ([@​s0up4200](https://github.com/s0up4200)) **Full Changelog**: <autobrr/qui@v1.16.0...v1.16.1> ##### Docker images - `docker pull ghcr.io/autobrr/qui:v1.16.1` - `docker pull ghcr.io/autobrr/qui:latest` ##### What to do next? - Join our [Discord server](https://discord.autobrr.com/qui) Thank you for using qui! ### [`v1.16.0`](https://github.com/autobrr/qui/releases/tag/v1.16.0) [Compare Source](autobrr/qui@v1.15.0...v1.16.0) ##### Changelog ##### Highlights - Automations got a major upgrade: rules can now match across instances, use system time, control AutoTMM, and opt out of notifications per workflow. - Cross-seed is more reliable during state changes. Completion searches now wait for torrents to finish checking or moving, disabled instances are skipped cleanly, and hardlink/reflink save-path handling is more accurate. - Dir Scan works better with real media libraries, with improved partial season-pack handling in link-tree mode, support for downloading missing files when needed, and better progress retention across restarts. - Managing torrents in the unified view is smoother, with more accurate tracker health, quicker instance-level actions, and more stable category and tag editing dialogs. - OIDC and backups both got practical quality-of-life improvements: OIDC now supports PKCE, backup settings can be applied across instances, and backup export handling is safer for tricky torrent layouts. ##### New Features - [`2b92c7b`](autobrr/qui@2b92c7b): feat(auth): add PKCE support to OIDC implementation ([#​1737](autobrr/qui#1737)) ([@​oynqr](https://github.com/oynqr)) - [`ba3d5d9`](autobrr/qui@ba3d5d9): feat(automations): add AutoTMM condition and action ([#​1698](autobrr/qui#1698)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`702e808`](autobrr/qui@702e808): feat(automations): add system time to query builder ([#​1677](autobrr/qui#1677)) ([@​wastaken7](https://github.com/wastaken7)) - [`e6493b3`](autobrr/qui@e6493b3): feat(automations): allow disable of notifications ([#​1652](autobrr/qui#1652)) ([@​heathlarsen](https://github.com/heathlarsen)) - [`565ac2d`](autobrr/qui@565ac2d): feat(automations): cross instance condition ([#​1648](autobrr/qui#1648)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`7e12a02`](autobrr/qui@7e12a02): feat(update): verify self-updates with signed release checksums ([#​1665](autobrr/qui#1665)) ([@​s0up4200](https://github.com/s0up4200)) - [`3778c7b`](autobrr/qui@3778c7b): feat(web): Add action buttons to unified instance. ([#​1637](autobrr/qui#1637)) ([@​drtaru](https://github.com/drtaru)) - [`bf9eaba`](autobrr/qui@bf9eaba): feat(web): Clarify dashboard quick links ([#​1636](autobrr/qui#1636)) ([@​drtaru](https://github.com/drtaru)) - [`b930530`](autobrr/qui@b930530): feat(web): add "Save changes to all instances" button to backup settings ([#​1651](autobrr/qui#1651)) ([@​drtaru](https://github.com/drtaru)) - [`5975c34`](autobrr/qui@5975c34): feat(web): add Discord perk section to license manager ([#​1656](autobrr/qui#1656)) ([@​s0up4200](https://github.com/s0up4200)) - [`d8ad0d6`](autobrr/qui@d8ad0d6): feat(web): unify tab styling and animations ([#​1632](autobrr/qui#1632)) ([@​nuxencs](https://github.com/nuxencs)) ##### Bug Fixes - [`44596b9`](autobrr/qui@44596b9): fix(automations): add AutoTMM to condition validation ([#​1726](autobrr/qui#1726)) ([@​s0up4200](https://github.com/s0up4200)) - [`8f757b2`](autobrr/qui@8f757b2): fix(automations): hardlink signature grouping ([#​1670](autobrr/qui#1670)) ([@​aulterego](https://github.com/aulterego)) - [`d242f0c`](autobrr/qui@d242f0c): fix(automations): include AutoManagement in delete standalone check ([#​1731](autobrr/qui#1731)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`744bdb8`](autobrr/qui@744bdb8): fix(backups): adaptive export throttle ([#​1630](autobrr/qui#1630)) ([@​s0up4200](https://github.com/s0up4200)) - [`d1dbb81`](autobrr/qui@d1dbb81): fix(backups): gate bulk save on resolved instance capabilities ([#​1682](autobrr/qui#1682)) ([@​s0up4200](https://github.com/s0up4200)) - [`2eea961`](autobrr/qui@2eea961): fix(backups): skip live export for hybrid torrents ([#​1669](autobrr/qui#1669)) ([@​s0up4200](https://github.com/s0up4200)) - [`2cac32d`](autobrr/qui@2cac32d): fix(crossseed): skip disabled instances ([#​1635](autobrr/qui#1635)) ([@​s0up4200](https://github.com/s0up4200)) - [`ebbba8e`](autobrr/qui@ebbba8e): fix(crossseed): tone down async cache reuse log ([#​1686](autobrr/qui#1686)) ([@​s0up4200](https://github.com/s0up4200)) - [`fd382b7`](autobrr/qui@fd382b7): fix(dirscan): link plan size tolerance + partial season pack injection in link tree mode ([#​1695](autobrr/qui#1695)) ([@​s0up4200](https://github.com/s0up4200)) - [`5131092`](autobrr/qui@5131092): fix(dirscan): retain recent runs and clarify restart behavior ([#​1564](autobrr/qui#1564)) ([@​s0up4200](https://github.com/s0up4200)) - [`3fbcc7a`](autobrr/qui@3fbcc7a): fix(openapi): document dirscan downloadMissingFiles ([#​1727](autobrr/qui#1727)) ([@​s0up4200](https://github.com/s0up4200)) - [`d16fee2`](autobrr/qui@d16fee2): fix(orphanscan): use content\_path to prevent false positives when Auto TMM changes save\_path ([#​1712](autobrr/qui#1712)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`e74bf02`](autobrr/qui@e74bf02): fix(qbittorrent): avoid tracker health URL false positives ([#​1738](autobrr/qui#1738)) ([@​s0up4200](https://github.com/s0up4200)) - [`632fc54`](autobrr/qui@632fc54): fix(torrents): honor tracker health in unified view ([#​1668](autobrr/qui#1668)) ([@​s0up4200](https://github.com/s0up4200)) - [`76fddc4`](autobrr/qui@76fddc4): fix(torrents): stabilize tag and category dialogs ([#​1638](autobrr/qui#1638)) ([@​s0up4200](https://github.com/s0up4200)) - [`c758b6d`](autobrr/qui@c758b6d): fix(torrents): validate creator output path ([#​1739](autobrr/qui#1739)) ([@​s0up4200](https://github.com/s0up4200)) - [`6c23f0e`](autobrr/qui@6c23f0e): fix(web): cross-seed warning in unified view ([#​1692](autobrr/qui#1692)) ([@​s0up4200](https://github.com/s0up4200)) - [`57822c0`](autobrr/qui@57822c0): fix(web): improve duplicate torrent state and check another field.state.value type in AddTorrentDialog ([#​1679](autobrr/qui#1679)) ([@​keatonhasse](https://github.com/keatonhasse)) - [`246c8f6`](autobrr/qui@246c8f6): fix(web): migrate vite chunk splitting config ([@​s0up4200](https://github.com/s0up4200)) ##### Other Changes - [`263b0bd`](autobrr/qui@263b0bd): build(deps): add cooldown to dependabot config ([#​1691](autobrr/qui#1691)) ([@​s0up4200](https://github.com/s0up4200)) - [`a394157`](autobrr/qui@a394157): chore(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 ([#​1713](autobrr/qui#1713)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`10612a7`](autobrr/qui@10612a7): chore(deps): bump golang.org/x/image from 0.36.0 to 0.38.0 ([#​1685](autobrr/qui#1685)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`16019dd`](autobrr/qui@16019dd): chore(deps): bump pnpm/action-setup from 4 to 5 in the github group ([#​1634](autobrr/qui#1634)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`fbb25fc`](autobrr/qui@fbb25fc): chore(deps): bump the golang group with 11 updates ([#​1693](autobrr/qui#1693)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`cbb9594`](autobrr/qui@cbb9594): chore(deps): bump the golang group with 3 updates ([#​1701](autobrr/qui#1701)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`805ab74`](autobrr/qui@805ab74): chore(deps): bump the npm group in /web with 25 updates ([#​1694](autobrr/qui#1694)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`e3f839c`](autobrr/qui@e3f839c): chore(deps): bump the npm group in /web with 5 updates ([#​1702](autobrr/qui#1702)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`b076ad4`](autobrr/qui@b076ad4): docs(dirscan): clarify re-identification after torrent removal ([#​1720](autobrr/qui#1720)) ([@​s0up4200](https://github.com/s0up4200)) - [`340f343`](autobrr/qui@340f343): docs: add license management page with deactivation guide ([#​1706](autobrr/qui#1706)) ([@​s0up4200](https://github.com/s0up4200)) - [`5d148be`](autobrr/qui@5d148be): docs: fix link in issue triage template ([@​s0up4200](https://github.com/s0up4200)) - [`0b64237`](autobrr/qui@0b64237): docs: update release follow-up docs ([#​1741](autobrr/qui#1741)) ([@​s0up4200](https://github.com/s0up4200)) **Full Changelog**: <autobrr/qui@v1.15.0...v1.16.0> ##### Docker images - `docker pull ghcr.io/autobrr/qui:v1.16.0` - `docker pull ghcr.io/autobrr/qui:latest` ##### What to do next? - Join our [Discord server](https://discord.autobrr.com/qui) Thank you for using qui! ### [`v1.15.0`](https://github.com/autobrr/qui/releases/tag/v1.15.0) [Compare Source](autobrr/qui@v1.14.1...v1.15.0) ##### Changelog ##### Breaking change CORS is disabled by default; enable by setting QUI\_\_CORS\_ALLOWED\_ORIGINS with explicit origins (http(s)://host\[:port]). See <https://getqui.com/docs/advanced/sso-proxy-cors> ##### New Features - [`93786a2`](autobrr/qui@93786a2): feat(automations): add configurable processing priority/sorting ([#​1235](autobrr/qui#1235)) ([@​Oscariremma](https://github.com/Oscariremma)) - [`45eaf1f`](autobrr/qui@45eaf1f): feat(database): add postgres and sqlite migration CLI ([#​1530](autobrr/qui#1530)) ([@​s0up4200](https://github.com/s0up4200)) - [`430f5d1`](autobrr/qui@430f5d1): feat(torrents): mediaInfo dialog ([#​1537](autobrr/qui#1537)) ([@​s0up4200](https://github.com/s0up4200)) - [`8eb8903`](autobrr/qui@8eb8903): feat(web): Add persistence to unified instance filter in sidebar ([#​1560](autobrr/qui#1560)) ([@​drtaru](https://github.com/drtaru)) - [`7aadde7`](autobrr/qui@7aadde7): feat(web): add path autocomplete to set location dialog ([#​1432](autobrr/qui#1432)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`077f32c`](autobrr/qui@077f32c): feat: add mediainfo api endpoint ([#​1545](autobrr/qui#1545)) ([@​Audionut](https://github.com/Audionut)) - [`99cf695`](autobrr/qui@99cf695): feat: endpoint to trigger directory scans from external tools ([#​1559](autobrr/qui#1559)) ([@​s0up4200](https://github.com/s0up4200)) - [`8956f9b`](autobrr/qui@8956f9b): feat: unify bulk tag editor ([#​1571](autobrr/qui#1571)) ([@​s0up4200](https://github.com/s0up4200)) ##### Bug Fixes - [`552d617`](autobrr/qui@552d617): fix(api): align add torrent OpenAPI field ([#​1617](autobrr/qui#1617)) ([@​s0up4200](https://github.com/s0up4200)) - [`424f7a0`](autobrr/qui@424f7a0): fix(api): restrict CORS to explicit allowlist ([#​1551](autobrr/qui#1551)) ([@​s0up4200](https://github.com/s0up4200)) - [`38991d8`](autobrr/qui@38991d8): fix(auth): allow loopback health probes ([#​1621](autobrr/qui#1621)) ([@​s0up4200](https://github.com/s0up4200)) - [`4ae88c9`](autobrr/qui@4ae88c9): fix(automations): align include-cross-seeds category apply ([#​1517](autobrr/qui#1517)) ([@​s0up4200](https://github.com/s0up4200)) - [`6a127a8`](autobrr/qui@6a127a8): fix(automations): scope skipWithin to only deleted action ([#​1538](autobrr/qui#1538)) ([@​jabloink](https://github.com/jabloink)) - [`c776189`](autobrr/qui@c776189): fix(crossseed): avoid completion timeout misses on non-Gazelle torrents ([#​1536](autobrr/qui#1536)) ([@​s0up4200](https://github.com/s0up4200)) - [`b1338a7`](autobrr/qui@b1338a7): fix(crossseed): handle missing webhook collection tags ([#​1610](autobrr/qui#1610)) ([@​s0up4200](https://github.com/s0up4200)) - [`eacbb68`](autobrr/qui@eacbb68): fix(crossseed): normalize hdr aliases ([#​1572](autobrr/qui#1572)) ([@​s0up4200](https://github.com/s0up4200)) - [`537ad46`](autobrr/qui@537ad46): fix(crossseed): queue completion searches and retry rate-limit waits ([#​1523](autobrr/qui#1523)) ([@​s0up4200](https://github.com/s0up4200)) - [`4fc550f`](autobrr/qui@4fc550f): fix(crossseed): use autobrr indexer ids for webhooks ([#​1614](autobrr/qui#1614)) ([@​s0up4200](https://github.com/s0up4200)) - [`08029ad`](autobrr/qui@08029ad): fix(crossseed): valid partial matches being rejected ([#​1291](autobrr/qui#1291)) ([@​rybertm](https://github.com/rybertm)) - [`77eedd9`](autobrr/qui@77eedd9): fix(database): avoid postgres temp-table statement caching ([#​1581](autobrr/qui#1581)) ([@​s0up4200](https://github.com/s0up4200)) - [`25daa17`](autobrr/qui@25daa17): fix(dirscan): honor canceled queued webhook runs ([#​1612](autobrr/qui#1612)) ([@​s0up4200](https://github.com/s0up4200)) - [`56995f1`](autobrr/qui@56995f1): fix(dirscan): queue webhook scans and tighten age filtering ([#​1603](autobrr/qui#1603)) ([@​s0up4200](https://github.com/s0up4200)) - [`444d07b`](autobrr/qui@444d07b): fix(dirscan): select concrete hardlink base dir ([#​1606](autobrr/qui#1606)) ([@​s0up4200](https://github.com/s0up4200)) - [`c35bea0`](autobrr/qui@c35bea0): fix(instances): improve settings dialog scrolling ([#​1569](autobrr/qui#1569)) ([@​nuxencs](https://github.com/nuxencs)) - [`dc501a0`](autobrr/qui@dc501a0): fix(proxy): reauth qbit passthrough requests ([#​1582](autobrr/qui#1582)) ([@​s0up4200](https://github.com/s0up4200)) - [`7950d1d`](autobrr/qui@7950d1d): fix(proxy): search endpoint handling ([#​1524](autobrr/qui#1524)) ([@​Audionut](https://github.com/Audionut)) - [`1076eea`](autobrr/qui@1076eea): fix(qbit): prune empty managed dirs after delete\_with\_files ([#​1604](autobrr/qui#1604)) ([@​s0up4200](https://github.com/s0up4200)) - [`5a3114b`](autobrr/qui@5a3114b): fix(qbittorrent): stop reboot torrent\_completed spam ([#​1515](autobrr/qui#1515)) ([@​s0up4200](https://github.com/s0up4200)) - [`1d02e6c`](autobrr/qui@1d02e6c): fix(settings): contain settings tab scrolling ([#​1567](autobrr/qui#1567)) ([@​nuxencs](https://github.com/nuxencs)) - [`f5d69f3`](autobrr/qui@f5d69f3): fix(settings): smoother gradient ([#​1570](autobrr/qui#1570)) ([@​nuxencs](https://github.com/nuxencs)) - [`1c0c3bc`](autobrr/qui@1c0c3bc): fix(torrents): copy MediaInfo summary without brackets ([#​1540](autobrr/qui#1540)) ([@​s0up4200](https://github.com/s0up4200)) - [`3ec913a`](autobrr/qui@3ec913a): fix(web): auto-append slash on path autocomplete selection ([#​1431](autobrr/qui#1431)) ([@​nitrobass24](https://github.com/nitrobass24)) - [`aa2f3da`](autobrr/qui@aa2f3da): fix(web): check field.state.value type in AddTorrentDialog ([#​1613](autobrr/qui#1613)) ([@​s0up4200](https://github.com/s0up4200)) - [`1abfc5e`](autobrr/qui@1abfc5e): fix(web): handle SSO proxy redirect to /index.html ([#​1600](autobrr/qui#1600)) ([@​s0up4200](https://github.com/s0up4200)) - [`1991f90`](autobrr/qui@1991f90): fix(web): warn before enabling reannounce ([#​1583](autobrr/qui#1583)) ([@​s0up4200](https://github.com/s0up4200)) ##### Other Changes - [`4069492`](autobrr/qui@4069492): chore(deps): bump the github group with 3 updates ([#​1535](autobrr/qui#1535)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`a02e9e8`](autobrr/qui@a02e9e8): chore(deps): bump the github group with 7 updates ([#​1558](autobrr/qui#1558)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`8713667`](autobrr/qui@8713667): chore(deps): bump the golang group with 15 updates ([#​1543](autobrr/qui#1543)) ([@​dependabot](https://github.com/dependabot)\[bot]) - [`420607e`](autobrr/qui@420607e): chore(go,ci): adopt go fix, bump to 1.26, and speed up PR checks ([#​1480](autobrr/qui#1480)) ([@​s0up4200](https://github.com/s0up4200)) - [`0d0df45`](autobrr/qui@0d0df45): docs: add password reset section to CLI commands ([#​1598](autobrr/qui#1598)) ([@​s0up4200](https://github.com/s0up4200)) - [`9ef56a2`](autobrr/qui@9ef56a2): refactor(makefile): windows support ([#​1546](autobrr/qui#1546)) ([@​Audionut](https://github.com/Audionut)) - [`7899cc8`](autobrr/qui@7899cc8): refactor(reflinking): add windows ReFS filesystem support ([#​1576](autobrr/qui#1576)) ([@​Audionut](https://github.com/Audionut)) - [`51d34ab`](autobrr/qui@51d34ab): refactor(releases): share hdr normalization helpers ([#​1586](autobrr/qui#1586)) ([@​s0up4200](https://github.com/s0up4200)) - [`c7f4e3d`](autobrr/qui@c7f4e3d): refactor(web): tighten unified scope navigation ([#​1618](autobrr/qui#1618)) ([@​s0up4200](https://github.com/s0up4200)) - [`4b05177`](autobrr/qui@4b05177): test(handlers): cover tag baseline field requests ([@​s0up4200](https://github.com/s0up4200)) **Full Changelog**: <autobrr/qui@v1.14.1...v1.15.0> ##### Docker images - `docker pull ghcr.io/autobrr/qui:v1.15.0` - `docker pull ghcr.io/autobrr/qui:latest` ##### What to do next? - Join our [Discord server](https://discord.autobrr.com/qui) Thank you for using qui! </details> --- ### Configuration 📅 **Schedule**: (in timezone Europe/London) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTUuMSIsInVwZGF0ZWRJblZlciI6IjQzLjE5NS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Reviewed-on: https://forgejo.hayden.moe/hayden/phoebe/pulls/12
Persist unified instance scope filter across navigation
Saves the selected unified instance scope to
localStorage(qui-unified-instance-filter) so it is restored when navigating back to the unified view after switching elsewhere in the sidebar.Clicking "All active" clears the saved filter and resets to all instances.
Sidebar badge: Changed from two separate badges
[3 active] [2/3]to a single combined[2/3 active]badge. The badge remains visible even when a single instance is selected, so the filter state is always visible without needing to be on the unified view.Input needed:
It might make sense to remove the word "active" to prevent confusion, however the individual instance statuses are displayed just below with a connectivity dot so that may not matter.
Happy to include that modification in this PR if it makes sense.
Summary by CodeRabbit
New Features
Bug Fixes / UX
Chores