• 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.

    Parameters

    • props: TrackActionsMenuProps

      Component properties

      Props for the TrackActionsMenu component

      • track: SkippedTrack

        The skipped track data object to act upon

      • onUnlikeTrack: (track: SkippedTrack) => Promise<void>

        Callback for removing the track from Spotify library

      • onRemoveTrackData: (track: SkippedTrack) => Promise<void>

        Callback for removing just the track's skip data

    Returns Element

    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>
    );
    }