Adds add to favorites button in SongRow

This commit is contained in:
2025-02-23 17:58:26 -08:00
parent 8ab927333b
commit d010d68056
8 changed files with 115 additions and 57 deletions

View File

@@ -1,11 +1,12 @@
import React, { useState, useEffect, useCallback } from 'react';
import React, { useState, useEffect, useCallback, ReactNode } from 'react';
import SongTable from './SongTable';
import NowPlaying from './NowPlaying';
import AddSongPanel from './AddSongPanel';
import { TabView, Tab } from './TabView';
import { API, getDisplayTitle, PlaylistItem, ServerEvent } from '../api/player';
import { FaMusic, FaHeart } from 'react-icons/fa';
import { FaMusic, FaHeart, FaPlus } from 'react-icons/fa';
import useWebSocket from 'react-use-websocket';
import classNames from 'classnames';
enum Tabs {
Playlist = "playlist",
@@ -21,10 +22,11 @@ const EmptyContent: React.FC<{ label: string}> = ({label}) => (
interface SonglistContentProps {
songs: PlaylistItem[];
isPlaying: boolean;
auxControlProvider?: (song: PlaylistItem) => ReactNode;
onNeedsRefresh: () => void;
}
const PlaylistContent: React.FC<SonglistContentProps> = ({ songs, isPlaying, onNeedsRefresh }) => {
const PlaylistContent: React.FC<SonglistContentProps> = ({ songs, isPlaying, auxControlProvider, onNeedsRefresh }) => {
const handleDelete = (index: number) => {
API.removeFromPlaylist(index);
onNeedsRefresh();
@@ -40,6 +42,7 @@ const PlaylistContent: React.FC<SonglistContentProps> = ({ songs, isPlaying, onN
<SongTable
songs={songs}
isPlaying={isPlaying}
auxControlProvider={auxControlProvider}
onDelete={handleDelete}
onSkipTo={handleSkipTo}
/>
@@ -49,9 +52,9 @@ const PlaylistContent: React.FC<SonglistContentProps> = ({ songs, isPlaying, onN
);
};
const FavoritesContent: React.FC<SonglistContentProps> = ({ songs, isPlaying, onNeedsRefresh }) => {
const FavoritesContent: React.FC<SonglistContentProps> = ({ songs, isPlaying, auxControlProvider, onNeedsRefresh }) => {
const handleDelete = (index: number) => {
API.removeFromFavorites(index);
API.removeFromFavorites(songs[index].filename);
onNeedsRefresh();
};
@@ -66,6 +69,7 @@ const FavoritesContent: React.FC<SonglistContentProps> = ({ songs, isPlaying, on
<SongTable
songs={songs}
isPlaying={isPlaying}
auxControlProvider={auxControlProvider}
onDelete={handleDelete}
onSkipTo={handleSkipTo}
/>
@@ -215,6 +219,62 @@ const App: React.FC = () => {
fetchFavorites();
}, [fetchPlaylist, fetchNowPlaying, fetchFavorites]);
const AuxButton: React.FC<{ children: ReactNode, className: string, title: string, onClick: () => void }> = (props) => (
<button
className={
classNames("hover:text-white transition-colors px-3 py-1 rounded", props.className)
}
title={props.title}
onClick={props.onClick}
>
{props.children}
</button>
);
const playlistAuxControlProvider = (song: PlaylistItem) => {
const isFavorite = favorites.some(f => f.filename === song.filename);
return (
<AuxButton
className={classNames({
"text-red-500": isFavorite,
"text-white/40": !isFavorite,
})}
title={isFavorite ? "Remove from favorites" : "Add to favorites"}
onClick={() => {
if (isFavorite) {
API.removeFromFavorites(song.filename);
} else {
API.addToFavorites(song.filename);
}
}}
>
<FaHeart />
</AuxButton>
);
};
const favoritesAuxControlProvider = (song: PlaylistItem) => {
const isInPlaylist = playlist.some(p => p.filename === song.filename);
return (
<AuxButton
className={classNames({
"text-white/40": isInPlaylist,
"text-white": !isInPlaylist,
})}
title={isInPlaylist ? "Remove from playlist" : "Add to playlist"}
onClick={() => {
if (isInPlaylist) {
API.removeFromPlaylist(playlist.findIndex(p => p.filename === song.filename));
} else {
API.addToPlaylist(song.filename);
}
}}
>
<FaPlus />
</AuxButton>
);
};
return (
<div className="flex items-center justify-center h-screen w-screen bg-black md:py-10">
<div className="bg-violet-900 w-full md:max-w-2xl h-full md:max-h-xl md:border md:rounded-2xl flex flex-col">
@@ -238,6 +298,7 @@ const App: React.FC = () => {
songs={playlist}
isPlaying={isPlaying}
onNeedsRefresh={refreshContent}
auxControlProvider={playlistAuxControlProvider}
/>
</Tab>
<Tab label="Favorites" identifier={Tabs.Favorites} icon={<FaHeart />}>
@@ -245,6 +306,7 @@ const App: React.FC = () => {
songs={favorites.map(f => ({ ...f, playing: f.filename === nowPlayingFileName }))}
isPlaying={isPlaying}
onNeedsRefresh={refreshContent}
auxControlProvider={favoritesAuxControlProvider}
/>
</Tab>
</TabView>