feat(ux): improve song details panel UX - hide panel by default, show only when song selected, add close button with X icon
This commit is contained in:
parent
96fdf64060
commit
dc8254772c
@ -83,6 +83,11 @@ const RekordboxReader: React.FC = () => {
|
||||
setSelectedSong(song);
|
||||
}, []);
|
||||
|
||||
// Handle closing the song details panel
|
||||
const handleCloseSongDetails = useCallback(() => {
|
||||
setSelectedSong(null);
|
||||
}, []);
|
||||
|
||||
// Handle playing a song from the main view
|
||||
const handlePlaySong = useCallback((song: Song) => {
|
||||
// Check if song has S3 file
|
||||
@ -685,7 +690,7 @@ const RekordboxReader: React.FC = () => {
|
||||
</Box>
|
||||
|
||||
{/* Details Panel */}
|
||||
{!isMobile && (
|
||||
{!isMobile && selectedSong && (
|
||||
<Box
|
||||
w="350px"
|
||||
minW="350px"
|
||||
@ -706,7 +711,7 @@ const RekordboxReader: React.FC = () => {
|
||||
'&::-webkit-scrollbar-track': { backgroundColor: 'var(--chakra-colors-gray-900)' },
|
||||
}}
|
||||
>
|
||||
<SongDetails song={selectedSong} />
|
||||
<SongDetails song={selectedSong} onClose={handleCloseSongDetails} />
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import React, { useMemo, memo } from "react";
|
||||
import { Box, VStack, Text, Divider } from "@chakra-ui/react";
|
||||
import { Box, VStack, Text, Divider, IconButton, HStack } from "@chakra-ui/react";
|
||||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
import { Song } from "../types/interfaces";
|
||||
import { formatDuration } from '../utils/formatters';
|
||||
|
||||
interface SongDetailsProps {
|
||||
song: Song | null;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const calculateBitrate = (size: string, totalTime: string): number | null => {
|
||||
@ -22,7 +24,7 @@ const calculateBitrate = (size: string, totalTime: string): number | null => {
|
||||
return Math.round(bits / seconds / 1000);
|
||||
};
|
||||
|
||||
export const SongDetails: React.FC<SongDetailsProps> = memo(({ song }) => {
|
||||
export const SongDetails: React.FC<SongDetailsProps> = memo(({ song, onClose }) => {
|
||||
// Memoize expensive calculations
|
||||
const songDetails = useMemo(() => {
|
||||
if (!song) return null;
|
||||
@ -72,7 +74,8 @@ export const SongDetails: React.FC<SongDetailsProps> = memo(({ song }) => {
|
||||
return (
|
||||
<Box p={4} bg="gray.800" borderRadius="md">
|
||||
<VStack align="stretch" spacing={4}>
|
||||
<Box>
|
||||
<HStack justify="space-between" align="flex-start">
|
||||
<Box flex={1}>
|
||||
<Text fontSize="lg" fontWeight="bold" color="white">
|
||||
{song.title}
|
||||
</Text>
|
||||
@ -80,6 +83,18 @@ export const SongDetails: React.FC<SongDetailsProps> = memo(({ song }) => {
|
||||
{song.artist}
|
||||
</Text>
|
||||
</Box>
|
||||
{onClose && (
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
icon={<CloseIcon />}
|
||||
onClick={onClose}
|
||||
aria-label="Close details"
|
||||
color="gray.400"
|
||||
_hover={{ bg: "gray.700", color: "white" }}
|
||||
/>
|
||||
)}
|
||||
</HStack>
|
||||
<Divider borderColor="gray.700" />
|
||||
<VStack align="stretch" spacing={3}>
|
||||
{songDetails.details.map(({ label, value }) => (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user