Adam Shaw 7 лет назад
Родитель
Сommit
2e9d28f352
2 измененных файлов с 168 добавлено и 0 удалено
  1. 168 0
      src/interactions/EventDragging.ts
  2. 0 0
      src/interactions/EventResizing.ts

+ 168 - 0
src/interactions/EventDragging.ts

@@ -0,0 +1,168 @@
+import { default as DateComponent, Seg } from '../component/DateComponent'
+import { PointerDragEvent } from '../dnd/PointerDragListener'
+import HitDragListener, { isHitsEqual } from '../dnd/HitDragListener'
+import { createMutation, EventMutation, computeEventDisplacement } from '../reducers/event-mutation'
+import { GlobalContext } from '../common/GlobalContext'
+
+export default class EventDragging {
+
+  component: DateComponent
+  globalContext: GlobalContext
+  hitListener: HitDragListener
+  draggingSeg: Seg
+  mutation: EventMutation
+
+  constructor(component: DateComponent, globalContext: GlobalContext) {
+    this.component = component
+    this.globalContext = globalContext
+
+    let hitListener = this.hitListener = new HitDragListener(
+      component,
+      globalContext.componentHash
+    )
+    hitListener.dragListener.pointerListener.selector = '.fc-draggable'
+    hitListener.dragListener.touchScrollAllowed = false
+    hitListener.subjectCenter = true
+    hitListener.on('pointerdown', this.onPointerDown)
+    hitListener.on('dragstart', this.onDragStart)
+    hitListener.on('hitover', this.onHitOver)
+    hitListener.on('hitout', this.onHitOut)
+    hitListener.on('dragend', this.onDragEnd)
+  }
+
+  destroy() {
+    this.hitListener.destroy()
+  }
+
+  onPointerDown = (ev: PointerDragEvent) => {
+    let { dragListener } = this.hitListener
+
+    dragListener.delay = this.computeDragDelay(ev)
+
+    // to prevent from cloning the sourceEl before it is selected
+    dragListener.dragMirror.disable()
+  }
+
+  computeDragDelay(ev: PointerDragEvent): number {
+    if (ev.isTouch) {
+      let seg = (ev.el as any).fcSeg
+      let eventInstanceId = seg.eventRange.eventInstance.instanceId
+
+      if (eventInstanceId !== this.component.selectedEventInstanceId) {
+        return 1000 // TODO: use setting
+      }
+    }
+  }
+
+  onDragStart = (ev: PointerDragEvent) => {
+    let { globalContext } = this
+    let calendar = this.component.getCalendar()
+
+    if (globalContext.eventSelectedCalendar && globalContext.eventSelectedCalendar !== calendar) {
+      globalContext.eventSelectedCalendar.dispatch({
+        type: 'CLEAR_SELECTED_EVENT'
+      })
+      globalContext.eventSelectedCalendar = null
+    }
+
+    this.draggingSeg = (ev.el as any).fcSeg
+
+    if (ev.isTouch) {
+      globalContext.eventSelectedCalendar = calendar
+
+      let eventInstanceId = this.draggingSeg.eventRange.eventInstance.instanceId
+
+      calendar.dispatch({
+        type: 'SELECT_EVENT',
+        eventInstanceId
+      })
+    }
+  }
+
+  onHitOver = (hit, ev) => {
+    let { initialHit } = this.hitListener
+
+    this.mutation = createMutation(
+      initialHit.range,
+      initialHit.isAllDay,
+      hit.range,
+      hit.isAllDay,
+      this.draggingSeg.eventRange.eventDef.hasEnd,
+      hit.component === initialHit.component ?
+        hit.component.largeUnit :
+        null,
+      hit.component.getDateEnv()
+    )
+
+    let calendar = hit.component.getCalendar()
+    let displacement = computeEventDisplacement(
+      calendar.state.eventStore,
+      this.draggingSeg.eventRange.eventInstance.instanceId,
+      this.mutation,
+      calendar
+    )
+
+    calendar.dispatch({
+      type: 'SET_DRAG',
+      displacement,
+      origSeg: this.draggingSeg,
+      isTouch: ev.isTouch
+    })
+
+    let { dragMirror } = this.hitListener.dragListener
+
+    // TODO wish we could somehow wait for dispatch to guarantee render
+    if (!document.querySelector('.fc-helper')) {
+      dragMirror.enable()
+    } else {
+      dragMirror.disable()
+    }
+
+    dragMirror.needsRevert = isHitsEqual(initialHit, hit)
+  }
+
+  onHitOut = (hit, ev) => { // TODO: onHitChange?
+    this.mutation = null
+
+    hit.component.getCalendar().dispatch({
+      type: 'SET_DRAG',
+      displacement: { defs: {}, instances: {} }, // TODO: better way to make empty event-store
+      origSeg: this.draggingSeg,
+      isTouch: ev.isTouch
+    })
+
+    let { dragMirror } = this.hitListener.dragListener
+
+    dragMirror.enable()
+    dragMirror.needsRevert = true
+  }
+
+  onDocumentPointerUp = (ev, isTouchScroll) => {
+    if (!this.mutation && !isTouchScroll) {
+      this.component.getCalendar().dispatch({
+        type: 'CLEAR_SELECTED_EVENT'
+      })
+    }
+  }
+
+  onDragEnd = () => {
+    let { initialHit } = this.hitListener
+    let initialCalendar = initialHit.component.getCalendar()
+
+    initialCalendar.dispatch({
+      type: 'CLEAR_DRAG'
+    })
+
+    if (this.mutation) {
+      initialCalendar.dispatch({
+        type: 'MUTATE_EVENTS',
+        mutation: this.mutation,
+        instanceId: this.draggingSeg.eventRange.eventInstance.instanceId
+      })
+    }
+
+    this.mutation = null
+    this.draggingSeg = null
+  }
+
+}

+ 0 - 0
src/interactions/EventResizing.ts