Component properties
Props for the TrackActionsMenu component
The skipped track data object to act upon
Callback for removing the track from Spotify library
Callback for removing just the track's skip data
React component for track actions dropdown
export default function TrackActionsMenu({
track,
onUnlikeTrack,
onRemoveTrackData,
}: TrackActionsMenuProps) {
// Create Spotify URL
const spotifyUrl = `https://open.spotify.com/track/${track.id}`;
// Handler to open link in system browser using IPC
const handleOpenInSpotify = (e: React.MouseEvent) => {
e.preventDefault();
// Use the app's IPC bridge to open URLs in default browser
window.spotify.openURL(spotifyUrl);
};
// Check if track is in library
const isInLibrary = track.isInLibrary !== false; // Default to true if undefined
return (
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={handleOpenInSpotify}
className="text-primary hover:text-primary/80 cursor-pointer"
>
<ExternalLink className="mr-2 h-4 w-4" />
<span>Open in Spotify</span>
</DropdownMenuItem>
<DropdownMenuSeparator />
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div>
<DropdownMenuItem
onClick={() => isInLibrary && onUnlikeTrack(track)}
className={`${
isInLibrary
? "cursor-pointer text-rose-600 hover:text-rose-800 dark:text-rose-400 hover:dark:text-rose-300"
: "text-muted-foreground/50 cursor-not-allowed"
}`}
disabled={!isInLibrary}
>
<Trash2 className="mr-2 h-4 w-4" />
<span>Remove from library</span>
{!isInLibrary && <InfoIcon className="ml-2 h-3 w-3" />}
</DropdownMenuItem>
</div>
</TooltipTrigger>
{!isInLibrary && (
<TooltipContent>
<p>This track is not in your library</p>
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
<DropdownMenuItem
onClick={() => onRemoveTrackData(track)}
className="cursor-pointer text-amber-600 hover:text-amber-800 dark:text-amber-400 hover:dark:text-amber-300"
>
<XCircle className="mr-2 h-4 w-4" />
<span>Remove tracking data</span>
</DropdownMenuItem>
</DropdownMenuContent>
);
}
Track actions dropdown menu
Renders a dropdown menu containing actions that can be performed on a specific track. Actions include opening in Spotify, removing from library, and clearing tracking data. Each action is color-coded according to its impact.
This component is extracted to enable lazy loading, reducing the initial bundle size and improving page load performance. It's only loaded when a user interacts with a track's menu button.