()
| 367 | }; |
| 368 | |
| 369 | const Root = () => { |
| 370 | const { organizationId, projectId } = useParams() as { |
| 371 | organizationId: string; |
| 372 | projectId: string; |
| 373 | }; |
| 374 | |
| 375 | const [importObject, setImportObject] = useState<ImportSource>({ type: 'clipboard', defaultValue: '' }); |
| 376 | const { submit: createCloudCredentials } = useCreateCloudCredentialActionFetcher(); |
| 377 | const { submit: authorizeSubmit } = useAuthorizeActionFetcher(); |
| 378 | const { submit: redirectToDefaultBrowserSubmit } = useDefaultBrowserRedirectActionFetcher(); |
| 379 | const { submit: gitProviderCompleteSignInSubmit } = useGitProviderCompleteSignInFetcher({ |
| 380 | key: GIT_PROVIDER_COMPLETE_SIGN_IN_FETCHER_KEY, |
| 381 | }); |
| 382 | const navigate = useNavigate(); |
| 383 | useAuthDeepLinkHandler(); |
| 384 | |
| 385 | const { revalidate } = useRevalidator(); |
| 386 | const inflightFetchers = useFetchers(); |
| 387 | const ifInSubmission = inflightFetchers.some(f => f.formMethod === 'POST'); |
| 388 | const latestInSubmission = useLatest(ifInSubmission); |
| 389 | |
| 390 | useEffect(() => { |
| 391 | const unsubLoggedIn = window.main.on('loggedIn', (_, isLoggedIn: boolean) => { |
| 392 | if (!latestInSubmission.current) { |
| 393 | if (!isLoggedIn) { |
| 394 | // If the user just logged out, navigate to the login page |
| 395 | navigate(href('/auth/login')); |
| 396 | } else { |
| 397 | navigate(href('/organization')); |
| 398 | } |
| 399 | } |
| 400 | }); |
| 401 | const unsubGitDbSynced = window.main.on('git.db-synced', () => { |
| 402 | if (!latestInSubmission.current) { |
| 403 | revalidate(); |
| 404 | } |
| 405 | }); |
| 406 | return () => { |
| 407 | unsubLoggedIn(); |
| 408 | unsubGitDbSynced(); |
| 409 | }; |
| 410 | }, [latestInSubmission, revalidate, navigate]); |
| 411 | |
| 412 | useEffect(() => { |
| 413 | return window.main.on('shell:open', async (_: IpcRendererEvent, url: string) => { |
| 414 | const parsed = parseDeepLinkUrl(url); |
| 415 | if (!parsed) { |
| 416 | return; |
| 417 | } |
| 418 | const { urlWithoutParams, params } = parsed; |
| 419 | // Handled by useAuthDeepLinkHandler (registered in both Root and ErrorBoundary) |
| 420 | if (urlWithoutParams === 'insomnia://app/auth/login') { |
| 421 | return; |
| 422 | } |
| 423 | if (urlWithoutParams === 'insomnia://app/alert') { |
| 424 | return showModal(AlertModal, { |
| 425 | title: params.title, |
| 426 | message: params.message, |
nothing calls this directly
no test coverage detected