|
1 | 1 | ---
|
2 | 2 | title: Routing & Navigation
|
3 |
| -description: Learn about the two-tiered routing architecture that powers the mobile client. |
| 3 | +description: Learn about the startup flow and routing architecture that powers the mobile client. |
4 | 4 | ---
|
5 |
| -import { Card, CardGrid } from '@astrojs/starlight/components'; |
| 5 | +import { Card, CardGrid, Aside } from '@astrojs/starlight/components'; |
6 | 6 |
|
7 |
| -The mobile client employs a robust, two-tiered architecture to manage application startup and navigation. This ensures the app is in a stable, valid state before rendering the main UI and its nested routes. |
| 7 | +The mobile client employs a sophisticated, multi-path startup sequence to handle authentication and remote configuration checks gracefully. This ensures the app is always in a valid state before rendering the main UI. |
8 | 8 |
|
9 |
| -## Tier 1: Pre-Router Status Pages |
| 9 | +## The Application Startup Flow |
10 | 10 |
|
11 |
| -The first tier of logic acts as a global gatekeeper. It is handled by the root `_AppView` widget (`lib/app/view/app.dart`) and the `AppBloc`. This tier determines if a critical, full-screen status page should be displayed *before* the main `GoRouter` instance is ever built. |
| 11 | +The startup logic is orchestrated by the `AppBloc` and the root `_AppView` widget. The path the user experiences depends on their initial authentication status. |
12 | 12 |
|
13 |
| -This pre-flight check is essential for handling states that must block the entire application. |
| 13 | +<Aside> |
| 14 | +A key architectural decision is that the **Remote Configuration API requires authentication**. This means the app must first establish a user session (even an anonymous one) before it can check for maintenance mode or required updates. |
| 15 | +</Aside> |
14 | 16 |
|
15 |
| -<CardGrid> |
16 |
| - <Card title="AppStatus.configFetching" icon="cloud-download"> |
17 |
| - On startup, the `AppBloc` immediately attempts to fetch the remote configuration. During this time, the `_AppView` displays a `StatusPage` with a loading indicator. |
18 |
| - </Card> |
19 |
| - <Card title="AppStatus.configFetchFailed" icon="error"> |
20 |
| - If the configuration fetch fails (e.g., due to a network error), the `StatusPage` updates to show an error message and a retry button, allowing the user to attempt the fetch again. |
21 |
| - </Card> |
22 |
| - <Card title="AppStatus.underMaintenance" icon="construction"> |
23 |
| - If the fetched config indicates that the app is in maintenance mode, the `_AppView` replaces the UI with a dedicated `MaintenancePage`. |
24 |
| - </Card> |
25 |
| - <Card title="AppStatus.updateRequired" icon="system-update"> |
26 |
| - If the config indicates a mandatory update is required, the `_AppView` displays an `UpdateRequiredPage` with a link to the appropriate app store. |
27 |
| - </Card> |
28 |
| -</CardGrid> |
| 17 | +### Path 1: New or Logged-Out User |
| 18 | + |
| 19 | +This is the flow for a user with no existing session. |
| 20 | + |
| 21 | +1. **Auth Check**: On startup, the `AppBloc` checks for a user. None is found. |
| 22 | +2. **State Transition**: The `AppBloc` immediately emits the `AppStatus.unauthenticated` state. |
| 23 | +3. **Router Activation**: The `_AppView` widget sees a "running" state (`unauthenticated`) and builds the main `MaterialApp.router`, activating `GoRouter`. |
| 24 | +4. **Redirection**: `GoRouter`'s `redirect` logic intercepts the navigation, sees the `unauthenticated` status, and immediately redirects the user to the `/authentication` page. |
| 25 | + |
| 26 | +In this scenario, the user is taken directly to the sign-in screen without any intermediate loading pages. |
| 27 | + |
| 28 | +### Path 2: Existing User (Authenticated or Anonymous) |
| 29 | + |
| 30 | +This flow handles users who already have an active session. |
| 31 | + |
| 32 | +1. **Auth Check**: On startup, the `AppBloc` finds an existing user session. |
| 33 | +2. **Initial State**: The `AppBloc` emits the corresponding status (`authenticated` or `anonymous`) and immediately dispatches an `AppConfigFetchRequested` event. |
| 34 | +3. **Pre-Router Status Pages**: The `_onAppConfigFetchRequested` handler sets the state to `AppStatus.configFetching`. The `_AppView` widget detects this critical status and displays a full-screen `StatusPage` *before* building the main router. This pre-flight check handles several possibilities: |
| 35 | + - **Loading**: A `StatusPage` with a loading indicator is shown. |
| 36 | + - **Failure**: If the config fetch fails, the `StatusPage` shows a retry button. |
| 37 | + - **Maintenance/Update**: If the config dictates, a `MaintenancePage` or `UpdateRequiredPage` is shown. |
| 38 | +4. **Router Activation**: Only after the remote config is successfully fetched and no critical status is found does the `_AppView` build the `MaterialApp.router`. |
| 39 | +5. **Redirection**: `GoRouter`'s `redirect` logic sees the `authenticated` or `anonymous` status and navigates the user to the main `/feed`. |
29 | 40 |
|
30 |
| -In any of these critical states, the main application router is not active. This architecture prevents race conditions and ensures the app only proceeds once it has confirmed it is in a healthy, runnable state. |
| 41 | +This two-path system correctly prioritizes authentication and then uses that session to securely fetch critical app configuration. |
31 | 42 |
|
32 |
| -## Tier 2: Authenticated Routing with GoRouter |
| 43 | +## GoRouter Implementation Details |
33 | 44 |
|
34 |
| -Once the pre-flight checks in Tier 1 are passed, the `_AppView` builds the main `MaterialApp.router`, activating `go_router`. From this point on, `go_router` is responsible for all in-app navigation. |
| 45 | +Once the startup flow is complete and the router is active, `go_router` manages all in-app navigation. |
35 | 46 |
|
36 | 47 | ### Core Concepts
|
37 | 48 |
|
|
0 commit comments