Skip to content

polish: debounce search + low-severity roundup - #36

Merged
EnesYilmazcode merged 2 commits into
mainfrom
claude/funny-hawking-930hed
Jul 15, 2026
Merged

EnesYilmazcode merged 2 commits into
mainfrom
claude/funny-hawking-930hed

Conversation

@EnesYilmazcode

Copy link
Copy Markdown
Owner

Fixes #16. Fixes #19.

#16 — search debounce

Feed the fuzzy search useDeferredValue(query) so fast typing over a large library doesn't drop input frames (React can skip intermediate list renders and catch up when idle).

#19 — low-severity roundup

  • formatTime hours — 3661 → "1:01:01" instead of "61:01" (sub-hour unchanged).
  • Uniform shuffle — replace the biased [...a].sort(() => Math.random() - 0.5) (Library + Playlist "Shuffle") with a shared Fisher–Yates shuffle() helper.
  • Object-URL leak on unmount — revoke the last object URL when PlayerProvider unmounts (the per-track effect only revoked the previous one on the next load).
  • MediaMetadata artwork — sizes: 'any' + type: 'image/jpeg' (ytimg thumbnails are JPEG) instead of a false hardcoded 512x512/png.
  • Unhandled rejections — .catch on the fire-and-forget mutations (toggleStar in TrackRow/Player/sheet, bumpPlayCount, seed/removeSamples).

The remaining #19 checklist item — auditing 44×44pt tap targets — is left as a visual pass on-device (no measurable defect found in code).

Verification

Check Result
formatTime 3661/605/73/0/NaN/3600 all correct (unit-tested) ✅
shuffle returns a valid permutation ✅
Search filters + shows no-match hint (deferred) ✅
Build clean ✅
page errors none ✅

🤖 Generated with Claude Code


Generated by Claude Code

claude added 2 commits July 15, 2026 01:24
#16: feed the fuzzy search a useDeferredValue(query) so fast typing over a large
library doesn't drop input frames (React can skip intermediate list renders).

#19 roundup:
- formatTime now shows hours (3661 → "1:01:01") instead of "61:01".
- Replace the biased `[...a].sort(() => Math.random() - 0.5)` shuffle (Library +
  Playlist "Shuffle") with a shared uniform Fisher–Yates `shuffle()` helper.
- Revoke the last object URL when PlayerProvider unmounts (the per-track effect
  only revoked the previous one on the next load).
- MediaMetadata artwork: use sizes 'any' + type 'image/jpeg' (ytimg thumbnails
  are JPEG) instead of a false hardcoded 512x512/png.
- Attach .catch to the fire-and-forget mutations (toggleStar in TrackRow/Player/
  sheet, bumpPlayCount, seed/removeSamples) so a rejected transaction doesn't
  become an unhandled rejection.

Verified: formatTime + shuffle unit-tested (hours, edge cases, permutation);
search still filters and shows the no-match hint in-browser; build clean.

Fixes #16. Fixes #19.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkDKh1Uo1a4D7n5wCKdcKF
Review follow-up: the "Nothing matches" hint used the immediate `q` while
`results` derives from the deferred query, so switching from a no-match to a
match term could flash the wrong hint for a frame. Drive the list/hint off the
deferred query (`dq`) so they always agree; the clear button stays on immediate
`q`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkDKh1Uo1a4D7n5wCKdcKF
@EnesYilmazcode
EnesYilmazcode merged commit 9ec7d8f into main Jul 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[LOW] Roundup: playback / media-session / import code-quality cleanups [MEDIUM] Fuzzy search runs synchronously on every keystroke (no debounce)

2 participants