Dragging events on desktop

This commit is contained in:
2025-03-28 13:16:32 -04:00
parent 6d592a6dfc
commit 4e159a354f

View File

@@ -71,8 +71,8 @@ const Calendar = () => {
const cleanup = monitorForElements({ const cleanup = monitorForElements({
onDrop: handleDragEnd, onDrop: handleDragEnd,
onDrag: ({ source, location }) => { onDrag: ({ source, location }) => {
console.log('Drag source data:', source?.data); //console.log('Drag source data:', source?.data);
console.log('Current drop targets:', location?.current?.dropTargets); //console.log('Current drop targets:', location?.current?.dropTargets);
if (!source?.data) { if (!source?.data) {
console.warn('No drag data found. Source:', source); console.warn('No drag data found. Source:', source);
@@ -466,83 +466,56 @@ const DraggableEvent = ({
}) => { }) => {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const [isDragging, setIsDragging] = useState(false); const [isDragging, setIsDragging] = useState(false);
const touchTimer = useRef<number | null>(null); const screenWidth = useRef(window.innerWidth);
const startPos = useRef({ x: 0, y: 0 });
const [position, setPosition] = useState({ x: 0, y: 0 });
const lastEdgeTrigger = useRef<number>(0);
const handleTouchStart = (e: React.TouchEvent) => { useEffect(() => {
touchTimer.current = window.setTimeout(() => { const element = ref.current;
const touch = e.touches[0]; if (!element) return;
startPos.current = { x: touch.clientX, y: touch.clientY };
setIsDragging(true);
onDragStart();
e.stopPropagation();
}, 500);
};
const handleTouchMove = (e: React.TouchEvent) => { const cleanup = draggable({
if (!isDragging) return; element,
onDragStart: () => {
screenWidth.current = window.innerWidth;
setIsDragging(true);
onDragStart();
},
onDrag: ({ location }) => {
const currentX = location.current.input.clientX;
const touch = e.touches[0]; // Simple edge detection without delta checks
const newX = touch.clientX - startPos.current.x; if (currentX < 50) {
const newY = touch.clientY - startPos.current.y; onDayChange('left');
setPosition({ x: newX, y: newY }); } else if (currentX > screenWidth.current - 50) {
e.stopPropagation(); onDayChange('right');
}
},
onDrop: () => {
setIsDragging(false);
onDragEnd();
},
getInitialData: () => ({ id: event.id, date }),
dragHandle: element
});
// Fixed edge detection logic return cleanup;
const screenWidth = window.innerWidth; }, [date, event.id, onDragEnd, onDragStart, onDayChange]);
const now = Date.now();
if (touch.clientX < 50 && now - lastEdgeTrigger.current > 500) {
onDayChange('left'); // Changed to 'left' for previous day
lastEdgeTrigger.current = now;
} else if (touch.clientX > screenWidth - 50 && now - lastEdgeTrigger.current > 500) {
onDayChange('right'); // Changed to 'right' for next day
lastEdgeTrigger.current = now;
}
};
const handleTouchEnd = () => {
if (touchTimer.current) {
clearTimeout(touchTimer.current);
touchTimer.current = null;
}
if (isDragging) {
setIsDragging(false);
onDragEnd();
}
// Force reset dragging state
setTimeout(() => setIsEventDragging(false), 100);
};
return ( return (
<motion.div <motion.div
ref={ref} ref={ref}
layoutId={event.id} layoutId={event.id}
onClick={() => onEventClick(event)} onClick={() => !isDragging && onEventClick(event)}
className="bg-white p-4 rounded shadow mb-2 cursor-grab active:cursor-grabbing transition-all relative" className="bg-white p-4 rounded shadow mb-2 cursor-grab active:cursor-grabbing transition-all relative select-none"
whileHover={{ scale: 1.01 }} whileHover={{ scale: 1.01 }}
onTouchStart={handleTouchStart} style={{
onTouchMove={handleTouchMove} opacity: isDragging ? 0.7 : 1,
onTouchEnd={handleTouchEnd} userSelect: 'none',
WebkitUserSelect: 'none',
touchAction: 'manipulation'
}}
> >
{/* Main event content */}
<h3 className="font-medium text-black">{event.title}</h3> <h3 className="font-medium text-black">{event.title}</h3>
<p className="text-sm text-gray-700">{event.time}</p> <p className="text-sm text-gray-700">{event.time}</p>
{/* Floating preview */}
{isDragging && (
<motion.div
className="absolute inset-0 bg-white rounded shadow-lg border-2 border-blue-500"
style={{
x: position.x,
y: position.y,
zIndex: 1000,
pointerEvents: 'none'
}}
/>
)}
</motion.div> </motion.div>
); );
}; };