diff --git a/src/renderer/src/components/downloadBar/useDownloadBar.ts b/src/renderer/src/components/downloadBar/useDownloadBar.ts index 2955ba0..0037d25 100644 --- a/src/renderer/src/components/downloadBar/useDownloadBar.ts +++ b/src/renderer/src/components/downloadBar/useDownloadBar.ts @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef } from 'react' +import { useState, useEffect, useRef, type Dispatch, type SetStateAction } from 'react' import { parseUrlShortcutContent, type MediaInfo, @@ -12,7 +12,12 @@ import { useDownloads, type MediaKind } from '../../store/downloads' import { QUALITY_OPTIONS } from '../../qualityOptions' import { sameVideo } from '../../store/queueStats' import { useSettings } from '../../store/settings' -import { useClipboardLink, looksLikeUrl, firstUrlInText } from '../../useClipboardLink' +import { + useClipboardLink, + looksLikeUrl, + firstUrlInText, + type SuggestionSource +} from '../../useClipboardLink' import { logError } from '../../reportError' /** Pull the URL= target out of a dropped Windows .url Internet Shortcut file. */ @@ -29,12 +34,78 @@ export function toLocalDatetimeValue(d: Date): string { return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}` } +/** Everything the DownloadBar render needs — the hook's public surface. */ +export interface DownloadBarController { + // form state + url: string + kind: MediaKind + quality: string + // trim / schedule + showTrim: boolean + setShowTrim: Dispatch> + trim: string + showSchedule: boolean + setShowSchedule: Dispatch> + scheduleAt: string + setScheduleAt: Dispatch> + // drag / dup + dragActive: boolean + setDragActive: Dispatch> + dup: string | null + setDup: Dispatch> + // advanced / preview + showAdvanced: boolean + setShowAdvanced: Dispatch> + downloadOptions: DownloadOptions + incognito: boolean + setIncognito: Dispatch> + commandPreview: CommandPreviewResult | null + previewLoading: boolean + // probe (single video) + info: MediaInfo | null + thumbFailed: string | null + setThumbFailed: Dispatch> + probing: boolean + probeError: string | null + usingFormats: boolean + selectedFormat: FormatOption | undefined + // playlist + playlist: PlaylistInfo | null + selected: Set + allSelected: boolean + // suggestion banner + suggestion: string | null + suggestionSource: SuggestionSource + dismissSuggestion: () => void + // handlers + onDragOver: (e: React.DragEvent) => void + onDrop: (e: React.DragEvent) => void + onUrlChange: (next: string) => void + onKindChange: (next: MediaKind) => void + onQualityChange: (v: string) => void + onFormatIdChange: (v: string) => void + onTrimChange: (v: string) => void + onDownloadOptionsChange: (next: DownloadOptions) => void + toggleCommandPreview: () => Promise + fetchFormats: () => Promise + paste: () => Promise + acceptSuggestion: () => void + download: () => void + downloadAnyway: () => void + addPlaylist: () => void + toggleEntry: (index: number, on: boolean) => void + toggleAll: () => void + effKind: (index: number) => MediaKind + toggleItemKind: (index: number) => void + setAllKinds: (k: MediaKind) => void +} + /** * All state and behaviour for the DownloadBar. Extracted from the component so * the ~17 interdependent state hooks and their handlers live in one place and * the component is render-only. */ -export function useDownloadBar() { +export function useDownloadBar(): DownloadBarController { const addFromUrl = useDownloads((s) => s.addFromUrl) const addMany = useDownloads((s) => s.addMany) const settingsLoaded = useSettings((s) => s.loaded)