perf: embedding calc in worker process
This commit is contained in:
@@ -2,14 +2,7 @@ import RowTextarea from '@/components/seal-form/row-textarea';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React, {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useRef
|
||||
} from 'react';
|
||||
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||
import '../style/input-list.less';
|
||||
|
||||
interface InputListProps {
|
||||
@@ -17,20 +10,15 @@ interface InputListProps {
|
||||
height?: number;
|
||||
extra?: (data: any) => React.ReactNode;
|
||||
showLabel?: boolean;
|
||||
sortIndex?: number[];
|
||||
textList: {
|
||||
text: string;
|
||||
uid: number | string;
|
||||
name: string;
|
||||
}[];
|
||||
sortable?: boolean;
|
||||
onChange?: (
|
||||
textList: { text: string; uid: number | string; name: string }[]
|
||||
) => void;
|
||||
onPaste?: (e: any, index: number) => void;
|
||||
onSort?: (
|
||||
textList: { text: string; uid: number | string; name: string }[]
|
||||
) => void;
|
||||
onSelect?: (data: {
|
||||
start: number;
|
||||
end: number;
|
||||
@@ -42,152 +30,12 @@ interface InputListProps {
|
||||
|
||||
const InputList: React.FC<InputListProps> = forwardRef(
|
||||
(
|
||||
{
|
||||
textList,
|
||||
showLabel = true,
|
||||
sortIndex = [],
|
||||
sortable,
|
||||
height,
|
||||
onSort,
|
||||
onChange,
|
||||
extra,
|
||||
onPaste,
|
||||
onSelect
|
||||
},
|
||||
{ textList, showLabel = true, height, onChange, extra, onPaste, onSelect },
|
||||
ref
|
||||
) => {
|
||||
const intl = useIntl();
|
||||
const messageId = useRef(0);
|
||||
const containerRef = useRef<any>(null);
|
||||
const childListRef = useRef<any[]>([]);
|
||||
|
||||
const getContainerChildList = () => {
|
||||
childListRef.current = Array.from(containerRef.current?.children || []);
|
||||
};
|
||||
|
||||
const getOffsetUsingBoundingClientRect = useCallback(
|
||||
(element: HTMLElement, targetElement: HTMLElement) => {
|
||||
const currentRect = element.getBoundingClientRect();
|
||||
const targetRect = targetElement.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
x: targetRect.left - currentRect.left,
|
||||
y: targetRect.top - currentRect.top
|
||||
};
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
// move item from fromIndex to toIndex
|
||||
const moveItem = useCallback((child: any, toIndex: number) => {
|
||||
const container = containerRef.current;
|
||||
if (!container) return;
|
||||
|
||||
const children = Array.from(container.children);
|
||||
|
||||
if (toIndex >= children.length) {
|
||||
if (container.firstChild) {
|
||||
container.insertBefore(child, container.firstChild);
|
||||
} else {
|
||||
container.appendChild(child);
|
||||
}
|
||||
} else {
|
||||
container.insertBefore(child, children[toIndex]);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const moveElement = (arr: any[], fromIndex: number, toIndex: number) => {
|
||||
if (
|
||||
fromIndex === toIndex ||
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= arr.length ||
|
||||
toIndex > arr.length
|
||||
) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
const element = arr.splice(fromIndex, 1)[0];
|
||||
arr.splice(toIndex > fromIndex ? toIndex - 1 : toIndex, 0, element);
|
||||
return arr;
|
||||
};
|
||||
|
||||
const sort = useCallback(() => {
|
||||
if (!sortable) return;
|
||||
getContainerChildList();
|
||||
const container = containerRef.current;
|
||||
if (!container) return;
|
||||
|
||||
const newOrder = [...textList];
|
||||
|
||||
const offsets = sortIndex.map((fromIndex, toIndex) => {
|
||||
const currentElement = childListRef.current[fromIndex];
|
||||
const targetElement = childListRef.current[toIndex];
|
||||
if (!currentElement || !targetElement) return null;
|
||||
|
||||
const offset = getOffsetUsingBoundingClientRect(
|
||||
currentElement,
|
||||
targetElement
|
||||
);
|
||||
return {
|
||||
element: currentElement,
|
||||
offset: {
|
||||
x: offset.x,
|
||||
y: offset.y
|
||||
},
|
||||
fromIndex,
|
||||
toIndex
|
||||
};
|
||||
});
|
||||
|
||||
const moveSequentially = async () => {
|
||||
for (const [index, data] of offsets.entries()) {
|
||||
if (!data) continue;
|
||||
|
||||
const { element, offset, fromIndex, toIndex } = data;
|
||||
console.log('sort+++++++', {
|
||||
textList,
|
||||
element,
|
||||
offset,
|
||||
fromIndex,
|
||||
toIndex
|
||||
});
|
||||
|
||||
await new Promise((resolve) => {
|
||||
element.style.opacity = 0.5;
|
||||
element.style.transform = `translate(${offset.x}px, ${offset.y}px)`;
|
||||
element.style.transition = 'transform 0.8s,opacity 0.8s';
|
||||
|
||||
element.addEventListener(
|
||||
'transitionend',
|
||||
() => {
|
||||
moveItem(element, toIndex);
|
||||
moveElement(newOrder, fromIndex, toIndex);
|
||||
getContainerChildList();
|
||||
|
||||
element.style.opacity = 1;
|
||||
element.style.transform = '';
|
||||
console.log('sort++++++++++end');
|
||||
|
||||
resolve(null);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
onSort?.(newOrder);
|
||||
};
|
||||
|
||||
moveSequentially();
|
||||
}, [
|
||||
sortable,
|
||||
sortIndex,
|
||||
textList,
|
||||
onSort,
|
||||
getContainerChildList,
|
||||
getOffsetUsingBoundingClientRect
|
||||
]);
|
||||
|
||||
const setMessageId = () => {
|
||||
messageId.current = messageId.current + 1;
|
||||
@@ -221,14 +69,6 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
||||
dataList[index].text = value;
|
||||
onChange?.(dataList);
|
||||
};
|
||||
const debounceSort = _.debounce(sort, 100);
|
||||
|
||||
useEffect(() => {
|
||||
if (sortIndex?.length) {
|
||||
console.log('sort++++2+++');
|
||||
debounceSort();
|
||||
}
|
||||
}, [sortIndex]);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
handleAdd,
|
||||
@@ -277,4 +117,4 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
||||
}
|
||||
);
|
||||
|
||||
export default React.memo(InputList);
|
||||
export default InputList;
|
||||
|
||||
Reference in New Issue
Block a user