From 7eb90d467a13659763705472aa79fc80f14e3b7f Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Sun, 14 Jun 2026 01:51:43 +0530 Subject: [PATCH] feat: wire batch media converter and document compare, remove coming-soon stubs - batch.showConverter: open BatchMediaConverterDialog for image/audio/video types (uses existing universal-convert-batch handler with ImageMagick/FFmpeg) - tools.documentCompare: line-by-line diff of two open tabs with confirmation dialog, shows diff count in toast and full diff in console - No more 'coming soon' toasts for any menu item --- src/main/GitOperations.js | 21 ++++++++--- .../lib/commands/register-menu-commands.ts | 37 +++++++++++++++++-- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/main/GitOperations.js b/src/main/GitOperations.js index bb43cb2..a67cbdf 100644 --- a/src/main/GitOperations.js +++ b/src/main/GitOperations.js @@ -12,10 +12,14 @@ async function getStatus(dir) { for (const [filePath, status] of Object.entries(result.files || {})) { files.push({ filePath, - status: status.working_dir === 'M' ? 'modified' - : status.working_dir === 'A' || status.index === 'A' ? 'added' - : status.working_dir === 'D' || status.index === 'D' ? 'deleted' - : 'untracked', + status: + status.working_dir === 'M' + ? 'modified' + : status.working_dir === 'A' || status.index === 'A' + ? 'added' + : status.working_dir === 'D' || status.index === 'D' + ? 'deleted' + : 'untracked', }); } return { files }; @@ -33,7 +37,14 @@ async function stage(dir, files) { for (const [filePath, status] of Object.entries(result.files || {})) { staged.push({ filePath, - status: status.index === 'A' ? 'added' : status.index === 'M' ? 'modified' : status.index === 'D' ? 'deleted' : 'untracked', + status: + status.index === 'A' + ? 'added' + : status.index === 'M' + ? 'modified' + : status.index === 'D' + ? 'deleted' + : 'untracked', }); } return { files: staged }; diff --git a/src/renderer/lib/commands/register-menu-commands.ts b/src/renderer/lib/commands/register-menu-commands.ts index 234c72a..ad15d53 100644 --- a/src/renderer/lib/commands/register-menu-commands.ts +++ b/src/renderer/lib/commands/register-menu-commands.ts @@ -236,12 +236,43 @@ export function registerMenuCommands(): void { } return; } - toast.info(`${type.charAt(0).toUpperCase() + type.slice(1)} batch conversion — coming soon!`); + useAppStore.getState().openModal('batch-media-converter'); }, - // Document compare — no modal yet, acknowledge with toast. 'tools.documentCompare': () => { - toast.info('Document compare — coming soon!'); + const paths = useFileStore.getState().openTabs.map((t) => t.path); + if (paths.length < 2) { + toast.info('Open at least 2 files to compare'); + return; + } + useAppStore.getState().openModal('confirm', { + title: 'Document Compare', + body: 'Select two open files to compare side-by-side and show differences.', + confirmLabel: 'Compare', + onConfirm: () => { + const tab0 = paths[0]; + const tab1 = paths[1]; + const content0 = useEditorStore.getState().buffers.get(tab0)?.content ?? ''; + const content1 = useEditorStore.getState().buffers.get(tab1)?.content ?? ''; + const lines0 = content0.split('\n'); + const lines1 = content1.split('\n'); + const diff: string[] = []; + const maxLines = Math.max(lines0.length, lines1.length); + for (let i = 0; i < maxLines; i++) { + if (lines0[i] !== lines1[i]) { + diff.push(`Line ${i + 1}:\n - ${lines0[i] ?? '(end)'}\n + ${lines1[i] ?? '(end)'}`); + } + } + if (diff.length === 0) { + toast.success('Files are identical'); + } else { + toast.info(`${diff.length} differences found — check console (F12)`); + console.log( + `\n--- Diff: ${tab0.split('/').pop()} vs ${tab1.split('/').pop()} ---\n${diff.join('\n\n')}` + ); + } + }, + }); }, 'tools.pdfEditor': () => useAppStore.getState().openModal('pdf-editor'),