From eb94326bb64552dbd7df62ae201ccca37f368467 Mon Sep 17 00:00:00 2001
From: Kristóf Marussy <kristof@marussy.com>
Date: Mon, 5 Sep 2022 01:29:11 +0200
Subject: feat(frontend): show connection status

---
 subprojects/frontend/src/editor/ConnectButton.tsx | 68 +++++++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 subprojects/frontend/src/editor/ConnectButton.tsx

(limited to 'subprojects/frontend/src/editor/ConnectButton.tsx')

diff --git a/subprojects/frontend/src/editor/ConnectButton.tsx b/subprojects/frontend/src/editor/ConnectButton.tsx
new file mode 100644
index 00000000..52e7b854
--- /dev/null
+++ b/subprojects/frontend/src/editor/ConnectButton.tsx
@@ -0,0 +1,68 @@
+import CloudIcon from '@mui/icons-material/Cloud';
+import CloudOffIcon from '@mui/icons-material/CloudOff';
+import SyncIcon from '@mui/icons-material/Sync';
+import SyncProblemIcon from '@mui/icons-material/SyncProblem';
+import IconButton from '@mui/material/IconButton';
+import { keyframes, styled } from '@mui/material/styles';
+import { observer } from 'mobx-react-lite';
+import React from 'react';
+
+import type EditorStore from './EditorStore';
+
+const rotateKeyframe = keyframes`
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(-360deg);
+  }
+`;
+
+const AnimatedSyncIcon = styled(SyncIcon)`
+  animation: ${rotateKeyframe} 1.4s linear infinite;
+`;
+
+export default observer(function ConnectButton({
+  editorStore,
+}: {
+  editorStore: EditorStore | undefined;
+}): JSX.Element {
+  if (
+    editorStore !== undefined &&
+    (editorStore.opening || editorStore.opened)
+  ) {
+    return (
+      <IconButton
+        onClick={() => editorStore.disconnect()}
+        aria-label="Disconnect"
+        color="inherit"
+      >
+        {editorStore.opening ? (
+          <AnimatedSyncIcon fontSize="small" />
+        ) : (
+          <CloudIcon fontSize="small" />
+        )}
+      </IconButton>
+    );
+  }
+
+  let disconnectedIcon: JSX.Element;
+  if (editorStore === undefined) {
+    disconnectedIcon = <SyncIcon fontSize="small" />;
+  } else if (editorStore.connectionErrors.length > 0) {
+    disconnectedIcon = <SyncProblemIcon fontSize="small" />;
+  } else {
+    disconnectedIcon = <CloudOffIcon fontSize="small" />;
+  }
+
+  return (
+    <IconButton
+      disabled={editorStore === undefined}
+      onClick={() => editorStore?.connect()}
+      aria-label="Connect"
+      color="inherit"
+    >
+      {disconnectedIcon}
+    </IconButton>
+  );
+});
-- 
cgit v1.2.3-70-g09d2

