From ad4e540952eadf0bfc7d24927977c7c1045be331 Mon Sep 17 00:00:00 2001 From: xRangerDE Date: Thu, 19 Mar 2026 17:55:33 +0100 Subject: [PATCH] feat(merge-split): add queue checkboxes and merge-group selection UI Co-Authored-By: Claude Opus 4.6 (1M context) --- src/renderer-queue.ts | 63 +++++++++++++++++++++++++++++++++++++++--- src/renderer-shared.ts | 1 + 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/renderer-queue.ts b/src/renderer-queue.ts index b40a103..921d21e 100644 --- a/src/renderer-queue.ts +++ b/src/renderer-queue.ts @@ -31,7 +31,8 @@ function getQueueRenderFingerprint(items: QueueItem[]): string { item.speed || '', item.eta || '', item.progressStatus || '', - item.last_error || '' + item.last_error || '', + item.mergeGroup?.mergePhase || '' ].join(':')); return `${lang}|${pieces.join('|')}`; @@ -138,6 +139,45 @@ function getQueueMetaText(item: QueueItem): string { return parts.join(' | '); } +function toggleQueueSelection(id: string): void { + if (selectedQueueIds.has(id)) { + selectedQueueIds.delete(id); + } else { + selectedQueueIds.add(id); + } + renderQueue(); + updateMergeGroupButton(); +} + +function updateMergeGroupButton(): void { + const btn = byId('btnMergeGroup'); + if (!btn) return; + + // Clean up selections: only keep IDs that are still pending in queue + const validIds = new Set( + queue.filter(item => item.status === 'pending' && !item.mergeGroup).map(item => item.id) + ); + selectedQueueIds = new Set([...selectedQueueIds].filter(id => validIds.has(id))); + + if (selectedQueueIds.size >= 2) { + btn.style.display = ''; + btn.textContent = `${UI_TEXT.mergeGroup.btn} (${selectedQueueIds.size})`; + btn.disabled = false; + } else { + btn.style.display = 'none'; + } +} + +async function createMergeGroupFromSelection(): Promise { + if (selectedQueueIds.size < 2) return; + + const ids = [...selectedQueueIds]; + selectedQueueIds.clear(); + queue = await window.api.createMergeGroup(ids); + renderQueue(); + updateMergeGroupButton(); +} + function renderQueue(): void { if (!Array.isArray(queue)) { queue = []; @@ -172,15 +212,29 @@ function renderQueue(): void { : (hasDeterminateProgress ? Math.max(0, Math.min(100, item.progress)) : 0); const progressClass = item.status === 'downloading' && !hasDeterminateProgress ? ' indeterminate' : ''; + const isMergeGroup = !!item.mergeGroup; + const showCheckbox = item.status === 'pending' && !isMergeGroup; + const isChecked = selectedQueueIds.has(item.id); + const mergeIcon = isMergeGroup + ? ' ' + : ''; + const mergeMetaExtra = isMergeGroup + ? ` (${item.mergeGroup!.items.length} VODs)` + : ''; + return ` -
+
+ ${showCheckbox + ? `` + : '' + }
-
${isClip}${safeTitle}
+
${mergeIcon}${isClip}${safeTitle}
${safeStatusLabel}
-
${safeMeta}
+
${safeMeta}${mergeMetaExtra}
@@ -191,6 +245,7 @@ function renderQueue(): void { `; }).join(''); + updateMergeGroupButton(); lastQueueRenderFingerprint = renderFingerprint; } diff --git a/src/renderer-shared.ts b/src/renderer-shared.ts index 963bfd3..a83f87a 100644 --- a/src/renderer-shared.ts +++ b/src/renderer-shared.ts @@ -24,6 +24,7 @@ let currentStreamer: string | null = null; let isConnected = false; let downloading = false; let queue: QueueItem[] = []; +let selectedQueueIds: Set = new Set(); let cutterFile: string | null = null; let cutterVideoInfo: VideoInfo | null = null;