From 49d66c07eef9de70ec87fcd4a1a9d61a6f457bfe Mon Sep 17 00:00:00 2001 From: Gronod Date: Tue, 19 May 2026 23:45:37 +0100 Subject: [PATCH] Update ARCHITECTURE.md, bump version to 1.5.4, add CHANGELOG entry --- ARCHITECTURE.md | 44 +++++++++++++++++++++++++++++++++++++++++++- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 09b43bf..47258f3 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -460,6 +460,21 @@ When a browser opens `GET /api/dashboard/stream`: The browser's native `EventSource` API handles reconnection automatically on network interruption. +**SSE Payload Structure** + +```javascript +{ + user: string, // Username + isAdmin: boolean, // Admin flag + downloads: DownloadObject[], // Matched download objects (see Section 5.4) + downloadClients: { // Configured download clients for ordering/filtering + id: string, // Instance identifier + name: string, // Instance display name + type: string // Client type ('sabnzbd', 'qbittorrent', 'transmission', 'rtorrent') + }[] +} +``` + ### 5.4 Download Matching Pipeline For each connected user the server: @@ -495,6 +510,14 @@ Users are matched to downloads via Sonarr/Radarr tags: 1. **Exact match** — tag label (lowercased) === username (lowercased). 2. **Sanitised match** — handles Ombi tag mangling: `sanitizeTagLabel()` converts to lowercase, replaces non-alphanumeric chars with hyphens, collapses runs, trims. +#### Client ordering and filtering + +Matched download objects include `client`, `instanceId`, and `instanceName` fields. The frontend: +1. Receives a `downloadClients` array from the SSE payload with all configured clients in configuration order +2. Displays a multi-select filter allowing users to choose which clients to view +3. Sorts downloads by client order (downloads from the first configured client appear first) +4. Filters downloads to show only those from selected client instances + #### Matched download object fields | Field | Type | Description | @@ -523,6 +546,9 @@ Users are matched to downloads via Sonarr/Radarr tags: | `arrInstanceKey` | string/null | (Admin) API key for the *arr instance | | `arrContentId` | number/null | (Admin) `episodeId` or `movieId` for triggering a new search | | `arrContentType` | `'episode'`/`'movie'`/null | (Admin) Content type for search command | +| `client` | string | Download client type ('sabnzbd', 'qbittorrent', 'transmission', 'rtorrent') | +| `instanceId` | string | Instance identifier matching the configured client ID | +| `instanceName` | string | Instance display name from configuration | | `addedOn` | number/null | (qBittorrent) Unix timestamp when torrent was added | | `availableForUpgrade` | boolean/undefined | (History) `true` when outcome is `failed` but content is on disk | @@ -683,7 +709,7 @@ stateDiagram-v2 | `handleLogin()` | Authenticate, fade login → splash → dashboard | | `startSSE()` | Open `EventSource` to `/stream`; handle incoming data | | `stopSSE()` | Close `EventSource` and cancel reconnect timer | -| `renderDownloads()` | Diff-based card rendering (create/update/remove) | +| `renderDownloads()` | Diff-based card rendering (create/update/remove); filters by selected download clients; sorts by client order | | `createDownloadCard()` | Build DOM for a single card; renders tag badges, import-issue badge, blocklist button | | `updateDownloadCard()` | Update existing card in-place (progress, speed, etc.) | | `handleBlocklistSearch()` | Confirm dialog → POST `/blocklist-search` → update button state | @@ -698,6 +724,22 @@ stateDiagram-v2 - **Regular user view** — a single accent-coloured badge showing the tag label that matched the current user's username (via `matchedUserTag`). - **Admin `showAll` view** — all tags on the download are rendered using `tagBadges[]`: tags with no matching Emby user → amber badge (leftmost); tags matched to a known Emby user → accent badge showing the Emby display name (rightmost). +#### Download Client Filter + +The Active Downloads tab includes a multi-select dropdown filter that allows users to: +- View all download clients with their type displayed as "Client Name (type)" +- Select multiple clients to filter the downloads list +- Use "Select All" / "Deselect All" buttons for bulk operations +- Persist selection across sessions via localStorage + +Downloads are sorted by client order (matching the configuration order) and filtered by the selected client IDs. + +Related functions: +- `initDownloadClientFilter()` — Sets up dropdown toggle, click-outside handler, Select/Deselect All buttons +- `updateDownloadClientFilter()` — Populates checkbox list with client name + type badges +- `toggleClientSelection()` — Updates selection array and localStorage +- `updateSelectedCountDisplay()` — Updates button text to show "All clients" / "1 selected" / "N selected" + --- ## 8. Directory Structure diff --git a/CHANGELOG.md b/CHANGELOG.md index 0df7154..a9e4d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,22 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm --- +## [1.5.4] - 2026-05-19 + +### Added + +- **Multi-select download client filter** — Active Downloads tab now includes a dropdown filter that allows users to select multiple download clients. Shows client name and type (e.g., "Main (qbitt)"). Includes Select All / Deselect All buttons. Selection persists across sessions via localStorage. +- **Download client ordering** — Downloads are now sorted by client order (matching the configuration order). Downloads from the first configured client appear first. +- **Client metadata in downloads** — Download objects now include `client`, `instanceId`, and `instanceName` fields for client identification and filtering. +- **SSE payload extension** — SSE stream now includes `downloadClients` array with all configured clients for UI ordering/filtering. +- **Automatic migration** — Existing single-select filter selection automatically migrates to new multi-select format on first load. + +### Fixed + +- **SABnzbd size and speed display** — Fixed SABnzbd downloads showing undefined size and speed values. Now correctly uses `slot.mb` for size calculation and `slot.kbpersec` for per-slot speed from cached data. + +--- + ## [1.5.3] - 2026-05-19 ### Fixed diff --git a/package.json b/package.json index ad0b571..2872f3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sofarr", - "version": "1.5.3", + "version": "1.5.4", "description": "A personal media download dashboard that shows your downloads 'so far' while you relax on the sofa waiting for your *arr services to finish", "main": "server/index.js", "scripts": {