import { MatrixClient, SyncState } from 'matrix-js-sdk'; import React, { useCallback, useState } from 'react'; import { useAtomValue } from 'jotai'; import { Box, config, Line, Text } from 'folds'; import { useSyncState } from '../../hooks/useSyncState'; import { ContainerColor } from '../../styles/ContainerColor.css'; import { serverStatusAtom } from '../../state/serverStatus'; import { serverConfirmedUpSince } from '../../utils/kumaStatus'; import { homeserverStalledAtom } from '../../hooks/useHomeserverStall'; type StateData = { current: SyncState | null; previous: SyncState | null | undefined; }; type SyncStatusProps = { mx: MatrixClient; }; export function SyncStatus({ mx }: SyncStatusProps) { const serverStatus = useAtomValue(serverStatusAtom); const stalled = useAtomValue(homeserverStalledAtom); const [stateData, setStateData] = useState({ current: null, previous: undefined, }); useSyncState( mx, useCallback((current, previous) => { setStateData((s) => { if (s.current === current && s.previous === previous) { return s; } return { current, previous }; }); }, []), ); // [Gitea #124] When Kuma confirms the homeserver is down, the status banner // says so ("Lotus Chat's server is down…") instead of "Connection Lost!". const serverDown = serverStatus.status?.homeserver === 'down'; // Only blame the user's connection when Kuma has checked the server since // the drop and it was fine (a stale "up" from before proves nothing). const serverUp = serverConfirmedUpSince(serverStatus.status, serverStatus.lostAt); // [Gitea #317] Sync still says SYNCING, but the server has stopped answering. if (stalled && stateData.current === SyncState.Syncing && !serverDown) { return ( Lotus Chat's server isn't responding. Messages will send when it's back. Still trying… ); } // [Gitea #274] Only while catching up after a drop. Upstream also showed it // for PREPARED and for the first SYNCING after PREPARED/RECONNECTING, i.e. // until the NEXT /sync returned: on a quiet account that long-polls ~30 s // while the app already works (a SYNCING means a sync just succeeded). // A real failure still surfaces as Reconnecting / Connection lost. if (stateData.current === SyncState.Catchup) { return ( Connecting... ); } if (stateData.current === SyncState.Reconnecting && !serverDown) { return ( {serverUp ? "Connection lost. Our status checks say Lotus Chat's server is up, so it may be your internet connection. Reconnecting…" : 'Connection Lost! Reconnecting...'} ); } if (stateData.current === SyncState.Error && !serverDown) { return ( {serverUp ? "Connection lost. Our status checks say Lotus Chat's server is up, so check your internet connection." : 'Connection Lost!'} ); } return null; }