mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-11 01:14:30 +00:00
fix(playlists): stay within the shipped Tailwind class set
Reverts the regenerated static/tailwind.min.css and reworks the tuning-check markup to use only classes already in the committed sheet. Regenerating that file is not reproducible off CI: nothing pins tailwindcss, autoprefixer or caniuse-lite, so a local `npx -y tailwindcss@3.4.19` resolves different browser data and rewrites unrelated bytes -- a clean checkout of main rebuilds with the -webkit-backdrop-filter prefixes dropped. Committing that output fails the tailwind-fresh gate no matter how many times it is regenerated. Six utilities were new: bg-fb-good/10, border-fb-accent/50, hover:bg-fb-accent/10, list-disc, list-inside, max-h-48, plus gap-x-3/gap-y-2. Substituted bg-fb-good/30, the amber border already used by the mismatch state, hover:bg-fb-card, a literal bullet in a div, max-h-32 and gap-3. Visual intent is unchanged. The removal-confirm test pinned the <li> markup; it now accepts either wrapper, since what it guards is that every song is named and escaped ahead of any DELETE, not which element wraps it. Signed-off-by: ChrisBeWithYou <christian.a.cowan@gmail.com>
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+12
-5
@@ -153,9 +153,13 @@
|
||||
if (!total) return '';
|
||||
const mism = results.filter((r) => r.state === 'mismatch').length;
|
||||
const unk = results.filter((r) => r.state === 'unknown').length;
|
||||
const box = 'mb-4 rounded-lg border px-3 py-2 text-sm flex flex-wrap items-center gap-x-3 gap-y-2 ';
|
||||
// Plain gap-3 rather than gap-x-3/gap-y-2: the axis-specific pair isn't
|
||||
// in the committed tailwind.min.css, and regenerating it is not
|
||||
// reproducible outside CI (autoprefixer/caniuse drift changes unrelated
|
||||
// bytes), so the summary bar stays within the shipped class set.
|
||||
const box = 'mb-4 rounded-lg border px-3 py-2 text-sm flex flex-wrap items-center gap-3 ';
|
||||
if (!mism) {
|
||||
return '<div class="' + box + 'border-fb-good/40 bg-fb-good/10 text-fb-good">' +
|
||||
return '<div class="' + box + 'border-fb-good/40 bg-fb-good/30 text-fb-good">' +
|
||||
'<span>✓ All ' + total + ' songs are in your tuning.</span>' +
|
||||
(unk ? '<span class="text-fb-textDim text-xs">' + unk + ' couldn\'t be checked (no tuning data).</span>' : '') +
|
||||
'</div>';
|
||||
@@ -165,7 +169,7 @@
|
||||
(unk ? '<span class="text-fb-textDim text-xs">' + unk + ' couldn\'t be checked (no tuning data) — left alone.</span>' : '') +
|
||||
'<span class="flex-1"></span>' +
|
||||
'<button id="v3-pl-tune-only" class="text-xs px-2 py-1 rounded border border-fb-border text-fb-textDim hover:text-fb-text" aria-pressed="false">Show only these</button>' +
|
||||
'<button id="v3-pl-tune-remove" class="text-xs px-2 py-1 rounded border border-fb-accent/50 text-fb-accent hover:bg-fb-accent/10">Remove them…</button>' +
|
||||
'<button id="v3-pl-tune-remove" class="text-xs px-2 py-1 rounded border border-amber-400/40 text-fb-text hover:bg-fb-card">Remove them…</button>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
@@ -201,10 +205,13 @@
|
||||
// user data, so the confirm has to be a list, not a count.
|
||||
const doomed = results.filter((r) => r.state === 'mismatch').map((r) => r.song);
|
||||
if (!doomed.length) return;
|
||||
const names = doomed.map((s) => '<li>' + esc(s.title || s.filename) + '</li>').join('');
|
||||
const names = doomed.map((s) => '<div>• ' + esc(s.title || s.filename) + '</div>').join('');
|
||||
const msg = 'Remove these ' + doomed.length + ' song' + (doomed.length === 1 ? '' : 's')
|
||||
+ ' from "' + esc(pl.name) + '"?'
|
||||
+ '<ul class="mt-2 text-xs list-disc list-inside max-h-48 overflow-auto">' + names + '</ul>'
|
||||
// Bulleted with a literal •, and sized with max-h-32, so the
|
||||
// confirm needs no Tailwind class the committed CSS lacks —
|
||||
// regenerating tailwind.min.css is not reproducible off CI.
|
||||
+ '<div class="mt-2 text-xs max-h-32 overflow-y-auto">' + names + '</div>'
|
||||
+ '<p class="text-xs text-fb-textDim mt-2">They stay in your library — only this playlist changes, and you can add them back.</p>';
|
||||
const ok = (typeof window.uiConfirm === 'function')
|
||||
? await window.uiConfirm({
|
||||
|
||||
@@ -261,8 +261,11 @@ test('the check itself never mutates the playlist', () => {
|
||||
|
||||
test('bulk removal names every song and is confirmed before any DELETE', () => {
|
||||
const body = extractBlock(PL_SRC, 'async function applyTuningCheck(');
|
||||
// The confirm is built from the doomed titles …
|
||||
assert.match(body, /doomed\.map\(\(s\) => '<li>' \+ esc\(s\.title \|\| s\.filename\)/);
|
||||
// The confirm is built from the doomed titles, each escaped. The row markup
|
||||
// moved from <li> to a bulleted <div> so the confirm needs no Tailwind class
|
||||
// the committed CSS lacks — what matters is that every song is named and
|
||||
// escaped, not which element wraps it.
|
||||
assert.match(body, /doomed\.map\(\(s\) => '<(?:li|div)>[^']*' \+ esc\(s\.title \|\| s\.filename\)/);
|
||||
// … it is awaited, and an early return happens before the delete loop.
|
||||
const confirmAt = body.indexOf('uiConfirm');
|
||||
const bailAt = body.indexOf('if (!ok) return;');
|
||||
|
||||
Reference in New Issue
Block a user