securityos/components/system/Window/RndWindow/useRnd.ts

103 lines
3.0 KiB
TypeScript

import { isWindowOutsideBounds } from "components/system/Window/functions";
import rndDefaults, {
RESIZING_DISABLED,
RESIZING_ENABLED,
} from "components/system/Window/RndWindow/rndDefaults";
import useDraggable from "components/system/Window/RndWindow/useDraggable";
import useResizable from "components/system/Window/RndWindow/useResizable";
import { useProcesses } from "contexts/process";
import { useSession } from "contexts/session";
import { useCallback, useMemo } from "react";
import type { DraggableEventHandler } from "react-draggable";
import type { Props, RndResizeCallback } from "react-rnd";
import { getWindowViewport, pxToNum } from "utils/functions";
const enableIframeCapture = (enable = true): void =>
document.querySelectorAll("iframe").forEach((iframe) => {
// eslint-disable-next-line no-param-reassign
iframe.style.pointerEvents = enable ? "initial" : "none";
});
const useRnd = (id: string): Props => {
const {
processes: {
[id]: {
allowResizing = true,
autoSizing = false,
lockAspectRatio = false,
maximized = false,
} = {},
},
} = useProcesses();
const { setWindowStates } = useSession();
const [size, setSize] = useResizable(id, autoSizing);
const [position, setPosition] = useDraggable(id, size);
const onDragStop: DraggableEventHandler = useCallback(
(_event, { x, y }) => {
enableIframeCapture();
const newPosition = { x, y };
if (
!isWindowOutsideBounds(
{ position: newPosition, size },
getWindowViewport(),
true
)
) {
setPosition(newPosition);
setWindowStates((currentWindowStates) => ({
...currentWindowStates,
[id]: {
...currentWindowStates[id],
position: newPosition,
},
}));
}
},
[id, setPosition, setWindowStates, size]
);
const onResizeStop: RndResizeCallback = useCallback(
(_event, _direction, { style: { height, width } }, _delta, newPositon) => {
enableIframeCapture();
const newSize = { height: pxToNum(height), width: pxToNum(width) };
setSize(newSize);
setPosition(newPositon);
setWindowStates((currentWindowStates) => ({
...currentWindowStates,
[id]: {
...currentWindowStates[id],
position: newPositon,
size: newSize,
},
}));
},
[id, setPosition, setSize, setWindowStates]
);
const disableIframeCapture = useCallback(
() => enableIframeCapture(false),
[]
);
const enableResizing = useMemo(
() => (allowResizing && !maximized ? RESIZING_ENABLED : RESIZING_DISABLED),
[allowResizing, maximized]
);
return {
disableDragging: maximized,
enableResizing,
lockAspectRatio,
onDragStart: disableIframeCapture,
onDragStop,
onResizeStart: disableIframeCapture,
onResizeStop,
position,
size,
...rndDefaults,
};
};
export default useRnd;