import React, { useState, useEffect } from 'react'; import { Song } from '../types'; import { songsApi, getAudioUrl } from '../services/api'; import { useAuth } from '../context/AuthContext'; import { ArrowLeft, Play, Pause, Heart, Share2, MoreHorizontal, ThumbsDown, Music as MusicIcon, Edit3, Eye } from 'lucide-react'; import { ShareModal } from './ShareModal'; interface SongProfileProps { songId: string; onBack: () => void; onPlay: (song: Song, list?: Song[]) => void; onNavigateToProfile: (username: string) => void; currentSong?: Song | null; isPlaying?: boolean; likedSongIds?: Set; onToggleLike?: (songId: string) => void; } const updateMetaTags = (song: Song) => { const baseUrl = window.location.origin; const songUrl = `${baseUrl}/song/${song.id}`; const title = `${song.title} by ${song.creator || 'Unknown Artist'} | ACE-Step UI`; const description = `Listen to "${song.title}" - ${song.style}. ${song.viewCount || 0} plays, ${song.likeCount || 0} likes. Create your own AI music with ACE-Step UI.`; document.title = title; const updateOrCreateMeta = (selector: string, attribute: string, value: string) => { let element = document.querySelector(selector) as HTMLMetaElement; if (!element) { element = document.createElement('meta'); const [attr, attrValue] = selector.replace(/[\[\]'"]/g, '').split('='); if (attr === 'property') element.setAttribute('property', attrValue); else if (attr === 'name') element.setAttribute('name', attrValue); document.head.appendChild(element); } element.setAttribute(attribute, value); }; updateOrCreateMeta('meta[name="description"]', 'content', description); updateOrCreateMeta('meta[name="title"]', 'content', title); updateOrCreateMeta('meta[property="og:type"]', 'content', 'music.song'); updateOrCreateMeta('meta[property="og:url"]', 'content', songUrl); updateOrCreateMeta('meta[property="og:title"]', 'content', title); updateOrCreateMeta('meta[property="og:description"]', 'content', description); updateOrCreateMeta('meta[property="og:image"]', 'content', song.coverUrl); updateOrCreateMeta('meta[property="og:image:width"]', 'content', '400'); updateOrCreateMeta('meta[property="og:image:height"]', 'content', '400'); updateOrCreateMeta('meta[property="og:audio"]', 'content', song.audioUrl || ''); updateOrCreateMeta('meta[property="og:audio:type"]', 'content', 'audio/mpeg'); updateOrCreateMeta('meta[name="twitter:card"]', 'content', 'summary_large_image'); updateOrCreateMeta('meta[name="twitter:url"]', 'content', songUrl); updateOrCreateMeta('meta[name="twitter:title"]', 'content', title); updateOrCreateMeta('meta[name="twitter:description"]', 'content', description); updateOrCreateMeta('meta[name="twitter:image"]', 'content', song.coverUrl); updateOrCreateMeta('meta[property="music:duration"]', 'content', String(song.duration || 0)); updateOrCreateMeta('meta[property="music:musician"]', 'content', song.creator || 'Unknown Artist'); }; const resetMetaTags = () => { document.title = 'ACE-Step UI - Local AI Music Generator'; const defaultDescription = 'Create original music with AI locally. Generate songs in any style with custom lyrics and professional quality using ACE-Step.'; const defaultImage = '/og-image.png'; const updateMeta = (selector: string, content: string) => { const element = document.querySelector(selector) as HTMLMetaElement; if (element) element.setAttribute('content', content); }; updateMeta('meta[name="description"]', defaultDescription); updateMeta('meta[property="og:title"]', 'ACE-Step UI - Local AI Music Generator'); updateMeta('meta[property="og:description"]', defaultDescription); updateMeta('meta[property="og:image"]', defaultImage); updateMeta('meta[property="og:type"]', 'website'); updateMeta('meta[name="twitter:title"]', 'ACE-Step UI - Local AI Music Generator'); updateMeta('meta[name="twitter:description"]', defaultDescription); updateMeta('meta[name="twitter:image"]', defaultImage); }; export const SongProfile: React.FC = ({ songId, onBack, onPlay, onNavigateToProfile, currentSong, isPlaying, likedSongIds = new Set(), onToggleLike }) => { const { user, token } = useAuth(); const [song, setSong] = useState(null); const [loading, setLoading] = useState(true); const [shareModalOpen, setShareModalOpen] = useState(false); const isCurrentSong = song && currentSong?.id === song.id; const isCurrentlyPlaying = isCurrentSong && isPlaying; const isLiked = song ? likedSongIds.has(song.id) : false; useEffect(() => { loadSongData(); return () => resetMetaTags(); }, [songId]); useEffect(() => { if (song) { updateMetaTags(song); } }, [song]); const loadSongData = async () => { setLoading(true); try { const response = await songsApi.getFullSong(songId, token); const transformedSong: Song = { id: response.song.id, title: response.song.title, lyrics: response.song.lyrics, style: response.song.style, coverUrl: `https://picsum.photos/seed/${response.song.id}/400/400`, duration: response.song.duration ? `${Math.floor(response.song.duration / 60)}:${String(Math.floor(response.song.duration % 60)).padStart(2, '0')}` : '0:00', createdAt: new Date(response.song.created_at), tags: response.song.tags || [], audioUrl: getAudioUrl(response.song.audio_url, response.song.id), isPublic: response.song.is_public, likeCount: response.song.like_count || 0, viewCount: response.song.view_count || 0, userId: response.song.user_id, creator: response.song.creator, creator_avatar: response.song.creator_avatar, }; setSong(transformedSong); } catch (error) { console.error('Failed to load song:', error); } finally { setLoading(false); } }; if (loading) { return (
Loading song...
); } if (!song) { return (
Song not found
); } return (
{/* Header */}

{song.title}

song.creator && onNavigateToProfile(song.creator)} className="flex items-center gap-2 cursor-pointer hover:underline" >
{song.creator_avatar ? ( {song.creator ) : ( song.creator ? song.creator[0].toUpperCase() : 'A' )}
{song.creator || 'Anonymous'}
{/* Tags */}
{song.style.split(',').slice(0, 4).map((tag, i) => ( {tag.trim()} ))}
{new Date(song.createdAt).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })} at {new Date(song.createdAt).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })} {!song.isPublic && song.userId === user?.id && ( Private )}
{/* Related Songs Tab - Hidden on mobile */}
{/* Content */}
{/* Left Column: Song Details */}
{/* Cover Art */}
{song.title} {isCurrentlyPlaying && (
)}
{/* Action Buttons */}
{song.viewCount || 0}
{user?.id === song.userId && ( )}
{/* Lyrics */} {song.lyrics && (

Lyrics

{song.lyrics}
)}
{song && ( setShareModalOpen(false)} song={song} /> )}
); };