Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions frontend/src/core/components/pageEditor/PageThumbnail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import HoverActionMenu, {
} from "@app/components/shared/HoverActionMenu";
import { StirlingFileStub } from "@app/types/fileContext";
import { PrivateContent } from "@app/components/shared/PrivateContent";
import { useDndContext } from "@dnd-kit/core";

interface PageThumbnailProps {
page: PDFPage;
Expand Down Expand Up @@ -121,6 +122,9 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
// Check if this page is currently being dragged
const isDragging = activeDragIds.includes(page.id);

const { over } = useDndContext();
const isOver = over?.id === page.id;

Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useDndContext() inside every PageThumbnail will subscribe each thumbnail to DnD context updates (e.g., over changes during pointer move). This can cause many thumbnails to re-render on every drag movement, undermining the memoization/virtualization work in DragDropGrid and potentially hurting performance on large PDFs. Prefer passing the current drop target id (or a per-item isOver boolean from useDroppable) down via props so only the relevant items update.

Copilot uses AI. Check for mistakes.
// Calculate document aspect ratio from first non-blank page
const getDocumentAspectRatio = useCallback(() => {
// Find first non-blank page with a thumbnail to get aspect ratio
Expand Down Expand Up @@ -554,8 +558,8 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
background: "rgba(162, 201, 255, 0.8)",
padding: "6px 8px",
borderRadius: 8,
zIndex: 2,
opacity: 0,
zIndex: 20,
opacity: isHovered || isOver ? 0.6 : 0,
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isOver is derived from over?.id === page.id, but in this grid each item is both draggable and droppable, so over.id can be the active dragged item itself. That can make the page number appear on the dragged thumbnail rather than the intended drop target, and it may also disagree with DragDropGrid’s cursor-based hoveredItemId (which explicitly excludes the active id and drives the actual reorder target). Consider driving this UI from the same drop-target state used for reordering (e.g., hoveredItemId) or at least ensuring the dragged item never counts as isOver.

Suggested change
opacity: isHovered || isOver ? 0.6 : 0,
opacity: isHovered || (isOver && !isDragging) ? 0.6 : 0,

Copilot uses AI. Check for mistakes.
transition: "opacity 0.2s ease-in-out",
}}
>
Expand Down
Loading