* Inner component that has access to both ProjectContext and WorkspaceContext. * Syncs stores and shows loading screen until ready.
()
| 152 | * Syncs stores and shows loading screen until ready. |
| 153 | */ |
| 154 | function AppLoaderInner() { |
| 155 | const policyState = usePolicy(); |
| 156 | const workspaceContext = useWorkspaceContext(); |
| 157 | const projectContext = useProjectContext(); |
| 158 | const apiState = useAPI(); |
| 159 | const api = apiState.api; |
| 160 | |
| 161 | // Get store instances |
| 162 | const workspaceStoreInstance = useWorkspaceStoreRaw(); |
| 163 | const gitStatusStore = useGitStatusStoreRaw(); |
| 164 | const runtimeStatusStore = useRuntimeStatusStoreRaw(); |
| 165 | const backgroundBashStore = useBackgroundBashStoreRaw(); |
| 166 | |
| 167 | const prefersReducedMotion = useReducedMotion(); |
| 168 | |
| 169 | // Track whether stores have been synced |
| 170 | const [storesSynced, setStoresSynced] = useState(false); |
| 171 | |
| 172 | // Track whether the initial load has completed. After the first successful |
| 173 | // load, we keep rendering the UI during reconnects instead of flashing the |
| 174 | // full-screen LoadingScreen again. |
| 175 | const [initialLoadComplete, setInitialLoadComplete] = useState(false); |
| 176 | |
| 177 | // Sync stores when metadata finishes loading |
| 178 | useEffect(() => { |
| 179 | // Keep store clients in sync even during backend restarts (api can be null while reconnecting). |
| 180 | workspaceStoreInstance.setClient(api ?? null); |
| 181 | gitStatusStore.setClient(api ?? null); |
| 182 | runtimeStatusStore.setClient(api ?? null); |
| 183 | backgroundBashStore.setClient(api ?? null); |
| 184 | getPRStatusStoreInstance().setClient(api ?? null); |
| 185 | getProvidersConfigStore().setClient(api ?? null); |
| 186 | |
| 187 | if (!workspaceContext.loading) { |
| 188 | workspaceStoreInstance.syncWorkspaces(workspaceContext.workspaceMetadata); |
| 189 | gitStatusStore.syncWorkspaces(workspaceContext.workspaceMetadata); |
| 190 | runtimeStatusStore.syncWorkspaces(workspaceContext.workspaceMetadata); |
| 191 | getPRStatusStoreInstance().syncWorkspaces(workspaceContext.workspaceMetadata); |
| 192 | |
| 193 | // Wire up file-modification subscription (idempotent - only subscribes once) |
| 194 | gitStatusStore.subscribeToFileModifications((listener) => |
| 195 | workspaceStore.subscribeFileModifyingTool(listener) |
| 196 | ); |
| 197 | |
| 198 | setStoresSynced(true); |
| 199 | } else { |
| 200 | setStoresSynced(false); |
| 201 | } |
| 202 | }, [ |
| 203 | workspaceContext.loading, |
| 204 | workspaceContext.workspaceMetadata, |
| 205 | workspaceStoreInstance, |
| 206 | gitStatusStore, |
| 207 | runtimeStatusStore, |
| 208 | backgroundBashStore, |
| 209 | api, |
| 210 | ]); |
| 211 |
nothing calls this directly
no test coverage detected