From d0caaffbbc1ed3a696c891bd33c575b8fe72319e Mon Sep 17 00:00:00 2001
From: Ajay Bura <32841439+ajbura@users.noreply.github.com>
Date: Mon, 22 Jul 2024 14:07:55 +0530
Subject: [PATCH] add sync connection status bar

---
 src/app/pages/client/ClientLayout.tsx |  2 +-
 src/app/pages/client/ClientRoot.tsx   |  2 +
 src/app/pages/client/SyncStatus.tsx   | 87 +++++++++++++++++++++++++++
 src/app/pages/client/WelcomePage.tsx  |  2 +-
 src/index.scss                        |  2 +
 5 files changed, 93 insertions(+), 2 deletions(-)
 create mode 100644 src/app/pages/client/SyncStatus.tsx

diff --git a/src/app/pages/client/ClientLayout.tsx b/src/app/pages/client/ClientLayout.tsx
index 208d12e4..4a077ba6 100644
--- a/src/app/pages/client/ClientLayout.tsx
+++ b/src/app/pages/client/ClientLayout.tsx
@@ -7,7 +7,7 @@ type ClientLayoutProps = {
 };
 export function ClientLayout({ nav, children }: ClientLayoutProps) {
   return (
-    <Box style={{ height: '100%' }}>
+    <Box grow="Yes">
       <Box shrink="No">{nav}</Box>
       <Box grow="Yes">{children}</Box>
     </Box>
diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx
index 6365d8e9..a590e0bc 100644
--- a/src/app/pages/client/ClientRoot.tsx
+++ b/src/app/pages/client/ClientRoot.tsx
@@ -37,6 +37,7 @@ import { settingsAtom } from '../../state/settings';
 import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
 import { useSyncState } from '../../hooks/useSyncState';
 import { stopPropagation } from '../../utils/keyboard';
+import { SyncStatus } from './SyncStatus';
 
 function SystemEmojiFeature() {
   const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji');
@@ -184,6 +185,7 @@ export function ClientRoot({ children }: ClientRootProps) {
 
   return (
     <SpecVersions baseUrl={baseUrl!}>
+      {mx && <SyncStatus mx={mx} />}
       {loading && mx && <ClientRootOptions mx={mx} />}
       {(loadState.status === AsyncStatus.Error || startState.status === AsyncStatus.Error) && (
         <SplashScreen>
diff --git a/src/app/pages/client/SyncStatus.tsx b/src/app/pages/client/SyncStatus.tsx
new file mode 100644
index 00000000..9cd4b0b2
--- /dev/null
+++ b/src/app/pages/client/SyncStatus.tsx
@@ -0,0 +1,87 @@
+import { MatrixClient, SyncState } from 'matrix-js-sdk';
+import React, { useCallback, useState } from 'react';
+import { Box, config, Line, Text } from 'folds';
+import { useSyncState } from '../../hooks/useSyncState';
+import { ContainerColor } from '../../styles/ContainerColor.css';
+
+type StateData = {
+  current: SyncState | null;
+  previous: SyncState | null | undefined;
+};
+
+type SyncStatusProps = {
+  mx: MatrixClient;
+};
+export function SyncStatus({ mx }: SyncStatusProps) {
+  const [stateData, setStateData] = useState<StateData>({
+    current: null,
+    previous: undefined,
+  });
+
+  useSyncState(
+    mx,
+    useCallback((current, previous) => {
+      setStateData((s) => {
+        if (s.current === current && s.previous === previous) {
+          return s;
+        }
+        return { current, previous };
+      });
+    }, [])
+  );
+
+  if (
+    (stateData.current === SyncState.Prepared ||
+      stateData.current === SyncState.Syncing ||
+      stateData.current === SyncState.Catchup) &&
+    stateData.previous !== SyncState.Syncing
+  ) {
+    return (
+      <Box direction="Column" shrink="No">
+        <Box
+          className={ContainerColor({ variant: 'Success' })}
+          style={{ padding: `${config.space.S100} 0` }}
+          alignItems="Center"
+          justifyContent="Center"
+        >
+          <Text size="L400">Connecting...</Text>
+        </Box>
+        <Line variant="Success" size="300" />
+      </Box>
+    );
+  }
+
+  if (stateData.current === SyncState.Reconnecting) {
+    return (
+      <Box direction="Column" shrink="No">
+        <Box
+          className={ContainerColor({ variant: 'Warning' })}
+          style={{ padding: `${config.space.S100} 0` }}
+          alignItems="Center"
+          justifyContent="Center"
+        >
+          <Text size="L400">Connection Lost! Reconnecting...</Text>
+        </Box>
+        <Line variant="Warning" size="300" />
+      </Box>
+    );
+  }
+
+  if (stateData.current === SyncState.Error) {
+    return (
+      <Box direction="Column" shrink="No">
+        <Box
+          className={ContainerColor({ variant: 'Critical' })}
+          style={{ padding: `${config.space.S100} 0` }}
+          alignItems="Center"
+          justifyContent="Center"
+        >
+          <Text size="L400">Connection Lost!</Text>
+        </Box>
+        <Line variant="Critical" size="300" />
+      </Box>
+    );
+  }
+
+  return null;
+}
diff --git a/src/app/pages/client/WelcomePage.tsx b/src/app/pages/client/WelcomePage.tsx
index 2486625f..5040d15f 100644
--- a/src/app/pages/client/WelcomePage.tsx
+++ b/src/app/pages/client/WelcomePage.tsx
@@ -18,7 +18,7 @@ export function WelcomePage() {
             title="Welcome to Cinny"
             subTitle={
               <span>
-                Yet anothor matrix client.{' '}
+                Yet another matrix client.{' '}
                 <a
                   href="https://github.com/cinnyapp/cinny/releases"
                   target="_blank"
diff --git a/src/index.scss b/src/index.scss
index 5903858a..1c223051 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -409,6 +409,8 @@ body {
 #root {
   width: 100%;
   height: 100%;
+  display: flex;
+  flex-direction: column;
 }
 
 *,