Self-review H1: give useDownloadBar an explicit return type
The extracted hook relied on inferred return typing, inconsistent with the codebase convention (useClipboardLink: ClipboardLink, useResolvedDark: boolean). Add a compiler-verified DownloadBarController interface and annotate the hook — the returned object is checked against it, so the surface can't silently drift. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect, useRef } from 'react'
|
import { useState, useEffect, useRef, type Dispatch, type SetStateAction } from 'react'
|
||||||
import {
|
import {
|
||||||
parseUrlShortcutContent,
|
parseUrlShortcutContent,
|
||||||
type MediaInfo,
|
type MediaInfo,
|
||||||
@@ -12,7 +12,12 @@ import { useDownloads, type MediaKind } from '../../store/downloads'
|
|||||||
import { QUALITY_OPTIONS } from '../../qualityOptions'
|
import { QUALITY_OPTIONS } from '../../qualityOptions'
|
||||||
import { sameVideo } from '../../store/queueStats'
|
import { sameVideo } from '../../store/queueStats'
|
||||||
import { useSettings } from '../../store/settings'
|
import { useSettings } from '../../store/settings'
|
||||||
import { useClipboardLink, looksLikeUrl, firstUrlInText } from '../../useClipboardLink'
|
import {
|
||||||
|
useClipboardLink,
|
||||||
|
looksLikeUrl,
|
||||||
|
firstUrlInText,
|
||||||
|
type SuggestionSource
|
||||||
|
} from '../../useClipboardLink'
|
||||||
import { logError } from '../../reportError'
|
import { logError } from '../../reportError'
|
||||||
|
|
||||||
/** Pull the URL= target out of a dropped Windows .url Internet Shortcut file. */
|
/** 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())}`
|
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<SetStateAction<boolean>>
|
||||||
|
trim: string
|
||||||
|
showSchedule: boolean
|
||||||
|
setShowSchedule: Dispatch<SetStateAction<boolean>>
|
||||||
|
scheduleAt: string
|
||||||
|
setScheduleAt: Dispatch<SetStateAction<string>>
|
||||||
|
// drag / dup
|
||||||
|
dragActive: boolean
|
||||||
|
setDragActive: Dispatch<SetStateAction<boolean>>
|
||||||
|
dup: string | null
|
||||||
|
setDup: Dispatch<SetStateAction<string | null>>
|
||||||
|
// advanced / preview
|
||||||
|
showAdvanced: boolean
|
||||||
|
setShowAdvanced: Dispatch<SetStateAction<boolean>>
|
||||||
|
downloadOptions: DownloadOptions
|
||||||
|
incognito: boolean
|
||||||
|
setIncognito: Dispatch<SetStateAction<boolean>>
|
||||||
|
commandPreview: CommandPreviewResult | null
|
||||||
|
previewLoading: boolean
|
||||||
|
// probe (single video)
|
||||||
|
info: MediaInfo | null
|
||||||
|
thumbFailed: string | null
|
||||||
|
setThumbFailed: Dispatch<SetStateAction<string | null>>
|
||||||
|
probing: boolean
|
||||||
|
probeError: string | null
|
||||||
|
usingFormats: boolean
|
||||||
|
selectedFormat: FormatOption | undefined
|
||||||
|
// playlist
|
||||||
|
playlist: PlaylistInfo | null
|
||||||
|
selected: Set<number>
|
||||||
|
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<void>
|
||||||
|
fetchFormats: () => Promise<void>
|
||||||
|
paste: () => Promise<void>
|
||||||
|
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
|
* 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 ~17 interdependent state hooks and their handlers live in one place and
|
||||||
* the component is render-only.
|
* the component is render-only.
|
||||||
*/
|
*/
|
||||||
export function useDownloadBar() {
|
export function useDownloadBar(): DownloadBarController {
|
||||||
const addFromUrl = useDownloads((s) => s.addFromUrl)
|
const addFromUrl = useDownloads((s) => s.addFromUrl)
|
||||||
const addMany = useDownloads((s) => s.addMany)
|
const addMany = useDownloads((s) => s.addMany)
|
||||||
const settingsLoaded = useSettings((s) => s.loaded)
|
const settingsLoaded = useSettings((s) => s.loaded)
|
||||||
|
|||||||
Reference in New Issue
Block a user