import { computeDragDates, pixelsToDays } from "~/components/timeline/dragMath.js"; type DragPositionLike = { originalStartDate: Date | null; originalEndDate: Date | null; currentStartDate: Date | null; currentEndDate: Date | null; startMouseX: number; pointerDeltaX: number; daysDelta: number; }; type DragMode = "move" | "resize-start" | "resize-end"; export type TimelineDragPositionResult = | { handled: false } | { handled: true; nextState: State; pointerDeltaX: number; daysDelta: number; shouldSyncState: boolean }; function resolveDragPosition( state: State, clientX: number, cellWidth: number, mode: DragMode, ): TimelineDragPositionResult { const pointerDeltaX = clientX - state.startMouseX; const daysDelta = pixelsToDays(pointerDeltaX, cellWidth); if (daysDelta === state.daysDelta) { return { handled: true, nextState: pointerDeltaX === state.pointerDeltaX ? state : { ...state, pointerDeltaX }, pointerDeltaX, daysDelta, shouldSyncState: false, }; } const { start, end } = computeDragDates(mode, state.originalStartDate!, state.originalEndDate!, daysDelta); return { handled: true, nextState: { ...state, currentStartDate: start, currentEndDate: end, pointerDeltaX, daysDelta, }, pointerDeltaX, daysDelta, shouldSyncState: true, }; } export function resolveProjectDragPosition( drag: State, clientX: number, cellWidth: number, ): TimelineDragPositionResult { if (!drag.isDragging || !drag.originalStartDate || !drag.originalEndDate) { return { handled: false }; } return resolveDragPosition(drag, clientX, cellWidth, "move"); } export function resolveAllocationDragPosition< State extends DragPositionLike & { isActive: boolean; mode: DragMode }, >(alloc: State, clientX: number, cellWidth: number): TimelineDragPositionResult { if (!alloc.isActive || !alloc.originalStartDate || !alloc.originalEndDate) { return { handled: false }; } return resolveDragPosition(alloc, clientX, cellWidth, alloc.mode); }