feat: add listening history page with grouped track display and clear history functionality
- Implemented HistoryPage component to display user's listening history. - Tracks are grouped by date and displayed with play and add to queue options. - Added clear history functionality with confirmation dialog. - Created AlertDialog component for consistent alert dialog UI.
This commit is contained in:
@@ -37,6 +37,8 @@ interface AudioPlayerContextProps {
|
||||
toggleShuffle: () => void;
|
||||
shuffleAllAlbums: () => Promise<void>;
|
||||
playArtist: (artistId: string) => Promise<void>;
|
||||
playedTracks: Track[];
|
||||
clearHistory: () => void;
|
||||
}
|
||||
|
||||
const AudioPlayerContext = createContext<AudioPlayerContextProps | undefined>(undefined);
|
||||
@@ -534,6 +536,27 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
|
||||
}
|
||||
}, [api, songToTrack, toast, shuffle, playTrack]);
|
||||
|
||||
const clearHistory = useCallback(() => {
|
||||
setPlayedTracks([]);
|
||||
localStorage.removeItem('navidrome-playedTracks');
|
||||
}, []);
|
||||
|
||||
// Persist played tracks to localStorage
|
||||
useEffect(() => {
|
||||
localStorage.setItem('navidrome-playedTracks', JSON.stringify(playedTracks));
|
||||
}, [playedTracks]);
|
||||
|
||||
// Load played tracks from localStorage on mount
|
||||
useEffect(() => {
|
||||
const savedPlayedTracks = localStorage.getItem('navidrome-playedTracks');
|
||||
if (savedPlayedTracks) {
|
||||
try {
|
||||
setPlayedTracks(JSON.parse(savedPlayedTracks));
|
||||
} catch (error) {
|
||||
console.error('Failed to parse saved played tracks:', error);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
const contextValue = useMemo(() => ({
|
||||
currentTrack,
|
||||
playTrack,
|
||||
@@ -552,7 +575,9 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
|
||||
shuffle,
|
||||
toggleShuffle,
|
||||
shuffleAllAlbums,
|
||||
playArtist
|
||||
playArtist,
|
||||
playedTracks,
|
||||
clearHistory
|
||||
}), [
|
||||
currentTrack,
|
||||
queue,
|
||||
@@ -571,7 +596,9 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
|
||||
shuffle,
|
||||
toggleShuffle,
|
||||
shuffleAllAlbums,
|
||||
playArtist
|
||||
playArtist,
|
||||
playedTracks,
|
||||
clearHistory
|
||||
]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -285,16 +285,15 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
|
||||
{/* Overlay for better contrast */}
|
||||
<div className="absolute inset-0 bg-black/50" />
|
||||
|
||||
<div className="relative h-full w-full flex flex-col">
|
||||
<div className="relative h-full w-full flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-4 lg:p-6 flex-shrink-0">
|
||||
<h2 className="text-lg lg:text-xl font-semibold text-white"></h2>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
{onOpenQueue && (
|
||||
<button
|
||||
onClick={onOpenQueue}
|
||||
className="text-white hover:bg-white/20 p-2 rounded-full transition-colors"
|
||||
className="text-white hover:bg-white/20 p-2 rounded-full transition-colors flex items-center justify-center w-10 h-10"
|
||||
title="Open Queue"
|
||||
>
|
||||
<FaListUl className="w-5 h-5" />
|
||||
@@ -302,7 +301,8 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
)}
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="text-white hover:bg-white/20 p-2 rounded-full transition-colors"
|
||||
className="text-white hover:bg-white/20 p-2 rounded-full transition-colors flex items-center justify-center w-10 h-10"
|
||||
title="Close Player"
|
||||
>
|
||||
<FaXmark className="w-5 h-5" />
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user