diff --git a/src/renderer/src/components/DownloadBar.tsx b/src/renderer/src/components/DownloadBar.tsx index c77b725..a98a070 100644 --- a/src/renderer/src/components/DownloadBar.tsx +++ b/src/renderer/src/components/DownloadBar.tsx @@ -25,13 +25,18 @@ import { AppsListRegular, CutRegular, CalendarClockRegular, - WarningRegular + WarningRegular, + SettingsRegular, + WindowConsoleRegular } from '@fluentui/react-icons' import { parseUrlShortcutContent, type MediaInfo, type FormatOption, - type PlaylistInfo + type PlaylistInfo, + type DownloadOptions, + DEFAULT_DOWNLOAD_OPTIONS, + type CommandPreviewResult } from '@shared/ipc' import { useDownloads, type MediaKind } from '../store/downloads' import { QUALITY_OPTIONS } from '../qualityOptions' @@ -41,6 +46,7 @@ import { Select } from './Select' import { Hint } from './Hint' import { SegmentedControl } from './ui/SegmentedControl' import { IconButton } from './ui/IconButton' +import { DownloadOptionsForm } from './DownloadOptionsForm' import { useClipboardLink, looksLikeUrl, firstUrlInText } from '../useClipboardLink' import { logError } from '../reportError' import { THUMB_LG } from '../thumbSizes' @@ -246,6 +252,28 @@ const useStyles = makeStyles({ backgroundColor: tokens.colorNeutralBackground1, color: tokens.colorNeutralForeground1, colorScheme: 'light dark' + }, + // --- command preview & options panels --- + commandBlock: { + display: 'flex', + flexDirection: 'column', + gap: '8px' + }, + commandPreviewPanel: { + padding: '12px', + backgroundColor: tokens.colorNeutralBackground2, + ...shorthands.borderRadius(tokens.borderRadiusLarge), + border: `1px solid ${tokens.colorNeutralStroke2}`, + fontFamily: 'monospace', + fontSize: tokens.fontSizeBase200, + overflowX: 'auto', + color: tokens.colorNeutralForeground1 + }, + optionsPanel: { + padding: '12px', + backgroundColor: tokens.colorNeutralBackground2, + ...shorthands.borderRadius(tokens.borderRadiusLarge), + border: `1px solid ${tokens.colorNeutralStroke2}` } }) @@ -285,6 +313,13 @@ export function DownloadBar(): React.JSX.Element { const [dup, setDup] = useState(null) const confirmDup = useRef(false) + // Per-download options (M5/M6/UX1): advanced features. + const [showAdvanced, setShowAdvanced] = useState(false) + const [downloadOptions, setDownloadOptions] = useState(DEFAULT_DOWNLOAD_OPTIONS) + const [incognito, setIncognito] = useState(false) + const [commandPreview, setCommandPreview] = useState(null) + const [previewLoading, setPreviewLoading] = useState(false) + function onDragOver(e: React.DragEvent): void { e.preventDefault() if (!dragActive) setDragActive(true) @@ -368,11 +403,35 @@ export function DownloadBar(): React.JSX.Element { setItemKinds({}) } + async function loadCommandPreview(): Promise { + const trimmed = url.trim() + if (!trimmed) { + setCommandPreview(null) + return + } + setPreviewLoading(true) + try { + const result = await window.api.previewCommand({ + id: 'preview', + url: trimmed, + kind, + quality, + options: downloadOptions + }) + setCommandPreview(result) + } catch (e) { + setCommandPreview({ ok: false, error: (e as Error).message }) + } finally { + setPreviewLoading(false) + } + } + function onUrlChange(next: string): void { setUrl(next) // Any probed info -- or a duplicate warning -- is stale once the URL changes. if (info || probeError || playlist) clearProbe() if (dup) setDup(null) + if (commandPreview) setCommandPreview(null) confirmDup.current = false } @@ -489,6 +548,8 @@ export function DownloadBar(): React.JSX.Element { ...meta, trim: trimSpec, scheduledFor, + options: downloadOptions, + incognito, format: { id: selectedFormat.id, hasAudio: selectedFormat.hasAudio, @@ -496,7 +557,13 @@ export function DownloadBar(): React.JSX.Element { } }) } else { - addFromUrl(trimmed, kind, quality, { ...meta, trim: trimSpec, scheduledFor }) + addFromUrl(trimmed, kind, quality, { + ...meta, + trim: trimSpec, + scheduledFor, + options: downloadOptions, + incognito + }) } setUrl('') @@ -504,6 +571,8 @@ export function DownloadBar(): React.JSX.Element { setShowTrim(false) setScheduleAt('') setShowSchedule(false) + setShowAdvanced(false) + setCommandPreview(null) clearProbe() } @@ -771,6 +840,59 @@ export function DownloadBar(): React.JSX.Element { )} + {!playlist && ( +
+
+ + +
+ {commandPreview && ( +
+ {commandPreview.ok ? ( + <> +
{commandPreview.command}
+ + ) : ( +
+ Error: {commandPreview.error} +
+ )} +
+ )} + {showAdvanced && ( +
+ setIncognito(!!d.checked)} + label="Incognito mode (no logging, no history, no cookies)" + /> +
+ +
+
+ )} +
+ )} +
Format