diff options
Diffstat (limited to 'packages/renderer/src/components/BrowserViewPlaceholder.tsx')
-rw-r--r-- | packages/renderer/src/components/BrowserViewPlaceholder.tsx | 128 |
1 files changed, 128 insertions, 0 deletions
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 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { throttle } from 'lodash'; | ||
22 | import { observer } from 'mobx-react-lite'; | ||
23 | import Box from '@mui/material/Box'; | ||
24 | import React, { | ||
25 | useCallback, | ||
26 | useEffect, | ||
27 | useRef, | ||
28 | useState, | ||
29 | } from 'react'; | ||
30 | import type { BrowserViewBounds } from '@sophie/shared'; | ||
31 | |||
32 | import { useStore } from './StoreProvider'; | ||
33 | |||
34 | export const BrowserViewPlaceholder = observer(function BrowserViewPlaceholder() { | ||
35 | const { | ||
36 | shared: { | ||
37 | browserViewBounds: { | ||
38 | x: storeX, | ||
39 | y: storeY, | ||
40 | width: storeWidth, | ||
41 | height: storeHeight, | ||
42 | }, | ||
43 | }, | ||
44 | setBrowserViewBounds, | ||
45 | } = useStore(); | ||
46 | |||
47 | const [ | ||
48 | { | ||
49 | x: currentX, | ||
50 | y: currentY, | ||
51 | width: currentWidth, | ||
52 | height: currentHeight, | ||
53 | }, | ||
54 | setBounds, | ||
55 | ] = useState<BrowserViewBounds>({ | ||
56 | x: 0, | ||
57 | y: 0, | ||
58 | width: 0, | ||
59 | height: 0, | ||
60 | }); | ||
61 | |||
62 | useEffect(() => { | ||
63 | if (storeX !== currentX | ||
64 | || storeY !== currentY | ||
65 | || storeWidth !== currentWidth | ||
66 | || storeHeight !== currentHeight) { | ||
67 | setBrowserViewBounds({ | ||
68 | x: currentX, | ||
69 | y: currentY, | ||
70 | width: currentWidth, | ||
71 | height: currentHeight, | ||
72 | }); | ||
73 | } | ||
74 | }, [ | ||
75 | storeX, | ||
76 | storeY, | ||
77 | storeWidth, | ||
78 | storeHeight, | ||
79 | setBrowserViewBounds, | ||
80 | currentX, | ||
81 | currentY, | ||
82 | currentWidth, | ||
83 | currentHeight, | ||
84 | ]); | ||
85 | |||
86 | const onResize = useCallback(throttle(([boxEntry]: ResizeObserverEntry[]) => { | ||
87 | if (boxEntry) { | ||
88 | const { | ||
89 | x, | ||
90 | y, | ||
91 | width, | ||
92 | height, | ||
93 | } = boxEntry.target.getBoundingClientRect(); | ||
94 | setBounds({ | ||
95 | x, | ||
96 | y, | ||
97 | width, | ||
98 | height, | ||
99 | }); | ||
100 | } | ||
101 | }, 100), [setBounds]); | ||
102 | |||
103 | const resizeObserverRef = useRef<ResizeObserver | null>(null); | ||
104 | |||
105 | const ref = useCallback((box: HTMLElement | null) => { | ||
106 | if (resizeObserverRef.current !== null) { | ||
107 | resizeObserverRef.current.disconnect(); | ||
108 | } | ||
109 | if (box === null) { | ||
110 | resizeObserverRef.current = null; | ||
111 | return; | ||
112 | } | ||
113 | resizeObserverRef.current = new ResizeObserver(onResize); | ||
114 | resizeObserverRef.current.observe(box); | ||
115 | }, [onResize, resizeObserverRef]); | ||
116 | |||
117 | return ( | ||
118 | <Box | ||
119 | sx={{ | ||
120 | flex: 1, | ||
121 | // Workaround: display a plain white background if we fail to set the BrowserView background color. | ||
122 | // https://github.com/electron/electron/issues/31019 | ||
123 | background: '#fff', | ||
124 | }} | ||
125 | ref={ref} | ||
126 | /> | ||
127 | ) | ||
128 | }); | ||