From 6aa11301a5dc06eb8674cfb6a834bf181a41eeee Mon Sep 17 00:00:00 2001 From: Viren070 Date: Wed, 28 May 2025 17:44:53 +0100 Subject: [PATCH] fix(frontend): try and make dnd better on touchscreen devices --- .../frontend/src/components/menu/addons.tsx | 45 ++++++++++++++++++- .../frontend/src/components/menu/services.tsx | 44 +++++++++++++++++- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/components/menu/addons.tsx b/packages/frontend/src/components/menu/addons.tsx index 28733381..72acb3cd 100644 --- a/packages/frontend/src/components/menu/addons.tsx +++ b/packages/frontend/src/components/menu/addons.tsx @@ -7,7 +7,13 @@ import { SettingsCard } from '../shared/settings-card'; import { Button, IconButton } from '../ui/button'; import { Modal } from '../ui/modal'; import { Switch } from '../ui/switch'; -import { DndContext } from '@dnd-kit/core'; +import { + DndContext, + useSensor, + useSensors, + PointerSensor, + TouchSensor, +} from '@dnd-kit/core'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; import { arrayMove, @@ -52,7 +58,7 @@ function Content() { Record >({}); const [editingAddonId, setEditingAddonId] = useState(null); - + const [isDragging, setIsDragging] = useState(false); // Filtering and search for marketplace const filteredPresets = useMemo(() => { if (!status?.settings?.presets) return []; @@ -152,6 +158,11 @@ function Content() { presets: newPresets, })); } + setIsDragging(false); + } + + function handleDragStart(event: any) { + setIsDragging(true); } // Service, stream type, and resource options @@ -168,6 +179,34 @@ function Content() { const activeFilterCount = serviceFilters.length + streamTypeFilters.length + resourceFilters.length; + // DND-kit setup + const sensors = useSensors( + useSensor(PointerSensor), + useSensor(TouchSensor, { + activationConstraint: { + delay: 150, + tolerance: 8, + }, + }) + ); + + useEffect(() => { + function preventTouchMove(e: TouchEvent) { + if (isDragging) { + e.preventDefault(); + } + } + if (isDragging) { + document.body.addEventListener('touchmove', preventTouchMove, { + passive: false, + }); + } else { + document.body.removeEventListener('touchmove', preventTouchMove); + } + return () => { + document.body.removeEventListener('touchmove', preventTouchMove); + }; + }, [isDragging]); return ( <>
@@ -248,6 +287,8 @@ function Content() { getPresetUniqueKey(a))} diff --git a/packages/frontend/src/components/menu/services.tsx b/packages/frontend/src/components/menu/services.tsx index 86e3c3cc..6efbff1b 100644 --- a/packages/frontend/src/components/menu/services.tsx +++ b/packages/frontend/src/components/menu/services.tsx @@ -20,7 +20,13 @@ import { Switch } from '../ui/switch'; import { Modal } from '../ui/modal'; import { toast } from 'sonner'; import { useState, useEffect } from 'react'; -import { DndContext } from '@dnd-kit/core'; +import { + DndContext, + useSensors, + PointerSensor, + TouchSensor, + useSensor, +} from '@dnd-kit/core'; import TemplateOption from '../shared/template-option'; import { Button } from '../ui/button'; import MarkdownLite from '../shared/markdown-lite'; @@ -50,6 +56,7 @@ function Content() { const [modalService, setModalService] = useState(null); const [modalValues, setModalValues] = useState>({}); const [invalidServices, setInvalidServices] = useState([]); + const [isDragging, setIsDragging] = useState(false); // DND logic function handleDragEnd(event: any) { @@ -64,6 +71,11 @@ function Content() { return { ...prev, services: newServices }; }); } + setIsDragging(false); + } + + function handleDragStart(event: any) { + setIsDragging(true); } // Modal handlers @@ -126,6 +138,34 @@ function Content() { } }, [userData.services, setUserData]); + const sensors = useSensors( + useSensor(PointerSensor), + useSensor(TouchSensor, { + activationConstraint: { + delay: 150, + tolerance: 8, + }, + }) + ); + + useEffect(() => { + function preventTouchMove(e: TouchEvent) { + if (isDragging) { + e.preventDefault(); + } + } + if (isDragging) { + document.body.addEventListener('touchmove', preventTouchMove, { + passive: false, + }); + } else { + document.body.removeEventListener('touchmove', preventTouchMove); + } + return () => { + document.body.removeEventListener('touchmove', preventTouchMove); + }; + }, [isDragging]); + // Render return ( <> @@ -163,6 +203,8 @@ function Content() { s.id) || []}