From d303f2e3415237e1a519db21ad4e089c2ba7e9f9 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 23 Dec 2021 21:29:26 +0100 Subject: feat: Add BrowserView and synchronize its position --- .../src/components/BrowserViewPlaceholder.tsx | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 packages/renderer/src/components/BrowserViewPlaceholder.tsx (limited to 'packages/renderer/src/components/BrowserViewPlaceholder.tsx') diff --git a/packages/renderer/src/components/BrowserViewPlaceholder.tsx b/packages/renderer/src/components/BrowserViewPlaceholder.tsx new file mode 100644 index 0000000..06dc7fe --- /dev/null +++ b/packages/renderer/src/components/BrowserViewPlaceholder.tsx @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2021-2022 Kristóf Marussy + * + * This file is part of Sophie. + * + * Sophie is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { throttle } from 'lodash'; +import { observer } from 'mobx-react-lite'; +import Box from '@mui/material/Box'; +import React, { + useCallback, + useEffect, + useRef, + useState, +} from 'react'; +import type { BrowserViewBounds } from '@sophie/shared'; + +import { useStore } from './StoreProvider'; + +export const BrowserViewPlaceholder = observer(function BrowserViewPlaceholder() { + const { + shared: { + browserViewBounds: { + x: storeX, + y: storeY, + width: storeWidth, + height: storeHeight, + }, + }, + setBrowserViewBounds, + } = useStore(); + + const [ + { + x: currentX, + y: currentY, + width: currentWidth, + height: currentHeight, + }, + setBounds, + ] = useState({ + x: 0, + y: 0, + width: 0, + height: 0, + }); + + useEffect(() => { + if (storeX !== currentX + || storeY !== currentY + || storeWidth !== currentWidth + || storeHeight !== currentHeight) { + setBrowserViewBounds({ + x: currentX, + y: currentY, + width: currentWidth, + height: currentHeight, + }); + } + }, [ + storeX, + storeY, + storeWidth, + storeHeight, + setBrowserViewBounds, + currentX, + currentY, + currentWidth, + currentHeight, + ]); + + const onResize = useCallback(throttle(([boxEntry]: ResizeObserverEntry[]) => { + if (boxEntry) { + const { + x, + y, + width, + height, + } = boxEntry.target.getBoundingClientRect(); + setBounds({ + x, + y, + width, + height, + }); + } + }, 100), [setBounds]); + + const resizeObserverRef = useRef(null); + + const ref = useCallback((box: HTMLElement | null) => { + if (resizeObserverRef.current !== null) { + resizeObserverRef.current.disconnect(); + } + if (box === null) { + resizeObserverRef.current = null; + return; + } + resizeObserverRef.current = new ResizeObserver(onResize); + resizeObserverRef.current.observe(box); + }, [onResize, resizeObserverRef]); + + return ( + + ) +}); -- cgit v1.2.3-54-g00ecf