This commit is contained in:
Janus Knudsen 2025-09-09 14:35:21 +02:00
parent 727a6ec53a
commit 72019a3d9a
15 changed files with 1056 additions and 1230 deletions

View file

@ -27,11 +27,16 @@ export class DragDropManager {
private lastLoggedPosition: Position = { x: 0, y: 0 };
private currentMouseY = 0;
private mouseOffset: Position = { x: 0, y: 0 };
private initialMousePosition: Position = { x: 0, y: 0 };
// Drag state
private draggedEventId: string | null = null;
private originalElement: HTMLElement | null = null;
private currentColumn: string | null = null;
private isDragStarted = false;
// Movement threshold to distinguish click from drag
private readonly dragThreshold = 5; // pixels
// Cached DOM elements for performance
private cachedElements: CachedElements = {
@ -105,8 +110,10 @@ export class DragDropManager {
private handleMouseDown(event: MouseEvent): void {
this.isMouseDown = true;
this.isDragStarted = false;
this.lastMousePosition = { x: event.clientX, y: event.clientY };
this.lastLoggedPosition = { x: event.clientX, y: event.clientY };
this.initialMousePosition = { x: event.clientX, y: event.clientY };
// Check if mousedown is on an event
const target = event.target as HTMLElement;
@ -125,7 +132,7 @@ export class DragDropManager {
return;
}
// Found an event - start dragging
// Found an event - prepare for potential dragging
if (eventElement) {
this.originalElement = eventElement;
this.draggedEventId = eventElement.dataset.eventId || null;
@ -143,15 +150,7 @@ export class DragDropManager {
this.currentColumn = column;
}
// Emit drag start event
this.eventBus.emit('drag:start', {
originalElement: eventElement,
eventId: this.draggedEventId,
mousePosition: { x: event.clientX, y: event.clientY },
mouseOffset: this.mouseOffset,
column: this.currentColumn
});
// Don't emit drag:start yet - wait for movement threshold
}
}
@ -163,40 +162,66 @@ export class DragDropManager {
if (this.isMouseDown && this.draggedEventId) {
const currentPosition: Position = { x: event.clientX, y: event.clientY };
const deltaY = Math.abs(currentPosition.y - this.lastLoggedPosition.y);
// Check for snap interval vertical movement (normal drag behavior)
if (deltaY >= this.snapDistancePx) {
this.lastLoggedPosition = currentPosition;
// Check if we need to start drag (movement threshold)
if (!this.isDragStarted) {
const deltaX = Math.abs(currentPosition.x - this.initialMousePosition.x);
const deltaY = Math.abs(currentPosition.y - this.initialMousePosition.y);
const totalMovement = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Consolidated position calculations with snapping for normal drag
const positionData = this.calculateDragPosition(currentPosition);
// Emit drag move event with snapped position (normal behavior)
this.eventBus.emit('drag:move', {
eventId: this.draggedEventId,
mousePosition: currentPosition,
snappedY: positionData.snappedY,
column: positionData.column,
mouseOffset: this.mouseOffset
});
if (totalMovement >= this.dragThreshold) {
// Start drag - emit drag:start event
this.isDragStarted = true;
this.eventBus.emit('drag:start', {
originalElement: this.originalElement,
eventId: this.draggedEventId,
mousePosition: this.initialMousePosition,
mouseOffset: this.mouseOffset,
column: this.currentColumn
});
} else {
// Not enough movement yet - don't start drag
return;
}
}
// Check for auto-scroll
this.checkAutoScroll(event);
// Check for column change using cached data
const newColumn = this.getColumnFromCache(currentPosition);
if (newColumn && newColumn !== this.currentColumn) {
const previousColumn = this.currentColumn;
this.currentColumn = newColumn;
// Continue with normal drag behavior only if drag has started
if (this.isDragStarted) {
const deltaY = Math.abs(currentPosition.y - this.lastLoggedPosition.y);
this.eventBus.emit('drag:column-change', {
eventId: this.draggedEventId,
previousColumn,
newColumn,
mousePosition: currentPosition
});
// Check for snap interval vertical movement (normal drag behavior)
if (deltaY >= this.snapDistancePx) {
this.lastLoggedPosition = currentPosition;
// Consolidated position calculations with snapping for normal drag
const positionData = this.calculateDragPosition(currentPosition);
// Emit drag move event with snapped position (normal behavior)
this.eventBus.emit('drag:move', {
eventId: this.draggedEventId,
mousePosition: currentPosition,
snappedY: positionData.snappedY,
column: positionData.column,
mouseOffset: this.mouseOffset
});
}
// Check for auto-scroll
this.checkAutoScroll(event);
// Check for column change using cached data
const newColumn = this.getColumnFromCache(currentPosition);
if (newColumn && newColumn !== this.currentColumn) {
const previousColumn = this.currentColumn;
this.currentColumn = newColumn;
this.eventBus.emit('drag:column-change', {
eventId: this.draggedEventId,
previousColumn,
newColumn,
mousePosition: currentPosition
});
}
}
}
}
@ -211,19 +236,29 @@ export class DragDropManager {
this.stopAutoScroll();
if (this.draggedEventId && this.originalElement) {
const finalPosition: Position = { x: event.clientX, y: event.clientY };
// Use consolidated position calculation
const positionData = this.calculateDragPosition(finalPosition);
// Emit drag end event
this.eventBus.emit('drag:end', {
eventId: this.draggedEventId,
originalElement: this.originalElement,
finalPosition,
finalColumn: positionData.column,
finalY: positionData.snappedY
});
// Only emit drag:end if drag was actually started
if (this.isDragStarted) {
const finalPosition: Position = { x: event.clientX, y: event.clientY };
// Use consolidated position calculation
const positionData = this.calculateDragPosition(finalPosition);
// Emit drag end event
this.eventBus.emit('drag:end', {
eventId: this.draggedEventId,
originalElement: this.originalElement,
finalPosition,
finalColumn: positionData.column,
finalY: positionData.snappedY
});
} else {
// This was just a click - emit click event instead
this.eventBus.emit('event:click', {
eventId: this.draggedEventId,
originalElement: this.originalElement,
mousePosition: { x: event.clientX, y: event.clientY }
});
}
// Clean up drag state
this.cleanupDragState();
@ -424,6 +459,7 @@ export class DragDropManager {
this.draggedEventId = null;
this.originalElement = null;
this.currentColumn = null;
this.isDragStarted = false;
// Clear cached elements
this.cachedElements.currentColumn = null;