refactor(web): extract drag position helpers
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
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<State> =
|
||||
| { handled: false }
|
||||
| { handled: true; nextState: State; pointerDeltaX: number; daysDelta: number; shouldSyncState: boolean };
|
||||
|
||||
function resolveDragPosition<State extends DragPositionLike>(
|
||||
state: State,
|
||||
clientX: number,
|
||||
cellWidth: number,
|
||||
mode: DragMode,
|
||||
): TimelineDragPositionResult<State> {
|
||||
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<State extends DragPositionLike & { isDragging: boolean }>(
|
||||
drag: State,
|
||||
clientX: number,
|
||||
cellWidth: number,
|
||||
): TimelineDragPositionResult<State> {
|
||||
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<State> {
|
||||
if (!alloc.isActive || !alloc.originalStartDate || !alloc.originalEndDate) {
|
||||
return { handled: false };
|
||||
}
|
||||
|
||||
return resolveDragPosition(alloc, clientX, cellWidth, alloc.mode);
|
||||
}
|
||||
Reference in New Issue
Block a user