aboutsummaryrefslogtreecommitdiffstats
path: root/packages/renderer/src/components
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-23 21:29:26 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-23 21:29:26 +0100
commitd303f2e3415237e1a519db21ad4e089c2ba7e9f9 (patch)
tree5d562dcaf7bb9c83c1930c7d7cf1b2c9de75e15b /packages/renderer/src/components
parentbuild: Enable asar (diff)
downloadsophie-d303f2e3415237e1a519db21ad4e089c2ba7e9f9.tar.gz
sophie-d303f2e3415237e1a519db21ad4e089c2ba7e9f9.tar.zst
sophie-d303f2e3415237e1a519db21ad4e089c2ba7e9f9.zip
feat: Add BrowserView and synchronize its position
Diffstat (limited to 'packages/renderer/src/components')
-rw-r--r--packages/renderer/src/components/App.tsx42
-rw-r--r--packages/renderer/src/components/BrowserViewPlaceholder.tsx128
-rw-r--r--packages/renderer/src/components/Sidebar.tsx42
-rw-r--r--packages/renderer/src/components/ThemeProvider.tsx4
-rw-r--r--packages/renderer/src/components/ToggleDarkModeButton.tsx40
5 files changed, 254 insertions, 2 deletions
diff --git a/packages/renderer/src/components/App.tsx b/packages/renderer/src/components/App.tsx
new file mode 100644
index 0000000..b627fa7
--- /dev/null
+++ b/packages/renderer/src/components/App.tsx
@@ -0,0 +1,42 @@
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
21import Box from '@mui/material/Box';
22import React from 'react';
23
24import { BrowserViewPlaceholder } from './BrowserViewPlaceholder';
25import { Sidebar } from './Sidebar';
26
27export function App(): JSX.Element {
28 return (
29 <Box
30 sx={{
31 display: 'flex',
32 flexDirection: 'row',
33 alignItems: 'stretch',
34 height: '100vh',
35 width: '100vw',
36 }}
37 >
38 <Sidebar />
39 <BrowserViewPlaceholder />
40 </Box>
41 )
42}
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
21import { throttle } from 'lodash';
22import { observer } from 'mobx-react-lite';
23import Box from '@mui/material/Box';
24import React, {
25 useCallback,
26 useEffect,
27 useRef,
28 useState,
29} from 'react';
30import type { BrowserViewBounds } from '@sophie/shared';
31
32import { useStore } from './StoreProvider';
33
34export 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});
diff --git a/packages/renderer/src/components/Sidebar.tsx b/packages/renderer/src/components/Sidebar.tsx
new file mode 100644
index 0000000..6c79932
--- /dev/null
+++ b/packages/renderer/src/components/Sidebar.tsx
@@ -0,0 +1,42 @@
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
21import Box from '@mui/material/Box';
22import React from 'react';
23
24import { ToggleDarkModeButton } from './ToggleDarkModeButton';
25
26export function Sidebar(): JSX.Element {
27 return (
28 <Box
29 sx={(theme) => ({
30 background: theme.palette.divider,
31 flex: 0,
32 display: 'flex',
33 flexDirection: 'column',
34 alignItems: 'center',
35 justifyContent: 'flex-end',
36 padding: 1,
37 })}
38 >
39 <ToggleDarkModeButton />
40 </Box>
41 );
42}
diff --git a/packages/renderer/src/components/ThemeProvider.tsx b/packages/renderer/src/components/ThemeProvider.tsx
index 7173a9d..9215f5c 100644
--- a/packages/renderer/src/components/ThemeProvider.tsx
+++ b/packages/renderer/src/components/ThemeProvider.tsx
@@ -27,9 +27,9 @@ import React from 'react';
27 27
28import { useStore } from './StoreProvider'; 28import { useStore } from './StoreProvider';
29 29
30export const ThemeProvider = observer(({ children }: { 30export const ThemeProvider = observer(function ThemeProvider({ children }: {
31 children: JSX.Element | JSX.Element[], 31 children: JSX.Element | JSX.Element[],
32}): JSX.Element => { 32}) {
33 const { shared: { shouldUseDarkColors } } = useStore(); 33 const { shared: { shouldUseDarkColors } } = useStore();
34 34
35 const theme = createTheme({ 35 const theme = createTheme({
diff --git a/packages/renderer/src/components/ToggleDarkModeButton.tsx b/packages/renderer/src/components/ToggleDarkModeButton.tsx
new file mode 100644
index 0000000..1b6757e
--- /dev/null
+++ b/packages/renderer/src/components/ToggleDarkModeButton.tsx
@@ -0,0 +1,40 @@
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
21import { observer } from 'mobx-react-lite';
22import DarkModeIcon from '@mui/icons-material/DarkMode';
23import LightModeIcon from '@mui/icons-material/LightMode';
24import IconButton from '@mui/material/IconButton';
25import React from 'react';
26
27import { useStore } from './StoreProvider';
28
29export const ToggleDarkModeButton = observer(function ToggleDarkModeButton() {
30 const { shared: { shouldUseDarkColors }, toggleDarkMode } = useStore();
31
32 return (
33 <IconButton
34 aria-label="Toggle dark mode"
35 onClick={() => toggleDarkMode()}
36 >
37 {shouldUseDarkColors ? <LightModeIcon /> : <DarkModeIcon />}
38 </IconButton>
39 );
40});