From 44daa65fe6f32eea47d6e44615b41bbf956a5be7 Mon Sep 17 00:00:00 2001 From: xRangerDE Date: Wed, 13 May 2026 14:30:21 +0200 Subject: [PATCH] =?UTF-8?q?release:=205.0.1=20=E2=80=94=20fix=20VOD=20hove?= =?UTF-8?q?r=20preview=20+=20merge-group=20progress=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug 1 — VOD-Hover Storyboard zeigte am unteren Rand einen statischen Streifen vom Original-Thumbnail (Subpixel-Mismatch + Aspect-Ratio-Konflikt). Fix: Overlay haengt jetzt an .vod-thumb-wrap statt .vod-card, mit explizitem width+height aus dem Thumbnail-BoundingRect — keine CSS-aspect-ratio-Interferenz mehr. Bug 2 — Merge-Group Download zeigte einen eingefrorenen Progress-Bar bei Multi-Part-VODs (Part X/Y). Root Cause: der weighted-progress Wrapper clamped progress=-1 (HLS unknown-total 1s-Tick) auf 0, was overallProgress auf priorWeight fix-nagelte. Bar oszillierte zwischen indeterminate-animation und einem fixen ~10% Wert. Fix: lastVodProgress persistiert zwischen Path-A-Ticks und Path-B-Streamlink-%-Lines, sodass der Bar smooth waehrend einer Part hochzaehlt. 210 unit tests + e2e:release gruen. Co-Authored-By: Claude Opus 4.7 (1M context) --- package-lock.json | 4 ++-- package.json | 2 +- src/main.ts | 13 +++++++++++-- src/renderer-vod-hover.ts | 31 ++++++++++++++++++++----------- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8377cac..1411729 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "twitch-vod-manager", - "version": "5.1.0-alpha.2", + "version": "5.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "twitch-vod-manager", - "version": "5.1.0-alpha.2", + "version": "5.0.1", "license": "MIT", "dependencies": { "axios": "^1.6.0", diff --git a/package.json b/package.json index 8bfcf72..244ac0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "twitch-vod-manager", - "version": "5.1.0-alpha.2", + "version": "5.0.1", "description": "Twitch VOD Manager - Download Twitch VODs easily", "main": "dist/main.js", "author": "xRangerDE", diff --git a/src/main.ts b/src/main.ts index fbc9649..a982dcc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5373,15 +5373,24 @@ async function processDownloadMergeGroup( const vodWeight = vodDuration / totalDurationSec; const priorWeight = mg.items.slice(0, i).reduce((s, v) => s + parseDuration(v.duration_str), 0) / totalDurationSec; + // Persistente per-part vodProgress, damit Path-A-Ticks (progress=-1, + // 1s-rhythmus mit unknown-total) den determinate Bar nicht auf + // priorWeight zuruecksetzen. Wir merken uns die letzte positive + // Streamlink-Prozentangabe (Path B) und nutzen sie, bis ein neuer + // Wert kommt. Ohne das oszilliert die Bar zwischen indeterminate + // und priorWeight, optisch eingefroren. + let lastVodProgress = 0; const result = await downloadVODPart( vodItem.url, tmpFilename, null, // startTime: null = full VOD null, // endTime: null = full VOD (progress) => { + if (progress.progress > 0 && progress.progress <= 100) { + lastVodProgress = progress.progress; + } // Weighted progress: download phase = 0-70% - const vodProgress = progress.progress > 0 ? progress.progress : 0; - const overallProgress = (priorWeight + vodWeight * (vodProgress / 100)) * 70; + const overallProgress = (priorWeight + vodWeight * (lastVodProgress / 100)) * 70; onProgress({ ...progress, id: item.id, diff --git a/src/renderer-vod-hover.ts b/src/renderer-vod-hover.ts index f754d6e..fae21db 100644 --- a/src/renderer-vod-hover.ts +++ b/src/renderer-vod-hover.ts @@ -12,6 +12,7 @@ interface ActiveHover { vodId: string; intervalId: number; overlay: HTMLElement; + card: HTMLElement; // .vod-card, fuer preview-active toggle (separat vom overlay-host) } const vodStoryboardClientCache = new Map(); @@ -79,8 +80,7 @@ function clearHoverPreview(): void { pendingHoverVodId = null; if (!activeHover) return; window.clearInterval(activeHover.intervalId); - const card = activeHover.overlay.parentElement; - if (card) card.classList.remove('preview-active'); + activeHover.card.classList.remove('preview-active'); // Brief opacity fade-out, then remove from DOM. activeHover.overlay.style.opacity = '0'; const overlayToRemove = activeHover.overlay; @@ -124,20 +124,29 @@ async function activateHoverPreview(card: HTMLElement, vodId: string): Promise { card.classList.add('preview-active'); }); @@ -148,7 +157,7 @@ async function activateHoverPreview(card: HTMLElement, vodId: string): Promise