Calendar/src/managers/ColumnDetector.ts

225 lines
7.8 KiB
TypeScript
Raw Normal View History

/**
* ColumnDetector - Bare detect hvilken kolonne musen er over
*/
export class ColumnDetector {
private currentColumn: string | null = null;
private isMouseDown = false;
private lastMousePosition = { x: 0, y: 0 };
private lastLoggedPosition = { x: 0, y: 0 };
private draggedClone: HTMLElement | null = null;
private mouseOffset = { x: 0, y: 0 };
constructor() {
this.init();
}
private init(): void {
// Lyt til mouse move på hele body
document.body.addEventListener('mousemove', this.handleMouseMove.bind(this));
// Lyt til click på hele body
document.body.addEventListener('click', this.handleClick.bind(this));
// Lyt til mouse down og up
document.body.addEventListener('mousedown', this.handleMouseDown.bind(this));
document.body.addEventListener('mouseup', this.handleMouseUp.bind(this));
}
private handleMouseMove(event: MouseEvent): void {
// Hvis musen er holdt nede, tjek for 25px vertikal bevægelse
if (this.isMouseDown) {
const deltaY = Math.abs(event.clientY - this.lastLoggedPosition.y);
if (deltaY >= 25) {
console.log('Mouse dragged 25px vertically:', {
from: this.lastLoggedPosition,
to: { x: event.clientX, y: event.clientY },
verticalDistance: Math.round(deltaY)
});
this.lastLoggedPosition = { x: event.clientX, y: event.clientY };
// Opdater klonens Y-position ved 25px snap (relativt til kolonne)
if (this.draggedClone && this.draggedClone.parentElement) {
const columnRect = this.draggedClone.parentElement.getBoundingClientRect();
const relativeY = event.clientY - columnRect.top - this.mouseOffset.y;
this.draggedClone.style.top = relativeY + 'px';
}
}
}
// Find hvilket element musen er over (altid)
{
const elementUnder = document.elementFromPoint(event.clientX, event.clientY);
if (!elementUnder) {
// Ingen element under musen
if (this.currentColumn !== null) {
console.log('Left all columns');
this.currentColumn = null;
}
return;
}
// Gå op gennem DOM træet for at finde swp-day-column
let element = elementUnder as HTMLElement;
while (element && element.tagName !== 'SWP-DAY-COLUMN') {
element = element.parentElement as HTMLElement;
if (!element) {
// Ikke i en kolonne
if (this.currentColumn !== null) {
console.log('Left all columns');
this.currentColumn = null;
}
return;
}
}
// Vi fandt en kolonne
const date = element.dataset.date;
if (date && date !== this.currentColumn) {
console.log('Entered column:', date);
this.currentColumn = date;
// Flyt klonen til ny kolonne ved kolonneskift
if (this.draggedClone && this.isMouseDown) {
// Flyt klonen til den nye kolonne
const newColumnElement = document.querySelector(`swp-day-column[data-date="${date}"]`);
if (newColumnElement) {
newColumnElement.appendChild(this.draggedClone);
// Opdater Y-position relativt til den nye kolonne
const columnRect = newColumnElement.getBoundingClientRect();
const relativeY = event.clientY - columnRect.top - this.mouseOffset.y;
this.draggedClone.style.top = relativeY + 'px';
}
}
}
}
}
private handleClick(event: MouseEvent): void {
const target = event.target as HTMLElement;
// Find event element
let eventElement = target;
while (eventElement && eventElement.tagName !== 'SWP-EVENTS-LAYER') {
if (eventElement.tagName === 'SWP-EVENT' || eventElement.tagName === 'SWP-ALLDAY-EVENT') {
break;
}
eventElement = eventElement.parentElement as HTMLElement;
if (!eventElement) return;
}
// Hvis vi nåede til SWP-EVENTS-LAYER uden at finde et event, så return
if (!eventElement || eventElement.tagName === 'SWP-EVENTS-LAYER') {
return;
}
// Log event info
const eventId = eventElement.dataset.eventId;
const eventType = eventElement.dataset.type;
console.log('Clicked event:', {
id: eventId,
type: eventType,
element: eventElement,
title: eventElement.textContent
});
}
private handleMouseDown(event: MouseEvent): void {
this.isMouseDown = true;
this.lastMousePosition = { x: event.clientX, y: event.clientY };
this.lastLoggedPosition = { x: event.clientX, y: event.clientY };
console.log('Mouse down at:', this.lastMousePosition);
// Tjek om mousedown er på et event
const target = event.target as HTMLElement;
let eventElement = target;
while (eventElement && eventElement.tagName !== 'SWP-EVENTS-LAYER') {
if (eventElement.tagName === 'SWP-EVENT' || eventElement.tagName === 'SWP-ALLDAY-EVENT') {
break;
}
eventElement = eventElement.parentElement as HTMLElement;
if (!eventElement) return;
}
// Hvis vi nåede til SWP-EVENTS-LAYER uden at finde et event, så return
if (!eventElement || eventElement.tagName === 'SWP-EVENTS-LAYER') {
return;
}
// Hvis vi fandt et event, lav en clone
if (eventElement) {
this.cloneEvent(eventElement, event);
}
}
private cloneEvent(originalEvent: HTMLElement, mouseEvent: MouseEvent): void {
// Lav en clone
const clone = originalEvent.cloneNode(true) as HTMLElement;
// Præfiks ID med "clone-"
const originalId = originalEvent.dataset.eventId;
if (originalId) {
clone.dataset.eventId = `clone-${originalId}`;
}
// Beregn hvor på event'et musen klikkede
const eventRect = originalEvent.getBoundingClientRect();
this.mouseOffset = {
x: mouseEvent.clientX - eventRect.left, // Stadig nødvendig for cursor placering
y: mouseEvent.clientY - eventRect.top
};
// Gør klonen ready til at blive trukket
clone.style.position = 'absolute';
clone.style.zIndex = '999999';
clone.style.pointerEvents = 'none';
// Sæt størrelse fra det originale event
clone.style.width = eventRect.width + 'px';
clone.style.height = eventRect.height + 'px';
// Find den aktuelle kolonne og placer klonen der
const currentColumnElement = document.querySelector(`swp-day-column[data-date="${this.currentColumn}"]`);
if (currentColumnElement) {
// Sæt initial position relativt til kolonnen
const columnRect = currentColumnElement.getBoundingClientRect();
const relativeY = mouseEvent.clientY - columnRect.top - this.mouseOffset.y;
clone.style.top = relativeY + 'px';
currentColumnElement.appendChild(clone);
} else {
console.error('Could not find current column element:', this.currentColumn);
// Fallback til original placering
originalEvent.parentNode?.insertBefore(clone, originalEvent.nextSibling);
}
// Gem reference til klonen
this.draggedClone = clone;
console.log('Cloned event:', {
original: originalId,
clone: clone.dataset.eventId,
offset: this.mouseOffset
});
}
private handleMouseUp(event: MouseEvent): void {
this.isMouseDown = false;
console.log('Mouse up at:', { x: event.clientX, y: event.clientY });
// Ryd op - fjern klonen (DISABLED FOR DEBUGGING)
// if (this.draggedClone) {
// this.draggedClone.remove();
// this.draggedClone = null;
// console.log('Removed clone');
// }
}
public destroy(): void {
document.body.removeEventListener('mousemove', this.handleMouseMove.bind(this));
document.body.removeEventListener('click', this.handleClick.bind(this));
document.body.removeEventListener('mousedown', this.handleMouseDown.bind(this));
document.body.removeEventListener('mouseup', this.handleMouseUp.bind(this));
}
}