From 8ebc24a5ba1c87cb5cb14fbaff3bee329e30fc15 Mon Sep 17 00:00:00 2001
From: Kristóf Marussy <kristof@marussy.com>
Date: Sun, 21 Aug 2022 00:33:01 +0200
Subject: 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
---
 subprojects/frontend/src/TopBar.tsx | 58 +++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

(limited to 'subprojects/frontend/src/TopBar.tsx')

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 @@
 import AppBar from '@mui/material/AppBar';
 import Toolbar from '@mui/material/Toolbar';
 import Typography from '@mui/material/Typography';
-import React from 'react';
+import { throttle } from 'lodash-es';
+import React, { useEffect, useMemo, useState } from 'react';
 
 import ToggleDarkModeButton from './ToggleDarkModeButton';
 
+function useWindowControlsOverlayVisible(): boolean {
+  const [windowControlsOverlayVisible, setWindowControlsOverlayVisible] =
+    useState(false);
+  const updateWindowControlsOverlayVisible = useMemo(
+    () =>
+      throttle(
+        ({ visible }: WindowControlsOverlayGeometryChangeEvent) =>
+          setWindowControlsOverlayVisible(visible),
+        250,
+      ),
+    [],
+  );
+  useEffect(() => {
+    if ('windowControlsOverlay' in navigator) {
+      const { windowControlsOverlay } = navigator;
+      setWindowControlsOverlayVisible(windowControlsOverlay.visible);
+      windowControlsOverlay.addEventListener(
+        'geometrychange',
+        updateWindowControlsOverlayVisible,
+      );
+      return () => {
+        windowControlsOverlay.removeEventListener(
+          'geometrychange',
+          updateWindowControlsOverlayVisible,
+        );
+      };
+    }
+    // Nothing to clean up if `windowControlsOverlay` is unsupported.
+    return () => {};
+  }, [updateWindowControlsOverlayVisible]);
+  return windowControlsOverlayVisible;
+}
+
 export default function TopBar(): JSX.Element {
+  const overlayVisible = useWindowControlsOverlayVisible();
+
   return (
     <AppBar
       position="static"
@@ -14,9 +50,27 @@ export default function TopBar(): JSX.Element {
       sx={(theme) => ({
         background: theme.palette.outer.background,
         borderBottom: `1px solid ${theme.palette.outer.border}`,
+        appRegion: 'drag',
+        '.MuiButtonBase-root': {
+          appRegion: 'no-drag',
+        },
       })}
     >
-      <Toolbar>
+      <Toolbar
+        sx={{
+          ...(overlayVisible
+            ? {
+                marginLeft: 'env(titlebar-area-x, 0)',
+                marginTop: 'env(titlebar-area-y, 0)',
+                width: 'env(titlebar-area-width, 100%)',
+                minHeight: 'env(titlebar-area-height, auto)',
+              }
+            : {
+                minHeight: 'auto',
+              }),
+          py: 0.5,
+        }}
+      >
         <Typography variant="h6" component="h1" flexGrow={1}>
           Refinery
         </Typography>
-- 
cgit v1.2.3-70-g09d2

