diff --git a/CHANGELOG.md b/CHANGELOG.md index c61ec45..7e1c32a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi --- +## [1.14.18] — 2026-07-09 + +### Fixed +- **Every retried/recast audiobook cast created a new duplicate Rehearsal Library entry** instead of overwriting the previous attempt — a fresh (non-resume) cast unconditionally nulled the in-memory link to the existing SQLite record, even when retrying or recasting a book that already had one from a prior attempt. The link is now only cleared for a genuinely first-ever cast; retries and "Recast all" overwrite the existing record instead of piling up near-duplicates. + +--- + ## [1.14.17] — 2026-07-09 ### Added diff --git a/VERSION b/VERSION index 02fd050..c442523 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.14.17 +1.14.18 diff --git a/static/index.html b/static/index.html index 29f9d33..99db6ba 100644 --- a/static/index.html +++ b/static/index.html @@ -10,7 +10,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -365,7 +365,7 @@ window.toggleNavTree = function(treeId, chevronId) { - + diff --git a/static/js/audiobook.js b/static/js/audiobook.js index bf014bf..3284b6d 100644 --- a/static/js/audiobook.js +++ b/static/js/audiobook.js @@ -3872,7 +3872,16 @@ async function audiobookCast(overrideUrl, overrideModel, resume) { _audiobook.cancel = false; if (!isResume) { - _audiobook.rehId = null; // fresh cast creates a new rehearsal record + // Deliberately does NOT null _audiobook.rehId here. It used to, on the + // theory that a fresh (non-resume) cast should always start a brand-new + // Rehearsal Library record — but "fresh cast" also covers "Recast all" + // and simply retrying after a failed/timed-out run for a book that + // already has a rehId (restored from its draft in _applyDraft above). + // Nulling it there meant every retry silently orphaned the previous + // record and created a new one, piling up near-duplicate scripts in the + // Rehearsal Library for the same book. Keeping whatever rehId is already + // known — null only for a genuinely first-ever cast — makes retries/ + // recasts overwrite that one record instead. _abClearDraft(); } if (typeof window.setNavCastingBadge === 'function') window.setNavCastingBadge(true);