mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
2b80a87bfc
Extract the drag-to-reorder boilerplate the sidebar, artist-layout, lyrics, queue-toolbar and servers customizers each hand-rolled into a single `useListReorderDnd` hook plus an id-based `applyListReorderById`, and migrate all five onto it. Reorders resolve by stable item id, never positional index, so a render filter can never share an index space with the reorder and desync it (the class behind #1164). No user-facing change. - New: useListReorderDnd, applyListReorderById (+ tests), ReorderGripHandle. - applySidebarReorderById now builds on the shared core; section/conserved guards stay sidebar-specific. - Queue/mini-queue/playlist reorder stay backend-index based (out of scope).
29 lines
884 B
TypeScript
29 lines
884 B
TypeScript
import { useTranslation } from 'react-i18next';
|
|
import { GripVertical } from 'lucide-react';
|
|
import { useDragSource } from '../../contexts/DragDropContext';
|
|
|
|
/**
|
|
* Drag handle shared by the reorder customizers. Emits an id-based payload
|
|
* (`{ type, id, section? }`) consumed by `useListReorderDnd`.
|
|
*/
|
|
export function ReorderGripHandle({
|
|
id, type, section, label,
|
|
}: { id: string; type: string; section?: string; label: string }) {
|
|
const { t } = useTranslation();
|
|
const { onMouseDown } = useDragSource(() => ({
|
|
data: JSON.stringify(section ? { type, id, section } : { type, id }),
|
|
label,
|
|
}));
|
|
return (
|
|
<span
|
|
className="sidebar-customizer-grip"
|
|
data-tooltip={t('settings.sidebarDrag')}
|
|
data-tooltip-pos="right"
|
|
onMouseDown={onMouseDown}
|
|
onClick={e => e.stopPropagation()}
|
|
>
|
|
<GripVertical size={16} />
|
|
</span>
|
|
);
|
|
}
|