94a9c8cbe38628d11a24133fb6d9269a0aa44055
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
94a9c8cbe3 |
chore(deps): SvelteKit 3 with adapter-static 4 and TypeScript 6, full-tree npm audit (#5021)
Merges Renovate's kit 3 (PR #149) and adapter-static 4 (PR #148) bumps, plus the migration they need. The mechanical part is `sv migrate sveltekit-3`, run one task at a time and reviewed: - svelte.config.js is gone. Its options move into sveltekit() in vite.config.ts, exported as kitOptions so vitest.config.ts runs the same kit setup, including the $test-utils alias the tests import. - $lib becomes #lib through package.json "imports". There is no src/lib/index, so only the "#lib/*" entry is kept. - tsconfig extends $app/tsconfig. - Peer floors raised to kit 3's requirements: svelte ^5.57.1, vite ^8.0.12, svelte-check ^4.7.5. By hand, from the codemod's list of non-automated tasks: - goto's replaceState option is now replace; keepFocus becomes reset: false. For the search typeahead, reset: false also stops the scroll-to-top, which is wanted while typing. - The test setup mocks drop pushState/replaceState and $app/paths base/assets, which kit 3 removed, and mock refreshAll in place of invalidateAll. - The other flagged files only read page.url or goto internal routes, so they needed no change. TypeScript goes to ^6, not the ^7 Renovate offers: kit 3 declares typescript ^6 as a peer and svelte-check 4.7 accepts ^5 || ^6. Move to 7 once both accept it. With Tailwind 4 and kit 3 in, `npm audit` on the whole tree reports 0, so the web lane now audits every dependency rather than only what ships to browsers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
fecd030b68 |
chore(deps): Tailwind 4 (#5021)
release / govulncheck (push) Successful in 42s
release / web (push) Successful in 1m39s
release / go (push) Successful in 1m53s
release / integration (push) Successful in 5m37s
release / android (push) Successful in 6m54s
release / Build signed APK (releases and dev) (push) Successful in 7m27s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Failing after 34s
release / Verify release artifacts (tag releases only) (push) Skipped
Renovate's tailwindcss bump (PR #150) plus the migration it needs: - Theme moves from tailwind.config.js into app.css as `@theme inline`, mapping the same FabledSword tokens. tailwind.config.js is gone. - PostCSS runs @tailwindcss/postcss; autoprefixer is dropped, since Tailwind 4 prefixes through Lightning CSS. - Class renames from @tailwindcss/upgrade 4.3.3, reviewed: outline-none -> outline-hidden, focus-visible:outline -> outline-solid, shadow -> shadow-sm, shadow-sm -> shadow-xs, flex-shrink-0 -> shrink-0. Bare `rounded` stays: v4 keeps it at 0.25rem, as before. - Three v3 preflight defaults kept in a base layer so nothing changes on screen: gray-200 default border colour, gray-400 placeholder text and the pointer cursor on buttons. - The unused class-based dark variant is not carried over; no template uses `dark:`. Clears the five high and two moderate npm audit findings that came in through Tailwind 3 (braces, chokidar, micromatch, fast-glob, postcss-selector-parser). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
b46c080d19 |
fix(web): all accent text and icons use accent-fg (#5318)
release / govulncheck (push) Successful in 17s
release / web (push) Successful in 1m11s
release / go (push) Successful in 1m26s
release / integration (push) Successful in 4m18s
release / android (push) Successful in 4m44s
release / Build signed APK (releases and dev) (push) Successful in 4m53s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 26s
release / Verify release artifacts (tag releases only) (push) Skipped
The raw accent fails AA as text on every dark surface, not only on its own tint: 3.04:1 on the page, 2.70 on iron, 2.21 on slate, against 4.5. accent-fg (the house formula, 45% toward parchment) measures 5.62 at worst across both modes. The operator chose the readable colour over the signature teal for text, on 2026-10-08. - 36 sites swap. They are 35 Tailwind uses: links, "Now playing", the ingest progress line, active shuffle/repeat, the liked heart, the app download icon and its hover. The last is the alphabet rail's pending spinner in CSS. Icons follow the text: as graphics they need only 3:1, and the raw accent misses even that on iron. - check-tint-contrast adds accent to TEXT_NEVER_RAW, so a new raw text-accent or color: var(--fs-accent) fails the web lane. Run against the files before the swap, it finds all 36. Borders, rings and fills keep the raw accent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4509f740f8 |
feat(web): sort the genre index A–Z as well as by count — #2468
test-web / test (push) Successful in 38s
Operator decision: the taxonomy this task proposed is cancelled. With their repaired library measured — 391 genres, 90,774 tag applications over ~24,185 tracks, so ~3.7 genres per track — multi-membership already puts each track under everything it claims, and grouping would add nothing while destroying real specificity (Neurofunk, Wassoulou, Soukous are not noise). The task's premise was also wrong. It argued from case variants, "Alt. Rock" abbreviations and a junk tail; none exist. That apparent mess was the scanner welding multi-value tags (#2499) plus ghost rows from deleted files (#2523), both ours, both now fixed. A category system would have papered over both. So the ask reduces to sorting and search. The search box already existed (QuickFilter, with its own no-matches state), so this adds only the sort: count-first by default — the server's order, and the right default since the head is where you're going — or A–Z for when you can already name the thing but can't find it among 391 rows. The filtered count now reads "12 of 391" so a filter's effect is visible. Client-side only: /api/library/genres is unpaged and already returns the whole set (~12KB), so neither control needs a round trip or a server change. Two things the tests pin down: - The sort COPIES before sorting. With no filter applied the derived list is the very array held by the query cache, and Array.sort mutates in place — sorting it directly would reorder cached data under every other consumer. - Count mode passes the server's order through rather than re-sorting. The fixture is deliberately not in count order so the test asserts pass-through instead of coincidence. Verified locally: svelte-check 0 errors, 110 files / 788 tests. |
||
|
|
feb1c2eca8 |
feat(web): genre and year browse pages — #367
test-web / test (push) Successful in 33s
Client half of #367. Two new Library tabs, each an index plus a drill-down. Genres are ordered by track count rather than alphabetically. Raw ID3 carries a long tail of one-off tags, so alphabetical would bury the handful of genres you actually have a library's worth of. Years are grouped into decades — a flat list of every year in a decades-deep library is a wall of numbers, and the decade is how people actually think about it. ## Selection travels in the query string, not the path `?g=Rock%2FPop`, not `/library/genres/Rock%2FPop`. A slash-bearing genre cannot survive a path segment — the server sees two segments, and a hard reload wouldn't reconstruct it through the SPA fallback either. There's a test pinning the encoded href and another pinning that the DECODED value reaches the API. ## Why these two pages don't use svelte-query for their lists The indexes do — fetched once per mount, so static options suffice and the cache survives bouncing in and out of a drill-down. The drill-down lists deliberately don't. Their selection comes from the URL and changes WITHOUT remounting the page, and this codebase has no reactive-query-options pattern anywhere; inventing one here would be a larger change than the feature justifies, and one I can't exercise locally. So they use $effect keyed on the derived selection with an explicit Load more. The stale-response guard is a plain `let`, not $state, and that's load-bearing: as reactive state, reading the token inside the fetch path would make the effect depend on its own writes. Its job is to discard a late response for a previously selected genre instead of painting it over the current one. ## Also Added the year filter to /library/albums' contract but NOT to that page's UI — its infinite scroll is a svelte-query infinite query, and making it react to a filter is the same reactive-options problem. The dedicated pages cover the capability, which is the shape the task offered as its alternative. Library tab bar's comment claims it mirrors Android's LibraryScreen. These two tabs have no Android equivalent, so I noted that inline rather than leaving the claim quietly false. Parity remains an open call. Not yet done from #367's bullet list: genre/year quick-jump links on album and artist detail. Year is free (AlbumRef already carries it) but genre is exposed nowhere client-side — AlbumDetail is AlbumRef + tracks, and neither carries genre — so it needs a small API addition. Following as its own commit. |