feat(reorder): add end-of-list drop zone to move track to end; show hover indicator

This commit is contained in:
Geert Rademakes 2025-08-08 14:52:48 +02:00
parent 2d42c6da71
commit d0a83a85f5

View File

@ -170,6 +170,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
const isTriggeringRef = useRef(false);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const [dragHoverIndex, setDragHoverIndex] = useState<number | null>(null);
const [endDropHover, setEndDropHover] = useState<boolean>(false);
// Store current values in refs to avoid stale closures
const hasMoreRef = useRef(hasMore);
@ -501,6 +502,36 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
))}
</Box>
{/* Drop zone to move item to end of playlist */}
{onReorder && currentPlaylist && selectedSongs.size === 0 && (
<Box
onDragOver={(e: React.DragEvent) => {
e.preventDefault();
setDragHoverIndex(null);
setEndDropHover(true);
try { e.dataTransfer.dropEffect = 'move'; } catch {}
}}
onDragLeave={() => setEndDropHover(false)}
onDrop={async (e: React.DragEvent) => {
e.preventDefault();
const fromId = e.dataTransfer.getData('text/song-id');
if (!fromId) return;
// Move to end: omit toId
console.debug('[Reorder] move to end request', { playlist: currentPlaylist, fromId });
await api.moveTrackInPlaylist(currentPlaylist, fromId);
await onReorder(songs.map(s => s.id));
setEndDropHover(false);
}}
position="relative"
height="28px"
mt={1}
>
{endDropHover && (
<Box position="absolute" top="50%" left={0} right={0} height="2px" bg="blue.400" />
)}
</Box>
)}
{/* Loading indicator for infinite scroll or playlist switching */}
{(loading || isSwitchingPlaylist) && (
<Flex justify="center" align="center" p={6} key="loading-spinner" gap={3}>