fix(nextjs): Fix DND & click event issue on sidepanel

This commit is contained in:
shiva raj badu 2025-07-23 21:46:22 +05:45
parent cd1bcb9536
commit 27781ef72b
No known key found for this signature in database
4 changed files with 39 additions and 71 deletions

View file

@ -18,13 +18,9 @@ import {
} from "../hooks";
import { PresentationPageProps } from "../types";
import LoadingState from "./LoadingState";
import { useRouter, useSearchParams } from "next/navigation";
const PresentationPage: React.FC<PresentationPageProps> = ({ presentation_id }) => {
const router = useRouter();
const searchParams = useSearchParams();
const isPresentMode = searchParams.get("mode") === "present";
const stream = searchParams.get("stream");
// State management
const [loading, setLoading] = useState(true);
const [selectedSlide, setSelectedSlide] = useState(0);
@ -51,6 +47,14 @@ const PresentationPage: React.FC<PresentationPageProps> = ({ presentation_id })
setError
);
const {
isPresentMode,
stream,
handleSlideClick,
toggleFullscreen,
handlePresentExit,
handleSlideChange,
} = usePresentationNavigation(presentation_id, selectedSlide, setSelectedSlide, setIsFullscreen);
// Initialize streaming
usePresentationStreaming(
@ -63,46 +67,12 @@ const PresentationPage: React.FC<PresentationPageProps> = ({ presentation_id })
const onSlideChange = (newSlide: number) => {
handleSlideChange(newSlide, presentationData);
};
const handleSlideClick = useCallback((index: number) => {
console.log("handleSlideClick", index);
const slideElement = document.getElementById(`slide-${index}`);
if (slideElement) {
slideElement.scrollIntoView({
behavior: "smooth",
block: "center",
});
setSelectedSlide(index);
}
}, [setSelectedSlide]);
const toggleFullscreen = useCallback(() => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
setIsFullscreen(true);
} else {
document.exitFullscreen();
setIsFullscreen(false);
}
}, [setIsFullscreen]);
const handlePresentExit = useCallback(() => {
setIsFullscreen(false);
router.push(`/presentation?id=${presentation_id}`);
}, [router, presentation_id, setIsFullscreen]);
const handleSlideChange = useCallback((newSlide: number, presentationData: any) => {
if (newSlide >= 0 && newSlide < presentationData?.slides.length!) {
setSelectedSlide(newSlide);
router.push(
`/presentation?id=${presentation_id}&mode=present&slide=${newSlide}`,
{ scroll: false }
);
}
}, [router, presentation_id, setSelectedSlide]);
// Presentation Mode View
if (isPresentMode) {
@ -110,7 +80,6 @@ const PresentationPage: React.FC<PresentationPageProps> = ({ presentation_id })
<PresentationMode
slides={presentationData?.slides!}
currentSlide={selectedSlide}
isFullscreen={isFullscreen}
onFullscreenToggle={toggleFullscreen}
onExit={handlePresentExit}

View file

@ -58,7 +58,11 @@ const SidePanel = ({
}, [isMobilePanelOpen]);
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(PointerSensor, {
activationConstraint: {
distance: 8, // Start drag after moving 8px
},
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})

View file

@ -1,7 +1,7 @@
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Slide } from '../../types/slide';
import { useState } from 'react';
import { useRef } from 'react';
interface SortableListItemProps {
slide: Slide;
@ -11,7 +11,7 @@ interface SortableListItemProps {
}
export function SortableListItem({ slide, index, selectedSlide, onSlideClick }: SortableListItemProps) {
const [mouseDownTime, setMouseDownTime] = useState(0);
const lastClickTime = useRef(0);
const {
attributes,
@ -28,16 +28,17 @@ export function SortableListItem({ slide, index, selectedSlide, onSlideClick }:
opacity: isDragging ? 0.5 : 1
};
const handleMouseDown = () => {
setMouseDownTime(Date.now());
};
const handleClick = (e: React.MouseEvent) => {
const now = Date.now();
const handleMouseUp = () => {
const mouseUpTime = Date.now();
const timeDiff = mouseUpTime - mouseDownTime;
// Debounce clicks - only allow one click every 300ms
if (now - lastClickTime.current < 300) {
return;
}
// If the mouse was down for less than 200ms, consider it a click
if (timeDiff < 200 && !isDragging) {
// Only trigger click if not dragging
if (!isDragging) {
lastClickTime.current = now;
onSlideClick(slide.index);
}
};
@ -48,8 +49,7 @@ export function SortableListItem({ slide, index, selectedSlide, onSlideClick }:
style={style}
{...attributes}
{...listeners}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onClick={handleClick}
className={`p-3 cursor-pointer ring-0 border-[3px] rounded-lg slide-box
${selectedSlide === index
? ' border-[#5141e5] '

View file

@ -1,7 +1,7 @@
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Slide } from '../../types/slide';
import { useState } from 'react';
import { useRef } from 'react';
interface SortableSlideProps {
slide: Slide;
@ -12,7 +12,7 @@ interface SortableSlideProps {
}
export function SortableSlide({ slide, index, selectedSlide, onSlideClick, renderSlideContent }: SortableSlideProps) {
const [mouseDownTime, setMouseDownTime] = useState(0);
const lastClickTime = useRef(0);
const {
attributes,
@ -29,20 +29,17 @@ export function SortableSlide({ slide, index, selectedSlide, onSlideClick, rende
opacity: isDragging ? 0.5 : 1
};
const handleMouseDown = () => {
console.log("mouse down");
setMouseDownTime(Date.now());
};
const handleClick = (e: React.MouseEvent) => {
const now = Date.now();
const handleMouseUp = () => {
console.log("mouse up");
const mouseUpTime = Date.now();
const timeDiff = mouseUpTime - mouseDownTime;
console.log("timeDiff", timeDiff);
// Debounce clicks - only allow one click every 300ms
if (now - lastClickTime.current < 300) {
return;
}
// If the mouse was down for less than 300ms, consider it a click
if (timeDiff < 300 && !isDragging) {
console.log("clicked");
// Only trigger click if not dragging
if (!isDragging) {
lastClickTime.current = now;
onSlideClick(slide.index);
}
};
@ -53,9 +50,7 @@ export function SortableSlide({ slide, index, selectedSlide, onSlideClick, rende
style={style}
{...attributes}
{...listeners}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onClick={handleClick}
className={` cursor-pointer border-[3px] relative p-1 shadow-lg rounded-md transition-all duration-200 ${selectedSlide === index ? ' border-[#5141e5]' : 'border-gray-300'
}`}
>