Skip to content

added new feature - New Page with dynamic background using color thief library and controls and progress bar.#188

Open
DARSHITSHAH-2906 wants to merge 1 commit intoAnmol-TheDev:mainfrom
DARSHITSHAH-2906:feature/add-new-page-for-each-song-with-controls-and-progressbar-with-dynamic-background-using-color-thief-library
Open

added new feature - New Page with dynamic background using color thief library and controls and progress bar.#188
DARSHITSHAH-2906 wants to merge 1 commit intoAnmol-TheDev:mainfrom
DARSHITSHAH-2906:feature/add-new-page-for-each-song-with-controls-and-progressbar-with-dynamic-background-using-color-thief-library

Conversation

@DARSHITSHAH-2906
Copy link

@DARSHITSHAH-2906 DARSHITSHAH-2906 commented Oct 17, 2025

New Feature..
Changes Made in the Code:

  1. Added new page for better UI and User experienece for each Song.
  2. Used Color thief Library for fetching the color for the background from the image.
Screenshot 2025-10-18 002716
Screen.Recording.2025-10-18.002902.mp4

@Anmol-TheDev Please assign this task to me under Hacktoberfest'25.
Kindly Inform if any suggestion / update required in the PR.

Summary by CodeRabbit

  • New Features
    • Added a dedicated song detail page accessible from album, artist, liked songs, playlist, and search sections.
    • Implemented dynamic background colors on song pages, automatically derived from album artwork.
    • Enhanced navigation throughout the app—song items now link directly to individual song detail pages, improving browsing experience.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

Warning

.coderabbit.yml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
end of the stream or a document separator is expected in ".coderabbit.yml" (17:1)

 14 | file_path_instructions:
 15 | - path: "src/**/*.{js,jsx,ts,tsx}"
 16 | instructions: |
 17 | - Components should be function ...
------^
 18 | - Use appropriate hooks for sta ...
 19 | - Implement proper loading stat ...
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

The pull request adds a dedicated song detail page accessible through React Router navigation, integrates ColorThief library for dynamic color extraction from song images, and refactors song list navigation across multiple components to use React Router Links instead of onClick handlers.

Changes

Cohort / File(s) Summary
Dependency Addition
package.json
Added colorthief to runtime dependencies for palette extraction.
Routing Setup
src/App.jsx
Imported SongPage component and registered new route /song/:songId to enable per-song navigation.
New Song Page Component
src/components/song/SongPage.jsx
Created full-screen song view with dynamic gradient background, artwork, title, artists, progress bar, and play/pause toggle; derives background colors from song image via ColorThief.
Song List Link Navigation
src/components/Album/Album.jsx, src/components/Artist/artist.jsx, src/components/LikedSongs/LikedSongs.jsx, src/components/playlist/Plylistinfo.jsx, src/components/search/SearchResult.jsx
Wrapped song items with Link components to /song/:id instead of onClick handlers; preserved internal play/pause and interaction controls with event propagation management.
Color Extraction Refactor
src/components/color/ColorGenrator.js
Replaced canvas-based pixel analysis with ColorThief palette extraction; added error handling for color derivation.

Sequence Diagram

sequenceDiagram
    participant User
    participant ListComponent as List Component
    participant Router as React Router
    participant SongPage
    participant ColorThief
    participant Store as Global Store

    User->>ListComponent: Click song item
    ListComponent->>Router: Navigate via Link to /song/:id (with song state)
    Router->>SongPage: Render SongPage with location state
    SongPage->>SongPage: Extract song from location.state
    SongPage->>ColorThief: Call getImageColors(song.image)
    ColorThief->>ColorThief: Extract palette (2 colors)
    ColorThief-->>SongPage: Return {dominantColor, averageColor}
    SongPage->>SongPage: Apply gradient background
    SongPage->>SongPage: Render artwork & metadata
    User->>SongPage: Click play/pause
    SongPage->>Store: Update isPlaying, set musicId
    Store-->>SongPage: Reflect changes in UI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Rationale: The changes introduce a new component with moderate logic (color extraction, state management, progress tracking) and refactor navigation consistently across five files with a repeatable pattern. The color extraction refactoring requires verification of ColorThief integration and error handling. The homogeneous nature of link wrapping reduces per-file cognitive load, but the diversity of affected components and the new SongPage logic require careful review.

Possibly related PRs

  • Anmol-TheDev/Music_app#111: Adds immersive now-playing component with ColorThief-based dynamic background coloring, sharing the same color extraction pattern.

Suggested reviewers

  • Anmol-TheDev

Poem

🐰 A song springs to life with a tap so light,
Links guide the way through routes so bright,
Colors bloom from images deep,
While gradients dance and memories leap,
Now every melody finds its own page—
Hopping through features, stage by stage! 🎵

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "added new feature - New Page with dynamic background using color thief library and controls and progress bar" directly and accurately describes the primary feature addition in this changeset. The title captures the core objectives: creating a new SongPage component with a dynamically generated background powered by the ColorThief library, along with playback controls and a progress bar. The supporting changes—refactoring song list components to navigate to this new page and integrating ColorThief into the color extraction utility—are enablers of the main feature rather than the main point itself. The title is specific and concrete, avoiding vague terminology, and clearly communicates what was added.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (4)
src/components/color/ColorGenrator.js (1)

7-29: Consider instantiating ColorThief once for efficiency.

The current implementation creates a new ColorThief instance on every call. While functional, instantiating it once outside the function would be more efficient.

+const colorThief = new ColorThief();
+
 export function getImageColors(imageUrl) {
   return new Promise((resolve, reject) => {
     const img = new Image();
     img.crossOrigin = "Anonymous";
     img.src = imageUrl;
-    const colorThief = new ColorThief();

     img.onload = () => {
       try {
         const palette = colorThief.getPalette(img, 2);
src/components/song/SongPage.jsx (2)

36-85: Consider adding navigation controls and improved UX.

The page lacks a back button for navigation and the progress bar is not interactive. Consider adding these features for better user experience.

Add a back button at the top:

import { useNavigate } from "react-router-dom";
import { ArrowLeft } from "lucide-react";

// Inside component:
const navigate = useNavigate();

// In JSX, before the main content:
<button 
  onClick={() => navigate(-1)}
  className="absolute top-4 left-4 text-white hover:scale-110 transition-transform"
>
  <ArrowLeft size={24} />
</button>

Consider making the progress bar interactive by adding an onClick handler to allow seeking.


26-30: Consider extracting formatTime as a shared utility.

This time formatting logic appears to be duplicated across multiple components (e.g., Artist.jsx, Plylistinfo.jsx). Consider extracting it to a shared utility function.

Create a utility file (e.g., src/utils/time.js):

export function formatTime(time) {
  const minutes = Math.floor(time / 60);
  const seconds = Math.floor(time % 60);
  return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}
src/components/search/SearchResult.jsx (1)

168-220: Consider using stopPropagation in addition to preventDefault.

The controls use e.preventDefault() to prevent Link navigation, which differs from other files (Plylistinfo.jsx, Artist.jsx, LikedSongs.jsx) that use e.stopPropagation(). For consistency and to ensure events don't bubble, consider using stopPropagation() as well.

-                          <div onClick={(e) => e.preventDefault()}>
+                          <div onClick={(e) => {
+                            e.preventDefault();
+                            e.stopPropagation();
+                          }}>
                             <Like songId={song.id} />
                           </div>
                           <div
                             onClick={(e) => {
                               e.preventDefault();
+                              e.stopPropagation();
                               if (isPlaying && song.id === musicId) {

This matches the pattern used in other files and provides more robust event handling.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db8c7a2 and 390f113.

📒 Files selected for processing (9)
  • package.json (1 hunks)
  • src/App.jsx (2 hunks)
  • src/components/Album/Album.jsx (2 hunks)
  • src/components/Artist/artist.jsx (2 hunks)
  • src/components/LikedSongs/LikedSongs.jsx (2 hunks)
  • src/components/color/ColorGenrator.js (1 hunks)
  • src/components/playlist/Plylistinfo.jsx (2 hunks)
  • src/components/search/SearchResult.jsx (4 hunks)
  • src/components/song/SongPage.jsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
src/components/Artist/artist.jsx (5)
src/components/song/SongPage.jsx (1)
  • song (10-10)
src/components/music/MusicPlayer.jsx (1)
  • song (24-24)
src/components/search/SearchResult.jsx (3)
  • musicId (15-15)
  • isPlaying (16-16)
  • setIsPlaying (17-17)
src/components/ui/Like.jsx (1)
  • Like (9-206)
src/components/Menu.jsx (1)
  • Menu (32-568)
src/components/playlist/Plylistinfo.jsx (3)
src/components/song/SongPage.jsx (1)
  • song (10-10)
src/components/music/MusicPlayer.jsx (1)
  • song (24-24)
src/components/search/SearchResult.jsx (3)
  • isPlaying (16-16)
  • musicId (15-15)
  • setIsPlaying (17-17)
src/components/search/SearchResult.jsx (2)
src/components/ui/Like.jsx (1)
  • Like (9-206)
src/components/Menu.jsx (1)
  • Menu (32-568)
src/components/color/ColorGenrator.js (1)
src/components/ThemeCustomizer.jsx (3)
  • r (164-164)
  • g (165-165)
  • b (166-166)
src/components/song/SongPage.jsx (2)
src/components/Album/Album.jsx (1)
  • useStore (36-45)
src/components/color/ColorGenrator.js (1)
  • getImageColors (7-30)
src/components/Album/Album.jsx (3)
src/hooks/SongCustomHooks.ts (1)
  • formatArtist (147-164)
src/components/Menu.jsx (3)
  • isMobile (35-35)
  • Menu (32-568)
  • open (36-36)
src/components/ui/Like.jsx (1)
  • Like (9-206)
src/components/LikedSongs/LikedSongs.jsx (3)
src/components/song/SongPage.jsx (1)
  • song (10-10)
src/components/ui/Like.jsx (1)
  • Like (9-206)
src/components/Menu.jsx (1)
  • Menu (32-568)
🪛 Biome (2.1.2)
src/components/Album/Album.jsx

[error] 396-396: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)


[error] 470-470: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🔇 Additional comments (20)
src/App.jsx (2)

10-10: LGTM - SongPage import added correctly.

The import follows the existing pattern and enables the new song detail route.


44-47: LGTM - Song detail route configured properly.

The new route correctly uses a dynamic :songId parameter and is properly nested within the main layout.

src/components/playlist/Plylistinfo.jsx (2)

6-6: LGTM - Link import added for navigation.

Properly imported to enable React Router-based navigation.


140-183: LGTM - Link-based navigation implemented correctly.

The song items are properly wrapped with Link components that navigate to the song detail page. The use of e.stopPropagation() on play/pause controls correctly prevents unintended navigation.

src/components/color/ColorGenrator.js (2)

1-1: LGTM - ColorThief library imported.

Enables palette-based color extraction for dynamic backgrounds.


3-5: LGTM - Helper function simplified.

The one-line implementation is more concise while maintaining correctness.

src/components/Artist/artist.jsx (2)

2-2: LGTM - Link import added.

Enables React Router-based navigation to song detail pages.


185-348: LGTM - Link-based navigation implemented consistently.

Both mobile and desktop layouts properly wrap song items with Link components while preserving playback controls through event propagation management.

src/components/search/SearchResult.jsx (2)

5-5: LGTM - Link import added.

Enables React Router navigation to song detail pages.


41-44: LGTM - Function signature maintained.

Parameter names are clear and function logic is preserved.

src/components/LikedSongs/LikedSongs.jsx (2)

2-2: LGTM - Link import added.

Enables navigation to song detail pages via React Router.


105-190: LGTM - Link-based navigation implemented correctly.

Song items are properly wrapped with Link components and playback controls correctly use stopPropagation to prevent unintended navigation.

package.json (1)

30-30: colorthief is current with no known security vulnerabilities.

The package.json specifies version ^2.6.0, which matches the latest version available (2.6.0). GitHub's security advisory database reports no known vulnerabilities for this package.

src/components/Album/Album.jsx (7)

3-3: LGTM: Link import added correctly.

The Link component is properly imported from react-router-dom to enable declarative navigation to individual song pages.


354-376: LGTM: Play/pause event handling is correct.

The event handlers properly use e.preventDefault() and e.stopPropagation() to prevent the Link navigation when clicking play/pause controls, while preserving the playback functionality.


402-407: LGTM: Like button interaction handling is correct.

The wrapper correctly uses e.stopPropagation() to prevent the Link navigation when interacting with the Like button.


409-420: LGTM: Menu interaction handling is correct.

The wrapper correctly uses e.stopPropagation() to prevent the Link navigation when opening the menu.


436-458: LGTM: Desktop play/pause event handling is correct.

The desktop layout properly implements event handlers with e.preventDefault() and e.stopPropagation() to prevent Link navigation when clicking play/pause controls.


482-497: LGTM: Desktop Like and Menu interaction handling is correct.

Both the Like button and Menu correctly prevent Link navigation through proper event handling.


335-501: Route configuration is properly set up.

The /song/:songId route is correctly defined in src/App.jsx and the SongPage component properly receives and handles the song data via the useLocation() hook, accessing location.state?.song as expected from the Link component's state prop.

Comment on lines +335 to +341
<Link key={song.id || index} to={`/song/${song.id}`} state={{ song }}>
<div
key={song.id || index}
className={`group rounded-lg transition-all duration-200 hover:bg-muted/50 ${
song.id === musicId || openMenuId === song.id ? "bg-muted/50" : ""
}`}
>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Remove duplicate key prop.

The key prop appears on both the Link (line 335) and the inner div (line 337). React only requires the key on the outermost element in the list iteration. The duplicate will cause React warnings and is unnecessary.

Apply this diff to remove the duplicate key:

-                <Link key={song.id || index} to={`/song/${song.id}`} state={{ song }}>
+                <Link to={`/song/${song.id}`} state={{ song }} key={song.id || index}>
                   <div
-                    key={song.id || index}
                     className={`group rounded-lg transition-all duration-200 hover:bg-muted/50 ${
                       song.id === musicId || openMenuId === song.id ? "bg-muted/50" : ""
                     }`}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Link key={song.id || index} to={`/song/${song.id}`} state={{ song }}>
<div
key={song.id || index}
className={`group rounded-lg transition-all duration-200 hover:bg-muted/50 ${
song.id === musicId || openMenuId === song.id ? "bg-muted/50" : ""
}`}
>
<Link to={`/song/${song.id}`} state={{ song }} key={song.id || index}>
<div
className={`group rounded-lg transition-all duration-200 hover:bg-muted/50 ${
song.id === musicId || openMenuId === song.id ? "bg-muted/50" : ""
}`}
>
🤖 Prompt for AI Agents
In src/components/Album/Album.jsx around lines 335 to 341, there's a duplicate
key prop on both the outer Link and the inner div; remove the key from the inner
div and keep the key only on the outermost iterated element (e.g., Link with
key={song.id || index}) so React list items have a single unique key and no
duplicate prop remains.

Comment on lines +394 to +399
<p
className="text-xs text-muted-foreground truncate mt-0.5"
dangerouslySetInnerHTML={{
__html: formatArtist(song, false, isMobile),
}}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

XSS risk and invalid nested links in artist rendering.

This code has two related issues:

  1. XSS vulnerability: formatArtist returns HTML with unescaped artist.name values that are injected via dangerouslySetInnerHTML. If the API returns malicious content in artist names (e.g., <img src=x onerror=alert(1)>), it will execute.

  2. Invalid nested links: formatArtist generates <a> tags for artist links, which are now nested inside the Link wrapper. This creates invalid HTML (anchor inside anchor) and breaks accessibility—screen readers cannot handle nested links correctly, and click behavior becomes unpredictable.

Recommended solution:

Refactor to use React Router's Link components and escape artist names:

-                          <p
-                            className="text-xs text-muted-foreground truncate mt-0.5"
-                            dangerouslySetInnerHTML={{
-                              __html: formatArtist(song, false, isMobile),
-                            }}
-                          />
+                          <p className="text-xs text-muted-foreground truncate mt-0.5">
+                            {song.artists.primary
+                              .slice(0, isMobile ? 1 : 3)
+                              .map((artist, i, arr) => (
+                                <span key={artist.id}>
+                                  <span
+                                    onClick={(e) => {
+                                      e.preventDefault();
+                                      e.stopPropagation();
+                                      navigate(`/artist?Id=${artist.id}`);
+                                    }}
+                                    className="hover:underline cursor-pointer"
+                                  >
+                                    {artist.name}
+                                  </span>
+                                  {i < arr.length - 1 && ", "}
+                                </span>
+                              ))}
+                            {song.artists.primary.length > (isMobile ? 1 : 3) && " & more"}
+                          </p>

This approach:

  • Eliminates XSS by rendering artist names as text
  • Removes nested links by using click handlers instead
  • Maintains the same visual appearance and functionality

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (2.1.2)

[error] 396-396: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

Comment on lines +468 to +473
<p
className="text-sm text-muted-foreground truncate mt-0.5"
dangerouslySetInnerHTML={{
__html: formatArtist(song, false, isMobile),
}}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Same XSS and nested links issue in desktop layout.

This has the identical security and HTML validity issues as the mobile layout (lines 394-399). Please apply the same fix here to eliminate XSS risk and nested links.

🧰 Tools
🪛 Biome (2.1.2)

[error] 470-470: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

Comment on lines +15 to +24
useEffect(() => {
if (location.state?.song) {
setSong(location.state.song);
if (location.state.song.image && location.state.song.image[2]) {
getImageColors(location.state.song.image[2].url).then(({ averageColor, dominantColor }) => {
setBgColor({ bg1: averageColor, bg2: dominantColor });
});
}
}
}, [location.state]);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for color extraction.

The getImageColors promise lacks error handling, which could cause the page to silently fail if color extraction encounters issues.

       if (location.state.song.image && location.state.song.image[2]) {
-        getImageColors(location.state.song.image[2].url).then(({ averageColor, dominantColor }) => {
-          setBgColor({ bg1: averageColor, bg2: dominantColor });
-        });
+        getImageColors(location.state.song.image[2].url)
+          .then(({ averageColor, dominantColor }) => {
+            setBgColor({ bg1: averageColor, bg2: dominantColor });
+          })
+          .catch((error) => {
+            console.error("Failed to extract colors:", error);
+            // Fallback to default colors
+          });
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
if (location.state?.song) {
setSong(location.state.song);
if (location.state.song.image && location.state.song.image[2]) {
getImageColors(location.state.song.image[2].url).then(({ averageColor, dominantColor }) => {
setBgColor({ bg1: averageColor, bg2: dominantColor });
});
}
}
}, [location.state]);
useEffect(() => {
if (location.state?.song) {
setSong(location.state.song);
if (location.state.song.image && location.state.song.image[2]) {
getImageColors(location.state.song.image[2].url)
.then(({ averageColor, dominantColor }) => {
setBgColor({ bg1: averageColor, bg2: dominantColor });
})
.catch((error) => {
console.error("Failed to extract colors:", error);
// Fallback to default colors
});
}
}
}, [location.state]);
🤖 Prompt for AI Agents
In src/components/song/SongPage.jsx around lines 15 to 24, the getImageColors
promise has no error handling; wrap the color extraction in a try/catch (or
attach a .catch) and handle failures by logging the error and setting a safe
fallback background (e.g., neutral hex values or previously stored defaults) so
setBgColor is always called with valid values; also guard state updates against
an unmounted component (use an abort/mounted flag) to avoid memory leaks when
the async call resolves.

Comment on lines +71 to +77
<button
onClick={() => {
if (musicId !== song.id) {
setMusicId(song.id);
}
setIsPlaying(!isPlaying);
}}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify playback logic handles song loading correctly.

The button sets musicId and toggles isPlaying, but it's unclear if this ensures the song starts playing correctly. Verify that the music player component responds appropriately to these state changes.


🏁 Script executed:

#!/bin/bash
# Description: Check how MusicPlayer component handles musicId and isPlaying state changes

# Find MusicPlayer component and examine its useEffect dependencies
ast-grep --pattern $'useEffect(() => {
  $$$
}, [$$$musicId$$$])'

# Also check setMusicId usage patterns
rg -nP 'setMusicId' --type=jsx --type=js -A 3 -B 3

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Description: Check how MusicPlayer component handles musicId and isPlaying state changes

# First, find MusicPlayer component file
echo "=== Searching for MusicPlayer component ==="
rg -n 'MusicPlayer' --type=js -B 2 -A 2

# Check useEffect patterns with musicId dependency
echo -e "\n=== Checking useEffect with musicId dependency ==="
rg -nP 'useEffect.*musicId' --type=js -B 2 -A 5

# Search for setMusicId usage patterns
echo -e "\n=== Checking setMusicId usage ==="
rg -nP 'setMusicId' --type=js -A 3 -B 3

# Check isPlaying state usage
echo -e "\n=== Checking isPlaying state handling ==="
rg -nP 'isPlaying' --type=js -B 2 -A 2 | head -50

Length of output: 6794


🏁 Script executed:

#!/bin/bash
# Description: Examine MusicPlayer component implementation details

# View MusicPlayer.jsx to see store subscription and useEffect hooks
echo "=== MusicPlayer.jsx full implementation ==="
cat src/components/music/MusicPlayer.jsx

# Also check if MusicPlayer imports useStore
echo -e "\n=== Check MusicPlayer imports ==="
head -30 src/components/music/MusicPlayer.jsx

Length of output: 10959


Fix race condition in playback logic: separate song-switching from play-pause toggling.

When clicking the button with a different song, setMusicId() triggers MusicPlayer's useEffect which auto-sets isPlaying(true), but then setIsPlaying(!isPlaying) immediately toggles it—causing the player to pause when switching songs.

Change the button logic to:

  • If switching songs: only call setMusicId() (let useEffect handle play)
  • If same song: only toggle isPlaying
onClick={() => {
  if (musicId !== song.id) {
    setMusicId(song.id);
  } else {
    setIsPlaying(!isPlaying);
  }
}}

This ensures songs auto-play on switch and only toggle play-pause when clicking the same song.

🤖 Prompt for AI Agents
In src/components/song/SongPage.jsx around lines 71 to 77, the button onClick
races: when switching to a different song the component calls
setMusicId(song.id) but then immediately calls setIsPlaying(!isPlaying), which
can flip the auto-play that MusicPlayer's useEffect sets. Fix by changing the
click handler so it only calls setMusicId(song.id) when musicId !== song.id
(letting the MusicPlayer useEffect enable playback), and only toggles
setIsPlaying(!isPlaying) when the clicked song is the current one.

@Anmol-TheDev
Copy link
Owner

@DARSHITSHAH-2906 but we are already using a custom function for that

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.

2 participants