Complete Phase C (custom commands & yt-dlp updater) and Phase D (library, UX & notifications)
Phase C had been implemented in the working tree but never committed: named custom-command templates (CRUD + per-download override), command preview, and the in-app yt-dlp self-updater. Phase D adds: history search/kind-filter/multi-select/bulk-delete/ re-download; native OS notifications on completion/failure; a private/ incognito download mode that skips history; settings+template backup/ restore via JSON; and a persistent error log surfaced as a Diagnostics report in Settings. See ROADMAP.md for the full per-item breakdown. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+36
-1
@@ -2,6 +2,8 @@ import { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron'
|
||||
import {
|
||||
IpcChannels,
|
||||
type YtdlpVersionResult,
|
||||
type YtdlpUpdateChannel,
|
||||
type YtdlpUpdateResult,
|
||||
type ProbeResult,
|
||||
type StartDownloadOptions,
|
||||
type StartDownloadResult,
|
||||
@@ -9,7 +11,12 @@ import {
|
||||
type Settings,
|
||||
type HistoryEntry,
|
||||
type CookiesStatus,
|
||||
type CookiesLoginResult
|
||||
type CookiesLoginResult,
|
||||
type CommandTemplate,
|
||||
type CommandPreviewResult,
|
||||
type ErrorLogEntry,
|
||||
type BackupExportResult,
|
||||
type BackupImportResult
|
||||
} from '@shared/ipc'
|
||||
|
||||
// The surface exposed to the renderer. Keep this thin: it only forwards to IPC.
|
||||
@@ -49,6 +56,9 @@ const api = {
|
||||
removeHistory: (id: string): Promise<HistoryEntry[]> =>
|
||||
ipcRenderer.invoke(IpcChannels.historyRemove, id),
|
||||
|
||||
removeManyHistory: (ids: string[]): Promise<HistoryEntry[]> =>
|
||||
ipcRenderer.invoke(IpcChannels.historyRemoveMany, ids),
|
||||
|
||||
clearHistory: (): Promise<HistoryEntry[]> => ipcRenderer.invoke(IpcChannels.historyClear),
|
||||
|
||||
/** Open the built-in sign-in window; resolves once the user closes it. */
|
||||
@@ -59,6 +69,31 @@ const api = {
|
||||
|
||||
cookiesClear: (): Promise<void> => ipcRenderer.invoke(IpcChannels.cookiesClear),
|
||||
|
||||
listTemplates: (): Promise<CommandTemplate[]> => ipcRenderer.invoke(IpcChannels.templatesList),
|
||||
|
||||
saveTemplate: (template: CommandTemplate): Promise<CommandTemplate[]> =>
|
||||
ipcRenderer.invoke(IpcChannels.templatesSave, template),
|
||||
|
||||
removeTemplate: (id: string): Promise<CommandTemplate[]> =>
|
||||
ipcRenderer.invoke(IpcChannels.templatesRemove, id),
|
||||
|
||||
/** Build the exact yt-dlp command line for the given form state, without running it. */
|
||||
previewCommand: (opts: StartDownloadOptions): Promise<CommandPreviewResult> =>
|
||||
ipcRenderer.invoke(IpcChannels.commandPreview, opts),
|
||||
|
||||
updateYtdlp: (channel: YtdlpUpdateChannel): Promise<YtdlpUpdateResult> =>
|
||||
ipcRenderer.invoke(IpcChannels.ytdlpUpdate, channel),
|
||||
|
||||
listErrorLog: (): Promise<ErrorLogEntry[]> => ipcRenderer.invoke(IpcChannels.errorLogList),
|
||||
|
||||
clearErrorLog: (): Promise<ErrorLogEntry[]> => ipcRenderer.invoke(IpcChannels.errorLogClear),
|
||||
|
||||
/** Opens a save dialog and writes settings + templates to the chosen JSON file. */
|
||||
exportBackup: (): Promise<BackupExportResult> => ipcRenderer.invoke(IpcChannels.backupExport),
|
||||
|
||||
/** Opens an open dialog and restores settings + templates from the chosen JSON file. */
|
||||
importBackup: (): Promise<BackupImportResult> => ipcRenderer.invoke(IpcChannels.backupImport),
|
||||
|
||||
/** Subscribe to live download events. Returns an unsubscribe function. */
|
||||
onDownloadEvent: (cb: (ev: DownloadEvent) => void): (() => void) => {
|
||||
const listener = (_e: IpcRendererEvent, ev: DownloadEvent): void => cb(ev)
|
||||
|
||||
Reference in New Issue
Block a user