RelaySetList.tsx raw
1 import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
2 import {
3 closestCenter,
4 DndContext,
5 DragEndEvent,
6 KeyboardSensor,
7 PointerSensor,
8 useSensor,
9 useSensors
10 } from '@dnd-kit/core'
11 import { restrictToParentElement, restrictToVerticalAxis } from '@dnd-kit/modifiers'
12 import {
13 arrayMove,
14 SortableContext,
15 sortableKeyboardCoordinates,
16 verticalListSortingStrategy
17 } from '@dnd-kit/sortable'
18 import { useTranslation } from 'react-i18next'
19 import PullRelaySetsButton from './PullRelaySetsButton'
20 import RelaySet from './RelaySet'
21
22 export default function RelaySetList() {
23 const { t } = useTranslation()
24 const { relaySets, reorderRelaySets } = useFavoriteRelays()
25
26 const sensors = useSensors(
27 useSensor(PointerSensor),
28 useSensor(KeyboardSensor, {
29 coordinateGetter: sortableKeyboardCoordinates
30 })
31 )
32
33 const handleDragEnd = (event: DragEndEvent) => {
34 const { active, over } = event
35
36 if (over && active.id !== over.id) {
37 const oldIndex = relaySets.findIndex((item) => item.id === active.id)
38 const newIndex = relaySets.findIndex((item) => item.id === over.id)
39
40 const reorderedSets = arrayMove(relaySets, oldIndex, newIndex)
41 reorderRelaySets(reorderedSets)
42 }
43 }
44
45 return (
46 <div className="space-y-2">
47 <div className="flex flex-wrap items-center justify-between gap-2">
48 <div className="text-muted-foreground font-semibold select-none shrink-0">
49 {t('Relay sets')}
50 </div>
51 <PullRelaySetsButton />
52 </div>
53 <DndContext
54 sensors={sensors}
55 collisionDetection={closestCenter}
56 onDragEnd={handleDragEnd}
57 modifiers={[restrictToVerticalAxis, restrictToParentElement]}
58 >
59 <SortableContext
60 items={relaySets.map((set) => set.id)}
61 strategy={verticalListSortingStrategy}
62 >
63 <div className="grid gap-2">
64 {relaySets.map((relaySet) => (
65 <RelaySet key={relaySet.id} relaySet={relaySet} />
66 ))}
67 </div>
68 </SortableContext>
69 </DndContext>
70 </div>
71 )
72 }
73