aboutsummaryrefslogtreecommitdiffstats
path: root/packages/renderer/src/components/ServicePanel.tsx
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-04-24 17:01:25 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-05-16 00:55:02 +0200
commit0b632445a933644c7eb10015eb04b7c21d562900 (patch)
tree5bd1fe200cc747086220dbcba90097bfe2cc4cdc /packages/renderer/src/components/ServicePanel.tsx
parentchore(deps): upgrade dependencies (diff)
downloadsophie-0b632445a933644c7eb10015eb04b7c21d562900.tar.gz
sophie-0b632445a933644c7eb10015eb04b7c21d562900.tar.zst
sophie-0b632445a933644c7eb10015eb04b7c21d562900.zip
refactor: reduce service switcher tearing
We render the location bar and notification banners separately for each service and keep track of the BrowserView size separately for each service to reduce the tearing that appears when people switch services. The tearing cannot be eliminated completely, because it comes from the separation between the main and renderer processes. But we can at least try and reduce the IPC round-tripping and layout calculations required to accurately position the services. This approach has an overhead compared to the single BrowserViewPlaceholder approach, because the renderer process has to layout the location bar and notification for all services, not only the selected one. The number of IPC messages during windows resize is also increased. To compensate, we increase the throttle interval for resize IPC messages and let electron itself resize the BrowserView between IPC updates. (We must still keep pumping IPC messages during window resize, because, e.g., changes in notification banner size due to re-layouting will still affect the required BrowserView size). If further reduction of IPC traffic is needed, we could implement batching for resize IPC messages and more intelligent throttling via a token bucker mechanism. Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/renderer/src/components/ServicePanel.tsx')
-rw-r--r--packages/renderer/src/components/ServicePanel.tsx76
1 files changed, 76 insertions, 0 deletions
diff --git a/packages/renderer/src/components/ServicePanel.tsx b/packages/renderer/src/components/ServicePanel.tsx
new file mode 100644
index 0000000..de58d24
--- /dev/null
+++ b/packages/renderer/src/components/ServicePanel.tsx
@@ -0,0 +1,76 @@
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 { observer } from 'mobx-react-lite';
23import React from 'react';
24
25import Service from '../stores/Service';
26
27import BrowserViewPlaceholder from './BrowserViewPlaceholder';
28import { useStore } from './StoreProvider';
29import InsecureConnectionBanner from './banner/InsecureConnectionBanner';
30import NewWindowBanner from './banner/NewWindowBanner';
31import ErrorPage from './errorPage/ErrorPage';
32import LocationBar from './locationBar/LocationBar';
33
34export function getServicePanelID(service: Service): string {
35 return `Sophie-${service.id}-ServicePanel`;
36}
37
38function ServicePanel({ service }: { service: Service }): JSX.Element {
39 const {
40 settings: { selectedService },
41 } = useStore();
42
43 const {
44 settings: { name },
45 } = service;
46 const visible = service === selectedService;
47
48 return (
49 <Box
50 id={getServicePanelID(service)}
51 role="tabpanel"
52 aria-label={name}
53 sx={{
54 position: 'absolute',
55 top: 0,
56 left: 0,
57 bottom: 0,
58 right: 0,
59 display: 'flex',
60 overflow: 'hidden',
61 visibility: visible ? 'visible' : 'hidden',
62 flexDirection: 'column',
63 alignItems: 'stretch',
64 }}
65 >
66 <LocationBar service={service} />
67 <InsecureConnectionBanner service={service} />
68 <NewWindowBanner service={service} />
69 <BrowserViewPlaceholder service={service}>
70 <ErrorPage service={service} />
71 </BrowserViewPlaceholder>
72 </Box>
73 );
74}
75
76export default observer(ServicePanel);