diff --git a/src/features/task-el/dnd/CustomHTML5BackendImpl.ts b/src/features/task-el/dnd/CustomHTML5BackendImpl.ts new file mode 100644 index 0000000..92fa889 --- /dev/null +++ b/src/features/task-el/dnd/CustomHTML5BackendImpl.ts @@ -0,0 +1,26 @@ +import { HTML5BackendImpl } from 'node_modules/react-dnd-html5-backend/dist/HTML5BackendImpl'; +import { DragDropManager } from 'dnd-core'; +import { HTML5BackendContext, HTML5BackendOptions } from 'react-dnd-html5-backend'; +import { isTaskElDragItemType } from './drag-item'; + + + +class CustomHTML5BackendImpl extends HTML5BackendImpl { + + constructor(manager: DragDropManager, globalContext?: HTML5BackendContext, options?: HTML5BackendOptions){ + super(manager, globalContext, options); + const originalHandleTopDropCapture = this.handleTopDropCapture; + this.handleTopDropCapture = (e: DragEvent) => { + const monitor = manager.getMonitor(); + const type = monitor.getItemType(); + if(typeof type === "string" && isTaskElDragItemType(type)){ + originalHandleTopDropCapture(e); + } + } + } + +} + +export const CustomHTML5Backend = (manager: DragDropManager, context: HTML5BackendContext, options: HTML5BackendOptions) => { + return new CustomHTML5BackendImpl(manager, context, options); +}; \ No newline at end of file diff --git a/src/features/task-el/dnd/CustomTouchBackendImpl copy.ts b/src/features/task-el/dnd/CustomTouchBackendImpl copy.ts new file mode 100644 index 0000000..65e138c --- /dev/null +++ b/src/features/task-el/dnd/CustomTouchBackendImpl copy.ts @@ -0,0 +1,26 @@ +import { DragDropManager } from 'dnd-core'; +import { HTML5BackendContext, HTML5BackendOptions } from 'react-dnd-html5-backend'; +import { isTaskElDragItemType } from './drag-item'; +import { TouchBackendContext, TouchBackendImpl, TouchBackendOptions } from 'react-dnd-touch-backend'; + + + +class CustomTouchBackendImpl extends TouchBackendImpl { + + constructor(manager: DragDropManager, globalContext: TouchBackendContext, options: Partial){ + super(manager, globalContext, options); + const originalHandleTopMoveEndCapture = this.handleTopMoveEndCapture; + this.handleTopMoveEndCapture = (e: Event) => { + const monitor = manager.getMonitor(); + const type = monitor.getItemType(); + if(typeof type === "string" && isTaskElDragItemType(type)){ + originalHandleTopMoveEndCapture(e); + } + } + } + +} + +export const CustomTouchBackend = (manager: DragDropManager, globalContext: TouchBackendContext, options: Partial) => { + return new CustomTouchBackendImpl(manager, globalContext, options); +}; \ No newline at end of file diff --git a/src/features/task-el/ui/dnd-context.tsx b/src/features/task-el/dnd/dnd-context.tsx similarity index 73% rename from src/features/task-el/ui/dnd-context.tsx rename to src/features/task-el/dnd/dnd-context.tsx index 4128fad..4b92ec1 100644 --- a/src/features/task-el/ui/dnd-context.tsx +++ b/src/features/task-el/dnd/dnd-context.tsx @@ -10,11 +10,13 @@ import { createTransition, } from "react-dnd-multi-backend"; import { Preview } from "react-dnd-preview"; -import { ElementPreview } from "./ElementPreview"; -import { useDndScroll } from "../dnd/use-dnd-scroll"; +import { ElementPreview } from "../ui/ElementPreview"; +import { useDndScroll } from "./use-dnd-scroll"; import { useDragDropManager } from "react-dnd"; -import { TaskElDragItem } from '../dnd/drag-item'; +import { TaskElDragItem } from './drag-item'; import { isNoteElement, isTaskGroup } from "@entities/note"; +import { CustomHTML5Backend } from "./CustomHTML5BackendImpl"; +import { CustomTouchBackend } from "./CustomTouchBackendImpl copy"; export const DELAY_TOUCH_START = 1000; @@ -36,27 +38,25 @@ export const TaskDndContext = ({ children }: {children: React.ReactNode }) => { }), [setBackend]) - const HTML5toTouch: MultiBackendOptions = useMemo(() => { - return { - backends: [ - { - id: "html5", - backend: HTML5Backend, - transition: MouseTransition, + const HTML5toTouch: MultiBackendOptions = useMemo(() => ({ + backends: [ + { + id: "html5", + backend: CustomHTML5Backend, + transition: MouseTransition, + }, + { + id: "touch", + backend: CustomTouchBackend, + options: { + enableMouseEvents: false, + delayTouchStart: DELAY_TOUCH_START, + ignoreContextMenu: false }, - { - id: "touch", - backend: TouchBackend, - options: { - enableMouseEvents: false, - delayTouchStart: DELAY_TOUCH_START, - ignoreContextMenu: false - }, - transition: TouchTransition - }, - ], - } - }, [MouseTransition, TouchTransition]) + transition: TouchTransition, + }, + ], + }), [MouseTransition, TouchTransition]) return ( @@ -64,9 +64,9 @@ export const TaskDndContext = ({ children }: {children: React.ReactNode }) => { {children}
- { + { // @ts-ignore - if(item.el !== undefined && isNoteElement(item.el)){ + if(item.el !== undefined && isNoteElement(item.el) && itemType !== "__NATIVE_TEXT__"){ return ( { const offset = monitor.getSourceClientOffset()?.y as number; updatePosition({ position: offset, isScrollAllowed: true }); }); + return unsubscribe; }, [monitor, updatePosition]); diff --git a/src/features/task-el/dnd/drag-item.ts b/src/features/task-el/dnd/drag-item.ts index 5db8ee0..ba9cb29 100644 --- a/src/features/task-el/dnd/drag-item.ts +++ b/src/features/task-el/dnd/drag-item.ts @@ -2,4 +2,9 @@ import { NoteElement } from "@entities/note"; export interface TaskElDragItem { el: NoteElement; +} + +export type TaskElDragItemType = "TASK" | "GROUP"; +export const isTaskElDragItemType = (type: string): type is TaskElDragItemType => { + return type === "TASK" || type === "GROUP"; } \ No newline at end of file diff --git a/src/features/task-el/dnd/use-group-dnd.tsx b/src/features/task-el/dnd/use-group-dnd.tsx index 59f02e0..5c89600 100644 --- a/src/features/task-el/dnd/use-group-dnd.tsx +++ b/src/features/task-el/dnd/use-group-dnd.tsx @@ -3,7 +3,7 @@ import { RoutineNote, Task, NoteElement, TaskGroup } from "@entities/note"; import { useLeaf } from "@shared/view/use-leaf"; import React, { RefObject, useCallback, useEffect, useMemo, useReducer, useState } from "react"; import { DropTargetMonitor, useDrag, useDrop } from "react-dnd"; -import { TaskElDragItem } from "./drag-item"; +import { TaskElDragItem, TaskElDragItemType } from "./drag-item"; import { GroupHitArea, HitAreaEvaluator } from "./hit-area"; import { DndIndicator } from "./indicator"; import { DroppedElReplacer } from "../model/reorder-elements"; @@ -22,7 +22,7 @@ interface UseGroupDndResult { isDragging: boolean; indicator: React.ReactNode | null; } -export const useGroupDnd = ({ +export const useGroupDnd = ({ group, groupRef, isGroupOpen, @@ -38,7 +38,7 @@ export const useGroupDnd = ({ }, [hit]) const [{ isDragging }, drag, preview] = useDrag({ - type: "GROUP", + type: "GROUP" as TaskElDragItemType, item: () => ({ el: group, diff --git a/src/features/task-el/dnd/use-task-dnd.tsx b/src/features/task-el/dnd/use-task-dnd.tsx index 20dcb2c..723ef0b 100644 --- a/src/features/task-el/dnd/use-task-dnd.tsx +++ b/src/features/task-el/dnd/use-task-dnd.tsx @@ -7,7 +7,7 @@ import { DropTargetMonitor, useDrag, useDrop } from "react-dnd"; import { HitAreaEvaluator, TaskHitArea } from "./hit-area"; import { DndIndicator } from "./indicator"; import { DroppedElReplacer } from "../model/reorder-elements"; -import { TaskElDragItem } from "./drag-item"; +import { TaskElDragItem, TaskElDragItemType } from "./drag-item"; import { useRoutineMutationMerge } from "@features/merge-note"; @@ -57,7 +57,7 @@ export const useTaskDnd = ({ }, [group, task.name]) const [{ isDragging }, drag, preview] = useDrag({ - type: "TASK", + type: "TASK" as TaskElDragItemType, item: () => ({ el: task, diff --git a/src/features/task-el/index.ts b/src/features/task-el/index.ts index e2447e7..8646821 100644 --- a/src/features/task-el/index.ts +++ b/src/features/task-el/index.ts @@ -1,4 +1,4 @@ -export { TaskDndContext } from "./ui/dnd-context"; +export { TaskDndContext } from "./dnd/dnd-context"; export { BaseTaskFeature } from "./ui/BaseTaskFeature"; export { BaseTaskGroupFeature } from "./ui/BaseTaskGroupFeature"; export { renderTask } from "./ui/render-task-widget"; \ No newline at end of file diff --git a/src/features/task-el/ui/BaseTaskFeature.tsx b/src/features/task-el/ui/BaseTaskFeature.tsx index d333960..51826cc 100644 --- a/src/features/task-el/ui/BaseTaskFeature.tsx +++ b/src/features/task-el/ui/BaseTaskFeature.tsx @@ -11,7 +11,7 @@ import { CancelLineName } from './CancelLineName'; import { Checkbox } from './Checkbox'; import { OptionIcon } from './OptionIcon'; import { baseHeaderStyle, dragReadyStyle, draggingStyle, elementHeight, pressedStyle } from './base-element-style'; -import { DELAY_TOUCH_START } from './dnd-context'; +import { DELAY_TOUCH_START } from '../dnd/dnd-context'; import { Menu } from 'obsidian'; diff --git a/src/features/task-el/ui/BaseTaskGroupFeature.tsx b/src/features/task-el/ui/BaseTaskGroupFeature.tsx index 534f6e6..0fa4f06 100644 --- a/src/features/task-el/ui/BaseTaskGroupFeature.tsx +++ b/src/features/task-el/ui/BaseTaskGroupFeature.tsx @@ -8,7 +8,7 @@ import { useLeaf } from '@shared/view/use-leaf'; import React, { useCallback, useEffect, useRef, useState } from "react"; import { useGroupDnd } from '../dnd/use-group-dnd'; import { baseHeaderStyle, draggingStyle, dragReadyStyle, elementHeight, pressedStyle } from './base-element-style'; -import { DELAY_TOUCH_START } from './dnd-context'; +import { DELAY_TOUCH_START } from '../dnd/dnd-context'; import { OptionIcon } from './OptionIcon'; import { CancelLineName } from './CancelLineName'; import { renderTask } from './render-task-widget';