From 0735d44f394f916ed3292d3bd66ae580ea9a166e Mon Sep 17 00:00:00 2001 From: byrongamatos Date: Sun, 5 Jul 2026 12:57:21 +0200 Subject: [PATCH] fix(library): mirror server year coercion in Write-to-file grid sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update_song_meta coerces a non-numeric/empty year to "" before persisting, but writeToFile optimistically set song.year to the raw typed text — so the library card flashed e.g. "abcd" until the next natural refresh. Apply the same integer coercion client-side so the in-memory song matches what was written. Co-Authored-By: Claude Opus 4.8 (1M context) --- static/v3/match-review.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/static/v3/match-review.js b/static/v3/match-review.js index 20cef62..edbc8e0 100644 --- a/static/v3/match-review.js +++ b/static/v3/match-review.js @@ -608,8 +608,16 @@ if (status) { status.className = 'text-xs leading-relaxed text-fb-accent'; status.textContent = 'Could not write to the file — try again.'; } return; } - // Keep the in-memory song + grid in step with what was written. - for (const [f] of DETAIL_FIELDS) song[f] = fields[f]; + // Keep the in-memory song + grid in step with what was *persisted*, not + // the raw input: the server coerces a non-numeric/empty year to "" (see + // update_song_meta), so mirror that here or the grid card flashes the + // typed text (e.g. "abcd") until the next natural refresh corrects it. + const applied = { ...fields }; + if ('year' in applied) { + const yr = /^[+-]?\d+$/.test(applied.year) ? parseInt(applied.year, 10) : 0; + applied.year = yr ? String(yr) : ''; + } + for (const [f] of DETAIL_FIELDS) song[f] = applied[f]; try { window.feedBack?.emit('library:changed', { reason: 'write' }); } catch (_) { } if (persisted) { const clear = {};