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:
+50
-7
@@ -5,16 +5,21 @@ import {
|
||||
IpcChannels,
|
||||
type StartDownloadOptions,
|
||||
type Settings,
|
||||
type HistoryEntry
|
||||
type HistoryEntry,
|
||||
type CommandTemplate,
|
||||
type YtdlpUpdateChannel
|
||||
} from '@shared/ipc'
|
||||
import { getYtdlpVersion } from './ytdlp'
|
||||
import { getYtdlpVersion, updateYtdlp } from './ytdlp'
|
||||
import { probeMedia } from './probe'
|
||||
import { startDownload, cancelDownload } from './download'
|
||||
import { startDownload, cancelDownload, previewCommand } from './download'
|
||||
import { getSettings, setSettings } from './settings'
|
||||
import { listHistory, addHistory, removeHistory, clearHistory } from './history'
|
||||
import { listHistory, addHistory, removeHistory, removeManyHistory, clearHistory } from './history'
|
||||
import { listTemplates, saveTemplate, removeTemplate } from './templates'
|
||||
import { setupPortableData } from './portable'
|
||||
import { safeOpenPath, safeShowInFolder } from './reveal'
|
||||
import { openCookieLoginWindow, getCookiesStatus, clearCookies } from './cookies'
|
||||
import { listErrorLog, addErrorLog, clearErrorLog } from './errorlog'
|
||||
import { exportBackup, importBackup } from './backup'
|
||||
|
||||
// Force software compositing (GPU acceleration off). On this dev machine's old GeForce
|
||||
// GT 625 — and plausibly on the old / locked-down public PCs this app targets —
|
||||
@@ -86,9 +91,21 @@ function registerIpcHandlers(): void {
|
||||
|
||||
ipcMain.handle(IpcChannels.probe, (_e, url: string) => probeMedia(url))
|
||||
|
||||
ipcMain.handle(IpcChannels.downloadStart, (e, opts: StartDownloadOptions) =>
|
||||
startDownload(e.sender, opts)
|
||||
)
|
||||
ipcMain.handle(IpcChannels.downloadStart, (e, opts: StartDownloadOptions) => {
|
||||
const result = startDownload(e.sender, opts)
|
||||
// Pre-spawn failures (missing yt-dlp.exe, bad URL, duplicate id) never reach
|
||||
// download.ts's own close/error handlers, so log them here instead.
|
||||
if (!result.ok) {
|
||||
addErrorLog({
|
||||
id: opts.id,
|
||||
url: opts.url,
|
||||
kind: opts.kind,
|
||||
error: result.error ?? 'Unknown error',
|
||||
occurredAt: Date.now()
|
||||
})
|
||||
}
|
||||
return result
|
||||
})
|
||||
ipcMain.handle(IpcChannels.downloadCancel, (_e, id: string) => cancelDownload(id))
|
||||
|
||||
ipcMain.handle(IpcChannels.defaultFolder, () => app.getPath('downloads'))
|
||||
@@ -121,11 +138,37 @@ function registerIpcHandlers(): void {
|
||||
ipcMain.handle(IpcChannels.historyList, () => listHistory())
|
||||
ipcMain.handle(IpcChannels.historyAdd, (_e, entry: HistoryEntry) => addHistory(entry))
|
||||
ipcMain.handle(IpcChannels.historyRemove, (_e, id: string) => removeHistory(id))
|
||||
ipcMain.handle(IpcChannels.historyRemoveMany, (_e, ids: string[]) => removeManyHistory(ids))
|
||||
ipcMain.handle(IpcChannels.historyClear, () => clearHistory())
|
||||
|
||||
ipcMain.handle(IpcChannels.cookiesLogin, (_e, url: string) => openCookieLoginWindow(url))
|
||||
ipcMain.handle(IpcChannels.cookiesStatus, () => getCookiesStatus())
|
||||
ipcMain.handle(IpcChannels.cookiesClear, () => clearCookies())
|
||||
|
||||
ipcMain.handle(IpcChannels.templatesList, () => listTemplates())
|
||||
ipcMain.handle(IpcChannels.templatesSave, (_e, template: CommandTemplate) => saveTemplate(template))
|
||||
ipcMain.handle(IpcChannels.templatesRemove, (_e, id: string) => removeTemplate(id))
|
||||
|
||||
ipcMain.handle(IpcChannels.commandPreview, (_e, opts: StartDownloadOptions) =>
|
||||
previewCommand(opts)
|
||||
)
|
||||
|
||||
ipcMain.handle(IpcChannels.ytdlpUpdate, (_e, channel: YtdlpUpdateChannel) => updateYtdlp(channel))
|
||||
|
||||
ipcMain.handle(IpcChannels.errorLogList, () => listErrorLog())
|
||||
ipcMain.handle(IpcChannels.errorLogClear, () => clearErrorLog())
|
||||
|
||||
ipcMain.handle(IpcChannels.backupExport, (e) =>
|
||||
exportBackup(BrowserWindow.fromWebContents(e.sender) ?? undefined)
|
||||
)
|
||||
ipcMain.handle(IpcChannels.backupImport, async (e) => {
|
||||
const win = BrowserWindow.fromWebContents(e.sender) ?? undefined
|
||||
const result = await importBackup(win)
|
||||
// A restored backup may have changed the theme; keep the native window
|
||||
// background in sync the same way settingsSet does.
|
||||
if (result.ok) win?.setBackgroundColor(THEME_BACKGROUND[getSettings().theme])
|
||||
return result
|
||||
})
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
Reference in New Issue
Block a user