diff --git a/src/components/FavoriteRelaysSetting/FavoriteRelayList.tsx b/src/components/FavoriteRelaysSetting/FavoriteRelayList.tsx index 7ff3574a..16a94a06 100644 --- a/src/components/FavoriteRelaysSetting/FavoriteRelayList.tsx +++ b/src/components/FavoriteRelaysSetting/FavoriteRelayList.tsx @@ -1,17 +1,63 @@ import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider' +import { + closestCenter, + DndContext, + DragEndEvent, + KeyboardSensor, + PointerSensor, + useSensor, + useSensors +} from '@dnd-kit/core' +import { restrictToParentElement, restrictToVerticalAxis } from '@dnd-kit/modifiers' +import { + arrayMove, + SortableContext, + sortableKeyboardCoordinates, + verticalListSortingStrategy +} from '@dnd-kit/sortable' import { useTranslation } from 'react-i18next' import RelayItem from './RelayItem' export default function FavoriteRelayList() { const { t } = useTranslation() - const { favoriteRelays } = useFavoriteRelays() + const { favoriteRelays, reorderFavoriteRelays } = useFavoriteRelays() + + const sensors = useSensors( + useSensor(PointerSensor), + useSensor(KeyboardSensor, { + coordinateGetter: sortableKeyboardCoordinates + }) + ) + + const handleDragEnd = (event: DragEndEvent) => { + const { active, over } = event + + if (over && active.id !== over.id) { + const oldIndex = favoriteRelays.findIndex((relay) => relay === active.id) + const newIndex = favoriteRelays.findIndex((relay) => relay === over.id) + + const reorderedRelays = arrayMove(favoriteRelays, oldIndex, newIndex) + reorderFavoriteRelays(reorderedRelays) + } + } return (
{t('Relays')}
- {favoriteRelays.map((relay) => ( - - ))} + + +
+ {favoriteRelays.map((relay) => ( + + ))} +
+
+
) } diff --git a/src/components/FavoriteRelaysSetting/RelayItem.tsx b/src/components/FavoriteRelaysSetting/RelayItem.tsx index 324c0e1d..ae57e257 100644 --- a/src/components/FavoriteRelaysSetting/RelayItem.tsx +++ b/src/components/FavoriteRelaysSetting/RelayItem.tsx @@ -1,18 +1,43 @@ import { toRelay } from '@/lib/link' import { useSecondaryPage } from '@/PageManager' +import { useSortable } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' +import { GripVertical } from 'lucide-react' import RelayIcon from '../RelayIcon' import SaveRelayDropdownMenu from '../SaveRelayDropdownMenu' export default function RelayItem({ relay }: { relay: string }) { const { push } = useSecondaryPage() + const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ + id: relay + }) + + const style = { + transform: CSS.Transform.toString(transform), + transition, + opacity: isDragging ? 0.5 : 1 + } return (
push(toRelay(relay))} > - -
{relay}
+
+
+ +
+
+ +
{relay}
+
+
) diff --git a/src/components/SaveRelayDropdownMenu/index.tsx b/src/components/SaveRelayDropdownMenu/index.tsx index edbd3251..96a4bc79 100644 --- a/src/components/SaveRelayDropdownMenu/index.tsx +++ b/src/components/SaveRelayDropdownMenu/index.tsx @@ -88,7 +88,9 @@ export default function SaveRelayDropdownMenu({ return ( - {trigger} + + {trigger} + e.stopPropagation()}> {t('Save to')} ... diff --git a/src/providers/FavoriteRelaysProvider.tsx b/src/providers/FavoriteRelaysProvider.tsx index 1fbaf738..63d3a98a 100644 --- a/src/providers/FavoriteRelaysProvider.tsx +++ b/src/providers/FavoriteRelaysProvider.tsx @@ -16,6 +16,7 @@ type TFavoriteRelaysContext = { favoriteRelays: string[] addFavoriteRelays: (relayUrls: string[]) => Promise deleteFavoriteRelays: (relayUrls: string[]) => Promise + reorderFavoriteRelays: (reorderedRelays: string[]) => Promise relaySets: TRelaySet[] createRelaySet: (relaySetName: string, relayUrls?: string[]) => Promise addRelaySets: (newRelaySetEvents: Event[]) => Promise @@ -219,6 +220,13 @@ export function FavoriteRelaysProvider({ children }: { children: React.ReactNode }) } + const reorderFavoriteRelays = async (reorderedRelays: string[]) => { + setFavoriteRelays(reorderedRelays) + const draftEvent = createFavoriteRelaysDraftEvent(reorderedRelays, relaySetEvents) + const newFavoriteRelaysEvent = await publish(draftEvent) + updateFavoriteRelaysEvent(newFavoriteRelaysEvent) + } + const reorderRelaySets = async (reorderedSets: TRelaySet[]) => { setRelaySets(reorderedSets) const draftEvent = createFavoriteRelaysDraftEvent( @@ -235,6 +243,7 @@ export function FavoriteRelaysProvider({ children }: { children: React.ReactNode favoriteRelays, addFavoriteRelays, deleteFavoriteRelays, + reorderFavoriteRelays, relaySets, createRelaySet, addRelaySets,