import React, { useMemo, memo } from "react"; import { Box, VStack, Text, Divider } from "@chakra-ui/react"; import { Song } from "../types/interfaces"; import { formatDuration } from '../utils/formatters'; interface SongDetailsProps { song: Song | null; } const calculateBitrate = (size: string, totalTime: string): number | null => { if (!size || !totalTime) return null; // Convert size from bytes to bits const bits = parseInt(size) * 8; // Convert duration to seconds (handle both milliseconds and seconds format) const seconds = parseInt(totalTime) / (totalTime.length > 4 ? 1000 : 1); if (seconds <= 0) return null; // Calculate bitrate in kbps return Math.round(bits / seconds / 1000); }; export const SongDetails: React.FC = memo(({ song }) => { // Memoize expensive calculations const songDetails = useMemo(() => { if (!song) return null; // Calculate bitrate only if imported value isn't available const calculatedBitrate = song.size && song.totalTime ? calculateBitrate(song.size, song.totalTime) : null; const displayBitrate = song.bitRate ? `${song.bitRate} kbps` : (calculatedBitrate ? `${calculatedBitrate} kbps (calculated)` : undefined); const details = [ { label: "Title", value: song.title }, { label: "Artist", value: song.artist }, { label: "Duration", value: formatDuration(song.totalTime || '') }, { label: "Album", value: song.album }, { label: "Genre", value: song.genre }, { label: "BPM", value: song.averageBpm }, { label: "Key", value: song.tonality }, { label: "Year", value: song.year }, { label: "Label", value: song.label }, { label: "Mix", value: song.mix }, { label: "Rating", value: song.rating }, { label: "Bitrate", value: displayBitrate }, { label: "Comments", value: song.comments }, ].filter(detail => detail.value); return { details, displayBitrate }; }, [song]); if (!song) { return ( Select a song to view details ); } if (!songDetails) { return ( Loading song details... ); } return ( {song.title} {song.artist} {songDetails.details.map(({ label, value }) => ( {label} {value} ))} {song.tempo && ( <> Tempo Details BPM {song.tempo.bpm} Beat {song.tempo.battito} Time Signature {song.tempo.metro} )} ); }); SongDetails.displayName = 'SongDetails';