Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/app/pages/client/ClientRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ type ClientRootProps = {
children: ReactNode;
};
export function ClientRoot({ children }: ClientRootProps) {
const [loading, setLoading] = useState(true);
const navigate = useNavigate();
const clientConfig = useClientConfig();
const sessions = useAtomValue(sessionsAtom);
Expand All @@ -191,6 +190,8 @@ export function ClientRoot({ children }: ClientRootProps) {
const syncStartTimeRef = useRef(performance.now());
const firstSyncReadyRef = useRef(false);

const [loading, setLoading] = useState(true);

const [loadState, loadMatrix, setLoadState] = useAsyncCallback<MatrixClient, Error, []>(
useCallback(async () => {
if (!activeSession) {
Expand Down Expand Up @@ -238,8 +239,8 @@ export function ClientRoot({ children }: ClientRootProps) {
if (mx?.clientRunning) {
stopClient(mx);
}
setLoading(true);
loadedUserIdRef.current = undefined;
setLoading(true);
setLoadState({ status: AsyncStatus.Idle });
navigate(getHomePath(), { replace: true });
}
Expand Down Expand Up @@ -288,18 +289,29 @@ export function ClientRoot({ children }: ClientRootProps) {
}
}, [mx]);

// Once the client has started (store loaded from IndexedDB, sync loop running),
// hide the splash immediately if there are cached rooms — no need to wait for
// the first server response. The SyncStatus banner shows "Connecting..." instead.
useEffect(() => {
if (startState.status !== AsyncStatus.Success || !mx) return;
if (isClientReady(mx.getSyncState())) return;
if (mx.getRooms().length > 0) {
setLoading(false);
}
}, [mx, startState.status]);
Comment on lines +292 to +301

useSyncState(
mx,
useCallback((state: string) => {
if (isClientReady(state)) {
setLoading(false);
if (!firstSyncReadyRef.current) {
firstSyncReadyRef.current = true;
Sentry.metrics.distribution(
'sable.sync.time_to_ready_ms',
performance.now() - syncStartTimeRef.current
);
}
setLoading(false);
}
}, [])
);
Expand Down Expand Up @@ -358,7 +370,7 @@ export function ClientRoot({ children }: ClientRootProps) {
<AutoDiscovery userId={userId ?? ''} baseUrl={baseUrl ?? ''}>
<SpecVersions baseUrl={baseUrl ?? ''}>
{mx && <SyncStatus mx={mx} />}
{loading && <ClientRootOptions mx={mx} onLogout={handleLogout} />}
{(loading || !mx) && <ClientRootOptions mx={mx} onLogout={handleLogout} />}
{(loadState.status === AsyncStatus.Error || startState.status === AsyncStatus.Error) && (
<SplashScreen>
<Box
Expand Down
Loading