mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 12:06:16 -08:00
feat(downloads): redesign download manager (#1313)
* docs(downloads): specify manager MVP redesign * docs(downloads): plan manager MVP implementation * docs(downloads): tighten manager validation plan * fix(downloads): keep renderer download state global * fix(downloads): make active count accessible * feat(downloads): derive queue and library view model * test(downloads): close view model coverage gaps * fix(downloads): stabilize malformed view model data * refactor(downloads): isolate library navigation * fix(downloads): report library navigation failures * feat(downloads): add ready-to-watch library * feat(downloads): add active download queue * feat(downloads): finish manager MVP * docs(downloads): clarify detail-first offline behavior * docs(downloads): plan detail navigation follow-up * fix(downloads): open completed movies in details * test(downloads): cover pending series navigation * fix(downloads): honor the global cover size * fix(downloads): prefer local playback in shared details * fix(downloads): preserve external launch priority * fix(downloads): prefer local playback in Xtream details * test(downloads): cover offline detail journey * docs(downloads): document offline detail behavior * docs(downloads): format detail navigation plan * fix(downloads): open Stalker items in provider details * docs(downloads): clarify Stalker navigation fallback * fix(xtream): isolate reused detail identities * fix(xtream): ignore stale VOD positions * fix(downloads): keep offline Xtream playback available * docs(downloads): clarify provider playback availability * docs(downloads): design missing-file recovery * docs(downloads): plan missing-file recovery * feat(downloads): derive completed file availability * feat(downloads): recover missing completed files * feat(downloads): refresh missing local files * feat(downloads): separate missing files from ready media * feat(downloads): surface missing files for recovery * refactor(downloads): simplify ready cards * test(downloads): cover missing-file and series journeys * feat(downloads): finish missing-file recovery * docs(downloads): design offline detail views * docs(downloads): plan offline detail views * feat(downloads): persist offline metadata snapshots * fix(downloads): complete metadata snapshot bridge contract * feat(downloads): manage offline metadata snapshots * fix(downloads): harden metadata snapshot updates * fix(downloads): restrict snapshot artwork * fix(downloads): guard restart artwork URL * fix(downloads): refine artwork URL checks * feat(downloads): expose offline metadata updates * fix(downloads): keep metadata service change focused * fix(downloads): preserve metadata error conventions * feat(downloads): derive offline detail content * fix(downloads): preserve unknown episode coordinates * feat(downloads): add focused offline detail routes * fix(downloads): ignore fragments in shell route state * fix(downloads): normalize fragments before queries * feat(downloads): open ready cards in offline details * fix(downloads): use native disabled card styles * feat(downloads): enrich offline detail metadata * fix(downloads): harden offline metadata resolution * fix(downloads): preserve stalker provider titles * fix(downloads): distinguish stalker metadata seeds * fix(downloads): stabilize offline metadata refresh * fix(downloads): throttle sparse metadata refreshes * fix(downloads): type metadata language settings * feat(downloads): render offline movie and series details * fix(downloads): harden offline detail interactions * fix(downloads): close offline detail edge cases * feat(downloads): hand off to provider-only details * fix(downloads): preserve stalker provider handoff * feat(downloads): capture metadata at download time * fix(downloads): preserve snapshot source semantics * fix(downloads): preserve episode snapshot identity * docs(downloads): document offline details flow * docs(downloads): clarify stalker provider fallback * test(downloads): cover offline detail journeys * test(downloads): stabilize offline detail selectors * style(downloads): format changed files * docs(downloads): clean design spec formatting * fix(downloads): preserve offline library ownership * test(downloads): fix Windows workspace navigation * test(database): preserve Electron tsconfig resolution * perf(downloads): avoid blocking file availability probes
This commit is contained in:
1 parent
46c58f4f57
commit
760099358b
188 files changed
+31245
-2281
No files matched your search
@@ -2,6 +2,7 @@ export * from './lib/channel-drm.interface';
|
||||
export * from './lib/channel.interface';
|
||||
export * from './lib/channel.model';
|
||||
export * from './lib/dev-logger.util';
|
||||
export * from './lib/download-metadata.interface';
|
||||
export * from './lib/embedded-mpv-session.interface';
|
||||
export * from './lib/electron-api.interface';
|
||||
export * from './lib/epg-channel-metadata.model';
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
export interface DownloadMetadataPerson {
|
||||
tmdbPersonId?: number;
|
||||
name: string;
|
||||
role?: string;
|
||||
profileUrl?: string;
|
||||
}
|
||||
|
||||
export interface DownloadEpisodeMetadata {
|
||||
title?: string;
|
||||
plot?: string;
|
||||
stillUrl?: string;
|
||||
seasonNumber: number;
|
||||
episodeNumber: number;
|
||||
}
|
||||
|
||||
export interface DownloadMetadataSnapshot {
|
||||
version: 1;
|
||||
language: string;
|
||||
mediaKind: 'movie' | 'series';
|
||||
title: string;
|
||||
originalTitle?: string;
|
||||
plot?: string;
|
||||
releaseDate?: string;
|
||||
year?: number;
|
||||
durationMinutes?: number;
|
||||
genres?: string[];
|
||||
rating?: number;
|
||||
status?: string;
|
||||
posterUrl?: string;
|
||||
backdropUrl?: string;
|
||||
tmdbId?: number;
|
||||
providerCategoryId?: string;
|
||||
cast?: DownloadMetadataPerson[];
|
||||
creators?: DownloadMetadataPerson[];
|
||||
episode?: DownloadEpisodeMetadata;
|
||||
enrichedAt?: string;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
EmbeddedMpvSession,
|
||||
EmbeddedMpvSupport,
|
||||
} from './embedded-mpv-session.interface';
|
||||
import { DownloadMetadataSnapshot } from './download-metadata.interface';
|
||||
import { EpgChannelMetadata } from './epg-channel-metadata.model';
|
||||
import { EpgProgram } from './epg-program.model';
|
||||
import { ExternalPlayerSession } from './external-player-session.interface';
|
||||
@@ -137,6 +138,9 @@ export const ELECTRON_BRIDGE_DOWNLOAD_STATUSES = {
|
||||
export type ElectronBridgeDownloadStatus =
|
||||
(typeof ELECTRON_BRIDGE_DOWNLOAD_STATUSES)[keyof typeof ELECTRON_BRIDGE_DOWNLOAD_STATUSES];
|
||||
|
||||
export type ElectronDownloadFileAvailability =
|
||||
'available' | 'missing' | 'not-applicable';
|
||||
|
||||
export const ELECTRON_BRIDGE_APP_UPDATE_STATUSES = {
|
||||
Unsupported: 'unsupported',
|
||||
Idle: 'idle',
|
||||
@@ -386,8 +390,7 @@ export interface ElectronBridgePlaylistRow {
|
||||
}
|
||||
|
||||
export type ElectronBridgePlaylistUpsertInput =
|
||||
| Playlist
|
||||
| ElectronBridgePlaylistInput;
|
||||
Playlist | ElectronBridgePlaylistInput;
|
||||
|
||||
export interface ElectronBridgeCategoryRow {
|
||||
id: number;
|
||||
@@ -514,6 +517,7 @@ export interface ElectronBridgeDownloadStartPayload {
|
||||
title: string;
|
||||
url: string;
|
||||
posterUrl?: string;
|
||||
metadataSnapshot?: DownloadMetadataSnapshot;
|
||||
downloadFolder: string;
|
||||
headers?: ElectronBridgeDownloadHeaders;
|
||||
seriesXtreamId?: number;
|
||||
@@ -530,6 +534,10 @@ export interface ElectronBridgeDownloadStartResult extends ElectronBridgeErrorRe
|
||||
id?: number;
|
||||
}
|
||||
|
||||
export interface ElectronBridgeDownloadRedownloadResult extends ElectronBridgeErrorResult {
|
||||
recovered?: boolean;
|
||||
}
|
||||
|
||||
export interface ElectronDownloadItem {
|
||||
id: number;
|
||||
playlistId: string;
|
||||
@@ -543,7 +551,9 @@ export interface ElectronDownloadItem {
|
||||
fileName?: string;
|
||||
filePath?: string;
|
||||
posterUrl?: string;
|
||||
metadataSnapshot?: DownloadMetadataSnapshot;
|
||||
status: ElectronBridgeDownloadStatus;
|
||||
fileAvailability: ElectronDownloadFileAvailability;
|
||||
bytesDownloaded?: number;
|
||||
totalBytes?: number;
|
||||
errorMessage?: string;
|
||||
@@ -928,9 +938,7 @@ export interface ElectronBridgeApi {
|
||||
playlistId: string,
|
||||
pins: VodSourcePin[]
|
||||
) => Promise<ElectronBridgeResult>;
|
||||
dbClearVodSourcePin: (
|
||||
matchKeys: string[]
|
||||
) => Promise<ElectronBridgeResult>;
|
||||
dbClearVodSourcePin: (matchKeys: string[]) => Promise<ElectronBridgeResult>;
|
||||
onChannelChange?: (
|
||||
callback: (data: { direction: 'up' | 'down' }) => void
|
||||
) => () => void;
|
||||
@@ -1072,9 +1080,16 @@ export interface ElectronBridgeApi {
|
||||
downloadId: number,
|
||||
downloadFolder: string
|
||||
) => Promise<ElectronBridgeErrorResult>;
|
||||
downloadsRedownloadMissing: (
|
||||
downloadId: number
|
||||
) => Promise<ElectronBridgeDownloadRedownloadResult>;
|
||||
downloadsRemove: (downloadId: number) => Promise<ElectronBridgeErrorResult>;
|
||||
downloadsGetList: (playlistId?: string) => Promise<ElectronDownloadItem[]>;
|
||||
downloadsGet: (downloadId: number) => Promise<ElectronDownloadItem | null>;
|
||||
downloadsUpdateMetadata: (
|
||||
downloadId: number,
|
||||
metadataSnapshot: DownloadMetadataSnapshot
|
||||
) => Promise<ElectronBridgeErrorResult>;
|
||||
downloadsGetDefaultFolder: () => Promise<string>;
|
||||
downloadsSelectFolder: () => Promise<string | null>;
|
||||
downloadsRevealFile: (
|
||||
|
||||
Reference in new issue
Block a user