feat(discover): wire A4 search + A5 downloads to backend
Adds DownloadJob/ExternalSearchResult/SourceInfo contract types + mappers, the downloads + search RTKQ endpoints, and the SearchDownloadPage (search external sources, per-result download states) and DownloadsManagerPage (active/history, progress, retry/cancel, poll-while-active). en/ru i18n. Snapshot also bundles in-progress queue/metadata-editor/storage UI work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+47
-5
@@ -78,20 +78,62 @@ export interface PlaylistTrack extends Track {
|
||||
addedAt: string;
|
||||
}
|
||||
|
||||
/** Lifecycle of a download job, mirroring the backend's `DownloadStatus`.
|
||||
* `enriching` = file fetched, metadata pipeline running; `done` = imported. */
|
||||
export type DownloadStatus =
|
||||
| 'queued'
|
||||
| 'downloading'
|
||||
| 'enriching'
|
||||
| 'done'
|
||||
| 'failed';
|
||||
|
||||
export interface DownloadJob {
|
||||
id: string;
|
||||
url: string;
|
||||
title?: string;
|
||||
artist?: string;
|
||||
album?: string;
|
||||
status: 'queued' | 'downloading' | 'processing' | 'done' | 'error';
|
||||
/** Source backend the job pulls from (e.g. `youtube`). */
|
||||
source: string;
|
||||
/** Stable per-source id of the item (e.g. a YouTube videoId). */
|
||||
sourceId?: string;
|
||||
/** The free-text query the job was created from, for display. */
|
||||
query?: string;
|
||||
status: DownloadStatus;
|
||||
/** Fraction complete, 0..1. */
|
||||
progress: number;
|
||||
errorMessage?: string;
|
||||
/** Set once the download finishes and the library track exists. */
|
||||
trackId?: string;
|
||||
retryCount: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
/** Result of POST /downloads. Either the item is already in the library
|
||||
* (`alreadyInLibrary`, `trackId` set), or a job covers it (`job`). */
|
||||
export interface DownloadRequestResult {
|
||||
alreadyInLibrary: boolean;
|
||||
trackId?: string;
|
||||
job?: DownloadJob;
|
||||
}
|
||||
|
||||
/** One hit from an external (fetch) source — the §A4 discover screen. */
|
||||
export interface ExternalSearchResult {
|
||||
source: string;
|
||||
sourceId: string;
|
||||
title: string;
|
||||
artist?: string;
|
||||
album?: string;
|
||||
durationMs?: number;
|
||||
thumbnailUrl?: string;
|
||||
}
|
||||
|
||||
/** A registered source backend, from GET /sources. `kind`: `indexable` (a
|
||||
* mounted folder) or `fetch` (searchable + downloadable, e.g. YouTube). */
|
||||
export interface SourceInfo {
|
||||
name: string;
|
||||
label: string;
|
||||
kind: 'indexable' | 'fetch';
|
||||
available: boolean;
|
||||
}
|
||||
|
||||
export interface UploadResponse {
|
||||
track_id: string;
|
||||
title: string;
|
||||
|
||||
Reference in New Issue
Block a user