feat(reorder): add end-of-list drop zone to move track to end; show hover indicator
This commit is contained in:
parent
2d42c6da71
commit
d0a83a85f5
@ -170,6 +170,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
|
|||||||
const isTriggeringRef = useRef(false);
|
const isTriggeringRef = useRef(false);
|
||||||
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
const [dragHoverIndex, setDragHoverIndex] = useState<number | null>(null);
|
const [dragHoverIndex, setDragHoverIndex] = useState<number | null>(null);
|
||||||
|
const [endDropHover, setEndDropHover] = useState<boolean>(false);
|
||||||
|
|
||||||
// Store current values in refs to avoid stale closures
|
// Store current values in refs to avoid stale closures
|
||||||
const hasMoreRef = useRef(hasMore);
|
const hasMoreRef = useRef(hasMore);
|
||||||
@ -500,6 +501,36 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
|
|||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</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 indicator for infinite scroll or playlist switching */}
|
||||||
{(loading || isSwitchingPlaylist) && (
|
{(loading || isSwitchingPlaylist) && (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user