From 4808406113bd0a62c442266a0aa01f9461d78fb0 Mon Sep 17 00:00:00 2001 From: Kagamine Rin Date: Fri, 29 May 2026 21:46:58 -0400 Subject: [PATCH] feat: Click album art in DetailPanel to play track MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DetailPanel.tsx: - Added optional onPlay prop to interface - Album art image now wrapped in clickable container with cursor-pointer - Hover overlay: semi-transparent black bg with white play triangle icon - Works for both artwork images and placeholder (treble clef) state - Placeholder gets hover:bg-white/10 for subtle feedback - App.tsx: passes handlePlay to DetailPanel onPlay prop Visual feedback: - group-hover opacity transition on overlay (0 → 1) - Play icon: w-12 h-12 white triangle (▶) centered - Smooth 150ms transition on overlay opacity --- frontend/src/App.tsx | 1 + frontend/src/components/DetailPanel.tsx | 33 +++++++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6dfb87f..4f3fb13 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -234,6 +234,7 @@ function App() { onDelete={handleDelete} onUploadArtwork={handleUploadArtwork} onRemoveArtwork={handleRemoveArtwork} + onPlay={handlePlay} /> )} diff --git a/frontend/src/components/DetailPanel.tsx b/frontend/src/components/DetailPanel.tsx index 54fa4bc..2508095 100644 --- a/frontend/src/components/DetailPanel.tsx +++ b/frontend/src/components/DetailPanel.tsx @@ -23,6 +23,7 @@ interface Props { onDelete: (id: string) => void onUploadArtwork: (id: string, file: File) => void onRemoveArtwork: (id: string) => void + onPlay?: (clip: Clip) => void } const modelName = (modelId: string) => { @@ -33,7 +34,7 @@ const modelName = (modelId: string) => { return names[modelId] || modelId } -export default function DetailPanel({ clip, onClose, onRename, onDelete, onUploadArtwork, onRemoveArtwork }: Props) { +export default function DetailPanel({ clip, onClose, onRename, onDelete, onUploadArtwork, onRemoveArtwork, onPlay }: Props) { const artworkInputRef = useRef(null) const [isEditingTitle, setIsEditingTitle] = useState(false) const [editTitle, setEditTitle] = useState(clip.title || '') @@ -146,17 +147,35 @@ export default function DetailPanel({ clip, onClose, onRename, onDelete, onUploa {clip.artwork_filename ? ( - Album art +
onPlay?.(clip)} + > + Album art +
+ + + +
+
) : ( -
+
onPlay?.(clip)} + > 𝄞 No album art +
+ + + +
)}