diff --git a/packages/frontend/src/components/PlaylistManager.tsx b/packages/frontend/src/components/PlaylistManager.tsx index 08e8ba7..9a79d32 100644 --- a/packages/frontend/src/components/PlaylistManager.tsx +++ b/packages/frontend/src/components/PlaylistManager.tsx @@ -143,27 +143,22 @@ const PlaylistItem: React.FC = React.memo(({ } onDragOver={(e) => { e.preventDefault(); - // Only highlight if payload looks like songs - const json = e.dataTransfer.getData('application/json') || e.dataTransfer.getData('text/plain'); - try { - const parsed = JSON.parse(json); - if (parsed?.type === 'songs') { - setIsDragOver(true); - } - console.debug('[DnD] dragover folder', node.name, parsed); - } catch (err) { - console.debug('[DnD] dragover folder parse failed', node.name, err); + const types = Array.from((e.dataTransfer.types || []) as any); + const hasOurType = types.includes('application/json') || types.includes('text/plain'); + if (hasOurType) { + setIsDragOver(true); } + console.debug('[DnD] dragover folder types', node.name, types); }} onDragLeave={() => setIsDragOver(false)} onDrop={(e) => { try { const json = e.dataTransfer.getData('application/json') || e.dataTransfer.getData('text/plain'); - const parsed = JSON.parse(json); + const parsed = json ? JSON.parse(json) : null; if (parsed?.type === 'songs' && Array.isArray(parsed.songIds) && onDropSongs) { onDropSongs(node.name, parsed.songIds); } - console.debug('[DnD] drop folder', node.name, parsed); + console.debug('[DnD] drop folder', node.name, parsed, 'raw len', json?.length || 0); } catch (err) { console.debug('[DnD] drop folder parse failed', node.name, err); } @@ -232,26 +227,22 @@ const PlaylistItem: React.FC = React.memo(({ position="relative" onDragOver={(e) => { e.preventDefault(); - const json = e.dataTransfer.getData('application/json') || e.dataTransfer.getData('text/plain'); - try { - const parsed = JSON.parse(json); - if (parsed?.type === 'songs') { - setIsDragOver(true); - } - console.debug('[DnD] dragover playlist', node.name, parsed); - } catch (err) { - console.debug('[DnD] dragover playlist parse failed', node.name, err); + const types = Array.from((e.dataTransfer.types || []) as any); + const hasOurType = types.includes('application/json') || types.includes('text/plain'); + if (hasOurType) { + setIsDragOver(true); } + console.debug('[DnD] dragover playlist types', node.name, types); }} onDragLeave={() => setIsDragOver(false)} onDrop={(e) => { try { const json = e.dataTransfer.getData('application/json') || e.dataTransfer.getData('text/plain'); - const parsed = JSON.parse(json); + const parsed = json ? JSON.parse(json) : null; if (parsed?.type === 'songs' && Array.isArray(parsed.songIds) && onDropSongs) { onDropSongs(node.name, parsed.songIds); } - console.debug('[DnD] drop playlist', node.name, parsed); + console.debug('[DnD] drop playlist', node.name, parsed, 'raw len', json?.length || 0); } catch (err) { console.debug('[DnD] drop playlist parse failed', node.name, err); }