mirror of
https://github.com/hexastack/hexabot
synced 2025-05-31 10:57:06 +00:00
Merge pull request #55 from AuraOfDivinity/fix/concurrent-update-requests-on-zoom-and-offset
fix: add request queue to handle concurrent zoom & offset requests
This commit is contained in:
commit
37f20f7d79
@ -22,7 +22,6 @@ import {
|
||||
Tab,
|
||||
Tabs,
|
||||
Tooltip,
|
||||
debounce,
|
||||
tabsClasses,
|
||||
} from "@mui/material";
|
||||
import {
|
||||
@ -32,7 +31,13 @@ import {
|
||||
DiagramModel,
|
||||
DiagramModelGenerics,
|
||||
} from "@projectstorm/react-diagrams";
|
||||
import { SyntheticEvent, useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
SyntheticEvent,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { DeleteDialog } from "@/app-components/dialogs";
|
||||
@ -41,6 +46,7 @@ import { useDelete, useDeleteFromCache } from "@/hooks/crud/useDelete";
|
||||
import { useFind } from "@/hooks/crud/useFind";
|
||||
import { useGetFromCache } from "@/hooks/crud/useGet";
|
||||
import { useUpdate, useUpdateCache } from "@/hooks/crud/useUpdate";
|
||||
import useDebouncedUpdate from "@/hooks/useDebouncedUpdate";
|
||||
import { getDisplayDialogs, useDialog } from "@/hooks/useDialog";
|
||||
import { useSearch } from "@/hooks/useSearch";
|
||||
import { EntityType, Format } from "@/services/types";
|
||||
@ -108,29 +114,36 @@ const Diagrams = () => {
|
||||
const { mutateAsync: updateBlock } = useUpdate(EntityType.BLOCK, {
|
||||
invalidate: false,
|
||||
});
|
||||
const debouncedZoomEvent = debounce((event) => {
|
||||
if (selectedCategoryId) {
|
||||
engine?.repaintCanvas();
|
||||
updateCategory({
|
||||
id: selectedCategoryId,
|
||||
params: {
|
||||
zoom: event.zoom,
|
||||
},
|
||||
});
|
||||
}
|
||||
event.stopPropagation();
|
||||
}, 200);
|
||||
const debouncedOffsetEvent = debounce((event) => {
|
||||
if (selectedCategoryId) {
|
||||
updateCategory({
|
||||
id: selectedCategoryId,
|
||||
params: {
|
||||
offset: [event.offsetX, event.offsetY],
|
||||
},
|
||||
});
|
||||
}
|
||||
event.stopPropagation();
|
||||
}, 200);
|
||||
const debouncedUpdateCategory = useDebouncedUpdate(updateCategory, 300);
|
||||
const debouncedZoomEvent = useCallback(
|
||||
(event: any) => {
|
||||
if (selectedCategoryId) {
|
||||
engine?.repaintCanvas();
|
||||
debouncedUpdateCategory({
|
||||
id: selectedCategoryId,
|
||||
params: {
|
||||
zoom: event.zoom,
|
||||
},
|
||||
});
|
||||
}
|
||||
event.stopPropagation();
|
||||
},
|
||||
[selectedCategoryId, engine, debouncedUpdateCategory],
|
||||
);
|
||||
const debouncedOffsetEvent = useCallback(
|
||||
(event: any) => {
|
||||
if (selectedCategoryId) {
|
||||
debouncedUpdateCategory({
|
||||
id: selectedCategoryId,
|
||||
params: {
|
||||
offset: [event.offsetX, event.offsetY],
|
||||
},
|
||||
});
|
||||
}
|
||||
event.stopPropagation();
|
||||
},
|
||||
[selectedCategoryId, debouncedUpdateCategory],
|
||||
);
|
||||
const getBlockFromCache = useGetFromCache(EntityType.BLOCK);
|
||||
const updateCachedBlock = useUpdateCache(EntityType.BLOCK);
|
||||
const deleteCachedBlock = useDeleteFromCache(EntityType.BLOCK);
|
||||
|
54
frontend/src/hooks/useDebouncedUpdate.tsx
Normal file
54
frontend/src/hooks/useDebouncedUpdate.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
* 3. SaaS Restriction: This software, or any derivative of it, may not be used to offer a competing product or service (SaaS) without prior written consent from Hexastack. Offering the software as a service or using it in a commercial cloud environment without express permission is strictly prohibited.
|
||||
*/
|
||||
|
||||
import { debounce } from "@mui/material";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
|
||||
type DebouncedUpdateParams = {
|
||||
id: string;
|
||||
params: Record<string, any>;
|
||||
};
|
||||
|
||||
function useDebouncedUpdate(
|
||||
apiUpdate: (params: DebouncedUpdateParams) => void,
|
||||
delay: number = 300,
|
||||
) {
|
||||
const accumulatedUpdates = useRef<DebouncedUpdateParams | null>(null);
|
||||
const processUpdates = useRef(
|
||||
debounce(() => {
|
||||
if (accumulatedUpdates.current) {
|
||||
apiUpdate(accumulatedUpdates.current);
|
||||
accumulatedUpdates.current = null;
|
||||
}
|
||||
}, delay),
|
||||
).current;
|
||||
const handleUpdate = useCallback(
|
||||
(params: DebouncedUpdateParams) => {
|
||||
accumulatedUpdates.current = {
|
||||
id: params.id,
|
||||
params: {
|
||||
...(accumulatedUpdates.current?.params || {}),
|
||||
...params.params,
|
||||
},
|
||||
};
|
||||
processUpdates();
|
||||
},
|
||||
[processUpdates],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
processUpdates.clear();
|
||||
};
|
||||
}, [processUpdates]);
|
||||
|
||||
return handleUpdate;
|
||||
}
|
||||
|
||||
export default useDebouncedUpdate;
|
Loading…
Reference in New Issue
Block a user