diff --git a/src/managers/EdgeScrollManager.ts b/src/managers/EdgeScrollManager.ts index ae71de0..7a30382 100644 --- a/src/managers/EdgeScrollManager.ts +++ b/src/managers/EdgeScrollManager.ts @@ -8,6 +8,8 @@ import { DragMoveEventPayload, DragStartEventPayload } from '../types/EventTypes export class EdgeScrollManager { private scrollableContent: HTMLElement | null = null; + private timeGrid: HTMLElement | null = null; + private draggedClone: HTMLElement | null = null; private scrollRAF: number | null = null; private mouseY = 0; private isDragging = false; @@ -31,6 +33,8 @@ export class EdgeScrollManager { // Wait for DOM to be ready setTimeout(() => { this.scrollableContent = document.querySelector('swp-scrollable-content'); + this.timeGrid = document.querySelector('swp-time-grid'); + if (this.scrollableContent) { // Disable smooth scroll for instant auto-scroll this.scrollableContent.style.scrollBehavior = 'auto'; @@ -54,7 +58,9 @@ export class EdgeScrollManager { private subscribeToEvents(): void { // Listen to drag events from DragDropManager - this.eventBus.on('drag:start', () => { + this.eventBus.on('drag:start', (event: Event) => { + const payload = (event as CustomEvent).detail; + this.draggedClone = payload.draggedClone; this.startDrag(); }); @@ -158,12 +164,52 @@ export class EdgeScrollManager { } } - if (vy !== 0 && this.isDragging) { - // Time-based scrolling for frame-rate independence - // The scroll listener will detect actual scrolling and emit edgescroll:started - this.scrollableContent.scrollTop += vy * dt; - this.rect = null; // Invalidate cache for next frame - this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts)); + if (vy !== 0 && this.isDragging && this.timeGrid && this.draggedClone) { + // Check if we can scroll in the requested direction + const currentScrollTop = this.scrollableContent.scrollTop; + const scrollableHeight = this.scrollableContent.clientHeight; + const timeGridHeight = this.timeGrid.clientHeight; + + // Get dragged element position and height + const cloneRect = this.draggedClone.getBoundingClientRect(); + const cloneBottom = cloneRect.bottom; + const timeGridRect = this.timeGrid.getBoundingClientRect(); + const timeGridBottom = timeGridRect.bottom; + + // Check boundaries + const atTop = currentScrollTop <= 0 && vy < 0; + const atBottom = (cloneBottom >= timeGridBottom) && vy > 0; + + console.log('📊 Scroll check:', { + currentScrollTop, + scrollableHeight, + timeGridHeight, + cloneBottom, + timeGridBottom, + atTop, + atBottom, + vy + }); + + if (atTop || atBottom) { + // At boundary - stop scrolling + if (this.isScrolling) { + this.isScrolling = false; + this.initialScrollTop = this.scrollableContent.scrollTop; + console.log('🛑 EdgeScrollManager: Edge-scroll stopped (reached boundary)'); + this.eventBus.emit('edgescroll:stopped', {}); + } + + // Continue RAF loop to detect when mouse moves away from boundary + if (this.isDragging) { + this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts)); + } + } else { + // Not at boundary - apply scroll + this.scrollableContent.scrollTop += vy * dt; + this.rect = null; // Invalidate cache for next frame + this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts)); + } } else { // Mouse moved away from edge - stop scrolling if (this.isScrolling) {