aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-08-21 00:33:01 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-08-21 02:01:59 +0200
commit8ebc24a5ba1c87cb5cb14fbaff3bee329e30fc15 (patch)
tree2ea323c637ef371d4bdfc9ccc69460147dd1597b /subprojects/frontend/src
parentfeat(frontend): try to match OS theme (diff)
downloadrefinery-8ebc24a5ba1c87cb5cb14fbaff3bee329e30fc15.tar.gz
refinery-8ebc24a5ba1c87cb5cb14fbaff3bee329e30fc15.tar.zst
refinery-8ebc24a5ba1c87cb5cb14fbaff3bee329e30fc15.zip
feat(frontend): overlay window controls
Might need manual intervention in browsers, e.g. https://docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/window-controls-overlay#enable-the-window-controls-overlay-api-in-microsoft-edge
Diffstat (limited to 'subprojects/frontend/src')
-rw-r--r--subprojects/frontend/src/TopBar.tsx58
-rw-r--r--subprojects/frontend/src/WindowControlsOverlayColor.tsx21
-rw-r--r--subprojects/frontend/src/index.tsx2
3 files changed, 79 insertions, 2 deletions
diff --git a/subprojects/frontend/src/TopBar.tsx b/subprojects/frontend/src/TopBar.tsx
index 5ad80d40..4424e6b3 100644
--- a/subprojects/frontend/src/TopBar.tsx
+++ b/subprojects/frontend/src/TopBar.tsx
@@ -1,11 +1,47 @@
1import AppBar from '@mui/material/AppBar'; 1import AppBar from '@mui/material/AppBar';
2import Toolbar from '@mui/material/Toolbar'; 2import Toolbar from '@mui/material/Toolbar';
3import Typography from '@mui/material/Typography'; 3import Typography from '@mui/material/Typography';
4import React from 'react'; 4import { throttle } from 'lodash-es';
5import React, { useEffect, useMemo, useState } from 'react';
5 6
6import ToggleDarkModeButton from './ToggleDarkModeButton'; 7import ToggleDarkModeButton from './ToggleDarkModeButton';
7 8
9function useWindowControlsOverlayVisible(): boolean {
10 const [windowControlsOverlayVisible, setWindowControlsOverlayVisible] =
11 useState(false);
12 const updateWindowControlsOverlayVisible = useMemo(
13 () =>
14 throttle(
15 ({ visible }: WindowControlsOverlayGeometryChangeEvent) =>
16 setWindowControlsOverlayVisible(visible),
17 250,
18 ),
19 [],
20 );
21 useEffect(() => {
22 if ('windowControlsOverlay' in navigator) {
23 const { windowControlsOverlay } = navigator;
24 setWindowControlsOverlayVisible(windowControlsOverlay.visible);
25 windowControlsOverlay.addEventListener(
26 'geometrychange',
27 updateWindowControlsOverlayVisible,
28 );
29 return () => {
30 windowControlsOverlay.removeEventListener(
31 'geometrychange',
32 updateWindowControlsOverlayVisible,
33 );
34 };
35 }
36 // Nothing to clean up if `windowControlsOverlay` is unsupported.
37 return () => {};
38 }, [updateWindowControlsOverlayVisible]);
39 return windowControlsOverlayVisible;
40}
41
8export default function TopBar(): JSX.Element { 42export default function TopBar(): JSX.Element {
43 const overlayVisible = useWindowControlsOverlayVisible();
44
9 return ( 45 return (
10 <AppBar 46 <AppBar
11 position="static" 47 position="static"
@@ -14,9 +50,27 @@ export default function TopBar(): JSX.Element {
14 sx={(theme) => ({ 50 sx={(theme) => ({
15 background: theme.palette.outer.background, 51 background: theme.palette.outer.background,
16 borderBottom: `1px solid ${theme.palette.outer.border}`, 52 borderBottom: `1px solid ${theme.palette.outer.border}`,
53 appRegion: 'drag',
54 '.MuiButtonBase-root': {
55 appRegion: 'no-drag',
56 },
17 })} 57 })}
18 > 58 >
19 <Toolbar> 59 <Toolbar
60 sx={{
61 ...(overlayVisible
62 ? {
63 marginLeft: 'env(titlebar-area-x, 0)',
64 marginTop: 'env(titlebar-area-y, 0)',
65 width: 'env(titlebar-area-width, 100%)',
66 minHeight: 'env(titlebar-area-height, auto)',
67 }
68 : {
69 minHeight: 'auto',
70 }),
71 py: 0.5,
72 }}
73 >
20 <Typography variant="h6" component="h1" flexGrow={1}> 74 <Typography variant="h6" component="h1" flexGrow={1}>
21 Refinery 75 Refinery
22 </Typography> 76 </Typography>
diff --git a/subprojects/frontend/src/WindowControlsOverlayColor.tsx b/subprojects/frontend/src/WindowControlsOverlayColor.tsx
new file mode 100644
index 00000000..14eda566
--- /dev/null
+++ b/subprojects/frontend/src/WindowControlsOverlayColor.tsx
@@ -0,0 +1,21 @@
1import { useTheme } from '@mui/material/styles';
2import { useEffect } from 'react';
3
4export default function WindowControlsOverlayColor(): null {
5 const {
6 palette: {
7 outer: { background },
8 },
9 } = useTheme();
10 useEffect(() => {
11 document.head
12 .querySelectorAll('meta[name="theme-color"]')
13 .forEach((meta) => meta.remove());
14 const meta = document.createElement('meta');
15 meta.name = 'theme-color';
16 meta.content = background;
17 document.head.appendChild(meta);
18 }, [background]);
19
20 return null;
21}
diff --git a/subprojects/frontend/src/index.tsx b/subprojects/frontend/src/index.tsx
index a65821ef..460f6f77 100644
--- a/subprojects/frontend/src/index.tsx
+++ b/subprojects/frontend/src/index.tsx
@@ -6,6 +6,7 @@ import { createRoot } from 'react-dom/client';
6import Loading from './Loading'; 6import Loading from './Loading';
7import RegisterServiceWorker from './RegisterServiceWorker'; 7import RegisterServiceWorker from './RegisterServiceWorker';
8import RootStore, { RootStoreProvider } from './RootStore'; 8import RootStore, { RootStoreProvider } from './RootStore';
9import WindowControlsOverlayColor from './WindowControlsOverlayColor';
9import ThemeProvider from './theme/ThemeProvider'; 10import ThemeProvider from './theme/ThemeProvider';
10import getLogger from './utils/getLogger'; 11import getLogger from './utils/getLogger';
11 12
@@ -67,6 +68,7 @@ const app = (
67 <RootStoreProvider rootStore={rootStore}> 68 <RootStoreProvider rootStore={rootStore}>
68 <ThemeProvider> 69 <ThemeProvider>
69 <CssBaseline enableColorScheme /> 70 <CssBaseline enableColorScheme />
71 <WindowControlsOverlayColor />
70 <SnackbarProvider> 72 <SnackbarProvider>
71 <RegisterServiceWorker /> 73 <RegisterServiceWorker />
72 <Suspense fallback={<Loading />}> 74 <Suspense fallback={<Loading />}>