From 2aecf5dd35ef4d91013ce25c925e5d1fe96b0211 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 29 Aug 2023 12:51:22 +0200 Subject: [PATCH 01/42] add DraggableList component --- package-lock.json | 203 ++++++++++++++++++ package.json | 3 + src/components/DraggableList/index.native.tsx | 9 + src/components/DraggableList/index.tsx | 117 ++++++++++ src/components/DraggableList/types.tsx | 22 ++ .../DraggableList/useDraggableInPortal.tsx | 43 ++++ 6 files changed, 397 insertions(+) create mode 100644 src/components/DraggableList/index.native.tsx create mode 100644 src/components/DraggableList/index.tsx create mode 100644 src/components/DraggableList/types.tsx create mode 100644 src/components/DraggableList/useDraggableInPortal.tsx diff --git a/package-lock.json b/package-lock.json index acef3146fb25..cfb78bedd32b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,6 +61,7 @@ "prop-types": "^15.7.2", "pusher-js": "7.4.0", "react": "18.2.0", + "react-beautiful-dnd": "^13.1.1", "react-collapse": "^5.1.0", "react-content-loader": "^6.1.0", "react-dom": "18.1.0", @@ -72,6 +73,7 @@ "react-native-dev-menu": "^4.1.1", "react-native-device-info": "^10.3.0", "react-native-document-picker": "^8.0.0", + "react-native-draggable-flatlist": "^4.0.1", "react-native-fast-image": "^8.6.3", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "2.12.0", @@ -154,6 +156,7 @@ "@types/mock-fs": "^4.13.1", "@types/pusher-js": "^5.1.0", "@types/react": "^18.2.12", + "@types/react-beautiful-dnd": "^13.1.4", "@types/react-collapse": "^5.0.1", "@types/react-dom": "^18.2.4", "@types/react-pdf": "^5.7.2", @@ -17984,6 +17987,15 @@ "@types/unist": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "dev": true, @@ -18255,6 +18267,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-beautiful-dnd": { + "version": "13.1.4", + "resolved": "https://registry.npmjs.org/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.4.tgz", + "integrity": "sha512-4bIBdzOr0aavN+88q3C7Pgz+xkb7tz3whORYrmSj77wfVEMfiWiooIwVWFR7KM2e+uGTe5BVrXqSfb0aHeflJA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-collapse": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/react-collapse/-/react-collapse-5.0.1.tgz", @@ -18289,6 +18310,17 @@ "pdfjs-dist": "^2.10.377" } }, + "node_modules/@types/react-redux": { + "version": "7.1.26", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.26.tgz", + "integrity": "sha512-UKPo7Cm7rswYU6PH6CmTNCRv5NYF3HrgKuHEYTK8g/3czYLrUux50gQ2pkxc9c7ZpQZi+PNhgmI8oNIRoiVIxg==", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "node_modules/@types/react-test-renderer": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz", @@ -23877,6 +23909,14 @@ "version": "3.3.0", "license": "MIT" }, + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "dependencies": { + "tiny-invariant": "^1.0.6" + } + }, "node_modules/css-color-keywords": { "version": "1.0.0", "license": "ISC", @@ -40317,6 +40357,11 @@ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" }, + "node_modules/raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" + }, "node_modules/ramda": { "version": "0.29.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz", @@ -40419,6 +40464,24 @@ "node": ">=0.10.0" } }, + "node_modules/react-beautiful-dnd": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz", + "integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==", + "dependencies": { + "@babel/runtime": "^7.9.2", + "css-box-model": "^1.2.0", + "memoize-one": "^5.1.1", + "raf-schd": "^4.0.2", + "react-redux": "^7.2.0", + "redux": "^4.0.4", + "use-memo-one": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.5 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-collapse": { "version": "5.1.1", "license": "MIT", @@ -40719,6 +40782,19 @@ } } }, + "node_modules/react-native-draggable-flatlist": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-native-draggable-flatlist/-/react-native-draggable-flatlist-4.0.1.tgz", + "integrity": "sha512-ZO1QUTNx64KZfXGXeXcBfql67l38X7kBcJ3rxUVZzPHt5r035GnGzIC0F8rqSXp6zgnwgUYMfB6zQc5PKmPL9Q==", + "dependencies": { + "@babel/preset-typescript": "^7.17.12" + }, + "peerDependencies": { + "react-native": ">=0.64.0", + "react-native-gesture-handler": ">=2.0.0", + "react-native-reanimated": ">=2.8.0" + } + }, "node_modules/react-native-fast-image": { "version": "8.6.3", "license": "(MIT AND Apache-2.0)", @@ -41421,6 +41497,35 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-redux": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, "node_modules/react-refresh": { "version": "0.11.0", "dev": true, @@ -46514,6 +46619,14 @@ "react": ">=16.8" } }, + "node_modules/use-memo-one": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", + "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/use-resize-observer": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", @@ -60770,6 +60883,15 @@ "@types/unist": "*" } }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "6.1.0", "dev": true @@ -61008,6 +61130,15 @@ "csstype": "^3.0.2" } }, + "@types/react-beautiful-dnd": { + "version": "13.1.4", + "resolved": "https://registry.npmjs.org/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.4.tgz", + "integrity": "sha512-4bIBdzOr0aavN+88q3C7Pgz+xkb7tz3whORYrmSj77wfVEMfiWiooIwVWFR7KM2e+uGTe5BVrXqSfb0aHeflJA==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-collapse": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/react-collapse/-/react-collapse-5.0.1.tgz", @@ -61040,6 +61171,17 @@ "pdfjs-dist": "^2.10.377" } }, + "@types/react-redux": { + "version": "7.1.26", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.26.tgz", + "integrity": "sha512-UKPo7Cm7rswYU6PH6CmTNCRv5NYF3HrgKuHEYTK8g/3czYLrUux50gQ2pkxc9c7ZpQZi+PNhgmI8oNIRoiVIxg==", + "requires": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "@types/react-test-renderer": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz", @@ -64954,6 +65096,14 @@ "crypto-js": { "version": "3.3.0" }, + "css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "requires": { + "tiny-invariant": "^1.0.6" + } + }, "css-color-keywords": { "version": "1.0.0" }, @@ -76213,6 +76363,11 @@ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" }, + "raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" + }, "ramda": { "version": "0.29.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz", @@ -76280,6 +76435,20 @@ "loose-envify": "^1.1.0" } }, + "react-beautiful-dnd": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz", + "integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==", + "requires": { + "@babel/runtime": "^7.9.2", + "css-box-model": "^1.2.0", + "memoize-one": "^5.1.1", + "raf-schd": "^4.0.2", + "react-redux": "^7.2.0", + "redux": "^4.0.4", + "use-memo-one": "^1.1.1" + } + }, "react-collapse": { "version": "5.1.1", "requires": {} @@ -76589,6 +76758,14 @@ "invariant": "^2.2.4" } }, + "react-native-draggable-flatlist": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-native-draggable-flatlist/-/react-native-draggable-flatlist-4.0.1.tgz", + "integrity": "sha512-ZO1QUTNx64KZfXGXeXcBfql67l38X7kBcJ3rxUVZzPHt5r035GnGzIC0F8rqSXp6zgnwgUYMfB6zQc5PKmPL9Q==", + "requires": { + "@babel/preset-typescript": "^7.17.12" + } + }, "react-native-fast-image": { "version": "8.6.3", "requires": {} @@ -76906,6 +77083,26 @@ "react-script-hook": "^1.6.0" } }, + "react-redux": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "requires": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } + } + }, "react-refresh": { "version": "0.11.0", "dev": true @@ -80412,6 +80609,12 @@ "integrity": "sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg==", "requires": {} }, + "use-memo-one": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", + "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", + "requires": {} + }, "use-resize-observer": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", diff --git a/package.json b/package.json index 58bb57b1bb98..14531261ed41 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,7 @@ "prop-types": "^15.7.2", "pusher-js": "7.4.0", "react": "18.2.0", + "react-beautiful-dnd": "^13.1.1", "react-collapse": "^5.1.0", "react-content-loader": "^6.1.0", "react-dom": "18.1.0", @@ -112,6 +113,7 @@ "react-native-dev-menu": "^4.1.1", "react-native-device-info": "^10.3.0", "react-native-document-picker": "^8.0.0", + "react-native-draggable-flatlist": "^4.0.1", "react-native-fast-image": "^8.6.3", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "2.12.0", @@ -194,6 +196,7 @@ "@types/mock-fs": "^4.13.1", "@types/pusher-js": "^5.1.0", "@types/react": "^18.2.12", + "@types/react-beautiful-dnd": "^13.1.4", "@types/react-collapse": "^5.0.1", "@types/react-dom": "^18.2.4", "@types/react-pdf": "^5.7.2", diff --git a/src/components/DraggableList/index.native.tsx b/src/components/DraggableList/index.native.tsx new file mode 100644 index 000000000000..fab164755f06 --- /dev/null +++ b/src/components/DraggableList/index.native.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import DraggableFlatList from 'react-native-draggable-flatlist'; +import _ from 'lodash'; +import type {DefaultItemProps, DraggableListProps} from './types'; + +export default function DraggableList({...props}: DraggableListProps) { + const viewProps = _.omit(props, ['renderClone', 'shouldUsePortal']); + return ; +} diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx new file mode 100644 index 000000000000..1c7fcf64c4bf --- /dev/null +++ b/src/components/DraggableList/index.tsx @@ -0,0 +1,117 @@ +import React, {useCallback} from 'react'; +import {DragDropContext, Droppable, Draggable, type OnDragEndResponder, type OnDragUpdateResponder} from 'react-beautiful-dnd'; +import {ScrollView} from 'react-native'; +import useDraggableInPortal from './useDraggableInPortal'; +import type {DraggableListProps, DefaultItemProps} from './types'; + +type ReoderParams = { + list: T[]; + startIndex: number; + endIndex: number; +}; + +// Function to help us with reordering the result +const reorder = ({list, startIndex, endIndex}: ReoderParams): T[] => { + const result = Array.from(list); + const [removed] = result.splice(startIndex, 1); + + if (removed !== undefined) { + result.splice(endIndex, 0, removed); + } + + return result; +}; + +export default function DraggableList({ + data = [], + renderItem, + keyExtractor, + onDragEnd: onDragEndCallback, + onDragBegin, + onPlaceholderIndexChange, + renderClone, + shouldUsePortal = false, +}: DraggableListProps) { + const onDragEnd: OnDragEndResponder = useCallback( + (result) => { + if (!result.destination) { + return; + } + + const reorderedItems = reorder({ + list: data, + startIndex: result.source.index, + endIndex: result.destination.index, + }); + + onDragEndCallback?.({data: reorderedItems}); + }, + [data, onDragEndCallback], + ); + + const onDragUpdate: OnDragUpdateResponder = useCallback( + (result) => { + if (!result.destination) { + return; + } + onPlaceholderIndexChange?.(result.destination.index); + }, + [onPlaceholderIndexChange], + ); + + const renderDraggable = useDraggableInPortal({shouldUsePortal}); + + return ( + + + {(droppableProvided) => ( + // We use ScrollView to match the native behavior of FlatList + + {/* We can't use the react-native View here, because it doesn't support all props */} +
+ {data.map((item, index) => { + const key = keyExtractor(item, index); + return ( + + {renderDraggable((draggableProvided, snapshot) => ( +
+ {renderItem({ + item, + getIndex: () => index, + isActive: snapshot.isDragging, + drag: () => {}, + })} +
+ ))} +
+ ); + })} + {droppableProvided.placeholder} +
+
+ )} +
+
+ ); +} diff --git a/src/components/DraggableList/types.tsx b/src/components/DraggableList/types.tsx new file mode 100644 index 000000000000..9cad93dfafb7 --- /dev/null +++ b/src/components/DraggableList/types.tsx @@ -0,0 +1,22 @@ +import type {DraggableChildrenFn} from 'react-beautiful-dnd'; +import type {RenderItemParams as OriginalRenderItemParams} from 'react-native-draggable-flatlist'; + +type DefaultItemProps = { + id: string; +}; + +type DraggableListProps = { + data: T[]; + keyExtractor: (item: T, index: number) => string; + renderItem: (params: RenderItemParams) => React.ReactNode; + onDragEnd?: (params: {data: T[]}) => void; + onDragBegin?: () => void; + onPlaceholderIndexChange?: ((placeholderIndex: number) => void) | undefined; + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + renderClone?: DraggableChildrenFn | undefined; + shouldUsePortal?: boolean; +}; + +type RenderItemParams = OriginalRenderItemParams; + +export type {DefaultItemProps, DraggableListProps, RenderItemParams}; diff --git a/src/components/DraggableList/useDraggableInPortal.tsx b/src/components/DraggableList/useDraggableInPortal.tsx new file mode 100644 index 000000000000..586bab459eb5 --- /dev/null +++ b/src/components/DraggableList/useDraggableInPortal.tsx @@ -0,0 +1,43 @@ +import type {DraggableChildrenFn, DraggingStyle} from 'react-beautiful-dnd'; +import {useEffect, useRef} from 'react'; +import {createPortal} from 'react-dom'; + +type DraggableInPortalProps = { + shouldUsePortal?: boolean; +}; + +export default function useDraggableInPortal({shouldUsePortal}: DraggableInPortalProps): (render: DraggableChildrenFn) => DraggableChildrenFn { + const element = useRef(document.createElement('div')).current; + + useEffect(() => { + if (!shouldUsePortal || !element) { + return () => {}; + } + element.style.pointerEvents = 'none'; + element.style.position = 'absolute'; + element.style.height = '100%'; + element.style.width = '100%'; + element.style.top = '0'; + + document.body.appendChild(element); + + return () => { + document.body.removeChild(element); + }; + }, [element, shouldUsePortal]); + + if (!shouldUsePortal) { + return (render) => render; + } + + return (render) => (provided, snapshot, rubric) => { + const result = render(provided, snapshot, rubric); + const style = provided.draggableProps.style as DraggingStyle; + if (style.position === 'fixed') { + return createPortal(result, element); + } + return result; + }; +} + +export type {DraggableInPortalProps}; From ec8708843cf9d7b766f0f7ae2d5a1eae043c8bc3 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 29 Aug 2023 12:59:02 +0200 Subject: [PATCH 02/42] use DraggableList in the DistanceRequest --- src/components/DistanceRequest.js | 35 +++++++++++++++++++------------ src/libs/actions/Transaction.js | 10 ++++++++- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index ecc36a824526..7506fc685d21 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -5,6 +5,7 @@ import _ from 'underscore'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import MapView from 'react-native-x-maps'; +import DraggableList from '../components/DraggableList'; import ONYXKEYS from '../ONYXKEYS'; import * as Transaction from '../libs/actions/Transaction'; import * as TransactionUtils from '../libs/TransactionUtils'; @@ -23,6 +24,7 @@ import useLocalize from '../hooks/useLocalize'; import Navigation from '../libs/Navigation/Navigation'; import ROUTES from '../ROUTES'; import transactionPropTypes from './transactionPropTypes'; +import ScreenWrapper from './ScreenWrapper'; import DotIndicatorMessage from './DotIndicatorMessage'; import * as ErrorUtils from '../libs/ErrorUtils'; import usePrevious from '../hooks/usePrevious'; @@ -64,6 +66,7 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { const {translate} = useLocalize(); const waypoints = lodashGet(transaction, 'comment.waypoints', {}); + const waypointsList = _.keys(waypoints); const numberOfWaypoints = _.size(waypoints); const lastWaypointIndex = numberOfWaypoints - 1; @@ -138,19 +141,24 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight]); return ( - <> + setScrollContainerHeight(lodashGet(event, 'nativeEvent.layout.height', 0))} > - setScrollContentHeight(height)} - onScroll={updateGradientVisibility} - scrollEventThrottle={16} - > - {_.map(waypoints, (waypoint, key) => { - // key is of the form waypoint0, waypoint1, ... - const index = Number(key.replace('waypoint', '')); + item} + shouldUsePortal + onDragEnd={({data}) => { + const newWaypoints = {}; + _.each(data, (waypoint, index) => { + newWaypoints[`waypoint${index}`] = lodashGet(waypoints, waypoint, null); + }); + Transaction.updateWaypoints(transactionID, newWaypoints); + }} + renderItem={({item, drag, getIndex}) => { + const index = getIndex(); let descriptionKey = 'distance.waypointDescription.'; let waypointIcon; if (index === 0) { @@ -174,11 +182,12 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { secondaryIconFill={theme.icon} shouldShowRightIcon onPress={() => Navigation.navigate(ROUTES.getMoneyRequestWaypointRoute('request', index))} - key={key} + onSecondaryInteraction={drag} + key={item} /> ); - })} - + }} + /> {shouldShowGradient && ( )} - + ); } diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 1dad0219db1a..3fc5bf30017d 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -199,4 +199,12 @@ function getRoute(transactionID, waypoints) { ); } -export {addStop, createInitialWaypoints, saveWaypoint, removeWaypoint, getRoute}; +function updateWaypoints(transactionID, waypoints) { + Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { + comment: { + waypoints, + }, + }); +} + +export {addStop, createInitialWaypoints, saveWaypoint, removeWaypoint, getRoute, updateWaypoints}; From 7e752d1328ce22f4be82754fe40eb34bd43067a0 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:04:30 +0200 Subject: [PATCH 03/42] patch react-beautiful-dnd --- patches/react-beautiful-dnd+13.1.1.patch | 259 +++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 patches/react-beautiful-dnd+13.1.1.patch diff --git a/patches/react-beautiful-dnd+13.1.1.patch b/patches/react-beautiful-dnd+13.1.1.patch new file mode 100644 index 000000000000..577d54d42004 --- /dev/null +++ b/patches/react-beautiful-dnd+13.1.1.patch @@ -0,0 +1,259 @@ +diff --git a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.cjs.js b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.cjs.js +index 12884e9..3a16e5e 100644 +--- a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.cjs.js ++++ b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.cjs.js +@@ -6227,8 +6227,10 @@ function useTouchSensor(api) { + x: clientX, + y: clientY + }; ++ var handle = api.findClosestDragHandle(event); ++ !handle ? process.env.NODE_ENV !== "production" ? invariant(false, 'Touch sensor unable to find drag handle') : invariant(false) : void 0; + unbindEventsRef.current(); +- startPendingDrag(actions, point); ++ startPendingDrag(actions, point, handle); + } + }; + }, [api]); +@@ -6268,7 +6270,7 @@ function useTouchSensor(api) { + phase.actions.abort(); + } + }, [stop]); +- var bindCapturingEvents = useMemoOne.useCallback(function bindCapturingEvents() { ++ var bindCapturingEvents = useMemoOne.useCallback(function bindCapturingEvents(target) { + var options = { + capture: true, + passive: false +@@ -6278,7 +6280,7 @@ function useTouchSensor(api) { + completed: stop, + getPhase: getPhase + }; +- var unbindTarget = bindEvents(window, getHandleBindings(args), options); ++ var unbindTarget = bindEvents(target, getHandleBindings(args), options); + var unbindWindow = bindEvents(window, getWindowBindings(args), options); + + unbindEventsRef.current = function unbindAll() { +@@ -6296,7 +6298,7 @@ function useTouchSensor(api) { + hasMoved: false + }); + }, [getPhase, setPhase]); +- var startPendingDrag = useMemoOne.useCallback(function startPendingDrag(actions, point) { ++ var startPendingDrag = useMemoOne.useCallback(function startPendingDrag(actions, point, target) { + !(getPhase().type === 'IDLE') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected to move from IDLE to PENDING drag') : invariant(false) : void 0; + var longPressTimerId = setTimeout(startDragging, timeForLongPress); + setPhase({ +@@ -6305,7 +6307,7 @@ function useTouchSensor(api) { + actions: actions, + longPressTimerId: longPressTimerId + }); +- bindCapturingEvents(); ++ bindCapturingEvents(target); + }, [bindCapturingEvents, getPhase, setPhase, startDragging]); + useIsomorphicLayoutEffect(function mount() { + listenForCapture(); +@@ -6454,7 +6456,6 @@ function findClosestDragHandleFromEvent(contextId, event) { + + return handle; + } +- + function tryGetClosestDraggableIdFromEvent(contextId, event) { + var handle = findClosestDragHandleFromEvent(contextId, event); + +@@ -6786,6 +6787,9 @@ function useSensorMarshal(_ref4) { + sourceEvent: options && options.sourceEvent ? options.sourceEvent : null + }); + }, [contextId, lockAPI, registry, store]); ++ var findClosestDragHandle = useMemoOne.useCallback(function (event) { ++ return findClosestDragHandleFromEvent(contextId, event); ++ }, [contextId]); + var findClosestDraggableId = useMemoOne.useCallback(function (event) { + return tryGetClosestDraggableIdFromEvent(contextId, event); + }, [contextId]); +@@ -6810,11 +6814,12 @@ function useSensorMarshal(_ref4) { + canGetLock: canGetLock, + tryGetLock: tryGetLock, + findClosestDraggableId: findClosestDraggableId, ++ findClosestDragHandle: findClosestDragHandle, + findOptionsForDraggable: findOptionsForDraggable, + tryReleaseLock: tryReleaseLock, + isLockClaimed: isLockClaimed + }; +- }, [canGetLock, tryGetLock, findClosestDraggableId, findOptionsForDraggable, tryReleaseLock, isLockClaimed]); ++ }, [canGetLock, tryGetLock, findClosestDraggableId, findClosestDragHandle, findOptionsForDraggable, tryReleaseLock, isLockClaimed]); + useValidateSensorHooks(useSensors); + + for (var i = 0; i < useSensors.length; i++) { +diff --git a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.esm.js b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.esm.js +index ecced69..3233bf8 100644 +--- a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.esm.js ++++ b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.esm.js +@@ -6220,8 +6220,10 @@ function useTouchSensor(api) { + x: clientX, + y: clientY + }; ++ var handle = api.findClosestDragHandle(event); ++ !handle ? process.env.NODE_ENV !== "production" ? invariant(false, 'Touch sensor unable to find drag handle') : invariant(false) : void 0; + unbindEventsRef.current(); +- startPendingDrag(actions, point); ++ startPendingDrag(actions, point, handle); + } + }; + }, [api]); +@@ -6261,7 +6263,7 @@ function useTouchSensor(api) { + phase.actions.abort(); + } + }, [stop]); +- var bindCapturingEvents = useCallback(function bindCapturingEvents() { ++ var bindCapturingEvents = useCallback(function bindCapturingEvents(target) { + var options = { + capture: true, + passive: false +@@ -6271,7 +6273,7 @@ function useTouchSensor(api) { + completed: stop, + getPhase: getPhase + }; +- var unbindTarget = bindEvents(window, getHandleBindings(args), options); ++ var unbindTarget = bindEvents(target, getHandleBindings(args), options); + var unbindWindow = bindEvents(window, getWindowBindings(args), options); + + unbindEventsRef.current = function unbindAll() { +@@ -6289,7 +6291,7 @@ function useTouchSensor(api) { + hasMoved: false + }); + }, [getPhase, setPhase]); +- var startPendingDrag = useCallback(function startPendingDrag(actions, point) { ++ var startPendingDrag = useCallback(function startPendingDrag(actions, point, target) { + !(getPhase().type === 'IDLE') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected to move from IDLE to PENDING drag') : invariant(false) : void 0; + var longPressTimerId = setTimeout(startDragging, timeForLongPress); + setPhase({ +@@ -6298,7 +6300,7 @@ function useTouchSensor(api) { + actions: actions, + longPressTimerId: longPressTimerId + }); +- bindCapturingEvents(); ++ bindCapturingEvents(target); + }, [bindCapturingEvents, getPhase, setPhase, startDragging]); + useIsomorphicLayoutEffect(function mount() { + listenForCapture(); +@@ -6447,7 +6449,6 @@ function findClosestDragHandleFromEvent(contextId, event) { + + return handle; + } +- + function tryGetClosestDraggableIdFromEvent(contextId, event) { + var handle = findClosestDragHandleFromEvent(contextId, event); + +@@ -6779,6 +6780,9 @@ function useSensorMarshal(_ref4) { + sourceEvent: options && options.sourceEvent ? options.sourceEvent : null + }); + }, [contextId, lockAPI, registry, store]); ++ var findClosestDragHandle = useCallback(function (event) { ++ return findClosestDragHandleFromEvent(contextId, event); ++ }, [contextId]); + var findClosestDraggableId = useCallback(function (event) { + return tryGetClosestDraggableIdFromEvent(contextId, event); + }, [contextId]); +@@ -6803,11 +6807,12 @@ function useSensorMarshal(_ref4) { + canGetLock: canGetLock, + tryGetLock: tryGetLock, + findClosestDraggableId: findClosestDraggableId, ++ findClosestDragHandle: findClosestDragHandle, + findOptionsForDraggable: findOptionsForDraggable, + tryReleaseLock: tryReleaseLock, + isLockClaimed: isLockClaimed + }; +- }, [canGetLock, tryGetLock, findClosestDraggableId, findOptionsForDraggable, tryReleaseLock, isLockClaimed]); ++ }, [canGetLock, tryGetLock, findClosestDraggableId, findClosestDragHandle, findOptionsForDraggable, tryReleaseLock, isLockClaimed]); + useValidateSensorHooks(useSensors); + + for (var i = 0; i < useSensors.length; i++) { +diff --git a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.js b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.js +index 84b63e9..c62471d 100644 +--- a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.js ++++ b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.js +@@ -9224,8 +9224,10 @@ + x: clientX, + y: clientY + }; ++ var handle = api.findClosestDragHandle(event); ++ !handle ? invariant(false, 'Touch sensor unable to find drag handle') : void 0; + unbindEventsRef.current(); +- startPendingDrag(actions, point); ++ startPendingDrag(actions, point, handle); + } + }; + }, [api]); +@@ -9265,7 +9267,7 @@ + phase.actions.abort(); + } + }, [stop]); +- var bindCapturingEvents = useCallback(function bindCapturingEvents() { ++ var bindCapturingEvents = useCallback(function bindCapturingEvents(target) { + var options = { + capture: true, + passive: false +@@ -9275,7 +9277,7 @@ + completed: stop, + getPhase: getPhase + }; +- var unbindTarget = bindEvents(window, getHandleBindings(args), options); ++ var unbindTarget = bindEvents(target, getHandleBindings(args), options); + var unbindWindow = bindEvents(window, getWindowBindings(args), options); + + unbindEventsRef.current = function unbindAll() { +@@ -9293,7 +9295,7 @@ + hasMoved: false + }); + }, [getPhase, setPhase]); +- var startPendingDrag = useCallback(function startPendingDrag(actions, point) { ++ var startPendingDrag = useCallback(function startPendingDrag(actions, point, target) { + !(getPhase().type === 'IDLE') ? invariant(false, 'Expected to move from IDLE to PENDING drag') : void 0; + var longPressTimerId = setTimeout(startDragging, timeForLongPress); + setPhase({ +@@ -9302,7 +9304,7 @@ + actions: actions, + longPressTimerId: longPressTimerId + }); +- bindCapturingEvents(); ++ bindCapturingEvents(target); + }, [bindCapturingEvents, getPhase, setPhase, startDragging]); + useIsomorphicLayoutEffect$1(function mount() { + listenForCapture(); +@@ -9451,7 +9453,6 @@ + + return handle; + } +- + function tryGetClosestDraggableIdFromEvent(contextId, event) { + var handle = findClosestDragHandleFromEvent(contextId, event); + +@@ -9783,6 +9784,9 @@ + sourceEvent: options && options.sourceEvent ? options.sourceEvent : null + }); + }, [contextId, lockAPI, registry, store]); ++ var findClosestDragHandle = useCallback(function (event) { ++ return findClosestDragHandleFromEvent(contextId, event); ++ }, [contextId]); + var findClosestDraggableId = useCallback(function (event) { + return tryGetClosestDraggableIdFromEvent(contextId, event); + }, [contextId]); +@@ -9807,11 +9811,12 @@ + canGetLock: canGetLock, + tryGetLock: tryGetLock, + findClosestDraggableId: findClosestDraggableId, ++ findClosestDragHandle: findClosestDragHandle, + findOptionsForDraggable: findOptionsForDraggable, + tryReleaseLock: tryReleaseLock, + isLockClaimed: isLockClaimed + }; +- }, [canGetLock, tryGetLock, findClosestDraggableId, findOptionsForDraggable, tryReleaseLock, isLockClaimed]); ++ }, [canGetLock, tryGetLock, findClosestDraggableId, findClosestDragHandle, findOptionsForDraggable, tryReleaseLock, isLockClaimed]); + useValidateSensorHooks(useSensors); + + for (var i = 0; i < useSensors.length; i++) { +diff --git a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.min.js b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.min.js +index a18e84d..9ec9c6d 100644 +--- a/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.min.js ++++ b/node_modules/react-beautiful-dnd/dist/react-beautiful-dnd.min.js +@@ -1 +1 @@ +-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-dom"],t):t((e=e||self).ReactBeautifulDnd={},e.React,e.ReactDOM)}(this,(function(e,t,r){"use strict";var n="default"in t?t.default:t,i="default"in r?r.default:r;function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(){}function l(){return(l=Object.assign||function(e){for(var t=1;t");return t.callbacks},t.setCallbacks=function(e){t.callbacks=e},t}o(t,e);var r=t.prototype;return r.componentDidMount=function(){this.unbind=u(window,[{eventName:"error",fn:this.onWindowError}])},r.componentDidCatch=function(e){if(!(e instanceof c))throw e;this.setState({})},r.componentWillUnmount=function(){this.unbind()},r.render=function(){return this.props.children(this.setCallbacks)},t}(n.Component),p=function(e){return e+1},f=function(e,t){var r=e.droppableId===t.droppableId,n=p(e.index),i=p(t.index);return r?"\n You have moved the item from position "+n+"\n to position "+i+"\n ":"\n You have moved the item from position "+n+"\n in list "+e.droppableId+"\n to list "+t.droppableId+"\n in position "+i+"\n "},g=function(e,t,r){return t.droppableId===r.droppableId?"\n The item "+e+"\n has been combined with "+r.draggableId:"\n The item "+e+"\n in list "+t.droppableId+"\n has been combined with "+r.draggableId+"\n in list "+r.droppableId+"\n "},v=function(e){return"\n The item has returned to its starting position\n of "+p(e.index)+"\n"},m="\n Press space bar to start a drag.\n When dragging you can use the arrow keys to move the item around and escape to cancel.\n Some screen readers may require you to be in focus mode or to use your pass through key\n",b=function(e){return"\n You have lifted an item in position "+p(e.source.index)+"\n"},h=function(e){var t=e.destination;if(t)return f(e.source,t);var r=e.combine;return r?g(e.draggableId,e.source,r):"You are over an area that cannot be dropped on"},y=function(e){if("CANCEL"===e.reason)return"\n Movement cancelled.\n "+v(e.source)+"\n ";var t=e.destination,r=e.combine;return t?"\n You have dropped the item.\n "+f(e.source,t)+"\n ":r?"\n You have dropped the item.\n "+g(e.draggableId,e.source,r)+"\n ":"\n The item has been dropped while not over a drop area.\n "+v(e.source)+"\n "};var x=function(e){var t,r=e.Symbol;return"function"==typeof r?r.observable?t=r.observable:(t=r("observable"),r.observable=t):t="@@observable",t}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof module?module:Function("return this")()),I=function(){return Math.random().toString(36).substring(7).split("").join(".")},D={INIT:"@@redux/INIT"+I(),REPLACE:"@@redux/REPLACE"+I(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+I()}};function w(e){if("object"!=typeof e||null===e)return!1;for(var t=e;null!==Object.getPrototypeOf(t);)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function E(e,t,r){var n;if("function"==typeof t&&"function"==typeof r||"function"==typeof r&&"function"==typeof arguments[3])throw new Error("It looks like you are passing several store enhancers to createStore(). This is not supported. Instead, compose them together to a single function.");if("function"==typeof t&&void 0===r&&(r=t,t=void 0),void 0!==r){if("function"!=typeof r)throw new Error("Expected the enhancer to be a function.");return r(E)(e,t)}if("function"!=typeof e)throw new Error("Expected the reducer to be a function.");var i=e,o=t,a=[],l=a,u=!1;function c(){l===a&&(l=a.slice())}function s(){if(u)throw new Error("You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.");return o}function d(e){if("function"!=typeof e)throw new Error("Expected the listener to be a function.");if(u)throw new Error("You may not call store.subscribe() while the reducer is executing. If you would like to be notified after the store has been updated, subscribe from a component and invoke store.getState() in the callback to access the latest state. See https://redux.js.org/api-reference/store#subscribelistener for more details.");var t=!0;return c(),l.push(e),function(){if(t){if(u)throw new Error("You may not unsubscribe from a store listener while the reducer is executing. See https://redux.js.org/api-reference/store#subscribelistener for more details.");t=!1,c();var r=l.indexOf(e);l.splice(r,1),a=null}}}function p(e){if(!w(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if(void 0===e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(u)throw new Error("Reducers may not dispatch actions.");try{u=!0,o=i(o,e)}finally{u=!1}for(var t=a=l,r=0;r=0||(i[r]=e[r]);return i}var K={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},Q={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},Z={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},ee={};function te(e){return L.isMemo(e)?Z:ee[e.$$typeof]||K}ee[L.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},ee[L.Memo]=Z;var re=Object.defineProperty,ne=Object.getOwnPropertyNames,ie=Object.getOwnPropertySymbols,oe=Object.getOwnPropertyDescriptor,ae=Object.getPrototypeOf,le=Object.prototype;var ue=function e(t,r,n){if("string"!=typeof r){if(le){var i=ae(r);i&&i!==le&&e(t,i,n)}var o=ne(r);ie&&(o=o.concat(ie(r)));for(var a=te(t),l=te(r),u=0;u=0;n--){var i=t[n](e);if(i)return i}return function(t,n){throw new Error("Invalid value of type "+typeof e+" for "+r+" argument when connecting component "+n.wrappedComponentName+".")}}function Ne(e,t){return e===t}function Be(e){var t=void 0===e?{}:e,r=t.connectHOC,n=void 0===r?be:r,i=t.mapStateToPropsFactories,o=void 0===i?Ee:i,a=t.mapDispatchToPropsFactories,l=void 0===a?we:a,u=t.mergePropsFactories,c=void 0===u?Se:u,s=t.selectorFactory,d=void 0===s?Ae:s;return function(e,t,r,i){void 0===i&&(i={});var a=i,u=a.pure,s=void 0===u||u,p=a.areStatesEqual,f=void 0===p?Ne:p,g=a.areOwnPropsEqual,v=void 0===g?ye:g,m=a.areStatePropsEqual,b=void 0===m?ye:m,h=a.areMergedPropsEqual,y=void 0===h?ye:h,x=X(a,["pure","areStatesEqual","areOwnPropsEqual","areStatePropsEqual","areMergedPropsEqual"]),I=Re(e,o,"mapStateToProps"),D=Re(t,l,"mapDispatchToProps"),w=Re(r,c,"mergeProps");return n(d,J({methodName:"connect",getDisplayName:function(e){return"Connect("+e+")"},shouldHandleStateChanges:Boolean(e),initMapStateToProps:I,initMapDispatchToProps:D,initMergeProps:w,pure:s,areStatesEqual:f,areOwnPropsEqual:v,areStatePropsEqual:b,areMergedPropsEqual:y},x))}}var Te,Me=Be();function Le(e,r){var n=t.useState((function(){return{inputs:r,result:e()}}))[0],i=t.useRef(n),o=Boolean(r&&i.current.inputs&&function(e,t){if(e.length!==t.length)return!1;for(var r=0;re.bottom,l=n.lefte.right;return!(!a||!l)||(a&&o||l&&i)}},Ot=function(e){var t=St(e.top,e.bottom),r=St(e.left,e.right);return function(e){return t(e.top)&&t(e.bottom)&&r(e.left)&&r(e.right)}},At={direction:"vertical",line:"y",crossAxisLine:"x",start:"top",end:"bottom",size:"height",crossAxisStart:"left",crossAxisEnd:"right",crossAxisSize:"width"},Rt={direction:"horizontal",line:"x",crossAxisLine:"y",start:"left",end:"right",size:"width",crossAxisStart:"top",crossAxisEnd:"bottom",crossAxisSize:"height"},Nt=function(e){var t=e.target,r=e.destination,n=e.viewport,i=e.withDroppableDisplacement,o=e.isVisibleThroughFrameFn,a=i?function(e,t){var r=t.frame?t.frame.scroll.diff.displacement:Fe;return nt(e,r)}(t,r):t;return function(e,t,r){return!!t.subject.active&&r(t.subject.active)(e)}(a,r,o)&&function(e,t,r){return r(t)(e)}(a,n,o)},Bt=function(e){return Nt(l({},e,{isVisibleThroughFrameFn:Pt}))},Tt=function(e){return Nt(l({},e,{isVisibleThroughFrameFn:Ot}))};function Mt(e){var t=e.afterDragging,r=e.destination,n=e.displacedBy,i=e.viewport,o=e.forceShouldAnimate,a=e.last;return t.reduce((function(e,t){var l=function(e,t){var r=e.page.marginBox,n={top:t.point.y,right:0,bottom:0,left:t.point.x};return $e(Ye(r,n))}(t,n),u=t.descriptor.id;if(e.all.push(u),!Bt({target:l,destination:r,viewport:i,withDroppableDisplacement:!0}))return e.invisible[t.descriptor.id]=!0,e;var c={draggableId:u,shouldAnimate:function(e,t,r){if("boolean"==typeof r)return r;if(!t)return!0;var n=t.invisible,i=t.visible;if(n[e])return!1;var o=i[e];return!o||o.shouldAnimate}(u,a,o)};return e.visible[u]=c,e}),{all:[],visible:{},invisible:{}})}function Lt(e){var t=e.insideDestination,r=e.inHomeList,n=e.displacedBy,i=e.destination,o=function(e,t){if(!e.length)return 0;var r=e[e.length-1].descriptor.index;return t.inHomeList?r:r+1}(t,{inHomeList:r});return{displaced:Et,displacedBy:n,at:{type:"REORDER",destination:{droppableId:i.descriptor.id,index:o}}}}function Gt(e){var t=e.draggable,r=e.insideDestination,n=e.destination,i=e.viewport,o=e.displacedBy,a=e.last,l=e.index,u=e.forceShouldAnimate,c=Dt(t,n);if(null==l)return Lt({insideDestination:r,inHomeList:c,displacedBy:o,destination:n});var s=pt(r,(function(e){return e.descriptor.index===l}));if(!s)return Lt({insideDestination:r,inHomeList:c,displacedBy:o,destination:n});var d=It(t,r),p=r.indexOf(s);return{displaced:Mt({afterDragging:d.slice(p),destination:n,displacedBy:o,last:a,viewport:i.frame,forceShouldAnimate:u}),displacedBy:o,at:{type:"REORDER",destination:{droppableId:n.descriptor.id,index:l}}}}function _t(e,t){return Boolean(t.effected[e])}var Ft=function(e){var t=e.isMovingForward,r=e.isInHomeList,n=e.draggable,i=e.draggables,o=e.destination,a=e.insideDestination,l=e.previousImpact,u=e.viewport,c=e.afterCritical,d=l.at;if(d||s(!1),"REORDER"===d.type){var p=function(e){var t=e.isMovingForward,r=e.isInHomeList,n=e.insideDestination,i=e.location;if(!n.length)return null;var o=i.index,a=t?o+1:o-1,l=n[0].descriptor.index,u=n[n.length-1].descriptor.index;return a(r?u:u+1)?null:a}({isMovingForward:t,isInHomeList:r,location:d.destination,insideDestination:a});return null==p?null:Gt({draggable:n,insideDestination:a,destination:o,viewport:u,last:l.displaced,displacedBy:l.displacedBy,index:p})}var f=function(e){var t=e.isMovingForward,r=e.destination,n=e.draggables,i=e.combine,o=e.afterCritical;if(!r.isCombineEnabled)return null;var a=i.draggableId,l=n[a].descriptor.index;return _t(a,o)?t?l:l-1:t?l+1:l}({isMovingForward:t,destination:o,displaced:l.displaced,draggables:i,combine:d.combine,afterCritical:c});return null==f?null:Gt({draggable:n,insideDestination:a,destination:o,viewport:u,last:l.displaced,displacedBy:l.displacedBy,index:f})},jt=function(e){var t=e.afterCritical,r=e.impact,n=e.draggables,i=xt(r);i||s(!1);var o=i.draggableId,a=n[o].page.borderBox.center,l=function(e){var t=e.displaced,r=e.afterCritical,n=e.combineWith,i=e.displacedBy,o=Boolean(t.visible[n]||t.invisible[n]);return _t(n,r)?o?Fe:Ue(i.point):o?i.point:Fe}({displaced:r.displaced,afterCritical:t,combineWith:o,displacedBy:r.displacedBy});return je(a,l)},kt=function(e,t){return t.margin[e.start]+t.borderBox[e.size]/2},Wt=function(e,t,r){return t[e.crossAxisStart]+r.margin[e.crossAxisStart]+r.borderBox[e.crossAxisSize]/2},Ut=function(e){var t=e.axis,r=e.moveRelativeTo,n=e.isMoving;return He(t.line,r.marginBox[t.end]+kt(t,n),Wt(t,r.marginBox,n))},Ht=function(e){var t=e.axis,r=e.moveRelativeTo,n=e.isMoving;return He(t.line,r.marginBox[t.start]-function(e,t){return t.margin[e.end]+t.borderBox[e.size]/2}(t,n),Wt(t,r.marginBox,n))},qt=function(e){var t=e.impact,r=e.draggable,n=e.draggables,i=e.droppable,o=e.afterCritical,a=ht(i.descriptor.id,n),l=r.page,u=i.axis;if(!a.length)return function(e){var t=e.axis,r=e.moveInto,n=e.isMoving;return He(t.line,r.contentBox[t.start]+kt(t,n),Wt(t,r.contentBox,n))}({axis:u,moveInto:i.page,isMoving:l});var c=t.displaced,s=t.displacedBy,d=c.all[0];if(d){var p=n[d];if(_t(d,o))return Ht({axis:u,moveRelativeTo:p.page,isMoving:l});var f=Ze(p.page,s.point);return Ht({axis:u,moveRelativeTo:f,isMoving:l})}var g=a[a.length-1];if(g.descriptor.id===r.descriptor.id)return l.borderBox.center;if(_t(g.descriptor.id,o)){var v=Ze(g.page,Ue(o.displacedBy.point));return Ut({axis:u,moveRelativeTo:v,isMoving:l})}return Ut({axis:u,moveRelativeTo:g.page,isMoving:l})},Vt=function(e,t){var r=e.frame;return r?je(t,r.scroll.diff.displacement):t},zt=function(e){var t=function(e){var t=e.impact,r=e.draggable,n=e.droppable,i=e.draggables,o=e.afterCritical,a=r.page.borderBox.center,l=t.at;return n&&l?"REORDER"===l.type?qt({impact:t,draggable:r,draggables:i,droppable:n,afterCritical:o}):jt({impact:t,draggables:i,afterCritical:o}):a}(e),r=e.droppable;return r?Vt(r,t):t},$t=function(e,t){var r=ke(t,e.scroll.initial),n=Ue(r);return{frame:$e({top:t.y,bottom:t.y+e.frame.height,left:t.x,right:t.x+e.frame.width}),scroll:{initial:e.scroll.initial,max:e.scroll.max,current:t,diff:{value:r,displacement:n}}}};function Yt(e,t){return e.map((function(e){return t[e]}))}var Jt=function(e){var t=e.pageBorderBoxCenter,r=e.draggable,n=function(e,t){return je(e.scroll.diff.displacement,t)}(e.viewport,t),i=ke(n,r.page.borderBox.center);return je(r.client.borderBox.center,i)},Xt=function(e){var t=e.draggable,r=e.destination,n=e.newPageBorderBoxCenter,i=e.viewport,o=e.withDroppableDisplacement,a=e.onlyOnMainAxis,u=void 0!==a&&a,c=ke(n,t.page.borderBox.center),s={target:nt(t.page.borderBox,c),destination:r,withDroppableDisplacement:o,viewport:i};return u?function(e){return Nt(l({},e,{isVisibleThroughFrameFn:(t=e.destination.axis,function(e){var r=St(e.top,e.bottom),n=St(e.left,e.right);return function(e){return t===At?r(e.top)&&r(e.bottom):n(e.left)&&n(e.right)}})}));var t}(s):Tt(s)},Kt=function(e){var t=e.isMovingForward,r=e.draggable,n=e.destination,i=e.draggables,o=e.previousImpact,a=e.viewport,u=e.previousPageBorderBoxCenter,c=e.previousClientSelection,d=e.afterCritical;if(!n.isEnabled)return null;var p=ht(n.descriptor.id,i),f=Dt(r,n),g=function(e){var t=e.isMovingForward,r=e.draggable,n=e.destination,i=e.insideDestination,o=e.previousImpact;if(!n.isCombineEnabled)return null;if(!yt(o))return null;function a(e){var t={type:"COMBINE",combine:{draggableId:e,droppableId:n.descriptor.id}};return l({},o,{at:t})}var u=o.displaced.all,c=u.length?u[0]:null;if(t)return c?a(c):null;var d=It(r,i);if(!c)return d.length?a(d[d.length-1].descriptor.id):null;var p=dt(d,(function(e){return e.descriptor.id===c}));-1===p&&s(!1);var f=p-1;return f<0?null:a(d[f].descriptor.id)}({isMovingForward:t,draggable:r,destination:n,insideDestination:p,previousImpact:o})||Ft({isMovingForward:t,isInHomeList:f,draggable:r,draggables:i,destination:n,insideDestination:p,previousImpact:o,viewport:a,afterCritical:d});if(!g)return null;var v=zt({impact:g,draggable:r,droppable:n,draggables:i,afterCritical:d});if(Xt({draggable:r,destination:n,newPageBorderBoxCenter:v,viewport:a.frame,withDroppableDisplacement:!1,onlyOnMainAxis:!0}))return{clientSelection:Jt({pageBorderBoxCenter:v,draggable:r,viewport:a}),impact:g,scrollJumpRequest:null};var m=ke(v,u);return{clientSelection:c,impact:function(e){var t=e.impact,r=e.viewport,n=e.destination,i=e.draggables,o=e.maxScrollChange,a=$t(r,je(r.scroll.current,o)),u=n.frame?lt(n,je(n.frame.scroll.current,o)):n,c=t.displaced,s=Mt({afterDragging:Yt(c.all,i),destination:n,displacedBy:t.displacedBy,viewport:a.frame,last:c,forceShouldAnimate:!1}),d=Mt({afterDragging:Yt(c.all,i),destination:u,displacedBy:t.displacedBy,viewport:r.frame,last:c,forceShouldAnimate:!1}),p={},f={},g=[c,s,d];return c.all.forEach((function(e){var t=function(e,t){for(var r=0;r1?s.sort((function(e,t){return Qt(e)[l.start]-Qt(t)[l.start]}))[0]:c.sort((function(e,t){var n=Ve(r,it(Qt(e))),i=Ve(r,it(Qt(t)));return n!==i?n-i:Qt(e)[l.start]-Qt(t)[l.start]}))[0]}({isMovingForward:t,pageBorderBoxCenter:r,source:i,droppables:a,viewport:l});if(!c)return null;var s=ht(c.descriptor.id,o),d=function(e){var t=e.previousPageBorderBoxCenter,r=e.moveRelativeTo,n=e.insideDestination,i=e.draggable,o=e.draggables,a=e.destination,l=e.viewport,u=e.afterCritical;if(!r){if(n.length)return null;var c={displaced:Et,displacedBy:wt,at:{type:"REORDER",destination:{droppableId:a.descriptor.id,index:0}}},s=zt({impact:c,draggable:i,droppable:a,draggables:o,afterCritical:u}),d=Dt(i,a)?a:nr(a,i,o);return Xt({draggable:i,destination:d,newPageBorderBoxCenter:s,viewport:l.frame,withDroppableDisplacement:!1,onlyOnMainAxis:!0})?c:null}var p,f=Boolean(t[a.axis.line]<=r.page.borderBox.center[a.axis.line]),g=(p=r.descriptor.index,r.descriptor.id===i.descriptor.id?p:f?p:p+1),v=tr(a.axis,i.displaceBy);return Gt({draggable:i,insideDestination:n,destination:a,viewport:l,displacedBy:v,last:Et,index:g})}({previousPageBorderBoxCenter:r,destination:c,draggable:n,draggables:o,moveRelativeTo:function(e){var t=e.pageBorderBoxCenter,r=e.viewport,n=e.destination,i=e.insideDestination,o=e.afterCritical;return i.filter((function(e){return Tt({target:er(e,o),destination:n,viewport:r.frame,withDroppableDisplacement:!0})})).sort((function(e,r){var i=qe(t,Vt(n,Zt(e,o))),a=qe(t,Vt(n,Zt(r,o)));return in.left&&r.topn.top))return!1;if(ur(i)(t.center))return!0;var o=e.axis,a=i.center[o.crossAxisLine],l=t[o.crossAxisStart],u=t[o.crossAxisEnd],c=St(i[o.crossAxisStart],i[o.crossAxisEnd]),s=c(l),d=c(u);return!s&&!d||(s?la)}));return i.length?1===i.length?i[0].descriptor.id:function(e){var t=e.pageBorderBox,r=e.draggable,n=e.candidates,i=r.page.borderBox.center,o=n.map((function(e){var r=e.axis,n=He(e.axis.line,t.center[r.line],e.page.borderBox.center[r.crossAxisLine]);return{id:e.descriptor.id,distance:qe(i,n)}})).sort((function(e,t){return t.distance-e.distance}));return o[0]?o[0].id:null}({pageBorderBox:t,draggable:r,candidates:i}):null}var sr=function(e,t){return $e(nt(e,t))};function dr(e){var t=e.displaced,r=e.id;return Boolean(t.visible[r]||t.invisible[r])}var pr=function(e){var t=e.pageOffset,r=e.draggable,n=e.draggables,i=e.droppables,o=e.previousImpact,a=e.viewport,l=e.afterCritical,u=sr(r.page.borderBox,t),c=cr({pageBorderBox:u,draggable:r,droppables:i});if(!c)return Ct;var s=i[c],d=ht(s.descriptor.id,n),p=function(e,t){var r=e.frame;return r?sr(t,r.scroll.diff.value):t}(s,u);return function(e){var t=e.draggable,r=e.pageBorderBoxWithDroppableScroll,n=e.previousImpact,i=e.destination,o=e.insideDestination,a=e.afterCritical;if(!i.isCombineEnabled)return null;var l=i.axis,u=tr(i.axis,t.displaceBy),c=u.value,s=r[l.start],d=r[l.end],p=pt(It(t,o),(function(e){var t=e.descriptor.id,r=e.page.borderBox,i=r[l.size]/4,o=_t(t,a),u=dr({displaced:n.displaced,id:t});return o?u?d>r[l.start]+i&&dr[l.start]-c+i&&sr[l.start]+c+i&&dr[l.start]+i&&st.descriptor.index?r.descriptor.index-1:r.descriptor.index:null}({draggable:r,closest:pt(It(r,i),(function(e){var t=e.descriptor.id,r=e.page.borderBox.center[u.line],n=_t(t,l),i=dr({displaced:o,id:t});return n?i?p<=r:d=1500)return Yr;var o=$r+Jr*(i/1500);return Number(("CANCEL"===n?.6*o:o).toFixed(2))}({current:i.current.client.offset,destination:h,reason:o});r(function(e){return{type:"DROP_ANIMATE",payload:e}}({newHomeClientOffset:h,dropDuration:x,completed:y}))}else r(Gr({completed:y}))}}else r(function(e){return{type:"DROP_PENDING",payload:e}}({reason:o}))}else e(n)}}},Kr=function(e){var t=[],r=null,n=function(){for(var n=arguments.length,i=new Array(n),o=0;ot.startScrollingFrom)return 0;if(e<=t.maxScrollValueAt)return Sn;if(e===t.startScrollingFrom)return 1;var r=An({startOfRange:t.maxScrollValueAt,endOfRange:t.startScrollingFrom,current:e}),n=Sn*Pn(1-r);return Math.ceil(n)}(t,r);return 0===o?0:i?Math.max(function(e,t){var r=t,n=Nn,i=Date.now()-r;if(i>=Nn)return e;if(it.height,o=r.width>t.width;return o||i?o&&i?null:{x:o?0:n.x,y:i?0:n.y}:n}({container:r,subject:n,proposedScroll:c});return s?We(s,Fe)?null:s:null},Gn=ze((function(e){return 0===e?0:e>0?1:-1})),_n=(bn=function(e,t){return e<0?e:e>t?e-t:0},function(e){var t=e.current,r=e.max,n=e.change,i=je(t,n),o={x:bn(i.x,r.x),y:bn(i.y,r.y)};return We(o,Fe)?null:o}),Fn=function(e){var t=e.max,r=e.current,n=e.change,i={x:Math.max(r.x,t.x),y:Math.max(r.y,t.y)},o=Gn(n),a=_n({max:i,current:r,change:o});return!a||(0!==o.x&&0===a.x||0!==o.y&&0===a.y)},jn=function(e,t){return Fn({current:e.scroll.current,max:e.scroll.max,change:t})},kn=function(e,t){var r=e.frame;return!!r&&Fn({current:r.scroll.current,max:r.scroll.max,change:t})},Wn=function(e){var t=e.state,r=e.dragStartTime,n=e.shouldUseTimeDampening,i=e.scrollWindow,o=e.scrollDroppable,a=t.current.page.borderBoxCenter,l=t.dimensions.draggables[t.critical.draggable.id].page.marginBox;if(t.isWindowScrollAllowed){var u=function(e){var t=e.viewport,r=e.subject,n=e.center,i=e.dragStartTime,o=e.shouldUseTimeDampening,a=Ln({dragStartTime:i,container:t.frame,subject:r,center:n,shouldUseTimeDampening:o});return a&&jn(t,a)?a:null}({dragStartTime:r,viewport:t.viewport,subject:l,center:a,shouldUseTimeDampening:n});if(u)return void i(u)}var c=wn({center:a,destination:or(t.impact),droppables:t.dimensions.droppables});if(c){var s=function(e){var t=e.droppable,r=e.subject,n=e.center,i=e.dragStartTime,o=e.shouldUseTimeDampening,a=t.frame;if(!a)return null;var l=Ln({dragStartTime:i,container:a.pageMarginBox,subject:r,center:n,shouldUseTimeDampening:o});return l&&kn(t,l)?l:null}({dragStartTime:r,droppable:c,subject:l,center:a,shouldUseTimeDampening:n});s&&o(c.descriptor.id,s)}},Un=function(e){var t=e.move,r=e.scrollDroppable,n=e.scrollWindow,i=function(e,t){if(!kn(e,t))return t;var n=function(e,t){var r=e.frame;return r&&kn(e,t)?_n({current:r.scroll.current,max:r.scroll.max,change:t}):null}(e,t);if(!n)return r(e.descriptor.id,t),null;var i=ke(t,n);return r(e.descriptor.id,i),ke(t,i)},o=function(e,t,r){if(!e)return r;if(!jn(t,r))return r;var i=function(e,t){if(!jn(e,t))return null;var r=e.scroll.max,n=e.scroll.current;return _n({current:n,max:r,change:t})}(t,r);if(!i)return n(r),null;var o=ke(r,i);return n(o),ke(r,o)};return function(e){var r=e.scrollJumpRequest;if(r){var n=or(e.impact);n||s(!1);var a=i(e.dimensions.droppables[n],r);if(a){var l=e.viewport,u=o(e.isWindowScrollAllowed,l,a);u&&function(e,r){var n=je(e.current.client.selection,r);t({client:n})}(e,u)}}}},Hn=function(e){var t=e.scrollDroppable,r=e.scrollWindow,n=e.move,i=function(e){var t=e.scrollWindow,r=e.scrollDroppable,n=Kr(t),i=Kr(r),o=null,a=function(e){o||s(!1);var t=o,r=t.shouldUseTimeDampening,a=t.dragStartTime;Wn({state:e,scrollWindow:n,scrollDroppable:i,dragStartTime:a,shouldUseTimeDampening:r})};return{start:function(e){o&&s(!1);var t=Date.now(),r=!1,n=function(){r=!0};Wn({state:e,dragStartTime:0,shouldUseTimeDampening:!1,scrollWindow:n,scrollDroppable:n}),o={dragStartTime:t,shouldUseTimeDampening:r},r&&a(e)},stop:function(){o&&(n.cancel(),i.cancel(),o=null)},scroll:a}}({scrollWindow:r,scrollDroppable:t}),o=Un({move:n,scrollWindow:r,scrollDroppable:t});return{scroll:function(e){"DRAGGING"===e.phase&&("FLUID"!==e.movementMode?e.scrollJumpRequest&&o(e):i.scroll(e))},start:i.start,stop:i.stop}},qn={base:hn="data-rbd-drag-handle",draggableId:hn+"-draggable-id",contextId:hn+"-context-id"},Vn=function(){var e="data-rbd-draggable";return{base:e,contextId:e+"-context-id",id:e+"-id"}}(),zn=function(){var e="data-rbd-droppable";return{base:e,contextId:e+"-context-id",id:e+"-id"}}(),$n={contextId:"data-rbd-scroll-container-context-id"},Yn=function(e,t){return e.map((function(e){var r=e.styles[t];return r?e.selector+" { "+r+" }":""})).join(" ")},Jn="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?t.useLayoutEffect:t.useEffect,Xn=function(){var e=document.querySelector("head");return e||s(!1),e},Kn=function(e){var t=document.createElement("style");return e&&t.setAttribute("nonce",e),t.type="text/css",t};function Qn(e,r){var n=Ge((function(){return function(e){var t,r,n,i=(t=e,function(e){return"["+e+'="'+t+'"]'}),o=(r="\n cursor: -webkit-grab;\n cursor: grab;\n ",{selector:i(qn.contextId),styles:{always:"\n -webkit-touch-callout: none;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n touch-action: manipulation;\n ",resting:r,dragging:"pointer-events: none;",dropAnimating:r}}),a=[(n="\n transition: "+Hr.outOfTheWay+";\n ",{selector:i(Vn.contextId),styles:{dragging:n,dropAnimating:n,userCancel:n}}),o,{selector:i(zn.contextId),styles:{always:"overflow-anchor: none;"}},{selector:"body",styles:{dragging:"\n cursor: grabbing;\n cursor: -webkit-grabbing;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n overflow-anchor: none;\n "}}];return{always:Yn(a,"always"),resting:Yn(a,"resting"),dragging:Yn(a,"dragging"),dropAnimating:Yn(a,"dropAnimating"),userCancel:Yn(a,"userCancel")}}(e)}),[e]),i=t.useRef(null),o=t.useRef(null),a=_e(ct((function(e){var t=o.current;t||s(!1),t.textContent=e})),[]),l=_e((function(e){var t=i.current;t||s(!1),t.textContent=e}),[]);Jn((function(){(i.current||o.current)&&s(!1);var t=Kn(r),u=Kn(r);return i.current=t,o.current=u,t.setAttribute("data-rbd-always",e),u.setAttribute("data-rbd-dynamic",e),Xn().appendChild(t),Xn().appendChild(u),l(n.always),a(n.resting),function(){var e=function(e){var t=e.current;t||s(!1),Xn().removeChild(t),e.current=null};e(i),e(o)}}),[r,l,a,n.always,n.resting,e]);var u=_e((function(){return a(n.dragging)}),[a,n.dragging]),c=_e((function(e){a("DROP"!==e?n.userCancel:n.dropAnimating)}),[a,n.dropAnimating,n.userCancel]),d=_e((function(){o.current&&a(n.resting)}),[a,n.resting]);return Ge((function(){return{dragging:u,dropping:c,resting:d}}),[u,c,d])}var Zn=function(e){return e&&e.ownerDocument?e.ownerDocument.defaultView:window};function ei(e){return e instanceof Zn(e).HTMLElement}function ti(e){var r=t.useRef({}),n=t.useRef(null),i=t.useRef(null),o=t.useRef(!1),a=_e((function(e,t){var n={id:e,focus:t};return r.current[e]=n,function(){var t=r.current;t[e]!==n&&delete t[e]}}),[]),l=_e((function(t){var r=function(e,t){var r="["+qn.contextId+'="'+e+'"]',n=ft(document.querySelectorAll(r));if(!n.length)return null;var i=pt(n,(function(e){return e.getAttribute(qn.draggableId)===t}));return i&&ei(i)?i:null}(e,t);r&&r!==document.activeElement&&r.focus()}),[e]),u=_e((function(e,t){n.current===e&&(n.current=t)}),[]),c=_e((function(){i.current||o.current&&(i.current=requestAnimationFrame((function(){i.current=null;var e=n.current;e&&l(e)})))}),[l]),s=_e((function(e){n.current=null;var t=document.activeElement;t&&t.getAttribute(qn.draggableId)===e&&(n.current=e)}),[]);return Jn((function(){return o.current=!0,function(){o.current=!1;var e=i.current;e&&cancelAnimationFrame(e)}}),[]),Ge((function(){return{register:a,tryRecordFocus:s,tryRestoreFocusRecorded:c,tryShiftRecord:u}}),[a,s,c,u])}function ri(){var e={draggables:{},droppables:{}},t=[];function r(e){t.length&&t.forEach((function(t){return t(e)}))}function n(t){return e.draggables[t]||null}function i(t){return e.droppables[t]||null}return{draggable:{register:function(t){e.draggables[t.descriptor.id]=t,r({type:"ADDITION",value:t})},update:function(t,r){var n=e.draggables[r.descriptor.id];n&&n.uniqueId===t.uniqueId&&(delete e.draggables[r.descriptor.id],e.draggables[t.descriptor.id]=t)},unregister:function(t){var i=t.descriptor.id,o=n(i);o&&t.uniqueId===o.uniqueId&&(delete e.draggables[i],r({type:"REMOVAL",value:t}))},getById:function(e){var t=n(e);return t||s(!1),t},findById:n,exists:function(e){return Boolean(n(e))},getAllByType:function(t){return st(e.draggables).filter((function(e){return e.descriptor.type===t}))}},droppable:{register:function(t){e.droppables[t.descriptor.id]=t},unregister:function(t){var r=i(t.descriptor.id);r&&t.uniqueId===r.uniqueId&&delete e.droppables[t.descriptor.id]},getById:function(e){var t=i(e);return t||s(!1),t},findById:i,exists:function(e){return Boolean(i(e))},getAllByType:function(t){return st(e.droppables).filter((function(e){return e.descriptor.type===t}))}},subscribe:function(e){return t.push(e),function(){var r=t.indexOf(e);-1!==r&&t.splice(r,1)}},clean:function(){e.draggables={},e.droppables={},t.length=0}}}var ni=n.createContext(null),ii=function(){var e=document.body;return e||s(!1),e},oi={position:"absolute",width:"1px",height:"1px",margin:"-1px",border:"0",padding:"0",overflow:"hidden",clip:"rect(0 0 0 0)","clip-path":"inset(100%)"};var ai=0,li={separator:"::"};function ui(e,t){return void 0===t&&(t=li),Ge((function(){return""+e+t.separator+ai++}),[t.separator,e])}var ci=n.createContext(null);function si(e){var r=t.useRef(e);return t.useEffect((function(){r.current=e})),r}var di,pi=((di={})[13]=!0,di[9]=!0,di),fi=function(e){pi[e.keyCode]&&e.preventDefault()},gi=function(){var e="visibilitychange";return"undefined"==typeof document?e:pt([e,"ms"+e,"webkit"+e,"moz"+e,"o"+e],(function(e){return"on"+e in document}))||e}();var vi,mi={type:"IDLE"};function bi(e){var t=e.cancel,r=e.completed,n=e.getPhase,i=e.setPhase;return[{eventName:"mousemove",fn:function(e){var t=e.button,r=e.clientX,o=e.clientY;if(0===t){var a={x:r,y:o},l=n();if("DRAGGING"===l.type)return e.preventDefault(),void l.actions.move(a);"PENDING"!==l.type&&s(!1);var u=l.point;if(c=u,d=a,Math.abs(d.x-c.x)>=5||Math.abs(d.y-c.y)>=5){var c,d;e.preventDefault();var p=l.actions.fluidLift(a);i({type:"DRAGGING",actions:p})}}}},{eventName:"mouseup",fn:function(e){var i=n();"DRAGGING"===i.type?(e.preventDefault(),i.actions.drop({shouldBlockNextClick:!0}),r()):t()}},{eventName:"mousedown",fn:function(e){"DRAGGING"===n().type&&e.preventDefault(),t()}},{eventName:"keydown",fn:function(e){if("PENDING"!==n().type)return 27===e.keyCode?(e.preventDefault(),void t()):void fi(e);t()}},{eventName:"resize",fn:t},{eventName:"scroll",options:{passive:!0,capture:!1},fn:function(){"PENDING"===n().type&&t()}},{eventName:"webkitmouseforcedown",fn:function(e){var r=n();"IDLE"===r.type&&s(!1),r.actions.shouldRespectForcePress()?t():e.preventDefault()}},{eventName:gi,fn:t}]}function hi(e){var r=t.useRef(mi),n=t.useRef(a),i=Ge((function(){return{eventName:"mousedown",fn:function(t){if(!t.defaultPrevented&&0===t.button&&!(t.ctrlKey||t.metaKey||t.shiftKey||t.altKey)){var r=e.findClosestDraggableId(t);if(r){var i=e.tryGetLock(r,c,{sourceEvent:t});if(i){t.preventDefault();var o={x:t.clientX,y:t.clientY};n.current(),f(i,o)}}}}}}),[e]),o=Ge((function(){return{eventName:"webkitmouseforcewillbegin",fn:function(t){if(!t.defaultPrevented){var r=e.findClosestDraggableId(t);if(r){var n=e.findOptionsForDraggable(r);n&&(n.shouldRespectForcePress||e.canGetLock(r)&&t.preventDefault())}}}}}),[e]),l=_e((function(){n.current=u(window,[o,i],{passive:!1,capture:!0})}),[o,i]),c=_e((function(){"IDLE"!==r.current.type&&(r.current=mi,n.current(),l())}),[l]),d=_e((function(){var e=r.current;c(),"DRAGGING"===e.type&&e.actions.cancel({shouldBlockNextClick:!0}),"PENDING"===e.type&&e.actions.abort()}),[c]),p=_e((function(){var e=bi({cancel:d,completed:c,getPhase:function(){return r.current},setPhase:function(e){r.current=e}});n.current=u(window,e,{capture:!0,passive:!1})}),[d,c]),f=_e((function(e,t){"IDLE"!==r.current.type&&s(!1),r.current={type:"PENDING",point:t,actions:e},p()}),[p]);Jn((function(){return l(),function(){n.current()}}),[l])}function yi(){}var xi=((vi={})[34]=!0,vi[33]=!0,vi[36]=!0,vi[35]=!0,vi);function Ii(e,t){function r(){t(),e.cancel()}return[{eventName:"keydown",fn:function(n){return 27===n.keyCode?(n.preventDefault(),void r()):32===n.keyCode?(n.preventDefault(),t(),void e.drop()):40===n.keyCode?(n.preventDefault(),void e.moveDown()):38===n.keyCode?(n.preventDefault(),void e.moveUp()):39===n.keyCode?(n.preventDefault(),void e.moveRight()):37===n.keyCode?(n.preventDefault(),void e.moveLeft()):void(xi[n.keyCode]?n.preventDefault():fi(n))}},{eventName:"mousedown",fn:r},{eventName:"mouseup",fn:r},{eventName:"click",fn:r},{eventName:"touchstart",fn:r},{eventName:"resize",fn:r},{eventName:"wheel",fn:r,options:{passive:!0}},{eventName:gi,fn:r}]}function Di(e){var r=t.useRef(yi),n=Ge((function(){return{eventName:"keydown",fn:function(t){if(!t.defaultPrevented&&32===t.keyCode){var n=e.findClosestDraggableId(t);if(n){var o=e.tryGetLock(n,c,{sourceEvent:t});if(o){t.preventDefault();var a=!0,l=o.snapLift();r.current(),r.current=u(window,Ii(l,c),{capture:!0,passive:!1})}}}function c(){a||s(!1),a=!1,r.current(),i()}}}}),[e]),i=_e((function(){r.current=u(window,[n],{passive:!1,capture:!0})}),[n]);Jn((function(){return i(),function(){r.current()}}),[i])}var wi={type:"IDLE"};function Ei(e){var r=t.useRef(wi),n=t.useRef(a),i=_e((function(){return r.current}),[]),o=_e((function(e){r.current=e}),[]),l=Ge((function(){return{eventName:"touchstart",fn:function(t){if(!t.defaultPrevented){var r=e.findClosestDraggableId(t);if(r){var i=e.tryGetLock(r,d,{sourceEvent:t});if(i){var o=t.touches[0],a={x:o.clientX,y:o.clientY};n.current(),v(i,a)}}}}}}),[e]),c=_e((function(){n.current=u(window,[l],{capture:!0,passive:!1})}),[l]),d=_e((function(){var e=r.current;"IDLE"!==e.type&&("PENDING"===e.type&&clearTimeout(e.longPressTimerId),o(wi),n.current(),c())}),[c,o]),p=_e((function(){var e=r.current;d(),"DRAGGING"===e.type&&e.actions.cancel({shouldBlockNextClick:!0}),"PENDING"===e.type&&e.actions.abort()}),[d]),f=_e((function(){var e={capture:!0,passive:!1},t={cancel:p,completed:d,getPhase:i},r=u(window,function(e){var t=e.cancel,r=e.completed,n=e.getPhase;return[{eventName:"touchmove",options:{capture:!1},fn:function(e){var r=n();if("DRAGGING"===r.type){r.hasMoved=!0;var i=e.touches[0],o={x:i.clientX,y:i.clientY};e.preventDefault(),r.actions.move(o)}else t()}},{eventName:"touchend",fn:function(e){var i=n();"DRAGGING"===i.type?(e.preventDefault(),i.actions.drop({shouldBlockNextClick:!0}),r()):t()}},{eventName:"touchcancel",fn:function(e){"DRAGGING"===n().type?(e.preventDefault(),t()):t()}},{eventName:"touchforcechange",fn:function(e){var r=n();"IDLE"===r.type&&s(!1);var i=e.touches[0];if(i&&i.force>=.15){var o=r.actions.shouldRespectForcePress();if("PENDING"!==r.type)return o?r.hasMoved?void e.preventDefault():void t():void e.preventDefault();o&&t()}}},{eventName:gi,fn:t}]}(t),e),o=u(window,function(e){var t=e.cancel,r=e.getPhase;return[{eventName:"orientationchange",fn:t},{eventName:"resize",fn:t},{eventName:"contextmenu",fn:function(e){e.preventDefault()}},{eventName:"keydown",fn:function(e){"DRAGGING"===r().type?(27===e.keyCode&&e.preventDefault(),t()):t()}},{eventName:gi,fn:t}]}(t),e);n.current=function(){r(),o()}}),[p,i,d]),g=_e((function(){var e=i();"PENDING"!==e.type&&s(!1);var t=e.actions.fluidLift(e.point);o({type:"DRAGGING",actions:t,hasMoved:!1})}),[i,o]),v=_e((function(e,t){"IDLE"!==i().type&&s(!1);var r=setTimeout(g,120);o({type:"PENDING",point:t,actions:e,longPressTimerId:r}),f()}),[f,i,o,g]);Jn((function(){return c(),function(){n.current();var e=i();"PENDING"===e.type&&(clearTimeout(e.longPressTimerId),o(wi))}}),[i,c,o]),Jn((function(){return u(window,[{eventName:"touchmove",fn:function(){},options:{capture:!1,passive:!1}}])}),[])}var Ci={input:!0,button:!0,textarea:!0,select:!0,option:!0,optgroup:!0,video:!0,audio:!0};function Si(e,t){var r=t.target;return!!ei(r)&&function e(t,r){if(null==r)return!1;if(Boolean(Ci[r.tagName.toLowerCase()]))return!0;var n=r.getAttribute("contenteditable");return"true"===n||""===n||r!==t&&e(t,r.parentElement)}(e,r)}var Pi=function(e){return $e(e.getBoundingClientRect()).center};var Oi="undefined"==typeof document?"matches":pt(["matches","msMatchesSelector","webkitMatchesSelector"],(function(e){return e in Element.prototype}))||"matches";function Ai(e,t){return e.closest?e.closest(t):function e(t,r){return null==t?null:t[Oi](r)?t:e(t.parentElement,r)}(e,t)}function Ri(e,t){var r,n=t.target;if(!((r=n)instanceof Zn(r).Element))return null;var i=Ai(n,function(e){return"["+qn.contextId+'="'+e+'"]'}(e));return i&&ei(i)?i:null}function Ni(e){e.preventDefault()}function Bi(e){var t=e.expected,r=e.phase,n=e.isLockActive;e.shouldWarn;return!!n()&&t===r}function Ti(e){var t=e.lockAPI,r=e.store,n=e.registry,i=e.draggableId;if(t.isClaimed())return!1;var o=n.draggable.findById(i);return!!o&&(!!o.options.isEnabled&&!!xn(r.getState(),i))}function Mi(e){var t=e.lockAPI,r=e.contextId,n=e.store,i=e.registry,o=e.draggableId,c=e.forceSensorStop,d=e.sourceEvent;if(!Ti({lockAPI:t,store:n,registry:i,draggableId:o}))return null;var p=i.draggable.getById(o),f=function(e,t){var r="["+Vn.contextId+'="'+e+'"]',n=pt(ft(document.querySelectorAll(r)),(function(e){return e.getAttribute(Vn.id)===t}));return n&&ei(n)?n:null}(r,p.descriptor.id);if(!f)return null;if(d&&!p.options.canDragInteractiveElements&&Si(f,d))return null;var g=t.claim(c||a),v="PRE_DRAG";function m(){return p.options.shouldRespectForcePress}function b(){return t.isActive(g)}var h=function(e,t){Bi({expected:e,phase:v,isLockActive:b,shouldWarn:!0})&&n.dispatch(t())}.bind(null,"DRAGGING");function y(e){function r(){t.release(),v="COMPLETED"}function i(t,i){if(void 0===i&&(i={shouldBlockNextClick:!1}),e.cleanup(),i.shouldBlockNextClick){var o=u(window,[{eventName:"click",fn:Ni,options:{once:!0,passive:!1,capture:!0}}]);setTimeout(o)}r(),n.dispatch(_r({reason:t}))}return"PRE_DRAG"!==v&&(r(),"PRE_DRAG"!==v&&s(!1)),n.dispatch(function(e){return{type:"LIFT",payload:e}}(e.liftActionArgs)),v="DRAGGING",l({isActive:function(){return Bi({expected:"DRAGGING",phase:v,isLockActive:b,shouldWarn:!1})},shouldRespectForcePress:m,drop:function(e){return i("DROP",e)},cancel:function(e){return i("CANCEL",e)}},e.actions)}return{isActive:function(){return Bi({expected:"PRE_DRAG",phase:v,isLockActive:b,shouldWarn:!1})},shouldRespectForcePress:m,fluidLift:function(e){var t=Kr((function(e){h((function(){return Nr({client:e})}))}));return l({},y({liftActionArgs:{id:o,clientSelection:e,movementMode:"FLUID"},cleanup:function(){return t.cancel()},actions:{move:t}}),{move:t})},snapLift:function(){var e={moveUp:function(){return h(Br)},moveRight:function(){return h(Mr)},moveDown:function(){return h(Tr)},moveLeft:function(){return h(Lr)}};return y({liftActionArgs:{id:o,clientSelection:Pi(f),movementMode:"SNAP"},cleanup:a,actions:e})},abort:function(){Bi({expected:"PRE_DRAG",phase:v,isLockActive:b,shouldWarn:!0})&&t.release()}}}var Li=[hi,Di,Ei];function Gi(e){var r=e.contextId,n=e.store,i=e.registry,o=e.customSensors,a=e.enableDefaultSensors,l=[].concat(a?Li:[],o||[]),u=t.useState((function(){return function(){var e=null;function t(){e||s(!1),e=null}return{isClaimed:function(){return Boolean(e)},isActive:function(t){return t===e},claim:function(t){e&&s(!1);var r={abandon:t};return e=r,r},release:t,tryAbandon:function(){e&&(e.abandon(),t())}}}()}))[0],c=_e((function(e,t){e.isDragging&&!t.isDragging&&u.tryAbandon()}),[u]);Jn((function(){var e=n.getState();return n.subscribe((function(){var t=n.getState();c(e,t),e=t}))}),[u,n,c]),Jn((function(){return u.tryAbandon}),[u.tryAbandon]);for(var d=_e((function(e){return Ti({lockAPI:u,registry:i,store:n,draggableId:e})}),[u,i,n]),p=_e((function(e,t,o){return Mi({lockAPI:u,registry:i,contextId:r,store:n,draggableId:e,forceSensorStop:t,sourceEvent:o&&o.sourceEvent?o.sourceEvent:null})}),[r,u,i,n]),f=_e((function(e){return function(e,t){var r=Ri(e,t);return r?r.getAttribute(qn.draggableId):null}(r,e)}),[r]),g=_e((function(e){var t=i.draggable.findById(e);return t?t.options:null}),[i.draggable]),v=_e((function(){u.isClaimed()&&(u.tryAbandon(),"IDLE"!==n.getState().phase&&n.dispatch({type:"FLUSH",payload:null}))}),[u,n]),m=_e(u.isClaimed,[u]),b=Ge((function(){return{canGetLock:d,tryGetLock:p,findClosestDraggableId:f,findOptionsForDraggable:g,tryReleaseLock:v,isLockClaimed:m}}),[d,p,f,g,v,m]),h=0;h");return t.callbacks},t.setCallbacks=function(e){t.callbacks=e},t}o(t,e);var r=t.prototype;return r.componentDidMount=function(){this.unbind=u(window,[{eventName:"error",fn:this.onWindowError}])},r.componentDidCatch=function(e){if(!(e instanceof c))throw e;this.setState({})},r.componentWillUnmount=function(){this.unbind()},r.render=function(){return this.props.children(this.setCallbacks)},t}(n.Component),p=function(e){return e+1},f=function(e,t){var r=e.droppableId===t.droppableId,n=p(e.index),i=p(t.index);return r?"\n You have moved the item from position "+n+"\n to position "+i+"\n ":"\n You have moved the item from position "+n+"\n in list "+e.droppableId+"\n to list "+t.droppableId+"\n in position "+i+"\n "},g=function(e,t,r){return t.droppableId===r.droppableId?"\n The item "+e+"\n has been combined with "+r.draggableId:"\n The item "+e+"\n in list "+t.droppableId+"\n has been combined with "+r.draggableId+"\n in list "+r.droppableId+"\n "},v=function(e){return"\n The item has returned to its starting position\n of "+p(e.index)+"\n"},m="\n Press space bar to start a drag.\n When dragging you can use the arrow keys to move the item around and escape to cancel.\n Some screen readers may require you to be in focus mode or to use your pass through key\n",b=function(e){return"\n You have lifted an item in position "+p(e.source.index)+"\n"},h=function(e){var t=e.destination;if(t)return f(e.source,t);var r=e.combine;return r?g(e.draggableId,e.source,r):"You are over an area that cannot be dropped on"},y=function(e){if("CANCEL"===e.reason)return"\n Movement cancelled.\n "+v(e.source)+"\n ";var t=e.destination,r=e.combine;return t?"\n You have dropped the item.\n "+f(e.source,t)+"\n ":r?"\n You have dropped the item.\n "+g(e.draggableId,e.source,r)+"\n ":"\n The item has been dropped while not over a drop area.\n "+v(e.source)+"\n "};var x=function(e){var t,r=e.Symbol;return"function"==typeof r?r.observable?t=r.observable:(t=r("observable"),r.observable=t):t="@@observable",t}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof module?module:Function("return this")()),I=function(){return Math.random().toString(36).substring(7).split("").join(".")},D={INIT:"@@redux/INIT"+I(),REPLACE:"@@redux/REPLACE"+I(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+I()}};function w(e){if("object"!=typeof e||null===e)return!1;for(var t=e;null!==Object.getPrototypeOf(t);)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function E(e,t,r){var n;if("function"==typeof t&&"function"==typeof r||"function"==typeof r&&"function"==typeof arguments[3])throw new Error("It looks like you are passing several store enhancers to createStore(). This is not supported. Instead, compose them together to a single function.");if("function"==typeof t&&void 0===r&&(r=t,t=void 0),void 0!==r){if("function"!=typeof r)throw new Error("Expected the enhancer to be a function.");return r(E)(e,t)}if("function"!=typeof e)throw new Error("Expected the reducer to be a function.");var i=e,o=t,a=[],l=a,u=!1;function c(){l===a&&(l=a.slice())}function s(){if(u)throw new Error("You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.");return o}function d(e){if("function"!=typeof e)throw new Error("Expected the listener to be a function.");if(u)throw new Error("You may not call store.subscribe() while the reducer is executing. If you would like to be notified after the store has been updated, subscribe from a component and invoke store.getState() in the callback to access the latest state. See https://redux.js.org/api-reference/store#subscribelistener for more details.");var t=!0;return c(),l.push(e),function(){if(t){if(u)throw new Error("You may not unsubscribe from a store listener while the reducer is executing. See https://redux.js.org/api-reference/store#subscribelistener for more details.");t=!1,c();var r=l.indexOf(e);l.splice(r,1),a=null}}}function p(e){if(!w(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if(void 0===e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(u)throw new Error("Reducers may not dispatch actions.");try{u=!0,o=i(o,e)}finally{u=!1}for(var t=a=l,r=0;r=0||(i[r]=e[r]);return i}var K={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},Q={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},Z={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},ee={};function te(e){return L.isMemo(e)?Z:ee[e.$$typeof]||K}ee[L.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},ee[L.Memo]=Z;var re=Object.defineProperty,ne=Object.getOwnPropertyNames,ie=Object.getOwnPropertySymbols,oe=Object.getOwnPropertyDescriptor,ae=Object.getPrototypeOf,le=Object.prototype;var ue=function e(t,r,n){if("string"!=typeof r){if(le){var i=ae(r);i&&i!==le&&e(t,i,n)}var o=ne(r);ie&&(o=o.concat(ie(r)));for(var a=te(t),l=te(r),u=0;u=0;n--){var i=t[n](e);if(i)return i}return function(t,n){throw new Error("Invalid value of type "+typeof e+" for "+r+" argument when connecting component "+n.wrappedComponentName+".")}}function Ne(e,t){return e===t}function Be(e){var t=void 0===e?{}:e,r=t.connectHOC,n=void 0===r?be:r,i=t.mapStateToPropsFactories,o=void 0===i?Ee:i,a=t.mapDispatchToPropsFactories,l=void 0===a?we:a,u=t.mergePropsFactories,c=void 0===u?Se:u,s=t.selectorFactory,d=void 0===s?Ae:s;return function(e,t,r,i){void 0===i&&(i={});var a=i,u=a.pure,s=void 0===u||u,p=a.areStatesEqual,f=void 0===p?Ne:p,g=a.areOwnPropsEqual,v=void 0===g?ye:g,m=a.areStatePropsEqual,b=void 0===m?ye:m,h=a.areMergedPropsEqual,y=void 0===h?ye:h,x=X(a,["pure","areStatesEqual","areOwnPropsEqual","areStatePropsEqual","areMergedPropsEqual"]),I=Re(e,o,"mapStateToProps"),D=Re(t,l,"mapDispatchToProps"),w=Re(r,c,"mergeProps");return n(d,J({methodName:"connect",getDisplayName:function(e){return"Connect("+e+")"},shouldHandleStateChanges:Boolean(e),initMapStateToProps:I,initMapDispatchToProps:D,initMergeProps:w,pure:s,areStatesEqual:f,areOwnPropsEqual:v,areStatePropsEqual:b,areMergedPropsEqual:y},x))}}var Te,Me=Be();function Le(e,r){var n=t.useState((function(){return{inputs:r,result:e()}}))[0],i=t.useRef(n),o=Boolean(r&&i.current.inputs&&function(e,t){if(e.length!==t.length)return!1;for(var r=0;re.bottom,l=n.lefte.right;return!(!a||!l)||(a&&o||l&&i)}},Ot=function(e){var t=St(e.top,e.bottom),r=St(e.left,e.right);return function(e){return t(e.top)&&t(e.bottom)&&r(e.left)&&r(e.right)}},At={direction:"vertical",line:"y",crossAxisLine:"x",start:"top",end:"bottom",size:"height",crossAxisStart:"left",crossAxisEnd:"right",crossAxisSize:"width"},Rt={direction:"horizontal",line:"x",crossAxisLine:"y",start:"left",end:"right",size:"width",crossAxisStart:"top",crossAxisEnd:"bottom",crossAxisSize:"height"},Nt=function(e){var t=e.target,r=e.destination,n=e.viewport,i=e.withDroppableDisplacement,o=e.isVisibleThroughFrameFn,a=i?function(e,t){var r=t.frame?t.frame.scroll.diff.displacement:Fe;return nt(e,r)}(t,r):t;return function(e,t,r){return!!t.subject.active&&r(t.subject.active)(e)}(a,r,o)&&function(e,t,r){return r(t)(e)}(a,n,o)},Bt=function(e){return Nt(l({},e,{isVisibleThroughFrameFn:Pt}))},Tt=function(e){return Nt(l({},e,{isVisibleThroughFrameFn:Ot}))};function Mt(e){var t=e.afterDragging,r=e.destination,n=e.displacedBy,i=e.viewport,o=e.forceShouldAnimate,a=e.last;return t.reduce((function(e,t){var l=function(e,t){var r=e.page.marginBox,n={top:t.point.y,right:0,bottom:0,left:t.point.x};return $e(Ye(r,n))}(t,n),u=t.descriptor.id;if(e.all.push(u),!Bt({target:l,destination:r,viewport:i,withDroppableDisplacement:!0}))return e.invisible[t.descriptor.id]=!0,e;var c={draggableId:u,shouldAnimate:function(e,t,r){if("boolean"==typeof r)return r;if(!t)return!0;var n=t.invisible,i=t.visible;if(n[e])return!1;var o=i[e];return!o||o.shouldAnimate}(u,a,o)};return e.visible[u]=c,e}),{all:[],visible:{},invisible:{}})}function Lt(e){var t=e.insideDestination,r=e.inHomeList,n=e.displacedBy,i=e.destination,o=function(e,t){if(!e.length)return 0;var r=e[e.length-1].descriptor.index;return t.inHomeList?r:r+1}(t,{inHomeList:r});return{displaced:Et,displacedBy:n,at:{type:"REORDER",destination:{droppableId:i.descriptor.id,index:o}}}}function Gt(e){var t=e.draggable,r=e.insideDestination,n=e.destination,i=e.viewport,o=e.displacedBy,a=e.last,l=e.index,u=e.forceShouldAnimate,c=Dt(t,n);if(null==l)return Lt({insideDestination:r,inHomeList:c,displacedBy:o,destination:n});var s=pt(r,(function(e){return e.descriptor.index===l}));if(!s)return Lt({insideDestination:r,inHomeList:c,displacedBy:o,destination:n});var d=It(t,r),p=r.indexOf(s);return{displaced:Mt({afterDragging:d.slice(p),destination:n,displacedBy:o,last:a,viewport:i.frame,forceShouldAnimate:u}),displacedBy:o,at:{type:"REORDER",destination:{droppableId:n.descriptor.id,index:l}}}}function _t(e,t){return Boolean(t.effected[e])}var Ft=function(e){var t=e.isMovingForward,r=e.isInHomeList,n=e.draggable,i=e.draggables,o=e.destination,a=e.insideDestination,l=e.previousImpact,u=e.viewport,c=e.afterCritical,d=l.at;if(d||s(!1),"REORDER"===d.type){var p=function(e){var t=e.isMovingForward,r=e.isInHomeList,n=e.insideDestination,i=e.location;if(!n.length)return null;var o=i.index,a=t?o+1:o-1,l=n[0].descriptor.index,u=n[n.length-1].descriptor.index;return a(r?u:u+1)?null:a}({isMovingForward:t,isInHomeList:r,location:d.destination,insideDestination:a});return null==p?null:Gt({draggable:n,insideDestination:a,destination:o,viewport:u,last:l.displaced,displacedBy:l.displacedBy,index:p})}var f=function(e){var t=e.isMovingForward,r=e.destination,n=e.draggables,i=e.combine,o=e.afterCritical;if(!r.isCombineEnabled)return null;var a=i.draggableId,l=n[a].descriptor.index;return _t(a,o)?t?l:l-1:t?l+1:l}({isMovingForward:t,destination:o,displaced:l.displaced,draggables:i,combine:d.combine,afterCritical:c});return null==f?null:Gt({draggable:n,insideDestination:a,destination:o,viewport:u,last:l.displaced,displacedBy:l.displacedBy,index:f})},jt=function(e){var t=e.afterCritical,r=e.impact,n=e.draggables,i=xt(r);i||s(!1);var o=i.draggableId,a=n[o].page.borderBox.center,l=function(e){var t=e.displaced,r=e.afterCritical,n=e.combineWith,i=e.displacedBy,o=Boolean(t.visible[n]||t.invisible[n]);return _t(n,r)?o?Fe:Ue(i.point):o?i.point:Fe}({displaced:r.displaced,afterCritical:t,combineWith:o,displacedBy:r.displacedBy});return je(a,l)},kt=function(e,t){return t.margin[e.start]+t.borderBox[e.size]/2},Wt=function(e,t,r){return t[e.crossAxisStart]+r.margin[e.crossAxisStart]+r.borderBox[e.crossAxisSize]/2},Ut=function(e){var t=e.axis,r=e.moveRelativeTo,n=e.isMoving;return He(t.line,r.marginBox[t.end]+kt(t,n),Wt(t,r.marginBox,n))},Ht=function(e){var t=e.axis,r=e.moveRelativeTo,n=e.isMoving;return He(t.line,r.marginBox[t.start]-function(e,t){return t.margin[e.end]+t.borderBox[e.size]/2}(t,n),Wt(t,r.marginBox,n))},qt=function(e){var t=e.impact,r=e.draggable,n=e.draggables,i=e.droppable,o=e.afterCritical,a=ht(i.descriptor.id,n),l=r.page,u=i.axis;if(!a.length)return function(e){var t=e.axis,r=e.moveInto,n=e.isMoving;return He(t.line,r.contentBox[t.start]+kt(t,n),Wt(t,r.contentBox,n))}({axis:u,moveInto:i.page,isMoving:l});var c=t.displaced,s=t.displacedBy,d=c.all[0];if(d){var p=n[d];if(_t(d,o))return Ht({axis:u,moveRelativeTo:p.page,isMoving:l});var f=Ze(p.page,s.point);return Ht({axis:u,moveRelativeTo:f,isMoving:l})}var g=a[a.length-1];if(g.descriptor.id===r.descriptor.id)return l.borderBox.center;if(_t(g.descriptor.id,o)){var v=Ze(g.page,Ue(o.displacedBy.point));return Ut({axis:u,moveRelativeTo:v,isMoving:l})}return Ut({axis:u,moveRelativeTo:g.page,isMoving:l})},Vt=function(e,t){var r=e.frame;return r?je(t,r.scroll.diff.displacement):t},zt=function(e){var t=function(e){var t=e.impact,r=e.draggable,n=e.droppable,i=e.draggables,o=e.afterCritical,a=r.page.borderBox.center,l=t.at;return n&&l?"REORDER"===l.type?qt({impact:t,draggable:r,draggables:i,droppable:n,afterCritical:o}):jt({impact:t,draggables:i,afterCritical:o}):a}(e),r=e.droppable;return r?Vt(r,t):t},$t=function(e,t){var r=ke(t,e.scroll.initial),n=Ue(r);return{frame:$e({top:t.y,bottom:t.y+e.frame.height,left:t.x,right:t.x+e.frame.width}),scroll:{initial:e.scroll.initial,max:e.scroll.max,current:t,diff:{value:r,displacement:n}}}};function Yt(e,t){return e.map((function(e){return t[e]}))}var Jt=function(e){var t=e.pageBorderBoxCenter,r=e.draggable,n=function(e,t){return je(e.scroll.diff.displacement,t)}(e.viewport,t),i=ke(n,r.page.borderBox.center);return je(r.client.borderBox.center,i)},Xt=function(e){var t=e.draggable,r=e.destination,n=e.newPageBorderBoxCenter,i=e.viewport,o=e.withDroppableDisplacement,a=e.onlyOnMainAxis,u=void 0!==a&&a,c=ke(n,t.page.borderBox.center),s={target:nt(t.page.borderBox,c),destination:r,withDroppableDisplacement:o,viewport:i};return u?function(e){return Nt(l({},e,{isVisibleThroughFrameFn:(t=e.destination.axis,function(e){var r=St(e.top,e.bottom),n=St(e.left,e.right);return function(e){return t===At?r(e.top)&&r(e.bottom):n(e.left)&&n(e.right)}})}));var t}(s):Tt(s)},Kt=function(e){var t=e.isMovingForward,r=e.draggable,n=e.destination,i=e.draggables,o=e.previousImpact,a=e.viewport,u=e.previousPageBorderBoxCenter,c=e.previousClientSelection,d=e.afterCritical;if(!n.isEnabled)return null;var p=ht(n.descriptor.id,i),f=Dt(r,n),g=function(e){var t=e.isMovingForward,r=e.draggable,n=e.destination,i=e.insideDestination,o=e.previousImpact;if(!n.isCombineEnabled)return null;if(!yt(o))return null;function a(e){var t={type:"COMBINE",combine:{draggableId:e,droppableId:n.descriptor.id}};return l({},o,{at:t})}var u=o.displaced.all,c=u.length?u[0]:null;if(t)return c?a(c):null;var d=It(r,i);if(!c)return d.length?a(d[d.length-1].descriptor.id):null;var p=dt(d,(function(e){return e.descriptor.id===c}));-1===p&&s(!1);var f=p-1;return f<0?null:a(d[f].descriptor.id)}({isMovingForward:t,draggable:r,destination:n,insideDestination:p,previousImpact:o})||Ft({isMovingForward:t,isInHomeList:f,draggable:r,draggables:i,destination:n,insideDestination:p,previousImpact:o,viewport:a,afterCritical:d});if(!g)return null;var v=zt({impact:g,draggable:r,droppable:n,draggables:i,afterCritical:d});if(Xt({draggable:r,destination:n,newPageBorderBoxCenter:v,viewport:a.frame,withDroppableDisplacement:!1,onlyOnMainAxis:!0}))return{clientSelection:Jt({pageBorderBoxCenter:v,draggable:r,viewport:a}),impact:g,scrollJumpRequest:null};var m=ke(v,u);return{clientSelection:c,impact:function(e){var t=e.impact,r=e.viewport,n=e.destination,i=e.draggables,o=e.maxScrollChange,a=$t(r,je(r.scroll.current,o)),u=n.frame?lt(n,je(n.frame.scroll.current,o)):n,c=t.displaced,s=Mt({afterDragging:Yt(c.all,i),destination:n,displacedBy:t.displacedBy,viewport:a.frame,last:c,forceShouldAnimate:!1}),d=Mt({afterDragging:Yt(c.all,i),destination:u,displacedBy:t.displacedBy,viewport:r.frame,last:c,forceShouldAnimate:!1}),p={},f={},g=[c,s,d];return c.all.forEach((function(e){var t=function(e,t){for(var r=0;r1?s.sort((function(e,t){return Qt(e)[l.start]-Qt(t)[l.start]}))[0]:c.sort((function(e,t){var n=Ve(r,it(Qt(e))),i=Ve(r,it(Qt(t)));return n!==i?n-i:Qt(e)[l.start]-Qt(t)[l.start]}))[0]}({isMovingForward:t,pageBorderBoxCenter:r,source:i,droppables:a,viewport:l});if(!c)return null;var s=ht(c.descriptor.id,o),d=function(e){var t=e.previousPageBorderBoxCenter,r=e.moveRelativeTo,n=e.insideDestination,i=e.draggable,o=e.draggables,a=e.destination,l=e.viewport,u=e.afterCritical;if(!r){if(n.length)return null;var c={displaced:Et,displacedBy:wt,at:{type:"REORDER",destination:{droppableId:a.descriptor.id,index:0}}},s=zt({impact:c,draggable:i,droppable:a,draggables:o,afterCritical:u}),d=Dt(i,a)?a:nr(a,i,o);return Xt({draggable:i,destination:d,newPageBorderBoxCenter:s,viewport:l.frame,withDroppableDisplacement:!1,onlyOnMainAxis:!0})?c:null}var p,f=Boolean(t[a.axis.line]<=r.page.borderBox.center[a.axis.line]),g=(p=r.descriptor.index,r.descriptor.id===i.descriptor.id?p:f?p:p+1),v=tr(a.axis,i.displaceBy);return Gt({draggable:i,insideDestination:n,destination:a,viewport:l,displacedBy:v,last:Et,index:g})}({previousPageBorderBoxCenter:r,destination:c,draggable:n,draggables:o,moveRelativeTo:function(e){var t=e.pageBorderBoxCenter,r=e.viewport,n=e.destination,i=e.insideDestination,o=e.afterCritical;return i.filter((function(e){return Tt({target:er(e,o),destination:n,viewport:r.frame,withDroppableDisplacement:!0})})).sort((function(e,r){var i=qe(t,Vt(n,Zt(e,o))),a=qe(t,Vt(n,Zt(r,o)));return in.left&&r.topn.top))return!1;if(ur(i)(t.center))return!0;var o=e.axis,a=i.center[o.crossAxisLine],l=t[o.crossAxisStart],u=t[o.crossAxisEnd],c=St(i[o.crossAxisStart],i[o.crossAxisEnd]),s=c(l),d=c(u);return!s&&!d||(s?la)}));return i.length?1===i.length?i[0].descriptor.id:function(e){var t=e.pageBorderBox,r=e.draggable,n=e.candidates,i=r.page.borderBox.center,o=n.map((function(e){var r=e.axis,n=He(e.axis.line,t.center[r.line],e.page.borderBox.center[r.crossAxisLine]);return{id:e.descriptor.id,distance:qe(i,n)}})).sort((function(e,t){return t.distance-e.distance}));return o[0]?o[0].id:null}({pageBorderBox:t,draggable:r,candidates:i}):null}var sr=function(e,t){return $e(nt(e,t))};function dr(e){var t=e.displaced,r=e.id;return Boolean(t.visible[r]||t.invisible[r])}var pr=function(e){var t=e.pageOffset,r=e.draggable,n=e.draggables,i=e.droppables,o=e.previousImpact,a=e.viewport,l=e.afterCritical,u=sr(r.page.borderBox,t),c=cr({pageBorderBox:u,draggable:r,droppables:i});if(!c)return Ct;var s=i[c],d=ht(s.descriptor.id,n),p=function(e,t){var r=e.frame;return r?sr(t,r.scroll.diff.value):t}(s,u);return function(e){var t=e.draggable,r=e.pageBorderBoxWithDroppableScroll,n=e.previousImpact,i=e.destination,o=e.insideDestination,a=e.afterCritical;if(!i.isCombineEnabled)return null;var l=i.axis,u=tr(i.axis,t.displaceBy),c=u.value,s=r[l.start],d=r[l.end],p=pt(It(t,o),(function(e){var t=e.descriptor.id,r=e.page.borderBox,i=r[l.size]/4,o=_t(t,a),u=dr({displaced:n.displaced,id:t});return o?u?d>r[l.start]+i&&dr[l.start]-c+i&&sr[l.start]+c+i&&dr[l.start]+i&&st.descriptor.index?r.descriptor.index-1:r.descriptor.index:null}({draggable:r,closest:pt(It(r,i),(function(e){var t=e.descriptor.id,r=e.page.borderBox.center[u.line],n=_t(t,l),i=dr({displaced:o,id:t});return n?i?p<=r:d=1500)return Yr;var o=$r+Jr*(i/1500);return Number(("CANCEL"===n?.6*o:o).toFixed(2))}({current:i.current.client.offset,destination:h,reason:o});r(function(e){return{type:"DROP_ANIMATE",payload:e}}({newHomeClientOffset:h,dropDuration:x,completed:y}))}else r(Gr({completed:y}))}}else r(function(e){return{type:"DROP_PENDING",payload:e}}({reason:o}))}else e(n)}}},Kr=function(e){var t=[],r=null,n=function(){for(var n=arguments.length,i=new Array(n),o=0;ot.startScrollingFrom)return 0;if(e<=t.maxScrollValueAt)return Sn;if(e===t.startScrollingFrom)return 1;var r=An({startOfRange:t.maxScrollValueAt,endOfRange:t.startScrollingFrom,current:e}),n=Sn*Pn(1-r);return Math.ceil(n)}(t,r);return 0===o?0:i?Math.max(function(e,t){var r=t,n=Nn,i=Date.now()-r;if(i>=Nn)return e;if(it.height,o=r.width>t.width;return o||i?o&&i?null:{x:o?0:n.x,y:i?0:n.y}:n}({container:r,subject:n,proposedScroll:c});return s?We(s,Fe)?null:s:null},Gn=ze((function(e){return 0===e?0:e>0?1:-1})),_n=(bn=function(e,t){return e<0?e:e>t?e-t:0},function(e){var t=e.current,r=e.max,n=e.change,i=je(t,n),o={x:bn(i.x,r.x),y:bn(i.y,r.y)};return We(o,Fe)?null:o}),Fn=function(e){var t=e.max,r=e.current,n=e.change,i={x:Math.max(r.x,t.x),y:Math.max(r.y,t.y)},o=Gn(n),a=_n({max:i,current:r,change:o});return!a||(0!==o.x&&0===a.x||0!==o.y&&0===a.y)},jn=function(e,t){return Fn({current:e.scroll.current,max:e.scroll.max,change:t})},kn=function(e,t){var r=e.frame;return!!r&&Fn({current:r.scroll.current,max:r.scroll.max,change:t})},Wn=function(e){var t=e.state,r=e.dragStartTime,n=e.shouldUseTimeDampening,i=e.scrollWindow,o=e.scrollDroppable,a=t.current.page.borderBoxCenter,l=t.dimensions.draggables[t.critical.draggable.id].page.marginBox;if(t.isWindowScrollAllowed){var u=function(e){var t=e.viewport,r=e.subject,n=e.center,i=e.dragStartTime,o=e.shouldUseTimeDampening,a=Ln({dragStartTime:i,container:t.frame,subject:r,center:n,shouldUseTimeDampening:o});return a&&jn(t,a)?a:null}({dragStartTime:r,viewport:t.viewport,subject:l,center:a,shouldUseTimeDampening:n});if(u)return void i(u)}var c=wn({center:a,destination:or(t.impact),droppables:t.dimensions.droppables});if(c){var s=function(e){var t=e.droppable,r=e.subject,n=e.center,i=e.dragStartTime,o=e.shouldUseTimeDampening,a=t.frame;if(!a)return null;var l=Ln({dragStartTime:i,container:a.pageMarginBox,subject:r,center:n,shouldUseTimeDampening:o});return l&&kn(t,l)?l:null}({dragStartTime:r,droppable:c,subject:l,center:a,shouldUseTimeDampening:n});s&&o(c.descriptor.id,s)}},Un=function(e){var t=e.move,r=e.scrollDroppable,n=e.scrollWindow,i=function(e,t){if(!kn(e,t))return t;var n=function(e,t){var r=e.frame;return r&&kn(e,t)?_n({current:r.scroll.current,max:r.scroll.max,change:t}):null}(e,t);if(!n)return r(e.descriptor.id,t),null;var i=ke(t,n);return r(e.descriptor.id,i),ke(t,i)},o=function(e,t,r){if(!e)return r;if(!jn(t,r))return r;var i=function(e,t){if(!jn(e,t))return null;var r=e.scroll.max,n=e.scroll.current;return _n({current:n,max:r,change:t})}(t,r);if(!i)return n(r),null;var o=ke(r,i);return n(o),ke(r,o)};return function(e){var r=e.scrollJumpRequest;if(r){var n=or(e.impact);n||s(!1);var a=i(e.dimensions.droppables[n],r);if(a){var l=e.viewport,u=o(e.isWindowScrollAllowed,l,a);u&&function(e,r){var n=je(e.current.client.selection,r);t({client:n})}(e,u)}}}},Hn=function(e){var t=e.scrollDroppable,r=e.scrollWindow,n=e.move,i=function(e){var t=e.scrollWindow,r=e.scrollDroppable,n=Kr(t),i=Kr(r),o=null,a=function(e){o||s(!1);var t=o,r=t.shouldUseTimeDampening,a=t.dragStartTime;Wn({state:e,scrollWindow:n,scrollDroppable:i,dragStartTime:a,shouldUseTimeDampening:r})};return{start:function(e){o&&s(!1);var t=Date.now(),r=!1,n=function(){r=!0};Wn({state:e,dragStartTime:0,shouldUseTimeDampening:!1,scrollWindow:n,scrollDroppable:n}),o={dragStartTime:t,shouldUseTimeDampening:r},r&&a(e)},stop:function(){o&&(n.cancel(),i.cancel(),o=null)},scroll:a}}({scrollWindow:r,scrollDroppable:t}),o=Un({move:n,scrollWindow:r,scrollDroppable:t});return{scroll:function(e){"DRAGGING"===e.phase&&("FLUID"!==e.movementMode?e.scrollJumpRequest&&o(e):i.scroll(e))},start:i.start,stop:i.stop}},qn={base:hn="data-rbd-drag-handle",draggableId:hn+"-draggable-id",contextId:hn+"-context-id"},Vn=function(){var e="data-rbd-draggable";return{base:e,contextId:e+"-context-id",id:e+"-id"}}(),zn=function(){var e="data-rbd-droppable";return{base:e,contextId:e+"-context-id",id:e+"-id"}}(),$n={contextId:"data-rbd-scroll-container-context-id"},Yn=function(e,t){return e.map((function(e){var r=e.styles[t];return r?e.selector+" { "+r+" }":""})).join(" ")},Jn="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?t.useLayoutEffect:t.useEffect,Xn=function(){var e=document.querySelector("head");return e||s(!1),e},Kn=function(e){var t=document.createElement("style");return e&&t.setAttribute("nonce",e),t.type="text/css",t};function Qn(e,r){var n=Ge((function(){return function(e){var t,r,n,i=(t=e,function(e){return"["+e+'="'+t+'"]'}),o=(r="\n cursor: -webkit-grab;\n cursor: grab;\n ",{selector:i(qn.contextId),styles:{always:"\n -webkit-touch-callout: none;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n touch-action: manipulation;\n ",resting:r,dragging:"pointer-events: none;",dropAnimating:r}}),a=[(n="\n transition: "+Hr.outOfTheWay+";\n ",{selector:i(Vn.contextId),styles:{dragging:n,dropAnimating:n,userCancel:n}}),o,{selector:i(zn.contextId),styles:{always:"overflow-anchor: none;"}},{selector:"body",styles:{dragging:"\n cursor: grabbing;\n cursor: -webkit-grabbing;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n overflow-anchor: none;\n "}}];return{always:Yn(a,"always"),resting:Yn(a,"resting"),dragging:Yn(a,"dragging"),dropAnimating:Yn(a,"dropAnimating"),userCancel:Yn(a,"userCancel")}}(e)}),[e]),i=t.useRef(null),o=t.useRef(null),a=_e(ct((function(e){var t=o.current;t||s(!1),t.textContent=e})),[]),l=_e((function(e){var t=i.current;t||s(!1),t.textContent=e}),[]);Jn((function(){(i.current||o.current)&&s(!1);var t=Kn(r),u=Kn(r);return i.current=t,o.current=u,t.setAttribute("data-rbd-always",e),u.setAttribute("data-rbd-dynamic",e),Xn().appendChild(t),Xn().appendChild(u),l(n.always),a(n.resting),function(){var e=function(e){var t=e.current;t||s(!1),Xn().removeChild(t),e.current=null};e(i),e(o)}}),[r,l,a,n.always,n.resting,e]);var u=_e((function(){return a(n.dragging)}),[a,n.dragging]),c=_e((function(e){a("DROP"!==e?n.userCancel:n.dropAnimating)}),[a,n.dropAnimating,n.userCancel]),d=_e((function(){o.current&&a(n.resting)}),[a,n.resting]);return Ge((function(){return{dragging:u,dropping:c,resting:d}}),[u,c,d])}var Zn=function(e){return e&&e.ownerDocument?e.ownerDocument.defaultView:window};function ei(e){return e instanceof Zn(e).HTMLElement}function ti(e){var r=t.useRef({}),n=t.useRef(null),i=t.useRef(null),o=t.useRef(!1),a=_e((function(e,t){var n={id:e,focus:t};return r.current[e]=n,function(){var t=r.current;t[e]!==n&&delete t[e]}}),[]),l=_e((function(t){var r=function(e,t){var r="["+qn.contextId+'="'+e+'"]',n=ft(document.querySelectorAll(r));if(!n.length)return null;var i=pt(n,(function(e){return e.getAttribute(qn.draggableId)===t}));return i&&ei(i)?i:null}(e,t);r&&r!==document.activeElement&&r.focus()}),[e]),u=_e((function(e,t){n.current===e&&(n.current=t)}),[]),c=_e((function(){i.current||o.current&&(i.current=requestAnimationFrame((function(){i.current=null;var e=n.current;e&&l(e)})))}),[l]),s=_e((function(e){n.current=null;var t=document.activeElement;t&&t.getAttribute(qn.draggableId)===e&&(n.current=e)}),[]);return Jn((function(){return o.current=!0,function(){o.current=!1;var e=i.current;e&&cancelAnimationFrame(e)}}),[]),Ge((function(){return{register:a,tryRecordFocus:s,tryRestoreFocusRecorded:c,tryShiftRecord:u}}),[a,s,c,u])}function ri(){var e={draggables:{},droppables:{}},t=[];function r(e){t.length&&t.forEach((function(t){return t(e)}))}function n(t){return e.draggables[t]||null}function i(t){return e.droppables[t]||null}return{draggable:{register:function(t){e.draggables[t.descriptor.id]=t,r({type:"ADDITION",value:t})},update:function(t,r){var n=e.draggables[r.descriptor.id];n&&n.uniqueId===t.uniqueId&&(delete e.draggables[r.descriptor.id],e.draggables[t.descriptor.id]=t)},unregister:function(t){var i=t.descriptor.id,o=n(i);o&&t.uniqueId===o.uniqueId&&(delete e.draggables[i],r({type:"REMOVAL",value:t}))},getById:function(e){var t=n(e);return t||s(!1),t},findById:n,exists:function(e){return Boolean(n(e))},getAllByType:function(t){return st(e.draggables).filter((function(e){return e.descriptor.type===t}))}},droppable:{register:function(t){e.droppables[t.descriptor.id]=t},unregister:function(t){var r=i(t.descriptor.id);r&&t.uniqueId===r.uniqueId&&delete e.droppables[t.descriptor.id]},getById:function(e){var t=i(e);return t||s(!1),t},findById:i,exists:function(e){return Boolean(i(e))},getAllByType:function(t){return st(e.droppables).filter((function(e){return e.descriptor.type===t}))}},subscribe:function(e){return t.push(e),function(){var r=t.indexOf(e);-1!==r&&t.splice(r,1)}},clean:function(){e.draggables={},e.droppables={},t.length=0}}}var ni=n.createContext(null),ii=function(){var e=document.body;return e||s(!1),e},oi={position:"absolute",width:"1px",height:"1px",margin:"-1px",border:"0",padding:"0",overflow:"hidden",clip:"rect(0 0 0 0)","clip-path":"inset(100%)"};var ai=0,li={separator:"::"};function ui(e,t){return void 0===t&&(t=li),Ge((function(){return""+e+t.separator+ai++}),[t.separator,e])}var ci=n.createContext(null);function si(e){var r=t.useRef(e);return t.useEffect((function(){r.current=e})),r}var di,pi=((di={})[13]=!0,di[9]=!0,di),fi=function(e){pi[e.keyCode]&&e.preventDefault()},gi=function(){var e="visibilitychange";return"undefined"==typeof document?e:pt([e,"ms"+e,"webkit"+e,"moz"+e,"o"+e],(function(e){return"on"+e in document}))||e}();var vi,mi={type:"IDLE"};function bi(e){var t=e.cancel,r=e.completed,n=e.getPhase,i=e.setPhase;return[{eventName:"mousemove",fn:function(e){var t=e.button,r=e.clientX,o=e.clientY;if(0===t){var a={x:r,y:o},l=n();if("DRAGGING"===l.type)return e.preventDefault(),void l.actions.move(a);"PENDING"!==l.type&&s(!1);var u=l.point;if(c=u,d=a,Math.abs(d.x-c.x)>=5||Math.abs(d.y-c.y)>=5){var c,d;e.preventDefault();var p=l.actions.fluidLift(a);i({type:"DRAGGING",actions:p})}}}},{eventName:"mouseup",fn:function(e){var i=n();"DRAGGING"===i.type?(e.preventDefault(),i.actions.drop({shouldBlockNextClick:!0}),r()):t()}},{eventName:"mousedown",fn:function(e){"DRAGGING"===n().type&&e.preventDefault(),t()}},{eventName:"keydown",fn:function(e){if("PENDING"!==n().type)return 27===e.keyCode?(e.preventDefault(),void t()):void fi(e);t()}},{eventName:"resize",fn:t},{eventName:"scroll",options:{passive:!0,capture:!1},fn:function(){"PENDING"===n().type&&t()}},{eventName:"webkitmouseforcedown",fn:function(e){var r=n();"IDLE"===r.type&&s(!1),r.actions.shouldRespectForcePress()?t():e.preventDefault()}},{eventName:gi,fn:t}]}function hi(e){var r=t.useRef(mi),n=t.useRef(a),i=Ge((function(){return{eventName:"mousedown",fn:function(t){if(!t.defaultPrevented&&0===t.button&&!(t.ctrlKey||t.metaKey||t.shiftKey||t.altKey)){var r=e.findClosestDraggableId(t);if(r){var i=e.tryGetLock(r,c,{sourceEvent:t});if(i){t.preventDefault();var o={x:t.clientX,y:t.clientY};n.current(),f(i,o)}}}}}}),[e]),o=Ge((function(){return{eventName:"webkitmouseforcewillbegin",fn:function(t){if(!t.defaultPrevented){var r=e.findClosestDraggableId(t);if(r){var n=e.findOptionsForDraggable(r);n&&(n.shouldRespectForcePress||e.canGetLock(r)&&t.preventDefault())}}}}}),[e]),l=_e((function(){n.current=u(window,[o,i],{passive:!1,capture:!0})}),[o,i]),c=_e((function(){"IDLE"!==r.current.type&&(r.current=mi,n.current(),l())}),[l]),d=_e((function(){var e=r.current;c(),"DRAGGING"===e.type&&e.actions.cancel({shouldBlockNextClick:!0}),"PENDING"===e.type&&e.actions.abort()}),[c]),p=_e((function(){var e=bi({cancel:d,completed:c,getPhase:function(){return r.current},setPhase:function(e){r.current=e}});n.current=u(window,e,{capture:!0,passive:!1})}),[d,c]),f=_e((function(e,t){"IDLE"!==r.current.type&&s(!1),r.current={type:"PENDING",point:t,actions:e},p()}),[p]);Jn((function(){return l(),function(){n.current()}}),[l])}function yi(){}var xi=((vi={})[34]=!0,vi[33]=!0,vi[36]=!0,vi[35]=!0,vi);function Ii(e,t){function r(){t(),e.cancel()}return[{eventName:"keydown",fn:function(n){return 27===n.keyCode?(n.preventDefault(),void r()):32===n.keyCode?(n.preventDefault(),t(),void e.drop()):40===n.keyCode?(n.preventDefault(),void e.moveDown()):38===n.keyCode?(n.preventDefault(),void e.moveUp()):39===n.keyCode?(n.preventDefault(),void e.moveRight()):37===n.keyCode?(n.preventDefault(),void e.moveLeft()):void(xi[n.keyCode]?n.preventDefault():fi(n))}},{eventName:"mousedown",fn:r},{eventName:"mouseup",fn:r},{eventName:"click",fn:r},{eventName:"touchstart",fn:r},{eventName:"resize",fn:r},{eventName:"wheel",fn:r,options:{passive:!0}},{eventName:gi,fn:r}]}function Di(e){var r=t.useRef(yi),n=Ge((function(){return{eventName:"keydown",fn:function(t){if(!t.defaultPrevented&&32===t.keyCode){var n=e.findClosestDraggableId(t);if(n){var o=e.tryGetLock(n,c,{sourceEvent:t});if(o){t.preventDefault();var a=!0,l=o.snapLift();r.current(),r.current=u(window,Ii(l,c),{capture:!0,passive:!1})}}}function c(){a||s(!1),a=!1,r.current(),i()}}}}),[e]),i=_e((function(){r.current=u(window,[n],{passive:!1,capture:!0})}),[n]);Jn((function(){return i(),function(){r.current()}}),[i])}var wi={type:"IDLE"};function Ei(e){var r=t.useRef(wi),n=t.useRef(a),i=_e((function(){return r.current}),[]),o=_e((function(e){r.current=e}),[]),l=Ge((function(){return{eventName:"touchstart",fn:function(t){if(!t.defaultPrevented){var r=e.findClosestDraggableId(t);if(r){var i=e.tryGetLock(r,d,{sourceEvent:t});if(i){var o=t.touches[0],a={x:o.clientX,y:o.clientY},l=e.findClosestDragHandle(t);l||s(!1),n.current(),v(i,a,l)}}}}}}),[e]),c=_e((function(){n.current=u(window,[l],{capture:!0,passive:!1})}),[l]),d=_e((function(){var e=r.current;"IDLE"!==e.type&&("PENDING"===e.type&&clearTimeout(e.longPressTimerId),o(wi),n.current(),c())}),[c,o]),p=_e((function(){var e=r.current;d(),"DRAGGING"===e.type&&e.actions.cancel({shouldBlockNextClick:!0}),"PENDING"===e.type&&e.actions.abort()}),[d]),f=_e((function(e){var t={capture:!0,passive:!1},r={cancel:p,completed:d,getPhase:i},o=u(e,function(e){var t=e.cancel,r=e.completed,n=e.getPhase;return[{eventName:"touchmove",options:{capture:!1},fn:function(e){var r=n();if("DRAGGING"===r.type){r.hasMoved=!0;var i=e.touches[0],o={x:i.clientX,y:i.clientY};e.preventDefault(),r.actions.move(o)}else t()}},{eventName:"touchend",fn:function(e){var i=n();"DRAGGING"===i.type?(e.preventDefault(),i.actions.drop({shouldBlockNextClick:!0}),r()):t()}},{eventName:"touchcancel",fn:function(e){"DRAGGING"===n().type?(e.preventDefault(),t()):t()}},{eventName:"touchforcechange",fn:function(e){var r=n();"IDLE"===r.type&&s(!1);var i=e.touches[0];if(i&&i.force>=.15){var o=r.actions.shouldRespectForcePress();if("PENDING"!==r.type)return o?r.hasMoved?void e.preventDefault():void t():void e.preventDefault();o&&t()}}},{eventName:gi,fn:t}]}(r),t),a=u(window,function(e){var t=e.cancel,r=e.getPhase;return[{eventName:"orientationchange",fn:t},{eventName:"resize",fn:t},{eventName:"contextmenu",fn:function(e){e.preventDefault()}},{eventName:"keydown",fn:function(e){"DRAGGING"===r().type?(27===e.keyCode&&e.preventDefault(),t()):t()}},{eventName:gi,fn:t}]}(r),t);n.current=function(){o(),a()}}),[p,i,d]),g=_e((function(){var e=i();"PENDING"!==e.type&&s(!1);var t=e.actions.fluidLift(e.point);o({type:"DRAGGING",actions:t,hasMoved:!1})}),[i,o]),v=_e((function(e,t,r){"IDLE"!==i().type&&s(!1);var n=setTimeout(g,120);o({type:"PENDING",point:t,actions:e,longPressTimerId:n}),f(r)}),[f,i,o,g]);Jn((function(){return c(),function(){n.current();var e=i();"PENDING"===e.type&&(clearTimeout(e.longPressTimerId),o(wi))}}),[i,c,o]),Jn((function(){return u(window,[{eventName:"touchmove",fn:function(){},options:{capture:!1,passive:!1}}])}),[])}var Ci={input:!0,button:!0,textarea:!0,select:!0,option:!0,optgroup:!0,video:!0,audio:!0};function Si(e,t){var r=t.target;return!!ei(r)&&function e(t,r){if(null==r)return!1;if(Boolean(Ci[r.tagName.toLowerCase()]))return!0;var n=r.getAttribute("contenteditable");return"true"===n||""===n||r!==t&&e(t,r.parentElement)}(e,r)}var Pi=function(e){return $e(e.getBoundingClientRect()).center};var Oi="undefined"==typeof document?"matches":pt(["matches","msMatchesSelector","webkitMatchesSelector"],(function(e){return e in Element.prototype}))||"matches";function Ai(e,t){return e.closest?e.closest(t):function e(t,r){return null==t?null:t[Oi](r)?t:e(t.parentElement,r)}(e,t)}function Ri(e,t){var r,n=t.target;if(!((r=n)instanceof Zn(r).Element))return null;var i=Ai(n,function(e){return"["+qn.contextId+'="'+e+'"]'}(e));return i&&ei(i)?i:null}function Ni(e){e.preventDefault()}function Bi(e){var t=e.expected,r=e.phase,n=e.isLockActive;e.shouldWarn;return!!n()&&t===r}function Ti(e){var t=e.lockAPI,r=e.store,n=e.registry,i=e.draggableId;if(t.isClaimed())return!1;var o=n.draggable.findById(i);return!!o&&(!!o.options.isEnabled&&!!xn(r.getState(),i))}function Mi(e){var t=e.lockAPI,r=e.contextId,n=e.store,i=e.registry,o=e.draggableId,c=e.forceSensorStop,d=e.sourceEvent;if(!Ti({lockAPI:t,store:n,registry:i,draggableId:o}))return null;var p=i.draggable.getById(o),f=function(e,t){var r="["+Vn.contextId+'="'+e+'"]',n=pt(ft(document.querySelectorAll(r)),(function(e){return e.getAttribute(Vn.id)===t}));return n&&ei(n)?n:null}(r,p.descriptor.id);if(!f)return null;if(d&&!p.options.canDragInteractiveElements&&Si(f,d))return null;var g=t.claim(c||a),v="PRE_DRAG";function m(){return p.options.shouldRespectForcePress}function b(){return t.isActive(g)}var h=function(e,t){Bi({expected:e,phase:v,isLockActive:b,shouldWarn:!0})&&n.dispatch(t())}.bind(null,"DRAGGING");function y(e){function r(){t.release(),v="COMPLETED"}function i(t,i){if(void 0===i&&(i={shouldBlockNextClick:!1}),e.cleanup(),i.shouldBlockNextClick){var o=u(window,[{eventName:"click",fn:Ni,options:{once:!0,passive:!1,capture:!0}}]);setTimeout(o)}r(),n.dispatch(_r({reason:t}))}return"PRE_DRAG"!==v&&(r(),"PRE_DRAG"!==v&&s(!1)),n.dispatch(function(e){return{type:"LIFT",payload:e}}(e.liftActionArgs)),v="DRAGGING",l({isActive:function(){return Bi({expected:"DRAGGING",phase:v,isLockActive:b,shouldWarn:!1})},shouldRespectForcePress:m,drop:function(e){return i("DROP",e)},cancel:function(e){return i("CANCEL",e)}},e.actions)}return{isActive:function(){return Bi({expected:"PRE_DRAG",phase:v,isLockActive:b,shouldWarn:!1})},shouldRespectForcePress:m,fluidLift:function(e){var t=Kr((function(e){h((function(){return Nr({client:e})}))}));return l({},y({liftActionArgs:{id:o,clientSelection:e,movementMode:"FLUID"},cleanup:function(){return t.cancel()},actions:{move:t}}),{move:t})},snapLift:function(){var e={moveUp:function(){return h(Br)},moveRight:function(){return h(Mr)},moveDown:function(){return h(Tr)},moveLeft:function(){return h(Lr)}};return y({liftActionArgs:{id:o,clientSelection:Pi(f),movementMode:"SNAP"},cleanup:a,actions:e})},abort:function(){Bi({expected:"PRE_DRAG",phase:v,isLockActive:b,shouldWarn:!0})&&t.release()}}}var Li=[hi,Di,Ei];function Gi(e){var r=e.contextId,n=e.store,i=e.registry,o=e.customSensors,a=e.enableDefaultSensors,l=[].concat(a?Li:[],o||[]),u=t.useState((function(){return function(){var e=null;function t(){e||s(!1),e=null}return{isClaimed:function(){return Boolean(e)},isActive:function(t){return t===e},claim:function(t){e&&s(!1);var r={abandon:t};return e=r,r},release:t,tryAbandon:function(){e&&(e.abandon(),t())}}}()}))[0],c=_e((function(e,t){e.isDragging&&!t.isDragging&&u.tryAbandon()}),[u]);Jn((function(){var e=n.getState();return n.subscribe((function(){var t=n.getState();c(e,t),e=t}))}),[u,n,c]),Jn((function(){return u.tryAbandon}),[u.tryAbandon]);for(var d=_e((function(e){return Ti({lockAPI:u,registry:i,store:n,draggableId:e})}),[u,i,n]),p=_e((function(e,t,o){return Mi({lockAPI:u,registry:i,contextId:r,store:n,draggableId:e,forceSensorStop:t,sourceEvent:o&&o.sourceEvent?o.sourceEvent:null})}),[r,u,i,n]),f=_e((function(e){return Ri(r,e)}),[r]),g=_e((function(e){return function(e,t){var r=Ri(e,t);return r?r.getAttribute(qn.draggableId):null}(r,e)}),[r]),v=_e((function(e){var t=i.draggable.findById(e);return t?t.options:null}),[i.draggable]),m=_e((function(){u.isClaimed()&&(u.tryAbandon(),"IDLE"!==n.getState().phase&&n.dispatch({type:"FLUSH",payload:null}))}),[u,n]),b=_e(u.isClaimed,[u]),h=Ge((function(){return{canGetLock:d,tryGetLock:p,findClosestDraggableId:g,findClosestDragHandle:f,findOptionsForDraggable:v,tryReleaseLock:m,isLockClaimed:b}}),[d,p,g,f,v,m,b]),y=0;y Date: Tue, 29 Aug 2023 17:19:01 +0200 Subject: [PATCH 04/42] fix types --- src/components/DraggableList/types.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/DraggableList/types.tsx b/src/components/DraggableList/types.tsx index 9cad93dfafb7..03c3fd4330d8 100644 --- a/src/components/DraggableList/types.tsx +++ b/src/components/DraggableList/types.tsx @@ -11,9 +11,8 @@ type DraggableListProps = { renderItem: (params: RenderItemParams) => React.ReactNode; onDragEnd?: (params: {data: T[]}) => void; onDragBegin?: () => void; - onPlaceholderIndexChange?: ((placeholderIndex: number) => void) | undefined; - // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents - renderClone?: DraggableChildrenFn | undefined; + onPlaceholderIndexChange?: ((placeholderIndex: number) => void); + renderClone?: DraggableChildrenFn; shouldUsePortal?: boolean; }; From 2b6e88bb50ea655770b6e349d311238c4bf6623d Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:28:36 +0200 Subject: [PATCH 05/42] fix lint issues --- src/components/DistanceRequest.js | 6 ++++-- src/components/DraggableList/index.native.tsx | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 7506fc685d21..49dea573c620 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,11 +1,11 @@ import React, {useEffect, useState} from 'react'; -import {ScrollView, View} from 'react-native'; +import {View} from 'react-native'; import lodashGet from 'lodash/get'; import _ from 'underscore'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import MapView from 'react-native-x-maps'; -import DraggableList from '../components/DraggableList'; +import DraggableList from './DraggableList'; import ONYXKEYS from '../ONYXKEYS'; import * as Transaction from '../libs/actions/Transaction'; import * as TransactionUtils from '../libs/TransactionUtils'; @@ -61,6 +61,8 @@ const defaultProps = { function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { const [shouldShowGradient, setShouldShowGradient] = useState(false); const [scrollContainerHeight, setScrollContainerHeight] = useState(0); + // TODO: Verify setScrollContentHeight is needed + // eslint-disable-next-line no-unused-vars const [scrollContentHeight, setScrollContentHeight] = useState(0); const {isOffline} = useNetwork(); const {translate} = useLocalize(); diff --git a/src/components/DraggableList/index.native.tsx b/src/components/DraggableList/index.native.tsx index fab164755f06..1e2eed52f4ad 100644 --- a/src/components/DraggableList/index.native.tsx +++ b/src/components/DraggableList/index.native.tsx @@ -1,9 +1,8 @@ import React from 'react'; import DraggableFlatList from 'react-native-draggable-flatlist'; -import _ from 'lodash'; import type {DefaultItemProps, DraggableListProps} from './types'; -export default function DraggableList({...props}: DraggableListProps) { - const viewProps = _.omit(props, ['renderClone', 'shouldUsePortal']); +export default function DraggableList({renderClone, shouldUsePortal, ...viewProps}: DraggableListProps) { + // eslint-disable-next-line react/jsx-props-no-spreading return ; } From 0fc64edeffa933c44176196009eadd9e8ebee6ad Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:34:57 +0200 Subject: [PATCH 06/42] experimentally add onContentSizeChange --- src/components/DistanceRequest.js | 3 +-- src/components/DraggableList/index.tsx | 3 ++- src/components/DraggableList/types.tsx | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 49dea573c620..b0d2aa8f081f 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -61,8 +61,6 @@ const defaultProps = { function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { const [shouldShowGradient, setShouldShowGradient] = useState(false); const [scrollContainerHeight, setScrollContainerHeight] = useState(0); - // TODO: Verify setScrollContentHeight is needed - // eslint-disable-next-line no-unused-vars const [scrollContentHeight, setScrollContentHeight] = useState(0); const {isOffline} = useNetwork(); const {translate} = useLocalize(); @@ -152,6 +150,7 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { data={waypointsList} keyExtractor={(item) => item} shouldUsePortal + onContentSizeChange={(width, height) => setScrollContentHeight(height)} onDragEnd={({data}) => { const newWaypoints = {}; _.each(data, (waypoint, index) => { diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index 1c7fcf64c4bf..35e3248a648a 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -31,6 +31,7 @@ export default function DraggableList({ onPlaceholderIndexChange, renderClone, shouldUsePortal = false, + onContentSizeChange, }: DraggableListProps) { const onDragEnd: OnDragEndResponder = useCallback( (result) => { @@ -73,7 +74,7 @@ export default function DraggableList({ > {(droppableProvided) => ( // We use ScrollView to match the native behavior of FlatList - + {/* We can't use the react-native View here, because it doesn't support all props */}
= { onPlaceholderIndexChange?: ((placeholderIndex: number) => void); renderClone?: DraggableChildrenFn; shouldUsePortal?: boolean; + onContentSizeChange?: ((w: number, h: number) => void) | undefined; }; type RenderItemParams = OriginalRenderItemParams; From fc617deb82e1df2da9f846ed527b9795eac7d164 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Wed, 30 Aug 2023 18:10:03 +0200 Subject: [PATCH 07/42] add comments --- src/components/DraggableList/index.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index 35e3248a648a..4752dd949dcc 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -33,8 +33,15 @@ export default function DraggableList({ shouldUsePortal = false, onContentSizeChange, }: DraggableListProps) { + + /** + * Function to be called when the user finishes dragging an item + * It will reorder the list and call the callback function + * to notify the parent component about the change + */ const onDragEnd: OnDragEndResponder = useCallback( (result) => { + // If user dropped the item outside of the list if (!result.destination) { return; } @@ -60,6 +67,12 @@ export default function DraggableList({ [onPlaceholderIndexChange], ); + /** + * The `react-beautiful-dnd` library uses `position: fixed` to move the dragged item to the top of the screen. + * But when the parent component uses the `transform` property, the `position: fixed` doesn't work as expected. + * Since the TabSelector component uses the `transform` property to animate the tab change + * we have to use portals when any of the parent components use the `transform` property. + */ const renderDraggable = useDraggableInPortal({shouldUsePortal}); return ( From f2dc8e32c37e752263b0dac3cee486e5189f8f9c Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Thu, 31 Aug 2023 09:26:04 +0200 Subject: [PATCH 08/42] Make small adjustements --- src/components/DraggableList/index.tsx | 4 ++-- src/components/DraggableList/types.tsx | 2 +- src/components/DraggableList/useDraggableInPortal.tsx | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index 4752dd949dcc..210fbc7cec1a 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -4,14 +4,14 @@ import {ScrollView} from 'react-native'; import useDraggableInPortal from './useDraggableInPortal'; import type {DraggableListProps, DefaultItemProps} from './types'; -type ReoderParams = { +type ReorderParams = { list: T[]; startIndex: number; endIndex: number; }; // Function to help us with reordering the result -const reorder = ({list, startIndex, endIndex}: ReoderParams): T[] => { +const reorder = ({list, startIndex, endIndex}: ReorderParams): T[] => { const result = Array.from(list); const [removed] = result.splice(startIndex, 1); diff --git a/src/components/DraggableList/types.tsx b/src/components/DraggableList/types.tsx index 10a2d713ef34..2aa3e6333f11 100644 --- a/src/components/DraggableList/types.tsx +++ b/src/components/DraggableList/types.tsx @@ -11,7 +11,7 @@ type DraggableListProps = { renderItem: (params: RenderItemParams) => React.ReactNode; onDragEnd?: (params: {data: T[]}) => void; onDragBegin?: () => void; - onPlaceholderIndexChange?: ((placeholderIndex: number) => void); + onPlaceholderIndexChange?: (placeholderIndex: number) => void; renderClone?: DraggableChildrenFn; shouldUsePortal?: boolean; onContentSizeChange?: ((w: number, h: number) => void) | undefined; diff --git a/src/components/DraggableList/useDraggableInPortal.tsx b/src/components/DraggableList/useDraggableInPortal.tsx index 586bab459eb5..3afaa8f6b626 100644 --- a/src/components/DraggableList/useDraggableInPortal.tsx +++ b/src/components/DraggableList/useDraggableInPortal.tsx @@ -1,4 +1,4 @@ -import type {DraggableChildrenFn, DraggingStyle} from 'react-beautiful-dnd'; +import type {DraggableChildrenFn} from 'react-beautiful-dnd'; import {useEffect, useRef} from 'react'; import {createPortal} from 'react-dom'; @@ -32,8 +32,8 @@ export default function useDraggableInPortal({shouldUsePortal}: DraggableInPorta return (render) => (provided, snapshot, rubric) => { const result = render(provided, snapshot, rubric); - const style = provided.draggableProps.style as DraggingStyle; - if (style.position === 'fixed') { + const style = provided.draggableProps.style; + if (style && 'position' in style && style.position === 'fixed') { return createPortal(result, element); } return result; From a306d70e6775da7e3282e023b72fbbb8de79b653 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Thu, 31 Aug 2023 09:44:43 +0200 Subject: [PATCH 09/42] Adjust updateWaypoints function --- src/libs/actions/Transaction.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 3fc5bf30017d..3ac0a4ff5ab5 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -199,11 +199,32 @@ function getRoute(transactionID, waypoints) { ); } +/** + * Updates full set of waypoints for the specific transaction. + * + * @param {String} transactionID - The ID of the transaction to be updated + * @param {Object} waypoints - An object containing all the waypoints + * which will replace the existing ones. + */ function updateWaypoints(transactionID, waypoints) { Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { comment: { waypoints, }, + + // Empty out errors when we're saving a new waypoint as this indicates the user is updating their input + errorFields: { + route: null, + }, + + // Clear the existing route so that we don't show an old route + routes: { + route0: { + geometry: { + coordinates: null, + }, + }, + }, }); } From ae045a3cd4e8841242a428c95b3c434991e316d2 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Thu, 31 Aug 2023 09:52:10 +0200 Subject: [PATCH 10/42] Fix the comment --- src/libs/actions/Transaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 3ac0a4ff5ab5..c01e5f5daf30 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -212,7 +212,7 @@ function updateWaypoints(transactionID, waypoints) { waypoints, }, - // Empty out errors when we're saving a new waypoint as this indicates the user is updating their input + // Empty out errors when we're saving new waypoints as this indicates the user is updating their input errorFields: { route: null, }, From 281e3e7a7e048490f869f0412fb82d303557dfc1 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Thu, 31 Aug 2023 15:24:55 +0200 Subject: [PATCH 11/42] Fix prettier diff --- src/components/DraggableList/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index 210fbc7cec1a..065304f1baf6 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -33,7 +33,6 @@ export default function DraggableList({ shouldUsePortal = false, onContentSizeChange, }: DraggableListProps) { - /** * Function to be called when the user finishes dragging an item * It will reorder the list and call the callback function From c974a3768b1777877cba48e5e92ca52b70de715b Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Fri, 1 Sep 2023 09:30:51 +0200 Subject: [PATCH 12/42] address review --- src/components/DraggableList/index.native.tsx | 8 ++++++-- src/components/DraggableList/index.tsx | 10 +++++++--- .../DraggableList/{types.tsx => types.ts} | 13 ++++++------- ...raggableInPortal.tsx => useDraggableInPortal.ts} | 0 src/libs/Permissions.js | 1 + 5 files changed, 20 insertions(+), 12 deletions(-) rename src/components/DraggableList/{types.tsx => types.ts} (73%) rename src/components/DraggableList/{useDraggableInPortal.tsx => useDraggableInPortal.ts} (100%) diff --git a/src/components/DraggableList/index.native.tsx b/src/components/DraggableList/index.native.tsx index 1e2eed52f4ad..c8b472c02c8a 100644 --- a/src/components/DraggableList/index.native.tsx +++ b/src/components/DraggableList/index.native.tsx @@ -1,8 +1,12 @@ import React from 'react'; import DraggableFlatList from 'react-native-draggable-flatlist'; -import type {DefaultItemProps, DraggableListProps} from './types'; +import type {DraggableListProps} from './types'; -export default function DraggableList({renderClone, shouldUsePortal, ...viewProps}: DraggableListProps) { +function DraggableList({renderClone, shouldUsePortal, ...viewProps}: DraggableListProps) { // eslint-disable-next-line react/jsx-props-no-spreading return ; } + +DraggableList.displayName = 'DraggableList'; + +export default DraggableList; diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index 065304f1baf6..fd23ad82fe22 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -2,7 +2,7 @@ import React, {useCallback} from 'react'; import {DragDropContext, Droppable, Draggable, type OnDragEndResponder, type OnDragUpdateResponder} from 'react-beautiful-dnd'; import {ScrollView} from 'react-native'; import useDraggableInPortal from './useDraggableInPortal'; -import type {DraggableListProps, DefaultItemProps} from './types'; +import type {DraggableListProps} from './types'; type ReorderParams = { list: T[]; @@ -15,14 +15,14 @@ const reorder = ({list, startIndex, endIndex}: ReorderParams): T[] => { const result = Array.from(list); const [removed] = result.splice(startIndex, 1); - if (removed !== undefined) { + if (removed) { result.splice(endIndex, 0, removed); } return result; }; -export default function DraggableList({ +function DraggableList({ data = [], renderItem, keyExtractor, @@ -128,3 +128,7 @@ export default function DraggableList({ ); } + +DraggableList.displayName = 'DraggableList'; + +export default DraggableList; diff --git a/src/components/DraggableList/types.tsx b/src/components/DraggableList/types.ts similarity index 73% rename from src/components/DraggableList/types.tsx rename to src/components/DraggableList/types.ts index 2aa3e6333f11..8057c2b64641 100644 --- a/src/components/DraggableList/types.tsx +++ b/src/components/DraggableList/types.ts @@ -1,22 +1,21 @@ import type {DraggableChildrenFn} from 'react-beautiful-dnd'; import type {RenderItemParams as OriginalRenderItemParams} from 'react-native-draggable-flatlist'; -type DefaultItemProps = { - id: string; +type DataType = { + data: T[]; }; -type DraggableListProps = { - data: T[]; +type DraggableListProps = { keyExtractor: (item: T, index: number) => string; renderItem: (params: RenderItemParams) => React.ReactNode; - onDragEnd?: (params: {data: T[]}) => void; + onDragEnd?: (params: DataType) => void; onDragBegin?: () => void; onPlaceholderIndexChange?: (placeholderIndex: number) => void; renderClone?: DraggableChildrenFn; shouldUsePortal?: boolean; onContentSizeChange?: ((w: number, h: number) => void) | undefined; -}; +} & DataType; type RenderItemParams = OriginalRenderItemParams; -export type {DefaultItemProps, DraggableListProps, RenderItemParams}; +export type {DraggableListProps, RenderItemParams}; diff --git a/src/components/DraggableList/useDraggableInPortal.tsx b/src/components/DraggableList/useDraggableInPortal.ts similarity index 100% rename from src/components/DraggableList/useDraggableInPortal.tsx rename to src/components/DraggableList/useDraggableInPortal.ts diff --git a/src/libs/Permissions.js b/src/libs/Permissions.js index 7f52c41ad0fd..d9363c386da1 100644 --- a/src/libs/Permissions.js +++ b/src/libs/Permissions.js @@ -7,6 +7,7 @@ import CONST from '../CONST'; * @returns {Boolean} */ function canUseAllBetas(betas) { + return true; return _.contains(betas, CONST.BETAS.ALL); } From 34337528de6fb3d571c1638251e76cfd56d60f50 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Fri, 1 Sep 2023 09:42:01 +0200 Subject: [PATCH 13/42] fix: lint --- src/libs/Permissions.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Permissions.js b/src/libs/Permissions.js index d9363c386da1..7f52c41ad0fd 100644 --- a/src/libs/Permissions.js +++ b/src/libs/Permissions.js @@ -7,7 +7,6 @@ import CONST from '../CONST'; * @returns {Boolean} */ function canUseAllBetas(betas) { - return true; return _.contains(betas, CONST.BETAS.ALL); } From 2612dcb2988d98431c6b36b5e44583c4158df7aa Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:07:18 +0200 Subject: [PATCH 14/42] fix: padding on iOS --- src/components/DistanceRequest.js | 8 ++++++-- src/components/DraggableList/types.ts | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index b0d2aa8f081f..60de5b4c02ab 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -126,7 +126,8 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { const updateGradientVisibility = (event = {}) => { // If a waypoint extends past the bottom of the visible area show the gradient, else hide it. const visibleAreaEnd = lodashGet(event, 'nativeEvent.contentOffset.y', 0) + scrollContainerHeight; - setShouldShowGradient(visibleAreaEnd < scrollContentHeight); + // TODO: Fix updating gradient visibility + setShouldShowGradient(visibleAreaEnd < scrollContentHeight && false); }; // Handle fetching the route when there are at least 2 waypoints @@ -141,7 +142,10 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight]); return ( - + setScrollContainerHeight(lodashGet(event, 'nativeEvent.layout.height', 0))} diff --git a/src/components/DraggableList/types.ts b/src/components/DraggableList/types.ts index 8057c2b64641..770f230fffd7 100644 --- a/src/components/DraggableList/types.ts +++ b/src/components/DraggableList/types.ts @@ -14,6 +14,8 @@ type DraggableListProps = { renderClone?: DraggableChildrenFn; shouldUsePortal?: boolean; onContentSizeChange?: ((w: number, h: number) => void) | undefined; + // TODO: implement on web + onScrollOffsetChange?: (() => void) | undefined; } & DataType; type RenderItemParams = OriginalRenderItemParams; From 418bf57560eabe1ecc77e8acec6aca56b640f73a Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:18:31 +0200 Subject: [PATCH 15/42] bottom padding --- src/components/DistanceRequest.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 60de5b4c02ab..772c6bc7f637 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -145,6 +145,7 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { Date: Fri, 1 Sep 2023 10:33:51 +0200 Subject: [PATCH 16/42] add icon --- src/components/DistanceRequest.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index cf20996fb0a4..332ca1b7a4d2 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -183,6 +183,7 @@ function DistanceRequest({transactionID, transaction, mapboxAccessToken}) { Date: Mon, 4 Sep 2023 12:35:56 +0200 Subject: [PATCH 17/42] forward refs in the DraggableList --- src/components/DistanceRequest.js | 9 +++-- src/components/DraggableList/index.native.tsx | 16 ++++++--- src/components/DraggableList/index.tsx | 34 +++++++++++-------- src/components/DraggableList/types.ts | 7 +++- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index d4a31cf95e76..0bc3110b6646 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,4 +1,4 @@ -import React, {useEffect, useMemo, useState} from 'react'; +import React, {useEffect, useMemo, useState, useRef} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; @@ -88,7 +88,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) const previousWaypoints = usePrevious(waypoints); const numberOfWaypoints = _.size(waypoints); const numberOfPreviousWaypoints = _.size(previousWaypoints); - // const scrollViewRef = useRef(null); + const scrollViewRef = useRef(null); const lastWaypointIndex = numberOfWaypoints - 1; const isLoadingRoute = lodashGet(transaction, 'comment.isLoading', false); @@ -177,8 +177,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) shouldUsePortal onContentSizeChange={(width, height) => { if (scrollContentHeight < height && numberOfWaypoints > numberOfPreviousWaypoints) { - // TODO: Fix refs - // scrollViewRef.current.scrollToEnd({animated: true}); + scrollViewRef.current.scrollToEnd({animated: true}); } setScrollContentHeight(height); }} @@ -191,7 +190,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) }} onScroll={updateGradientVisibility} // scrollEventThrottle={16} - // ref={scrollViewRef} + ref={scrollViewRef} renderItem={({item, drag, getIndex}) => { // key is of the form waypoint0, waypoint1, ... const index = getIndex(); diff --git a/src/components/DraggableList/index.native.tsx b/src/components/DraggableList/index.native.tsx index c8b472c02c8a..5d8abc42bf39 100644 --- a/src/components/DraggableList/index.native.tsx +++ b/src/components/DraggableList/index.native.tsx @@ -1,12 +1,18 @@ import React from 'react'; import DraggableFlatList from 'react-native-draggable-flatlist'; -import type {DraggableListProps} from './types'; +import {FlatList} from 'react-native-gesture-handler'; +import type {DraggableListProps, DraggableListType} from './types'; -function DraggableList({renderClone, shouldUsePortal, ...viewProps}: DraggableListProps) { - // eslint-disable-next-line react/jsx-props-no-spreading - return ; +function DraggableList({renderClone, shouldUsePortal, ...viewProps}: DraggableListProps, ref: React.ForwardedRef>) { + return ( + + ); } DraggableList.displayName = 'DraggableList'; -export default DraggableList; +export default React.forwardRef(DraggableList) as DraggableListType; diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index fd23ad82fe22..6835e382c1f7 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -2,7 +2,7 @@ import React, {useCallback} from 'react'; import {DragDropContext, Droppable, Draggable, type OnDragEndResponder, type OnDragUpdateResponder} from 'react-beautiful-dnd'; import {ScrollView} from 'react-native'; import useDraggableInPortal from './useDraggableInPortal'; -import type {DraggableListProps} from './types'; +import type {DraggableListProps, DraggableListType} from './types'; type ReorderParams = { list: T[]; @@ -22,17 +22,20 @@ const reorder = ({list, startIndex, endIndex}: ReorderParams): T[] => { return result; }; -function DraggableList({ - data = [], - renderItem, - keyExtractor, - onDragEnd: onDragEndCallback, - onDragBegin, - onPlaceholderIndexChange, - renderClone, - shouldUsePortal = false, - onContentSizeChange, -}: DraggableListProps) { +function DraggableList( + { + data = [], + renderItem, + keyExtractor, + onDragEnd: onDragEndCallback, + onDragBegin, + onPlaceholderIndexChange, + renderClone, + shouldUsePortal = false, + onContentSizeChange, + }: DraggableListProps, + ref: React.ForwardedRef, +) { /** * Function to be called when the user finishes dragging an item * It will reorder the list and call the callback function @@ -86,7 +89,10 @@ function DraggableList({ > {(droppableProvided) => ( // We use ScrollView to match the native behavior of FlatList - + {/* We can't use the react-native View here, because it doesn't support all props */}
({ DraggableList.displayName = 'DraggableList'; -export default DraggableList; +export default React.forwardRef(DraggableList) as DraggableListType; diff --git a/src/components/DraggableList/types.ts b/src/components/DraggableList/types.ts index 770f230fffd7..d43250c5cbe0 100644 --- a/src/components/DraggableList/types.ts +++ b/src/components/DraggableList/types.ts @@ -1,6 +1,11 @@ import type {DraggableChildrenFn} from 'react-beautiful-dnd'; +import {FlatList} from 'react-native-gesture-handler'; import type {RenderItemParams as OriginalRenderItemParams} from 'react-native-draggable-flatlist'; +type RefType = Pick, 'scrollToEnd'>; + +type DraggableListType = (props: DraggableListProps & {ref?: React.ForwardedRef>}) => JSX.Element; + type DataType = { data: T[]; }; @@ -20,4 +25,4 @@ type DraggableListProps = { type RenderItemParams = OriginalRenderItemParams; -export type {DraggableListProps, RenderItemParams}; +export type {DraggableListProps, RenderItemParams, RefType, DraggableListType}; From 3e95fd3d9b729d09c0b2aeb4584218cc776803a3 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 4 Sep 2023 12:39:45 +0200 Subject: [PATCH 18/42] rename type --- src/components/DraggableList/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/DraggableList/types.ts b/src/components/DraggableList/types.ts index d43250c5cbe0..2a5235cbda11 100644 --- a/src/components/DraggableList/types.ts +++ b/src/components/DraggableList/types.ts @@ -6,14 +6,14 @@ type RefType = Pick, 'scrollToEnd'>; type DraggableListType = (props: DraggableListProps & {ref?: React.ForwardedRef>}) => JSX.Element; -type DataType = { +type DraggableListData = { data: T[]; }; type DraggableListProps = { keyExtractor: (item: T, index: number) => string; renderItem: (params: RenderItemParams) => React.ReactNode; - onDragEnd?: (params: DataType) => void; + onDragEnd?: (params: DraggableListData) => void; onDragBegin?: () => void; onPlaceholderIndexChange?: (placeholderIndex: number) => void; renderClone?: DraggableChildrenFn; @@ -21,7 +21,7 @@ type DraggableListProps = { onContentSizeChange?: ((w: number, h: number) => void) | undefined; // TODO: implement on web onScrollOffsetChange?: (() => void) | undefined; -} & DataType; +} & DraggableListData; type RenderItemParams = OriginalRenderItemParams; From ccddce0719bac3d5263f714eef09ad069ddff033 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:20:02 +0200 Subject: [PATCH 19/42] refactor types --- src/components/DraggableList/types.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/DraggableList/types.ts b/src/components/DraggableList/types.ts index 2a5235cbda11..64e0f0b09fd3 100644 --- a/src/components/DraggableList/types.ts +++ b/src/components/DraggableList/types.ts @@ -1,10 +1,9 @@ import type {DraggableChildrenFn} from 'react-beautiful-dnd'; import {FlatList} from 'react-native-gesture-handler'; import type {RenderItemParams as OriginalRenderItemParams} from 'react-native-draggable-flatlist'; +import { ScrollView } from 'react-native'; -type RefType = Pick, 'scrollToEnd'>; - -type DraggableListType = (props: DraggableListProps & {ref?: React.ForwardedRef>}) => JSX.Element; +type DraggableListType = (props: DraggableListProps & {ref?: React.ForwardedRef | ScrollView>}) => JSX.Element; type DraggableListData = { data: T[]; @@ -25,4 +24,4 @@ type DraggableListProps = { type RenderItemParams = OriginalRenderItemParams; -export type {DraggableListProps, RenderItemParams, RefType, DraggableListType}; +export type {DraggableListProps, RenderItemParams, DraggableListType}; From 15d51667ad9595bbfeb0d6e3929654ceda731f49 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:40:04 +0200 Subject: [PATCH 20/42] Fix gradient --- src/components/DistanceRequest.js | 16 +++++++++------- src/components/DraggableList/index.tsx | 6 ++++++ src/components/DraggableList/types.ts | 5 +++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 0bc3110b6646..ff9fe19aef63 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,4 +1,4 @@ -import React, {useEffect, useMemo, useState, useRef} from 'react'; +import React, {useEffect, useMemo, useState, useRef, useCallback} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; @@ -79,6 +79,8 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) const [shouldShowGradient, setShouldShowGradient] = useState(false); const [scrollContainerHeight, setScrollContainerHeight] = useState(0); const [scrollContentHeight, setScrollContentHeight] = useState(0); + const [scrollContentOffset, setScrollContentOffset] = useState(0); + const {isOffline} = useNetwork(); const {translate} = useLocalize(); @@ -149,11 +151,11 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) Transaction.createInitialWaypoints(iou.transactionID); }, [iou.transactionID, waypoints]); - const updateGradientVisibility = (event = {}) => { + const updateGradientVisibility = () => { // If a waypoint extends past the bottom of the visible area show the gradient, else hide it. - const visibleAreaEnd = lodashGet(event, 'nativeEvent.contentOffset.y', 0) + scrollContainerHeight; + const visibleAreaEnd = scrollContentOffset + scrollContainerHeight; // TODO: Fix updating gradient visibility - setShouldShowGradient(visibleAreaEnd < scrollContentHeight && false); + setShouldShowGradient(visibleAreaEnd < scrollContentHeight); }; useEffect(() => { if (isOffline || !shouldFetchRoute) { @@ -163,7 +165,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) Transaction.getRoute(iou.transactionID, validatedWaypoints); }, [shouldFetchRoute, iou.transactionID, validatedWaypoints, isOffline]); - useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight]); + useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight, scrollContentOffset]); return ( <> @@ -188,8 +190,8 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) }); Transaction.updateWaypoints(iou.transactionID, newWaypoints); }} - onScroll={updateGradientVisibility} - // scrollEventThrottle={16} + onScrollOffsetChange={setScrollContentOffset} + scrollEventThrottle={16} ref={scrollViewRef} renderItem={({item, drag, getIndex}) => { // key is of the form waypoint0, waypoint1, ... diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index 6835e382c1f7..ff5c7c8f2b3e 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -33,6 +33,8 @@ function DraggableList( renderClone, shouldUsePortal = false, onContentSizeChange, + onScrollOffsetChange, + scrollEventThrottle = 16, }: DraggableListProps, ref: React.ForwardedRef, ) { @@ -91,6 +93,10 @@ function DraggableList( // We use ScrollView to match the native behavior of FlatList { + onScrollOffsetChange?.(e.nativeEvent.contentOffset.y); + }} + scrollEventThrottle={scrollEventThrottle} ref={ref} > {/* We can't use the react-native View here, because it doesn't support all props */} diff --git a/src/components/DraggableList/types.ts b/src/components/DraggableList/types.ts index 64e0f0b09fd3..ff1620a4e7f9 100644 --- a/src/components/DraggableList/types.ts +++ b/src/components/DraggableList/types.ts @@ -1,7 +1,7 @@ import type {DraggableChildrenFn} from 'react-beautiful-dnd'; import {FlatList} from 'react-native-gesture-handler'; import type {RenderItemParams as OriginalRenderItemParams} from 'react-native-draggable-flatlist'; -import { ScrollView } from 'react-native'; +import {ScrollView} from 'react-native'; type DraggableListType = (props: DraggableListProps & {ref?: React.ForwardedRef | ScrollView>}) => JSX.Element; @@ -19,7 +19,8 @@ type DraggableListProps = { shouldUsePortal?: boolean; onContentSizeChange?: ((w: number, h: number) => void) | undefined; // TODO: implement on web - onScrollOffsetChange?: (() => void) | undefined; + onScrollOffsetChange?: ((offset: number) => void) | undefined; + scrollEventThrottle?: number; } & DraggableListData; type RenderItemParams = OriginalRenderItemParams; From 28d095bdf9a689d922a190c60f2327437fa425df Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 4 Sep 2023 15:27:20 +0200 Subject: [PATCH 21/42] fix background when dragging --- src/components/DistanceRequest.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index ff9fe19aef63..c99f34f8850e 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,4 +1,4 @@ -import React, {useEffect, useMemo, useState, useRef, useCallback} from 'react'; +import React, {useEffect, useMemo, useState, useRef} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; @@ -193,7 +193,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) onScrollOffsetChange={setScrollContentOffset} scrollEventThrottle={16} ref={scrollViewRef} - renderItem={({item, drag, getIndex}) => { + renderItem={({item, drag, getIndex, isActive}) => { // key is of the form waypoint0, waypoint1, ... const index = getIndex(); let descriptionKey = 'distance.waypointDescription.'; @@ -220,6 +220,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) shouldShowRightIcon onPress={() => Navigation.navigate(ROUTES.getMoneyRequestWaypointRoute('request', index))} onSecondaryInteraction={drag} + focused={isActive} key={item} /> ); From 5a95c8740d3b13db4ebe8d9995dcf3611224b6bf Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Mon, 4 Sep 2023 15:30:50 +0200 Subject: [PATCH 22/42] add comment --- src/components/DraggableList/index.native.tsx | 2 ++ src/components/DraggableList/index.tsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/components/DraggableList/index.native.tsx b/src/components/DraggableList/index.native.tsx index 5d8abc42bf39..75985fa33ab6 100644 --- a/src/components/DraggableList/index.native.tsx +++ b/src/components/DraggableList/index.native.tsx @@ -15,4 +15,6 @@ function DraggableList({renderClone, shouldUsePortal, ...viewProps}: Draggabl DraggableList.displayName = 'DraggableList'; +// We have to assert the type here because we use generic forwrded ref +// https://fettblog.eu/typescript-react-generic-forward-refs/#option-1%3A-type-assertion export default React.forwardRef(DraggableList) as DraggableListType; diff --git a/src/components/DraggableList/index.tsx b/src/components/DraggableList/index.tsx index ff5c7c8f2b3e..8554642b8958 100644 --- a/src/components/DraggableList/index.tsx +++ b/src/components/DraggableList/index.tsx @@ -143,4 +143,6 @@ function DraggableList( DraggableList.displayName = 'DraggableList'; +// We have to assert the type here because we use generic forwrded ref +// https://fettblog.eu/typescript-react-generic-forward-refs/#option-1%3A-type-assertion export default React.forwardRef(DraggableList) as DraggableListType; From c3803c05644deb600036255f8aacb9f60115b29e Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:41:57 +0200 Subject: [PATCH 23/42] fix merge --- src/components/DistanceRequest.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index d959b30856a8..21a1d16245a2 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -190,13 +190,6 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken, scrollViewRef.current.scrollToEnd({animated: true}); }, [numberOfPreviousWaypoints, numberOfWaypoints]); - useEffect(() => { - if (numberOfWaypoints <= numberOfPreviousWaypoints) { - return; - } - scrollViewRef.current.scrollToEnd({animated: true}); - }, [numberOfPreviousWaypoints, numberOfWaypoints]); - useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight, scrollContentOffset]); const navigateBack = () => { From f764c47bd9bc56c52695dd895d2ec0bed919c612 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:55:13 +0200 Subject: [PATCH 24/42] fix import --- src/components/DistanceRequest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 21a1d16245a2..2002334fc1f6 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,5 +1,5 @@ import React, {useEffect, useMemo, useState, useRef} from 'react'; -import {View} from 'react-native'; +import {View, ScrollView} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; import lodashHas from 'lodash/has'; From a0c17cb74e4f63cbf9be56778b94a9463aa04fb5 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:42:29 +0200 Subject: [PATCH 25/42] draft of new designs --- src/components/DistanceRequest.js | 143 ++++++++++--------------- src/components/DraggableList/index.tsx | 44 ++++---- src/components/DraggableList/types.ts | 5 +- 3 files changed, 77 insertions(+), 115 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 4306088d1374..a97efb36eda3 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -1,5 +1,5 @@ -import React, {useEffect, useMemo, useState, useRef} from 'react'; -import {View, ScrollView} from 'react-native'; +import React, {useEffect, useMemo, useRef} from 'react'; +import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; import lodashIsNil from 'lodash/isNil'; @@ -30,7 +30,6 @@ import * as IOUUtils from '../libs/IOUUtils'; import Button from './Button'; import DistanceMapView from './DistanceMapView'; import DraggableList from './DraggableList'; -import LinearGradient from './LinearGradient'; import * as Expensicons from './Icon/Expensicons'; import PendingMapView from './MapView/PendingMapView'; import DotIndicatorMessage from './DotIndicatorMessage'; @@ -38,13 +37,11 @@ import MenuItemWithTopDescription from './MenuItemWithTopDescription'; import {iouPropTypes} from '../pages/iou/propTypes'; import reportPropTypes from '../pages/reportPropTypes'; import * as IOU from '../libs/actions/IOU'; -import * as StyleUtils from '../styles/StyleUtils'; import ScreenWrapper from './ScreenWrapper'; import FullPageNotFoundView from './BlockingViews/FullPageNotFoundView'; import HeaderWithBackButton from './HeaderWithBackButton'; const MAX_WAYPOINTS = 25; -const MAX_WAYPOINTS_TO_DISPLAY = 4; const propTypes = { /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ @@ -92,11 +89,6 @@ const defaultProps = { }; function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken, route}) { - const [shouldShowGradient, setShouldShowGradient] = useState(false); - const [scrollContainerHeight, setScrollContainerHeight] = useState(0); - const [scrollContentHeight, setScrollContentHeight] = useState(0); - const [scrollContentOffset, setScrollContentOffset] = useState(0); - const {isOffline} = useNetwork(); const {translate} = useLocalize(); @@ -153,10 +145,6 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken, [waypoints, lastWaypointIndex], ); - // Show up to the max number of waypoints plus 1/2 of one to hint at scrolling - const halfMenuItemHeight = Math.floor(variables.optionRowHeight / 2); - const scrollContainerMaxHeight = variables.optionRowHeight * MAX_WAYPOINTS_TO_DISPLAY + halfMenuItemHeight; - useEffect(() => { MapboxToken.init(); return MapboxToken.stop; @@ -170,12 +158,6 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken, Transaction.createInitialWaypoints(iou.transactionID); }, [iou.transactionID, waypoints]); - const updateGradientVisibility = () => { - // If a waypoint extends past the bottom of the visible area show the gradient, else hide it. - const visibleAreaEnd = scrollContentOffset + scrollContainerHeight; - // TODO: Fix updating gradient visibility - setShouldShowGradient(visibleAreaEnd < scrollContentHeight); - }; useEffect(() => { if (isOffline || !shouldFetchRoute) { return; @@ -191,8 +173,6 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken, scrollViewRef.current.scrollToEnd({animated: true}); }, [numberOfPreviousWaypoints, numberOfWaypoints]); - useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight, scrollContentOffset]); - const navigateBack = () => { Navigation.goBack(isEditing ? ROUTES.getMoneyRequestConfirmationRoute(iouType, reportID) : null); }; @@ -206,22 +186,58 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken, IOU.navigateToNextPage(iou, iouType, reportID, report); }; + const footer = ( + <> + {hasRouteError && ( + + )} + +