|
1 | 1 | ---
|
2 | 2 | title: Routing & Navigation
|
3 |
| -description: Learn about the navigation structure and routing implementation in the mobile client. |
| 3 | +description: Learn about the two-tiered routing architecture that powers the mobile client. |
4 | 4 | ---
|
5 | 5 | import { Card, CardGrid } from '@astrojs/starlight/components';
|
6 | 6 |
|
7 |
| -Navigation in the mobile client is managed by the powerful `go_router` package. This provides a declarative, URL-based routing system that is robust, type-safe, and easy to maintain. All routing configuration is centralized within the `lib/router/` directory. |
| 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. |
8 | 8 |
|
| 9 | +## Tier 1: Pre-Router Status Pages |
| 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. |
| 12 | + |
| 13 | +This pre-flight check is essential for handling states that must block the entire application. |
| 14 | + |
| 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> |
| 29 | + |
| 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. |
| 31 | + |
| 32 | +## Tier 2: Authenticated Routing with GoRouter |
| 33 | + |
| 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. |
| 35 | + |
| 36 | +### Core Concepts |
| 37 | + |
| 38 | +- **`GoRouter`**: The main router instance that controls the application's navigation stack. It is configured with a list of routes, redirect logic, and a refresh listener. |
| 39 | + |
| 40 | +- **`Routes` Class**: A class located in `lib/router/routes.dart` that defines all route paths and names as `static const String` constants. Using named routes (e.g., `context.goNamed(Routes.settingsName)`) instead of raw path strings is a best practice that prevents typos and makes the code more maintainable. |
| 41 | + |
| 42 | +- **`StatefulShellRoute`**: This is a key component from `go_router` used to implement persistent UI elements, such as the main bottom navigation bar. It wraps the main sections of the app (e.g., Headlines Feed, Search, Account) and manages a separate navigation stack for each section, preserving the navigation state as the user switches between tabs. |
| 43 | + |
| 44 | +### Key Implementations |
| 45 | + |
| 46 | +<CardGrid> |
| 47 | + <Card title="Centralized Configuration" icon="file-tree"> |
| 48 | + All route definitions are located in `lib/router/router.dart`. This file contains the `GoRouter` setup, including the tree of `GoRoute` and `StatefulShellRoute` widgets that define the entire navigation map of the application. |
| 49 | + </Card> |
| 50 | + <Card title="Authentication-Aware Redirects" icon="shield-check"> |
| 51 | + The router is configured with a `redirect` logic that depends on the application's authentication status, which is provided by the `AppBloc`. This ensures that unauthenticated users are automatically redirected to the sign-in page, while authenticated users are directed to the main app content, creating a secure and seamless user experience. |
| 52 | + </Card> |
| 53 | + <Card title="Type-Safe Navigation" icon="shield"> |
| 54 | + By using named routes defined in the `Routes` class, navigation calls throughout the app are type-safe. This approach reduces runtime errors and makes it easy to refactor or update routes, as any changes only need to be made in one central location. |
| 55 | + </Card> |
| 56 | + <Card title="Passing Arguments" icon="box"> |
| 57 | + The router is used to pass complex data between pages. For example, when navigating to a details page, the full `Headline` object is passed via the `extra` parameter of the navigation call. This is more efficient than passing an ID and re-fetching data that is already available. |
| 58 | + </Card> |
| 59 | +</CardGrid> |
| 60 | + |
| 61 | +### Route Structure |
| 62 | + |
| 63 | +The main application routes are structured using a `StatefulShellRoute`, which provides the bottom navigation bar. Top-level routes are used for pages that should appear over the main shell, such as authentication or detailed content views. |
| 64 | + |
| 65 | +```tree title="Main Route Tree" |
| 66 | +/ |
| 67 | +├─ /feed |
| 68 | +│ ├─ article/:id |
| 69 | +│ ├─ notifications |
| 70 | +│ └─ filter |
| 71 | +│ ├─ topics |
| 72 | +│ └─ sources |
| 73 | +├─ /search |
| 74 | +│ └─ article/:id |
| 75 | +└─ /account |
| 76 | + ├─ settings |
| 77 | + │ ├─ appearance |
| 78 | + │ │ ├─ theme |
| 79 | + │ │ └─ font |
| 80 | + │ ├─ feed |
| 81 | + │ └─ language |
| 82 | + ├─ manage-followed-items |
| 83 | + │ ├─ topics |
| 84 | + │ │ └─ add-topic |
| 85 | + │ └─ sources |
| 86 | + │ └─ add-source |
| 87 | + └─ saved-headlines |
| 88 | + └─ article/:id |
| 89 | +``` |
9 | 90 | ## Core Concepts
|
10 | 91 |
|
11 | 92 | - **`GoRouter`**: The main router instance that controls the application's navigation stack. It is configured with a list of routes, redirect logic, and a refresh listener.
|
|
0 commit comments