Skip to content

[fix] fixing the laggy playlist render and scrolling#8

Merged
CupOfMakiato merged 3 commits into
mainfrom
fix/playlist-tanstack
May 22, 2026
Merged

[fix] fixing the laggy playlist render and scrolling#8
CupOfMakiato merged 3 commits into
mainfrom
fix/playlist-tanstack

Conversation

@CupOfMakiato

@CupOfMakiato CupOfMakiato commented May 22, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added shuffle, repeat, and track menu buttons to the music player.
    • Implemented optimized playlist rendering for improved performance with large playlists.
  • Style

    • Updated player button styling and sizing for better visual consistency.
    • Redesigned playlist table layout and control appearance.
  • Documentation

    • Updated README with more conversational tone and roadmap clarifications.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@CupOfMakiato has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 28 minutes and 14 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c4bbd9a5-3c0c-4f31-9405-dfb492968db2

📥 Commits

Reviewing files that changed from the base of the PR and between bb6bb5d and bb7cd3c.

📒 Files selected for processing (2)
  • ui/components/bottom-player/player.html
  • ui/pages/playlist/playlist.js
📝 Walkthrough

Walkthrough

This PR overhauls playlist rendering to support virtualization for large track lists, adds shuffle/repeat/menu controls to the bottom player, and updates documentation with a more conversational tone. The changes introduce TanStack virtual-core integration, concurrent duration resolution, centralized state and event handling, and refactored table styling for fixed-layout virtual rendering.

Changes

Bottom Player & Documentation

Layer / File(s) Summary
Documentation & Player Controls
README.md, ui/components/bottom-player/player.html
README adopts informal tone, adds Electron/RAM drawback note, and rewrites roadmap items conversationally. Bottom player gains shuffle, repeat, and track menu buttons with Lucide icons and accessibility labels.
Bottom Player Styling
ui/components/bottom-player/player.css
Play/pause button and SVG resized to 40px and 30px; base button border rule removed.

Playlist Virtualization & Rendering

Layer / File(s) Summary
Virtualization Infrastructure Module
ui/pages/playlist/playlist-virtualizer.js
New module exports loadPlaylistVirtualCore() (lazy async loader with process shim), canUsePlaylistVirtualizer() (capability check), and createPlaylistVirtualizer(options) (factory with mount/destroy callbacks).
Row Renderer & Table Layout Styling
ui/pages/playlist/playlist-row-renderer.js, ui/pages/playlist/playlist.css
renderTrackRow() signature accepts optional pre-normalized track for efficient virtual DOM reuse. CSS switches to fixed table-layout, redefines header/cell padding/borders, adds explicit column widths, z-index layering for menus and virtual padding rows, and hover transitions for track controls.
Module Setup: Imports, Constants & State
ui/pages/playlist/playlist.js (import section, constants, state variables)
Virtualizer utilities imported; tuning constants added for row height/overscan/cache limits; new state variables for virtual row DOM cache, duration-cell scheduling, scroll-margin caching, ResizeObserver, and virtualizer instance.
Duration & Scroll Management
ui/pages/playlist/playlist.js (scroll margin, duration resolution)
Implements scrollMarginCache computation with ResizeObserver invalidation on header/image layout changes. Adds resolveTrackDurationsLimited() for concurrent duration probing with per-result callbacks. Refactors renderTotalDuration() to use limited resolver, updating cells incrementally via scheduled rendering.
State Management & Event Delegation
ui/pages/playlist/playlist.js (state setters, event handlers)
Introduces setActivePlaylistState() for centralized state updates and savePlaylistsAndRender() for persistence. Refactors track menu/action handling to delegated pattern with closeAllTrackMenus(). Updates remove-track, play-track, sortable, undo, and image-editing handlers to use centralized persistence.
Virtual Rendering, Hydration & Page Lifecycle
ui/pages/playlist/playlist.js (renderTracks, render, hydrate, setup, cleanup)
Implements virtual row DOM cache with reuse/trimming. Rewrites renderTracks() to switch between virtual and full modes, calculate padding rows, reuse cached rows, sync tbody efficiently, and apply decorations. Updates render() and hydrate() to load virtual core with fallback. Extends setup/cleanup for ResizeObserver, animation frames, virtualizer destruction, and delegated action cleanup.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • CupOfMakiato/MusicHub#3: Adds the playlist image picker feature (electronAPI.selectImageFile, dialog:openImageFile) and image edit button UI that this PR integrates and wires into savePlaylistsAndRender().

Poem

🐰 Hop, hop! Virtual rows now bloom,
No more render gloom in the playlist room!
Shuffle and repeat buttons shine so bright,
Durations flow gently through the night.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: fixing performance issues in playlist rendering and scrolling through virtualization implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/playlist-tanstack

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 97: Fix the spelling mistake in the README sentence "Audio normalization
(or loudness nomalization something i'm not an audio engineer)." by replacing
"nomalization" with "normalization" and ensure the sentence reads correctly
(e.g., "Audio normalization (or loudness normalization, something I'm not an
audio engineer)."); update capitalization/apostrophe as needed for consistency.
- Around line 5-9: The README paragraph for "Blueberry Music Player" has
multiple grammar and capitalization errors; update the text to use correct
capitalization and grammar: change "Support" to "Supports", "VanillaJs" to
"Vanilla JS", both instances of "Window Media Player" to "Windows Media Player",
all lowercase "i" to "I", change "is i didn't know" to "is that I didn't know"
(or rephrase to "I didn't realize"), and replace "critics" with "criticism" or
"feedback"; also tidy the sentence about playlists (e.g., "I don't like how
Windows Media Player playlists work, and I like how Spotify playlists work, so I
combined those ideas") and rephrase the RAM/Tauri sentence more formally.

In `@ui/components/bottom-player/player.html`:
- Around line 58-60: The button with id "TrackMenuBtn" is inconsistent with the
other camelCase IDs and lacks an aria-label; rename the id to "trackMenuBtn"
(matching peers like trackShuffleBtn, trackRepeatBtn, playPauseBtn) and add an
appropriate aria-label attribute (e.g., aria-label="Track menu") to the <button>
element to restore naming consistency and screen-reader accessibility.

In `@ui/pages/playlist/playlist-virtualizer.js`:
- Around line 37-39: Remove the private/manual lifecycle usage: delete calls to
virtualizer._willUpdate() and the assignment of virtualizer._didMount()’s return
value to virtualizer.destroy; instead rely on the public API and call
virtualizer.destroy() when you need to tear down the virtualizer. Specifically,
remove references to virtualizer._willUpdate and virtualizer._didMount and
ensure any teardown code invokes the public virtualizer.destroy() method (and
use public update/measure APIs if you need to trigger re-renders) rather than
assigning a private cleanup function.
- Around line 9-16: The dynamic import in playlist-virtualizer.js uses a brittle
deep path; change the import target used by virtualCorePromise to the package
entry '`@tanstack/virtual-core`' (i.e. virtualCorePromise ||=
import('`@tanstack/virtual-core`')), and ensure the package is moved from
devDependencies to dependencies in package.json so it is available at runtime;
also stop calling private internals on the Virtualizer instance (remove uses of
virtualizer._willUpdate(), virtualizer._didMount() and replacing
virtualizer.destroy) and instead rely on the public lifecycle methods
(virtualizer.destroy()) and the library’s supported measurement/init APIs for
setup/cleanup.

In `@ui/pages/playlist/playlist.js`:
- Around line 274-281: renderTotalDuration() and per-cell updates can write
stale state after teardown because cleanup() doesn't invalidate
totalDurationRunId or cancel durationCellsRaf; update cleanup() to increment or
change totalDurationRunId to invalidate any in-flight
resolveTrackDurationsLimited onResolved callbacks, call
cancelAnimationFrame(durationCellsRaf) (and null it) to stop pending RAF work,
and ensure scheduleDurationCellUpdate and any other callbacks (the onResolved
passed into resolveTrackDurationsLimited) continue to compare the captured runId
against totalDurationRunId before mutating state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ae931999-819a-4557-8854-a1b1f7169aeb

📥 Commits

Reviewing files that changed from the base of the PR and between d687d33 and bb6bb5d.

📒 Files selected for processing (7)
  • README.md
  • ui/components/bottom-player/player.css
  • ui/components/bottom-player/player.html
  • ui/pages/playlist/playlist-row-renderer.js
  • ui/pages/playlist/playlist-virtualizer.js
  • ui/pages/playlist/playlist.css
  • ui/pages/playlist/playlist.js

Comment thread README.md
Comment thread README.md
Comment thread ui/components/bottom-player/player.html Outdated
Comment thread ui/pages/playlist/playlist-virtualizer.js
Comment thread ui/pages/playlist/playlist-virtualizer.js
Comment thread ui/pages/playlist/playlist.js
@CupOfMakiato CupOfMakiato merged commit c28e586 into main May 22, 2026
5 checks passed
@CupOfMakiato CupOfMakiato deleted the fix/playlist-tanstack branch May 22, 2026 09:30
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.

1 participant