diff --git a/src/components/window/WindowFrame.tsx b/src/components/window/WindowFrame.tsx index 3b23b867..8026846b 100644 --- a/src/components/window/WindowFrame.tsx +++ b/src/components/window/WindowFrame.tsx @@ -1,10 +1,11 @@ import { css, cx } from "@emotion/css"; +import { isEqual } from "lodash"; import { mapValues } from "lodash/fp"; import React, { forwardRef, PropsWithChildren, RefObject, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import FocusLock from "react-focus-lock"; import { Position, Rnd } from "react-rnd"; import { CSSTransition } from "react-transition-group"; -import { useMutationObserver, usePreviousDifferent, usePreviousImmediate } from "rooks"; +import { useDebounce, useMutationObserver, usePreviousDifferent, usePreviousImmediate } from "rooks"; import { DRAG_HANDLE_CLASS_NAME, DRAG_PREVENT_CLASS_NAME } from "../../consts"; import { useViewportSize } from "../../hooks"; import { useScrollFix } from "../../hooks/useScrollFix"; @@ -113,7 +114,6 @@ export const WindowFrame = forwardRef((props: PropsWithChildren { - if (ref.current && !wasMaximized) { + if (ref.current) { const randomize = mapValues((v: number) => Math.max(0, v + random(randomizePosition))); const { height, width } = ref.current.getBoundingClientRect(); const x = (viewport.width - width) / 2; - const y = (viewport.height * 0.65 - height) / 2; + const y = (viewport.height * 0.75 - height) / 2; const center = randomize({ x, y }); setPosition( roundCoords({ - x: initialPosition.x ?? calcCoord(center.x, center.x + width, width, viewport.width, windowMargin), - y: initialPosition.y ?? calcCoord(center.y, center.y + height, height, viewport.height, windowMargin), + x: initialPosition.x ?? center.x, + y: initialPosition.y ?? center.y, }), ); } }, - [randomizePosition, viewport.height, viewport.width, wasMaximized, windowMargin], + [randomizePosition, viewport.height, viewport.width], ); const onContentChanged = useCallback(() => { @@ -154,6 +154,31 @@ export const WindowFrame = forwardRef((props: PropsWithChildren { + const width = size?.width || box?.width || 0; + const height = size?.height || box?.height || 0; + return roundCoords({ + x: calcCoord(box.x, box.x + box.width, width, viewport.width, windowMargin), + y: calcCoord(box.y, box.y + box.height, height, viewport.height, windowMargin), + }); + }, + [size, windowMargin], + ); + + // it fixes an issue with Maximum update depth exceeded error + const debounceSetPosition = useDebounce(setPosition, 0, { leading: true }); + + useLayoutEffect(() => { + if (contentAvailable && position && !(maximized || wasMaximized)) { + const newValue = calcEdgePosition(viewport); + debounceSetPosition((current) => (isEqual(newValue, current) ? current : newValue)); + } + }, [contentAvailable, wasMaximized, calcEdgePosition, maximized, position, viewport, debounceSetPosition]); + const savePosition = useCallback((position: Position) => !maximized && setPosition(roundCoords(position)), [maximized]); const [side, setSide] = useState(Side.none); @@ -238,7 +263,7 @@ export const WindowFrame = forwardRef((props: PropsWithChildren ({ width: `calc(100% - ${position?.x <= windowMargin ? windowMargin * 2 : position?.x || 0}px)`, - height: viewport.height - (position?.y <= windowMargin ? windowMargin * 2 : position?.y + windowMargin || 0), + height: viewport.height - (position?.y <= windowMargin ? windowMargin * 2 : position?.y || 0), }), [windowMargin, position, viewport.height], );