From 6a7005299a8e9c70fa712421d0462f6dc9380b0f Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 23 Sep 2024 16:41:06 -0400 Subject: [PATCH 1/3] IO-2931-Visual-Production-Board-Drag-and-Drop-on-Touch-Devices - Fix Drag and Drop on Android and IOS devices. Signed-off-by: Dave Richer --- .../production-board-kanban.styles.scss | 6 +++++- .../find-closest-draggable-id-from-event.js | 2 +- .../sensors/use-touch-sensor.js | 13 +++++++----- .../use-sensor-marshal/use-sensor-marshal.js | 20 ++++++++++++++++--- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/client/src/components/production-board-kanban/production-board-kanban.styles.scss b/client/src/components/production-board-kanban/production-board-kanban.styles.scss index 6e7ee63ce..8b04aaa5d 100644 --- a/client/src/components/production-board-kanban/production-board-kanban.styles.scss +++ b/client/src/components/production-board-kanban/production-board-kanban.styles.scss @@ -17,7 +17,6 @@ border-radius: 5px 5px 0 0; } - .production-alert { background: transparent; border: none; @@ -70,3 +69,8 @@ } } } + +.clone.is-dragging .ant-card { + border: #1890ff 2px solid !important; + border-radius: 12px; +} diff --git a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/find-closest-draggable-id-from-event.js b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/find-closest-draggable-id-from-event.js index 60285d2a4..f17be1759 100644 --- a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/find-closest-draggable-id-from-event.js +++ b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/find-closest-draggable-id-from-event.js @@ -8,7 +8,7 @@ function getSelector(contextId) { return `[${attributes.dragHandle.contextId}="${contextId}"]`; } -function findClosestDragHandleFromEvent(contextId, event) { +export function findClosestDragHandleFromEvent(contextId, event) { const target = event.target; if (!isElement(target)) { warning("event.target must be a Element"); diff --git a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/sensors/use-touch-sensor.js b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/sensors/use-touch-sensor.js index 3210e2188..d679f7442 100644 --- a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/sensors/use-touch-sensor.js +++ b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/sensors/use-touch-sensor.js @@ -240,11 +240,14 @@ export default function useTouchSensor(api) { y: clientY }; + const handle = api.findClosestDragHandle(event); + invariant(handle, "Touch sensor unable to find drag handle"); + // unbind this event handler unbindEventsRef.current(); // eslint-disable-next-line no-use-before-define - startPendingDrag(actions, point); + startPendingDrag(actions, point, handle); } }), // not including stop or startPendingDrag as it is not defined initially @@ -288,7 +291,7 @@ export default function useTouchSensor(api) { } }, [stop]); const bindCapturingEvents = useCallback( - function bindCapturingEvents() { + function bindCapturingEvents(target) { const options = { capture: true, passive: false @@ -307,7 +310,7 @@ export default function useTouchSensor(api) { // Old behaviour: // https://gist.github.com/parris/dda613e3ae78f14eb2dc9fa0f4bfce3d // https://stackoverflow.com/questions/33298828/touch-move-event-dont-fire-after-touch-start-target-is-removed - const unbindTarget = bindEvents(window, getHandleBindings(args), options); + const unbindTarget = bindEvents(target, getHandleBindings(args), options); const unbindWindow = bindEvents(window, getWindowBindings(args), options); unbindEventsRef.current = function unbindAll() { unbindTarget(); @@ -330,7 +333,7 @@ export default function useTouchSensor(api) { [getPhase, setPhase] ); const startPendingDrag = useCallback( - function startPendingDrag(actions, point) { + function startPendingDrag(actions, point, target) { invariant(getPhase().type === "IDLE", "Expected to move from IDLE to PENDING drag"); const longPressTimerId = setTimeout(startDragging, timeForLongPress); setPhase({ @@ -339,7 +342,7 @@ export default function useTouchSensor(api) { actions, longPressTimerId }); - bindCapturingEvents(); + bindCapturingEvents(target); }, [bindCapturingEvents, getPhase, setPhase, startDragging] ); diff --git a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/use-sensor-marshal.js b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/use-sensor-marshal.js index 17f84ee6b..c559a56ab 100644 --- a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/use-sensor-marshal.js +++ b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-sensor-marshal/use-sensor-marshal.js @@ -23,7 +23,9 @@ import getBorderBoxCenterPosition from "../get-border-box-center-position"; import { warning } from "../../dev-warning"; import useLayoutEffect from "../use-isomorphic-layout-effect"; import { noop } from "../../empty"; -import findClosestDraggableIdFromEvent from "./find-closest-draggable-id-from-event"; +import findClosestDraggableIdFromEvent, { + findClosestDragHandleFromEvent +} from "./find-closest-draggable-id-from-event"; import findDraggable from "../get-elements/find-draggable"; import bindEvents from "../event-bindings/bind-events"; @@ -339,6 +341,9 @@ export default function useSensorMarshal({ contextId, store, registry, customSen }), [contextId, lockAPI, registry, store] ); + + const findClosestDragHandle = useCallback((event) => findClosestDragHandleFromEvent(contextId, event), [contextId]); + const findClosestDraggableId = useCallback((event) => findClosestDraggableIdFromEvent(contextId, event), [contextId]); const findOptionsForDraggable = useCallback( (id) => { @@ -370,9 +375,18 @@ export default function useSensorMarshal({ contextId, store, registry, customSen findClosestDraggableId, findOptionsForDraggable, tryReleaseLock, - isLockClaimed + isLockClaimed, + findClosestDragHandle }), - [canGetLock, tryGetLock, findClosestDraggableId, findOptionsForDraggable, tryReleaseLock, isLockClaimed] + [ + canGetLock, + tryGetLock, + findClosestDraggableId, + findOptionsForDraggable, + tryReleaseLock, + isLockClaimed, + findClosestDragHandle + ] ); // Bad ass From 4dffbfe6fafd55e6a5b75629386a7283a2ece360 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 23 Sep 2024 19:26:40 -0400 Subject: [PATCH 2/3] IO-2931-Visual-Production-Board-Drag-and-Drop-on-Touch-Devices - Add additional fixes / optimizations, from parent repo Signed-off-by: Dave Richer --- .../trello-board/dnd/lib/state/get-droppable-over.js | 4 ++-- .../use-droppable-publisher/get-closest-scrollable.js | 3 ++- .../dnd/lib/view/use-style-marshal/get-styles.js | 8 +++++++- .../dnd/lib/view/use-style-marshal/use-style-marshal.js | 4 +++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/client/src/components/production-board-kanban/trello-board/dnd/lib/state/get-droppable-over.js b/client/src/components/production-board-kanban/trello-board/dnd/lib/state/get-droppable-over.js index dcf0cf04c..cb7f7c75b 100644 --- a/client/src/components/production-board-kanban/trello-board/dnd/lib/state/get-droppable-over.js +++ b/client/src/components/production-board-kanban/trello-board/dnd/lib/state/get-droppable-over.js @@ -25,8 +25,8 @@ function getFurthestAway({ pageBorderBox, draggable, candidates }) { const axis = candidate.axis; const target = patch( candidate.axis.line, - // use the current center of the dragging item on the main axis - pageBorderBox.center[axis.line], + // use the center of the list on the main axis + candidate.page.borderBox.center[axis.line], // use the center of the list on the cross axis candidate.page.borderBox.center[axis.crossAxisLine] ); diff --git a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-droppable-publisher/get-closest-scrollable.js b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-droppable-publisher/get-closest-scrollable.js index 923622788..0b069cce5 100644 --- a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-droppable-publisher/get-closest-scrollable.js +++ b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-droppable-publisher/get-closest-scrollable.js @@ -5,6 +5,7 @@ import getBodyElement from "../get-body-element"; const isEqual = (base) => (value) => base === value; const isScroll = isEqual("scroll"); const isAuto = isEqual("auto"); +const isOverlay = isEqual("overlay"); const isVisible = isEqual("visible"); const isEither = (overflow, fn) => fn(overflow.overflowX) || fn(overflow.overflowY); const isBoth = (overflow, fn) => fn(overflow.overflowX) && fn(overflow.overflowY); @@ -14,7 +15,7 @@ const isElementScrollable = (el) => { overflowX: style.overflowX, overflowY: style.overflowY }; - return isEither(overflow, isScroll) || isEither(overflow, isAuto); + return isEither(overflow, isScroll) || isEither(overflow, isAuto) || isEither(overflow, isOverlay); }; // Special case for a body element diff --git a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/get-styles.js b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/get-styles.js index 418acb50b..f62947525 100644 --- a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/get-styles.js +++ b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/get-styles.js @@ -83,7 +83,13 @@ const getFinalStyles = (contextId) => { return { selector: getSelector(attributes.draggable.contextId), styles: { - dragging: transition, + dragging: ` + ${transition} + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + `, dropAnimating: transition, userCancel: transition } diff --git a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/use-style-marshal.js b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/use-style-marshal.js index 19457b312..b27b4d534 100644 --- a/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/use-style-marshal.js +++ b/client/src/components/production-board-kanban/trello-board/dnd/lib/view/use-style-marshal/use-style-marshal.js @@ -67,7 +67,9 @@ export default function useStyleMarshal(contextId, nonce) { const remove = (ref) => { const current = ref.current; invariant(current, "Cannot unmount ref as it is not set"); - getHead().removeChild(current); + if (getHead().contains(current)) { + getHead().removeChild(current); + } ref.current = null; }; remove(alwaysRef); From f287ba2dac8d5d2401badab2d4a40ce247739c9a Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Tue, 24 Sep 2024 10:35:46 -0400 Subject: [PATCH 3/3] IO-2931-Visual-Production-Board-Drag-and-Drop-on-Touch-Devices - Remove reference to /public on apple-touch-icon Signed-off-by: Dave Richer --- client/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/index.html b/client/index.html index 2ba9559dc..0d1e9bcfe 100644 --- a/client/index.html +++ b/client/index.html @@ -17,7 +17,7 @@ - +