diff options
Diffstat (limited to 'packages/renderer/src/components')
-rw-r--r-- | packages/renderer/src/components/App.tsx | 42 | ||||
-rw-r--r-- | packages/renderer/src/components/BrowserViewPlaceholder.tsx | 128 | ||||
-rw-r--r-- | packages/renderer/src/components/Sidebar.tsx | 42 | ||||
-rw-r--r-- | packages/renderer/src/components/ThemeProvider.tsx | 4 | ||||
-rw-r--r-- | packages/renderer/src/components/ToggleDarkModeButton.tsx | 40 |
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 | |||
21 | import Box from '@mui/material/Box'; | ||
22 | import React from 'react'; | ||
23 | |||
24 | import { BrowserViewPlaceholder } from './BrowserViewPlaceholder'; | ||
25 | import { Sidebar } from './Sidebar'; | ||
26 | |||
27 | export 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 | |||
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 | }); | ||
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 | |||
21 | import Box from '@mui/material/Box'; | ||
22 | import React from 'react'; | ||
23 | |||
24 | import { ToggleDarkModeButton } from './ToggleDarkModeButton'; | ||
25 | |||
26 | export 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 | ||
28 | import { useStore } from './StoreProvider'; | 28 | import { useStore } from './StoreProvider'; |
29 | 29 | ||
30 | export const ThemeProvider = observer(({ children }: { | 30 | export 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 | |||
21 | import { observer } from 'mobx-react-lite'; | ||
22 | import DarkModeIcon from '@mui/icons-material/DarkMode'; | ||
23 | import LightModeIcon from '@mui/icons-material/LightMode'; | ||
24 | import IconButton from '@mui/material/IconButton'; | ||
25 | import React from 'react'; | ||
26 | |||
27 | import { useStore } from './StoreProvider'; | ||
28 | |||
29 | export 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 | }); | ||