fix(frontend): try and make dnd better on touchscreen devices

This commit is contained in:
Viren070
2025-05-28 17:44:53 +01:00
parent 384bdc3a52
commit 6aa11301a5
2 changed files with 86 additions and 3 deletions
@@ -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<string, any>
>({});
const [editingAddonId, setEditingAddonId] = useState<string | null>(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 (
<>
<div className="flex items-center w-full">
@@ -248,6 +287,8 @@ function Content() {
<DndContext
modifiers={[restrictToVerticalAxis]}
onDragEnd={handleDragEnd}
onDragStart={handleDragStart}
sensors={sensors}
>
<SortableContext
items={userData.presets.map((a) => getPresetUniqueKey(a))}
@@ -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<ServiceId | null>(null);
const [modalValues, setModalValues] = useState<Record<string, any>>({});
const [invalidServices, setInvalidServices] = useState<string[]>([]);
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() {
<DndContext
modifiers={[restrictToVerticalAxis]}
onDragEnd={handleDragEnd}
onDragStart={handleDragStart}
sensors={sensors}
>
<SortableContext
items={userData.services?.map((s) => s.id) || []}