Update ARCHITECTURE.md, bump version to 1.5.4, add CHANGELOG entry
Some checks failed
CI / Security audit (push) Failing after 23s
Build and Push Docker Image / build (push) Successful in 52s
Docs Check / Markdown lint (push) Successful in 58s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m17s
CI / Tests & coverage (push) Successful in 1m36s
Docs Check / Mermaid diagram parse check (push) Successful in 1m45s
Some checks failed
CI / Security audit (push) Failing after 23s
Build and Push Docker Image / build (push) Successful in 52s
Docs Check / Markdown lint (push) Successful in 58s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m17s
CI / Tests & coverage (push) Successful in 1m36s
Docs Check / Mermaid diagram parse check (push) Successful in 1m45s
This commit is contained in:
@@ -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
|
||||
|
||||
16
CHANGELOG.md
16
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
|
||||
|
||||
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user