fix(mobile): auth-gated hydrates and telemetry flush on background
- Run notes/workspace/inbox hydrate, broadcast/survey polling, and offline queue flush timers only when hasBootstrapped && isAuthenticated - Split effects: kill switch, bootstrap, initPlatform, global AppState flush - Avoid pre-auth 401s from parallel API hydrates Made-with: Cursor
This commit is contained in:
parent
e920d724e4
commit
6620e5dabb
@ -3,10 +3,10 @@ import { Stack } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { AppState, Modal, Pressable, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';
|
||||
import { useAuthStore, type AuthState } from '../store/auth-store';
|
||||
import { useInboxStore, type InboxState } from '../store/inbox-store';
|
||||
import { useNotesStore, type NotesState } from '../store/notes-store';
|
||||
import { useWorkspaceStore, type WorkspaceState } from '../store/workspace-store';
|
||||
import { checkKillSwitch, initPlatform } from '../lib/platform';
|
||||
import { useInboxStore } from '../store/inbox-store';
|
||||
import { useNotesStore } from '../store/notes-store';
|
||||
import { useWorkspaceStore } from '../store/workspace-store';
|
||||
import { checkKillSwitch, flushTelemetry, initPlatform } from '../lib/platform';
|
||||
import { getBroadcastClient } from '../lib/broadcast-client';
|
||||
import { getSurveyClient } from '../lib/survey-client';
|
||||
import { flushNoteQueue, getNoteQueueSize } from '../lib/offline-queue';
|
||||
@ -37,9 +37,8 @@ export default function RootLayout() {
|
||||
});
|
||||
|
||||
const bootstrapAuth = useAuthStore((state: AuthState) => state.bootstrap);
|
||||
const hydrateInbox = useInboxStore((state: InboxState) => state.hydrate);
|
||||
const hydrateNotes = useNotesStore((state: NotesState) => state.hydrate);
|
||||
const hydrateWorkspaces = useWorkspaceStore((state: WorkspaceState) => state.hydrate);
|
||||
const hasBootstrapped = useAuthStore((state: AuthState) => state.hasBootstrapped);
|
||||
const isAuthenticated = useAuthStore((state: AuthState) => state.isAuthenticated);
|
||||
|
||||
function toSurveyAnswer(question: Question, value: string): QuestionAnswer {
|
||||
if (question.type === 'single_choice' || question.type === 'dropdown') {
|
||||
@ -99,15 +98,45 @@ export default function RootLayout() {
|
||||
.catch(() => {
|
||||
setKillSwitchState({ checked: true, disabled: false, message: null });
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
void bootstrapAuth();
|
||||
}, [bootstrapAuth]);
|
||||
|
||||
useEffect(() => {
|
||||
void initPlatform();
|
||||
void hydrateNotes();
|
||||
void hydrateWorkspaces();
|
||||
void hydrateInbox();
|
||||
void flushQueuedNoteMutations();
|
||||
void loadBroadcasts();
|
||||
void loadSurvey();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const sub = AppState.addEventListener('change', (nextState) => {
|
||||
if (nextState === 'background' || nextState === 'inactive') {
|
||||
flushTelemetry();
|
||||
}
|
||||
});
|
||||
return () => sub.remove();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasBootstrapped || !isAuthenticated) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
void (async () => {
|
||||
await Promise.all([
|
||||
useNotesStore.getState().hydrate(),
|
||||
useWorkspaceStore.getState().hydrate(),
|
||||
useInboxStore.getState().hydrate(),
|
||||
]);
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
void flushQueuedNoteMutations();
|
||||
void loadBroadcasts();
|
||||
void loadSurvey();
|
||||
})();
|
||||
|
||||
const broadcastTimer = setInterval(() => {
|
||||
void loadBroadcasts();
|
||||
@ -124,11 +153,12 @@ export default function RootLayout() {
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
clearInterval(broadcastTimer);
|
||||
clearInterval(surveyTimer);
|
||||
appStateSubscription.remove();
|
||||
};
|
||||
}, [bootstrapAuth, hydrateInbox, hydrateNotes, hydrateWorkspaces]);
|
||||
}, [hasBootstrapped, isAuthenticated]);
|
||||
|
||||
if (killSwitchState.checked && killSwitchState.disabled) {
|
||||
return (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user