// Mirrors of the Rust structs in src-tauri/src/models.rs. Field names match // serde's output exactly so no mapping layer is needed. export type DownloadState = | "queued" | "running" | "done" | "failed" | "cancelled"; export interface ChannelWithCount { id: string; title: string; url: string; video_count: number; downloaded_count: number; } export interface FeedItem { id: string; channel_id: string; channel_title: string; title: string; description: string; /** Unix seconds. */ published: number; thumb_url: string; thumb_path: string | null; views: number; is_short: boolean; state: DownloadState | null; path: string | null; pct: number | null; error: string | null; /** Seconds watched, and the video's length — drives the feed progress bar. */ position: number | null; duration: number | null; } export interface FeedFilter { channel_id?: string | null; search?: string | null; downloaded_only: boolean; hide_shorts: boolean; limit?: number | null; } export interface Prereqs { yt_dlp: string | null; ffmpeg: string | null; library_path: string; } export interface RefreshSummary { channels: number; new_videos: number; failures: string[]; } export interface RefreshProgress { done: number; total: number; channel: string; } export interface DownloadProgressEvent { video_id: string; pct: number | null; bytes_done: number; bytes_total: number | null; speed: number | null; eta: number | null; } export interface DownloadStateEvent { video_id: string; state: DownloadState; error: string | null; path: string | null; } export interface ImportPreview { incoming: number; removed_channels: number; removed_videos: number; removed_downloads: number; } export type Quality = "best" | "compatible";