diff --git a/src/managers/ColumnDetector.ts b/src/managers/ColumnDetector.ts index 29758c3..ce9be43 100644 --- a/src/managers/ColumnDetector.ts +++ b/src/managers/ColumnDetector.ts @@ -14,6 +14,12 @@ export class ColumnDetector { private originalEvent: HTMLElement | null = null; private mouseOffset = { x: 0, y: 0 }; + // Auto-scroll properties + private scrollContainer: HTMLElement | null = null; + private autoScrollAnimationId: number | null = null; + private scrollSpeed = 10; // pixels per frame + private scrollThreshold = 30; // pixels from edge + // Konfiguration for snap interval private snapIntervalMinutes = 15; // 15 minutter private hourHeightPx = 60; // Fra CSS --hour-height @@ -103,6 +109,12 @@ export class ColumnDetector { this.draggedClone.style.top = relativeY + 'px'; } } + + // Auto-scroll detection når der er en aktiv clone + if (this.draggedClone) { + console.log('ColumnDetector: Checking auto-scroll, mouse at:', event.clientY); + this.checkAutoScroll(event); + } } // Find hvilket element musen er over (altid) @@ -270,6 +282,9 @@ export class ColumnDetector { this.isMouseDown = false; console.log('Mouse up at:', { x: event.clientX, y: event.clientY }); + // Stop auto-scroll + this.stopAutoScroll(); + // Drop operationen: fade out original og remove clone suffix if (this.originalEvent && this.draggedClone) { // Fade out og fjern originalen @@ -281,6 +296,7 @@ export class ColumnDetector { // Ryd op this.originalEvent = null; this.draggedClone = null; + this.scrollContainer = null; console.log('Drop completed: original faded out and removed, clone became permanent'); } @@ -306,7 +322,89 @@ export class ColumnDetector { } } + /** + * Check if auto-scroll should be triggered based on mouse position + */ + private checkAutoScroll(event: MouseEvent): void { + // Find scrollable content if not cached + if (!this.scrollContainer) { + this.scrollContainer = document.querySelector('swp-scrollable-content') as HTMLElement; + if (!this.scrollContainer) { + console.warn('ColumnDetector: Could not find swp-scrollable-content for auto-scroll'); + return; + } + console.log('ColumnDetector: Found scroll container:', this.scrollContainer); + } + + const containerRect = this.scrollContainer.getBoundingClientRect(); + const mouseY = event.clientY; + + // Calculate distances from edges + const distanceFromTop = mouseY - containerRect.top; + const distanceFromBottom = containerRect.bottom - mouseY; + + console.log('ColumnDetector: Auto-scroll check:', { + mouseY, + containerTop: containerRect.top, + containerBottom: containerRect.bottom, + distanceFromTop: Math.round(distanceFromTop), + distanceFromBottom: Math.round(distanceFromBottom), + threshold: this.scrollThreshold + }); + + // Check if we need to scroll up + if (distanceFromTop <= this.scrollThreshold && distanceFromTop > 0) { + this.startAutoScroll('up'); + console.log(`Auto-scroll up triggered: ${Math.round(distanceFromTop)}px from top edge`); + } + // Check if we need to scroll down + else if (distanceFromBottom <= this.scrollThreshold && distanceFromBottom > 0) { + this.startAutoScroll('down'); + console.log(`Auto-scroll down triggered: ${Math.round(distanceFromBottom)}px from bottom edge`); + } + // Stop scrolling if not in threshold zone + else { + this.stopAutoScroll(); + } + } + + /** + * Start auto-scroll animation in specified direction + */ + private startAutoScroll(direction: 'up' | 'down'): void { + // Don't start if already scrolling in same direction + if (this.autoScrollAnimationId !== null) { + return; + } + + const scroll = () => { + if (!this.scrollContainer || !this.isMouseDown || !this.draggedClone) { + this.stopAutoScroll(); + return; + } + + const scrollAmount = direction === 'up' ? -this.scrollSpeed : this.scrollSpeed; + this.scrollContainer.scrollTop += scrollAmount; + + // Continue animation + this.autoScrollAnimationId = requestAnimationFrame(scroll); + }; + + this.autoScrollAnimationId = requestAnimationFrame(scroll); + } + + /** + * Stop auto-scroll animation + */ + private stopAutoScroll(): void { + if (this.autoScrollAnimationId !== null) { + cancelAnimationFrame(this.autoScrollAnimationId); + this.autoScrollAnimationId = null; + } + } + public destroy(): void { + this.stopAutoScroll(); document.body.removeEventListener('mousemove', this.handleMouseMove.bind(this)); document.body.removeEventListener('click', this.handleClick.bind(this)); document.body.removeEventListener('mousedown', this.handleMouseDown.bind(this));