Skip to content

feat(i18n): add German (de) translation - #1965

Merged
s0up4200 merged 2 commits into
developfrom
feat/german-i18n
May 31, 2026
Merged

feat(i18n): add German (de) translation#1965
s0up4200 merged 2 commits into
developfrom
feat/german-i18n

Conversation

@s0up4200

@s0up4200 s0up4200 commented May 31, 2026

Copy link
Copy Markdown
Collaborator

Adds a complete German locale in informal "du" register (consistent with autobrr) covering all 10 namespaces, with a check-de-coverage.mjs gate mirroring the existing zh-CN/fr checkers. de is wired into supportedLanguages/languageNames and the full check:i18n suite passes.

It also switches locale loading so only English (the fallback) is bundled eagerly while every other language loads as its own on-demand chunk — this drops the main JS bundle from ~3.2 MB to ~2.5 MB and keeps it under the PWA precache cap as more languages are added.

Summary by CodeRabbit

  • New Features

    • Added full German (de) language support across the app.
    • Language resources now load lazily for non-English locales to speed initial startup.
  • Documentation

    • Updated i18n docs to describe the new locale-loading strategy and how to expose new languages.
  • Chores

    • Added translation coverage/validation tooling and reintroduced a combined i18n check script.
    • App initialization now awaits language resources before rendering.

Adds a complete German locale in informal "du" register (consistent with autobrr) covering all 10 namespaces, wired into supportedLanguages/languageNames with a check-de-coverage.mjs gate matching the existing zh-CN/fr checkers.

Also switches locale loading so only English (the fallback) is bundled eagerly while other languages load as on-demand chunks, keeping the main bundle under the PWA precache size cap as more languages are added.
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d7a0047e-4978-4a84-b07c-a7368a974075

📥 Commits

Reviewing files that changed from the base of the PR and between f0df99b and 38ceead.

📒 Files selected for processing (1)
  • web/src/i18n/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/i18n/index.ts

Walkthrough

This PR adds German (de) locale files, refactors i18n to bundle English eagerly and lazy-load other language namespaces, introduces async changeLanguage and initI18n() (awaited before render), updates supportedLanguages/languageNames, and adds a de translation coverage checker plus package script wiring.

Changes

German Language Support with Lazy-Loading i18n Architecture

Layer / File(s) Summary
i18n Lazy-Loading Architecture
web/src/i18n/index.ts, web/src/main.tsx
English namespaces are eagerly imported and bundled; non-English languages are registered as lazy namespace loaders via import.meta.glob. Adds loadedLanguages, loadLanguageResources, exported initI18n(), and makes changeLanguage() async so it loads resources before switching language. Initial i18next resources start with English and detected/stored language is applied after loading.
i18n Strategy Documentation
AGENTS.md
Updates docs to describe English eager bundling, lazy-loaded non-English chunks, expanded supported languages (en, zh-CN, fr, de), and notes PWA precache size cap and how to expose new languages via supportedLanguages/languageNames.
German Translation Resources
web/src/i18n/locales/de/*.json (auth.json, automations.json, common.json, crossseed.json, dashboard.json, rss.json, search.json, settings.json, torrents.json)
Adds complete German translations covering authentication, automations, common UI, cross-seed, dashboard, RSS, search, settings, and torrents, including interpolation and pluralization keys.
Translation Coverage Validation
web/scripts/check-de-coverage.mjs, web/package.json
Adds a Node.js script to validate de coverage against en (missing/extra keys, interpolation, HTML tags, empty/untranslated strings) and updates package.json to include a combined check:i18n script that runs i18n checks and coverage checks.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer / App Startup
  participant InitI18n as initI18n()
  participant Loader as loadLanguageResources()
  participant I18n as i18next
  participant UI as React render
  Dev->>InitI18n: call await initI18n()
  InitI18n->>Loader: load non-en namespace chunks (via import.meta.glob)
  Loader->>I18n: addResourceBundle(namespace, resources)
  InitI18n->>I18n: changeLanguage(active)
  InitI18n-->>Dev: resolved
  Dev->>UI: createRoot().render()
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • autobrr/qui#1956: Directly modifies web/src/i18n/index.ts to refactor locale loading and updates supportedLanguages/languageNames with similar i18n initialization changes.
  • autobrr/qui#1732: Updates i18n validation tooling in web/package.json with check:i18n-style scripts for translation coverage checks across multiple languages.

Suggested labels

enhancement, web

Suggested reviewers

  • martylukyy

Poem

🐰 A German voice hops into view,
Lazy loaders fetch strings anew,
English waits bundled, calm and bright,
Other tongues arrive on demand at night.
Hooray — translators danced and cheered!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.04% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(i18n): add German (de) translation' accurately describes the main change—adding complete German locale support across all i18n namespaces.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/german-i18n

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/i18n/index.ts`:
- Around line 98-101: changeLanguage suffers a race: concurrent calls can finish
out-of-order and overwrite the latest selection; fix by adding a module-level
request token/counter (e.g., changeRequestId) that you increment at the start of
changeLanguage, capture into a local variable, await loadLanguageResources(lng),
then only call i18n.changeLanguage(lng) and persistLanguage(lng) if the local
token matches the current latest token (meaning this is the most recent
request); reference changeLanguage, loadLanguageResources, persistLanguage and
i18n.changeLanguage so the check guards the post-await side effects and prevents
stale async finishes from applying older languages.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 390892fd-a2a3-45d0-8bd0-0bee9f1ea7f8

📥 Commits

Reviewing files that changed from the base of the PR and between b10ef98 and f0df99b.

📒 Files selected for processing (15)
  • AGENTS.md
  • web/package.json
  • web/scripts/check-de-coverage.mjs
  • web/src/i18n/index.ts
  • web/src/i18n/locales/de/auth.json
  • web/src/i18n/locales/de/automations.json
  • web/src/i18n/locales/de/common.json
  • web/src/i18n/locales/de/crossseed.json
  • web/src/i18n/locales/de/dashboard.json
  • web/src/i18n/locales/de/instances.json
  • web/src/i18n/locales/de/rss.json
  • web/src/i18n/locales/de/search.json
  • web/src/i18n/locales/de/settings.json
  • web/src/i18n/locales/de/torrents.json
  • web/src/main.tsx

Comment thread web/src/i18n/index.ts
Rapid switches between not-yet-loaded languages could resolve their chunk loads out of order and apply an older selection last. A monotonic request token now skips applying a selection that a newer one superseded mid-load.
@s0up4200
s0up4200 merged commit 77c6ea8 into develop May 31, 2026
13 checks passed
@s0up4200
s0up4200 deleted the feat/german-i18n branch May 31, 2026 16:59
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request Jun 9, 2026
… (#950)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.19.0` → `v1.20.0` |

---

### Release Notes

<details>
<summary>autobrr/qui (ghcr.io/autobrr/qui)</summary>

### [`v1.20.0`](https://github.com/autobrr/qui/releases/tag/v1.20.0)

[Compare Source](autobrr/qui@v1.19.0...v1.20.0)

##### Changelog

##### New Features

- [`9ad7ffe`](autobrr/qui@9ad7ffe): feat(automations): add include/exclude for trackers ([#&#8203;1953](autobrr/qui#1953)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`e73867f`](autobrr/qui@e73867f): feat(ci): build binaries for develop branch ([#&#8203;1969](autobrr/qui#1969)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`2020847`](autobrr/qui@2020847): feat(crossseed): match cross-tracker relabels and alternate and/& title spellings ([#&#8203;1990](autobrr/qui#1990)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`719866b`](autobrr/qui@719866b): feat(crossseed): route season packs to categories by resolution and source ([#&#8203;1972](autobrr/qui#1972)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`a6e22ba`](autobrr/qui@a6e22ba): feat(i18n): add French translation, dynamic loading, and browser locale auto-detect ([#&#8203;1956](autobrr/qui#1956)) ([@&#8203;OlziYT](https://github.com/OlziYT))
- [`77c6ea8`](autobrr/qui@77c6ea8): feat(i18n): add German (de) translation ([#&#8203;1965](autobrr/qui#1965)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`fc8664b`](autobrr/qui@fc8664b): feat(i18n): add multi-language support with Simplified Chinese ([#&#8203;1732](autobrr/qui#1732)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`11ace50`](autobrr/qui@11ace50): feat(sse): stream torrent and activity updates, replacing background polling ([#&#8203;551](autobrr/qui#551)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`9b7ed6c`](autobrr/qui@9b7ed6c): feat(torrents): filter for torrents with other tracker errors ([#&#8203;1945](autobrr/qui#1945)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`62bbdb4`](autobrr/qui@62bbdb4): feat(web): virtualized and memoized the indexer search results  ([#&#8203;1944](autobrr/qui#1944)) ([@&#8203;GtwoK](https://github.com/GtwoK))

##### Bug Fixes

- [`b10ef98`](autobrr/qui@b10ef98): fix(api): remove WriteTimeout that aborted downloads and SSE at 120s ([#&#8203;1964](autobrr/qui#1964)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`255bb3e`](autobrr/qui@255bb3e): fix(arr): make arr\_id\_cache expiry timezone-independent ([#&#8203;1986](autobrr/qui#1986)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`4c1d743`](autobrr/qui@4c1d743): fix(crossseed): harden filesystem fallback and post-add rechecks ([#&#8203;1912](autobrr/qui#1912)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`8b278e5`](autobrr/qui@8b278e5): fix(crossseed): pin explicit savepath when cross category save path diverges ([#&#8203;1993](autobrr/qui#1993)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`cab1e0f`](autobrr/qui@cab1e0f): fix(gazelle): pre-search content matching and api limits ([#&#8203;1981](autobrr/qui#1981)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`c3fa169`](autobrr/qui@c3fa169): fix(i18n): translate torrent state labels ([#&#8203;1955](autobrr/qui#1955)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`ccb601d`](autobrr/qui@ccb601d): fix(proxy): forward API key auth to qBittorrent on passthrough requests ([#&#8203;1948](autobrr/qui#1948)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`3cba046`](autobrr/qui@3cba046): fix(qbittorrent): match 'repack available'/'grab internal' as unregistered ([#&#8203;1960](autobrr/qui#1960)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`591941a`](autobrr/qui@591941a): fix(sse): pause torrent-list stream while the tab is hidden ([#&#8203;1994](autobrr/qui#1994)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`f75a1eb`](autobrr/qui@f75a1eb): fix(sse): stop intermittent "offline" flips that fall back to polling ([#&#8203;1992](autobrr/qui#1992)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`c720c39`](autobrr/qui@c720c39): fix(web): emit allowSubcategories from the filtered-data callback ([#&#8203;1979](autobrr/qui#1979)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`602d440`](autobrr/qui@602d440): fix(web): preserve paginated rows on unified-view SSE updates ([#&#8203;1985](autobrr/qui#1985)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))

##### Other Changes

- [`1006338`](autobrr/qui@1006338): chore(deps): bump actions/checkout from 6 to 6.0.2 in the github group ([#&#8203;1999](autobrr/qui#1999)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`667d654`](autobrr/qui@667d654): chore(deps): bump rls to v0.8.1 ([#&#8203;2007](autobrr/qui#2007)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`cc7d70a`](autobrr/qui@cc7d70a): chore(deps): bump the github group with 5 updates ([#&#8203;1937](autobrr/qui#1937)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`cc49a49`](autobrr/qui@cc49a49): chore(deps): bump the github group with 5 updates ([#&#8203;1959](autobrr/qui#1959)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`eff1a65`](autobrr/qui@eff1a65): chore(deps): bump the golang group with 14 updates ([#&#8203;1988](autobrr/qui#1988)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`11da2c7`](autobrr/qui@11da2c7): chore(deps): bump the npm group in /web with 11 updates ([#&#8203;1989](autobrr/qui#1989)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`33aad41`](autobrr/qui@33aad41): chore(deps): bump the npm group in /web with 28 updates ([#&#8203;1946](autobrr/qui#1946)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`5c74fcf`](autobrr/qui@5c74fcf): chore(refactor): remove explicit any and enable no-explicit-any rule ([#&#8203;1966](autobrr/qui#1966)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`fefa624`](autobrr/qui@fefa624): chore(web): add vitest test infrastructure and CI gating ([#&#8203;1936](autobrr/qui#1936)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`90b573a`](autobrr/qui@90b573a): chore(web): remove unused code and packages ([#&#8203;1957](autobrr/qui#1957)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`078fae9`](autobrr/qui@078fae9): docs(agents): scope agent guidance ([#&#8203;1995](autobrr/qui#1995)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`264ccfb`](autobrr/qui@264ccfb): refactor(go): remove dead code ([#&#8203;1740](autobrr/qui#1740)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`48d6f57`](autobrr/qui@48d6f57): refactor(web): extract TorrentTableDialogs from TorrentTableOptimized ([#&#8203;1980](autobrr/qui#1980)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`022f553`](autobrr/qui@022f553): refactor(web): extract compact-sort, cross-seed, and hotkey hooks ([#&#8203;1976](autobrr/qui#1976)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`298c78c`](autobrr/qui@298c78c): refactor(web): extract torrent-table display helpers and row components ([#&#8203;1970](autobrr/qui#1970)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`a5b741a`](autobrr/qui@a5b741a): refactor(web): extract useBulkActionWrappers ([#&#8203;1977](autobrr/qui#1977)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`d4a051e`](autobrr/qui@d4a051e): refactor(web): extract useTorrentSelection ([#&#8203;1974](autobrr/qui#1974)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`cf84390`](autobrr/qui@cf84390): refactor(web): extract useTorrentSelectionDerivations ([#&#8203;1975](autobrr/qui#1975)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`18adff9`](autobrr/qui@18adff9): refactor(web): extract useTorrentTableColumns and useTorrentTableNotifications ([#&#8203;1978](autobrr/qui#1978)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`eb336ac`](autobrr/qui@eb336ac): refactor(web): extract useTorrentTableFilterExpr ([#&#8203;1973](autobrr/qui#1973)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`f1556e8`](autobrr/qui@f1556e8): refactor(web): extract useTrackerIconCache and useEffectiveServerState ([#&#8203;1971](autobrr/qui#1971)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`31f2cd9`](autobrr/qui@31f2cd9): refactor(web): extract virtualization, filter-lifecycle FSM, and column DnD from TorrentTableOptimized ([#&#8203;1982](autobrr/qui#1982)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`fdd0e56`](autobrr/qui@fdd0e56): refactor(web): split types/index.ts into domain modules behind a barrel ([#&#8203;1968](autobrr/qui#1968)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`2cca076`](autobrr/qui@2cca076): test(db): speed up migrated database tests ([#&#8203;1938](autobrr/qui#1938)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`a10e697`](autobrr/qui@a10e697): test(sse): warm up subscription before coalescing burst ([#&#8203;1987](autobrr/qui#1987)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`05fda2a`](autobrr/qui@05fda2a): test(web): add unit tests for Priority 1 pure utilities ([#&#8203;1940](autobrr/qui#1940)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`8df70a5`](autobrr/qui@8df70a5): test: fan out testdb helper to remaining database.New callers ([#&#8203;1962](autobrr/qui#1962)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))

**Full Changelog**: <autobrr/qui@v1.19.0...v1.20.0>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.20.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 becomes conflicted, 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 [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/950
hbjydev pushed a commit to hbjydev/phoebe that referenced this pull request Jun 10, 2026
… ) (#78)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.19.0` → `v1.20.0` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the Dependency Dashboard for more information.

---

### Release Notes

<details>
<summary>autobrr/qui (ghcr.io/autobrr/qui)</summary>

### [`v1.20.0`](https://github.com/autobrr/qui/releases/tag/v1.20.0)

[Compare Source](autobrr/qui@v1.19.0...v1.20.0)

##### Changelog

##### New Features

- [`9ad7ffe`](autobrr/qui@9ad7ffe): feat(automations): add include/exclude for trackers ([#&#8203;1953](autobrr/qui#1953)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`e73867f`](autobrr/qui@e73867f): feat(ci): build binaries for develop branch ([#&#8203;1969](autobrr/qui#1969)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`2020847`](autobrr/qui@2020847): feat(crossseed): match cross-tracker relabels and alternate and/& title spellings ([#&#8203;1990](autobrr/qui#1990)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`719866b`](autobrr/qui@719866b): feat(crossseed): route season packs to categories by resolution and source ([#&#8203;1972](autobrr/qui#1972)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`a6e22ba`](autobrr/qui@a6e22ba): feat(i18n): add French translation, dynamic loading, and browser locale auto-detect ([#&#8203;1956](autobrr/qui#1956)) ([@&#8203;OlziYT](https://github.com/OlziYT))
- [`77c6ea8`](autobrr/qui@77c6ea8): feat(i18n): add German (de) translation ([#&#8203;1965](autobrr/qui#1965)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`fc8664b`](autobrr/qui@fc8664b): feat(i18n): add multi-language support with Simplified Chinese ([#&#8203;1732](autobrr/qui#1732)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`11ace50`](autobrr/qui@11ace50): feat(sse): stream torrent and activity updates, replacing background polling ([#&#8203;551](autobrr/qui#551)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`9b7ed6c`](autobrr/qui@9b7ed6c): feat(torrents): filter for torrents with other tracker errors ([#&#8203;1945](autobrr/qui#1945)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`62bbdb4`](autobrr/qui@62bbdb4): feat(web): virtualized and memoized the indexer search results  ([#&#8203;1944](autobrr/qui#1944)) ([@&#8203;GtwoK](https://github.com/GtwoK))

##### Bug Fixes

- [`b10ef98`](autobrr/qui@b10ef98): fix(api): remove WriteTimeout that aborted downloads and SSE at 120s ([#&#8203;1964](autobrr/qui#1964)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`255bb3e`](autobrr/qui@255bb3e): fix(arr): make arr\_id\_cache expiry timezone-independent ([#&#8203;1986](autobrr/qui#1986)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`4c1d743`](autobrr/qui@4c1d743): fix(crossseed): harden filesystem fallback and post-add rechecks ([#&#8203;1912](autobrr/qui#1912)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`8b278e5`](autobrr/qui@8b278e5): fix(crossseed): pin explicit savepath when cross category save path diverges ([#&#8203;1993](autobrr/qui#1993)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`cab1e0f`](autobrr/qui@cab1e0f): fix(gazelle): pre-search content matching and api limits ([#&#8203;1981](autobrr/qui#1981)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`c3fa169`](autobrr/qui@c3fa169): fix(i18n): translate torrent state labels ([#&#8203;1955](autobrr/qui#1955)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`ccb601d`](autobrr/qui@ccb601d): fix(proxy): forward API key auth to qBittorrent on passthrough requests ([#&#8203;1948](autobrr/qui#1948)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`3cba046`](autobrr/qui@3cba046): fix(qbittorrent): match 'repack available'/'grab internal' as unregistered ([#&#8203;1960](autobrr/qui#1960)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`591941a`](autobrr/qui@591941a): fix(sse): pause torrent-list stream while the tab is hidden ([#&#8203;1994](autobrr/qui#1994)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`f75a1eb`](autobrr/qui@f75a1eb): fix(sse): stop intermittent "offline" flips that fall back to polling ([#&#8203;1992](autobrr/qui#1992)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`c720c39`](autobrr/qui@c720c39): fix(web): emit allowSubcategories from the filtered-data callback ([#&#8203;1979](autobrr/qui#1979)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`602d440`](autobrr/qui@602d440): fix(web): preserve paginated rows on unified-view SSE updates ([#&#8203;1985](autobrr/qui#1985)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))

##### Other Changes

- [`1006338`](autobrr/qui@1006338): chore(deps): bump actions/checkout from 6 to 6.0.2 in the github group ([#&#8203;1999](autobrr/qui#1999)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`667d654`](autobrr/qui@667d654): chore(deps): bump rls to v0.8.1 ([#&#8203;2007](autobrr/qui#2007)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`cc7d70a`](autobrr/qui@cc7d70a): chore(deps): bump the github group with 5 updates ([#&#8203;1937](autobrr/qui#1937)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`cc49a49`](autobrr/qui@cc49a49): chore(deps): bump the github group with 5 updates ([#&#8203;1959](autobrr/qui#1959)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`eff1a65`](autobrr/qui@eff1a65): chore(deps): bump the golang group with 14 updates ([#&#8203;1988](autobrr/qui#1988)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`11da2c7`](autobrr/qui@11da2c7): chore(deps): bump the npm group in /web with 11 updates ([#&#8203;1989](autobrr/qui#1989)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`33aad41`](autobrr/qui@33aad41): chore(deps): bump the npm group in /web with 28 updates ([#&#8203;1946](autobrr/qui#1946)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`5c74fcf`](autobrr/qui@5c74fcf): chore(refactor): remove explicit any and enable no-explicit-any rule ([#&#8203;1966](autobrr/qui#1966)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`fefa624`](autobrr/qui@fefa624): chore(web): add vitest test infrastructure and CI gating ([#&#8203;1936](autobrr/qui#1936)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`90b573a`](autobrr/qui@90b573a): chore(web): remove unused code and packages ([#&#8203;1957](autobrr/qui#1957)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`078fae9`](autobrr/qui@078fae9): docs(agents): scope agent guidance ([#&#8203;1995](autobrr/qui#1995)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`264ccfb`](autobrr/qui@264ccfb): refactor(go): remove dead code ([#&#8203;1740](autobrr/qui#1740)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`48d6f57`](autobrr/qui@48d6f57): refactor(web): extract TorrentTableDialogs from TorrentTableOptimized ([#&#8203;1980](autobrr/qui#1980)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`022f553`](autobrr/qui@022f553): refactor(web): extract compact-sort, cross-seed, and hotkey hooks ([#&#8203;1976](autobrr/qui#1976)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`298c78c`](autobrr/qui@298c78c): refactor(web): extract torrent-table display helpers and row components ([#&#8203;1970](autobrr/qui#1970)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`a5b741a`](autobrr/qui@a5b741a): refactor(web): extract useBulkActionWrappers ([#&#8203;1977](autobrr/qui#1977)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`d4a051e`](autobrr/qui@d4a051e): refactor(web): extract useTorrentSelection ([#&#8203;1974](autobrr/qui#1974)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`cf84390`](autobrr/qui@cf84390): refactor(web): extract useTorrentSelectionDerivations ([#&#8203;1975](autobrr/qui#1975)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`18adff9`](autobrr/qui@18adff9): refactor(web): extract useTorrentTableColumns and useTorrentTableNotifications ([#&#8203;1978](autobrr/qui#1978)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`eb336ac`](autobrr/qui@eb336ac): refactor(web): extract useTorrentTableFilterExpr ([#&#8203;1973](autobrr/qui#1973)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`f1556e8`](autobrr/qui@f1556e8): refactor(web): extract useTrackerIconCache and useEffectiveServerState ([#&#8203;1971](autobrr/qui#1971)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`31f2cd9`](autobrr/qui@31f2cd9): refactor(web): extract virtualization, filter-lifecycle FSM, and column DnD from TorrentTableOptimized ([#&#8203;1982](autobrr/qui#1982)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`fdd0e56`](autobrr/qui@fdd0e56): refactor(web): split types/index.ts into domain modules behind a barrel ([#&#8203;1968](autobrr/qui#1968)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`2cca076`](autobrr/qui@2cca076): test(db): speed up migrated database tests ([#&#8203;1938](autobrr/qui#1938)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`a10e697`](autobrr/qui@a10e697): test(sse): warm up subscription before coalescing burst ([#&#8203;1987](autobrr/qui#1987)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`05fda2a`](autobrr/qui@05fda2a): test(web): add unit tests for Priority 1 pure utilities ([#&#8203;1940](autobrr/qui#1940)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`8df70a5`](autobrr/qui@8df70a5): test: fan out testdb helper to remaining database.New callers ([#&#8203;1962](autobrr/qui#1962)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))

**Full Changelog**: <autobrr/qui@v1.19.0...v1.20.0>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.20.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/78
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant