@bdayadev/flutter-ultra-mcp 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dart/ultra_flutter/pubspec.yaml +1 -1
- package/dart/ultra_flutter_devtools/pubspec.yaml +1 -1
- package/package.json +1 -1
- package/skills/add-integration-test/SKILL.md +72 -20
- package/skills/add-unit-test/SKILL.md +1 -0
- package/skills/add-widget-preview/SKILL.md +75 -26
- package/skills/add-widget-test/SKILL.md +51 -22
- package/skills/apply-architecture-best-practices/SKILL.md +55 -29
- package/skills/build-cli-app/SKILL.md +36 -9
- package/skills/build-responsive-layout/SKILL.md +65 -31
- package/skills/collect-coverage/SKILL.md +12 -1
- package/skills/fix-layout-issues/SKILL.md +71 -20
- package/skills/fix-runtime-errors/SKILL.md +79 -20
- package/skills/generate-test-mocks/SKILL.md +43 -13
- package/skills/implement-json-serialization/SKILL.md +82 -17
- package/skills/migrate-to-checks-package/SKILL.md +46 -14
- package/skills/resolve-package-conflicts/SKILL.md +41 -12
- package/skills/run-static-analysis/SKILL.md +29 -16
- package/skills/setup-declarative-routing/SKILL.md +166 -30
- package/skills/setup-localization/SKILL.md +90 -20
- package/skills/use-http-package/SKILL.md +61 -23
- package/skills/use-pattern-matching/SKILL.md +63 -26
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: resolve-package-conflicts
|
|
3
3
|
description: Workflow for fixing package version conflicts. Use this when `pub get` fails due to incompatible package versions.
|
|
4
|
+
last_modified: Fri, 24 Apr 2026 15:11:14 GMT
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Managing Dart Dependencies
|
|
@@ -16,46 +17,54 @@ description: Workflow for fixing package version conflicts. Use this when `pub g
|
|
|
16
17
|
|
|
17
18
|
## Core Concepts
|
|
18
19
|
|
|
19
|
-
Dart enforces a strict single-version rule for dependencies: a project and all its transitive dependencies must resolve to a single, shared version of any given package.
|
|
20
|
+
Dart enforces a strict single-version rule for dependencies: a project and all its transitive dependencies must resolve to a single, shared version of any given package. This prevents runtime type mismatches but introduces the risk of "version lock."
|
|
21
|
+
|
|
22
|
+
To mitigate version lock, Dart relies on version constraints rather than pinned versions in the `pubspec.yaml`. The `pubspec.lock` file maintains the exact resolved versions for reproducible builds.
|
|
20
23
|
|
|
21
24
|
Understand the output columns of `dart pub outdated`:
|
|
22
25
|
|
|
23
26
|
- **Current:** The version currently recorded in `pubspec.lock`.
|
|
24
27
|
- **Upgradable:** The latest version allowed by the constraints in `pubspec.yaml`. `dart pub upgrade` resolves to this.
|
|
25
|
-
- **Resolvable:** The absolute latest version that can be resolved when factoring in all other dependencies.
|
|
28
|
+
- **Resolvable:** The absolute latest version that can be resolved when factoring in all other dependencies in the project.
|
|
26
29
|
- **Latest:** The latest published version of the package (excluding prereleases).
|
|
27
30
|
|
|
28
31
|
## Version Constraints
|
|
29
32
|
|
|
30
|
-
- **Use Caret Syntax:** Always use caret syntax (e.g., `^1.2.3`) for dependencies.
|
|
31
|
-
- **Tighten Dev Dependencies:** Set the lower bound of `dev_dependencies` to the exact version currently used.
|
|
32
|
-
- **Enforce Lockfiles in CI:** Use `dart pub get --enforce-lockfile` in CI/CD pipelines.
|
|
33
|
+
- **Use Caret Syntax:** Always use caret syntax (e.g., `^1.2.3`) for dependencies in `pubspec.yaml`. This allows `pub` to select newer, non-breaking versions (up to, but not including, the next major version) during resolution.
|
|
34
|
+
- **Tighten Dev Dependencies:** Set the lower bound of `dev_dependencies` to the exact version currently used. This reduces resolution complexity and prevents older, incompatible dev tools from being selected.
|
|
35
|
+
- **Enforce Lockfiles in CI:** Use `dart pub get --enforce-lockfile` in CI/CD pipelines to ensure the exact versions tested locally are used in production.
|
|
33
36
|
|
|
34
37
|
## Workflow: Auditing Dependencies
|
|
35
38
|
|
|
39
|
+
Run this workflow periodically to identify stale packages that may impact stability or performance.
|
|
40
|
+
|
|
36
41
|
**Task Progress:**
|
|
37
42
|
|
|
38
43
|
- [ ] Run `dart pub outdated`.
|
|
39
|
-
- [ ] Review the **Upgradable** column.
|
|
40
|
-
- [ ] Review the **Resolvable** column.
|
|
44
|
+
- [ ] Review the **Upgradable** column to identify packages that can be updated without modifying `pubspec.yaml`.
|
|
45
|
+
- [ ] Review the **Resolvable** column to identify packages that require constraint modifications in `pubspec.yaml` to update.
|
|
41
46
|
- [ ] Identify any packages marked as retracted or discontinued.
|
|
42
47
|
|
|
43
48
|
## Workflow: Upgrading Dependencies
|
|
44
49
|
|
|
50
|
+
Use conditional logic based on the audit results to upgrade dependencies.
|
|
51
|
+
|
|
45
52
|
**Task Progress:**
|
|
46
53
|
|
|
47
54
|
- [ ] **If updating to "Upgradable" versions:**
|
|
48
55
|
- [ ] Run `dart pub upgrade`.
|
|
49
|
-
- [ ] Run `dart pub upgrade --tighten` to update lower bounds.
|
|
56
|
+
- [ ] Run `dart pub upgrade --tighten` to automatically update the lower bounds in `pubspec.yaml` to match the newly resolved versions.
|
|
50
57
|
- [ ] **If updating to "Resolvable" versions (Major updates):**
|
|
51
|
-
- [ ] Manually edit `pubspec.yaml` to bump the version constraint.
|
|
52
|
-
- [ ] Run `dart pub upgrade` to resolve the new constraints.
|
|
58
|
+
- [ ] Manually edit `pubspec.yaml` to bump the version constraint to match the "Resolvable" column (e.g., change `^0.11.0` to `^0.12.1`).
|
|
59
|
+
- [ ] Run `dart pub upgrade` to resolve the new constraints and update `pubspec.lock`.
|
|
53
60
|
- [ ] **Feedback Loop:**
|
|
54
61
|
- [ ] Run `dart analyze` -> review errors -> fix breaking API changes.
|
|
55
62
|
- [ ] Run `dart test` -> review failures -> fix regressions.
|
|
56
63
|
|
|
57
64
|
## Workflow: Resolving Version Conflicts
|
|
58
65
|
|
|
66
|
+
When `pub` cannot find a set of concrete versions that satisfy all constraints, or when dealing with a retracted package version, manipulate the lockfile surgically.
|
|
67
|
+
|
|
59
68
|
**NEVER** delete the entire `pubspec.lock` file and run `dart pub get`. This causes uncontrolled upgrades across the entire dependency graph.
|
|
60
69
|
|
|
61
70
|
**Task Progress:**
|
|
@@ -63,7 +72,7 @@ Understand the output columns of `dart pub outdated`:
|
|
|
63
72
|
- [ ] Open `pubspec.lock`.
|
|
64
73
|
- [ ] Locate the specific YAML block for the conflicting or retracted package.
|
|
65
74
|
- [ ] Delete ONLY that package's entry from the lockfile.
|
|
66
|
-
- [ ] Run `dart pub get` to fetch the newest compatible version.
|
|
75
|
+
- [ ] Run `dart pub get` to fetch the newest compatible, non-retracted version for that specific package.
|
|
67
76
|
- [ ] **Feedback Loop:**
|
|
68
77
|
- [ ] Run `dart pub deps` -> verify the dependency graph resolves correctly.
|
|
69
78
|
- [ ] If resolution fails, identify the transitive dependency causing the lock, update its constraint in `pubspec.yaml`, and retry.
|
|
@@ -72,6 +81,8 @@ Understand the output columns of `dart pub outdated`:
|
|
|
72
81
|
|
|
73
82
|
### Tightening Constraints
|
|
74
83
|
|
|
84
|
+
When `dart pub outdated` shows a package is resolvable to a higher minor/patch version, use the `--tighten` flag to update the `pubspec.yaml` automatically.
|
|
85
|
+
|
|
75
86
|
**Input (`pubspec.yaml`):**
|
|
76
87
|
|
|
77
88
|
```yaml
|
|
@@ -94,7 +105,25 @@ dependencies:
|
|
|
94
105
|
|
|
95
106
|
### Surgical Lockfile Removal
|
|
96
107
|
|
|
97
|
-
If `package_a` is retracted or locked in a conflict, remove only its block from `pubspec.lock`.
|
|
108
|
+
If `package_a` is retracted or locked in a conflict, remove only its block from `pubspec.lock`.
|
|
109
|
+
|
|
110
|
+
**Before (`pubspec.lock`):**
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
packages:
|
|
114
|
+
package_a:
|
|
115
|
+
dependency: 'direct main'
|
|
116
|
+
description:
|
|
117
|
+
name: package_a
|
|
118
|
+
url: 'https://pub.dev'
|
|
119
|
+
source: hosted
|
|
120
|
+
version: '1.0.0' # Retracted version
|
|
121
|
+
package_b:
|
|
122
|
+
dependency: 'direct main'
|
|
123
|
+
# ...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Action:** Delete the `package_a` block entirely. Leave `package_b` untouched. Run `dart pub get`.
|
|
98
127
|
|
|
99
128
|
## Flutter Ultra Integration
|
|
100
129
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: run-static-analysis
|
|
3
3
|
description: Execute `dart analyze` to identify warnings and errors, and use `dart fix --apply` to automatically resolve mechanical lint issues. Use during development to ensure code quality and before committing changes.
|
|
4
|
+
last_modified: Fri, 24 Apr 2026 15:09:34 GMT
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Analyzing and Fixing Dart Code
|
|
@@ -15,38 +16,48 @@ description: Execute `dart analyze` to identify warnings and errors, and use `da
|
|
|
15
16
|
|
|
16
17
|
## Analysis Configuration
|
|
17
18
|
|
|
18
|
-
Configure the Dart analyzer using the `analysis_options.yaml` file at the package root.
|
|
19
|
+
Configure the Dart analyzer using the `analysis_options.yaml` file located at the package root.
|
|
19
20
|
|
|
20
|
-
- **Base Configuration:**
|
|
21
|
-
- **Strict Type Checks:** Enable `strict-casts: true`, `strict-inference: true`, and `strict-raw-types: true
|
|
22
|
-
- **Linter Rules:**
|
|
23
|
-
- **Formatter Configuration:** Configure `dart format` behavior under the `formatter:` node. Set `page_width` and `trailing_commas
|
|
21
|
+
- **Base Configuration:** Always include a standard rule set (e.g., `package:lints/recommended.yaml` or `package:flutter_lints/flutter.yaml`) using the `include:` directive.
|
|
22
|
+
- **Strict Type Checks:** Enable strict type checks under the `analyzer: language:` node to prevent implicit downcasts and dynamic inferences. Set `strict-casts: true`, `strict-inference: true`, and `strict-raw-types: true`.
|
|
23
|
+
- **Linter Rules:** Explicitly enable or disable specific rules under the `linter: rules:` node. Use a key-value map (`rule_name: true/false`) when overriding included rules, or a list (`- rule_name`) when defining a fresh set. Do not mix list and map syntax in the same `rules` block.
|
|
24
|
+
- **Formatter Configuration:** Configure `dart format` behavior under the `formatter:` node. Set `page_width` (default 80) and `trailing_commas` (`automate` or `preserve`).
|
|
25
|
+
- **Analyzer Plugins:** Enable custom diagnostics by adding plugins under the `analyzer: plugins:` node. Ensure the plugin package is added as a `dev_dependency` in `pubspec.yaml`.
|
|
24
26
|
|
|
25
27
|
## Diagnostic Suppression
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- **
|
|
29
|
+
When a diagnostic (lint or warning) yields a false positive or applies to generated code, suppress it explicitly.
|
|
30
|
+
|
|
31
|
+
- **File-level Exclusion:** Use the `analyzer: exclude:` node in `analysis_options.yaml` to exclude entire files or directories (e.g., `**/*.g.dart`) using glob patterns.
|
|
32
|
+
- **File-level Suppression:** Add `// ignore_for_file: <diagnostic_code>` at the top of a Dart file to suppress specific diagnostics for the entire file. Use `// ignore_for_file: type=lint` to suppress all linter rules.
|
|
33
|
+
- **Line-level Suppression:** Add `// ignore: <diagnostic_code>` on the line directly above the offending code, or appended to the end of the offending line.
|
|
34
|
+
- **Pubspec Suppression:** Add `# ignore: <diagnostic_code>` above the offending line in `pubspec.yaml` files (e.g., `# ignore: sort_pub_dependencies`).
|
|
35
|
+
- **Plugin Diagnostics:** Prefix the diagnostic code with the plugin name when suppressing plugin-specific issues (e.g., `// ignore: some_plugin/some_code`).
|
|
30
36
|
|
|
31
37
|
## Workflow: Executing Static Analysis
|
|
32
38
|
|
|
39
|
+
Use this workflow to identify type-related bugs, style violations, and potential runtime errors.
|
|
40
|
+
|
|
33
41
|
**Task Progress:**
|
|
34
42
|
|
|
35
43
|
- [ ] 1. Verify `analysis_options.yaml` exists at the project root.
|
|
36
|
-
- [ ] 2. Run the analyzer
|
|
44
|
+
- [ ] 2. Run the analyzer using the `analyze_files` MCP tool (if available) or the CLI command `dart analyze <target_directory>`.
|
|
37
45
|
- [ ] 3. Review the diagnostic output.
|
|
38
|
-
- [ ] 4. If info-level issues must be treated as failures, append `--fatal-infos
|
|
39
|
-
- [ ] 5. Resolve reported errors manually or proceed to Automated Fixes.
|
|
46
|
+
- [ ] 4. If info-level issues must be treated as failures, append the `--fatal-infos` flag.
|
|
47
|
+
- [ ] 5. Resolve reported errors manually or proceed to the Automated Fixes workflow.
|
|
40
48
|
|
|
41
49
|
## Workflow: Applying Automated Fixes
|
|
42
50
|
|
|
51
|
+
Use this workflow to resolve outdated API usages, apply quick fixes, and migrate code (e.g., Dart 3 migrations).
|
|
52
|
+
|
|
43
53
|
**Task Progress:**
|
|
44
54
|
|
|
45
|
-
- [ ] 1.
|
|
46
|
-
- [ ] 2. Review the proposed fixes.
|
|
47
|
-
- [ ] 3.
|
|
48
|
-
- [ ] 4.
|
|
49
|
-
- [ ] 5.
|
|
55
|
+
- [ ] 1. Execute a dry run to preview proposed changes using the `dart_fix` MCP tool or CLI command `dart fix --dry-run`.
|
|
56
|
+
- [ ] 2. Review the proposed fixes to ensure they align with the intended architecture.
|
|
57
|
+
- [ ] 3. If additional fixes are required, verify that the corresponding linter rules are enabled in `analysis_options.yaml`.
|
|
58
|
+
- [ ] 4. Apply the fixes using the `dart_fix` MCP tool or CLI command `dart fix --apply`.
|
|
59
|
+
- [ ] 5. Format the modified code using the `dart_format` MCP tool or CLI command `dart format .`.
|
|
60
|
+
- [ ] 6. Run the static analysis workflow to verify all diagnostics are resolved.
|
|
50
61
|
|
|
51
62
|
## Examples
|
|
52
63
|
|
|
@@ -82,9 +93,11 @@ formatter:
|
|
|
82
93
|
### Inline Diagnostic Suppression
|
|
83
94
|
|
|
84
95
|
```dart
|
|
96
|
+
// Suppress for the entire file
|
|
85
97
|
// ignore_for_file: unused_local_variable, dead_code
|
|
86
98
|
|
|
87
99
|
void processData() {
|
|
100
|
+
// Suppress for a specific line
|
|
88
101
|
// ignore: invalid_assignment
|
|
89
102
|
int x = '';
|
|
90
103
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: setup-declarative-routing
|
|
3
3
|
description: Configure `MaterialApp.router` using a package like `go_router` for advanced URL-based navigation. Use when developing web applications or mobile apps that require specific deep linking and browser history support.
|
|
4
|
+
last_modified: Tue, 21 Apr 2026 21:08:03 GMT
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Implementing Routing and Deep Linking
|
|
@@ -15,29 +16,46 @@ description: Configure `MaterialApp.router` using a package like `go_router` for
|
|
|
15
16
|
|
|
16
17
|
## Core Concepts
|
|
17
18
|
|
|
18
|
-
Use the `go_router` package for declarative routing in Flutter.
|
|
19
|
+
Use the `go_router` package for declarative routing in Flutter. It provides a robust API for complex routing scenarios, deep linking, and nested navigation.
|
|
19
20
|
|
|
20
|
-
- **GoRouter**:
|
|
21
|
-
- **GoRoute**:
|
|
22
|
-
- **ShellRoute / StatefulShellRoute**: Wraps child routes in a persistent UI shell (e.g., `BottomNavigationBar`). `StatefulShellRoute` maintains state of parallel branches.
|
|
23
|
-
- **Path URL Strategy**: Removes the default `#` from web URLs.
|
|
21
|
+
- **GoRouter**: The central configuration object defining the application's route tree.
|
|
22
|
+
- **GoRoute**: A standard route mapping a URL path to a Flutter screen.
|
|
23
|
+
- **ShellRoute / StatefulShellRoute**: Wraps child routes in a persistent UI shell (e.g., a `BottomNavigationBar`). `StatefulShellRoute` maintains the state of parallel navigation branches.
|
|
24
|
+
- **Path URL Strategy**: Removes the default `#` fragment from web URLs, essential for clean deep linking across platforms.
|
|
24
25
|
|
|
25
26
|
## Workflow: Initializing the Application and Router
|
|
26
27
|
|
|
28
|
+
Follow this workflow to bootstrap a new Flutter application with `go_router` and configure the root routing mechanism.
|
|
29
|
+
|
|
27
30
|
### Task Progress
|
|
28
31
|
|
|
29
32
|
- [ ] Create the Flutter application.
|
|
30
|
-
- [ ] Add `go_router
|
|
31
|
-
- [ ] Configure URL strategy
|
|
33
|
+
- [ ] Add the `go_router` dependency.
|
|
34
|
+
- [ ] Configure the URL strategy for web/deep linking.
|
|
32
35
|
- [ ] Implement the `GoRouter` configuration.
|
|
33
36
|
- [ ] Bind the router to `MaterialApp.router`.
|
|
34
37
|
|
|
38
|
+
### 1. Scaffold the Application
|
|
39
|
+
|
|
40
|
+
Run the following commands to create the app and add the required routing package:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
flutter create <app-name>
|
|
44
|
+
cd <app-name>
|
|
45
|
+
flutter pub add go_router
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Configure the Router
|
|
49
|
+
|
|
50
|
+
Define a top-level `GoRouter` instance. Handle authentication or state-based routing using the `redirect` parameter.
|
|
51
|
+
|
|
35
52
|
```dart
|
|
36
53
|
import 'package:flutter/material.dart';
|
|
37
54
|
import 'package:go_router/go_router.dart';
|
|
38
55
|
import 'package:flutter_web_plugins/url_strategy.dart';
|
|
39
56
|
|
|
40
57
|
void main() {
|
|
58
|
+
// Use path URL strategy to remove the '#' from web URLs
|
|
41
59
|
usePathUrlStrategy();
|
|
42
60
|
runApp(const MyApp());
|
|
43
61
|
}
|
|
@@ -61,25 +79,115 @@ final GoRouter _router = GoRouter(
|
|
|
61
79
|
|
|
62
80
|
class MyApp extends StatelessWidget {
|
|
63
81
|
const MyApp({super.key});
|
|
82
|
+
|
|
64
83
|
@override
|
|
65
84
|
Widget build(BuildContext context) {
|
|
66
|
-
return MaterialApp.router(
|
|
85
|
+
return MaterialApp.router(
|
|
86
|
+
routerConfig: _router,
|
|
87
|
+
title: 'Routing App',
|
|
88
|
+
);
|
|
67
89
|
}
|
|
68
90
|
}
|
|
69
91
|
```
|
|
70
92
|
|
|
71
93
|
## Workflow: Configuring Platform Deep Linking
|
|
72
94
|
|
|
95
|
+
Configure the native platforms to intercept specific URLs and route them into the Flutter application.
|
|
96
|
+
|
|
73
97
|
### Task Progress
|
|
74
98
|
|
|
75
99
|
- [ ] Determine target platforms (iOS, Android, or both).
|
|
76
|
-
- [ ]
|
|
77
|
-
- [ ]
|
|
78
|
-
- [ ]
|
|
100
|
+
- [ ] Apply conditional configuration for Android (Manifest + Asset Links).
|
|
101
|
+
- [ ] Apply conditional configuration for iOS (Plist + Entitlements + AASA).
|
|
102
|
+
- [ ] Run validator -> review errors -> fix.
|
|
103
|
+
|
|
104
|
+
### If configuring for Android:
|
|
105
|
+
|
|
106
|
+
1. **Modify `AndroidManifest.xml`**: Add the intent filter inside the `<activity>` tag for `.MainActivity`.
|
|
107
|
+
|
|
108
|
+
```xml
|
|
109
|
+
<intent-filter android:autoVerify="true">
|
|
110
|
+
<action android:name="android.intent.action.VIEW" />
|
|
111
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
112
|
+
<category android:name="android.intent.category.BROWSABLE" />
|
|
113
|
+
<data android:scheme="http" android:host="yourdomain.com" />
|
|
114
|
+
<data android:scheme="https" />
|
|
115
|
+
</intent-filter>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
2. **Host `assetlinks.json`**: Serve the following JSON at `https://yourdomain.com/.well-known/assetlinks.json`.
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
[
|
|
122
|
+
{
|
|
123
|
+
"relation": ["delegate_permission/common.handle_all_urls"],
|
|
124
|
+
"target": {
|
|
125
|
+
"namespace": "android_app",
|
|
126
|
+
"package_name": "com.yourcompany.yourapp",
|
|
127
|
+
"sha256_cert_fingerprints": ["YOUR_SHA256_FINGERPRINT"]
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### If configuring for iOS:
|
|
134
|
+
|
|
135
|
+
1. **Modify `Info.plist`**: Opt-in to Flutter's default deep link handler.
|
|
136
|
+
_Note: If using a third-party deep linking plugin (e.g., `app_links`), set this to `NO` to prevent conflicts._
|
|
137
|
+
|
|
138
|
+
```xml
|
|
139
|
+
<key>FlutterDeepLinkingEnabled</key>
|
|
140
|
+
<true/>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
2. **Modify `Runner.entitlements`**: Add the associated domain.
|
|
144
|
+
|
|
145
|
+
```xml
|
|
146
|
+
<key>com.apple.developer.associated-domains</key>
|
|
147
|
+
<array>
|
|
148
|
+
<string>applinks:yourdomain.com</string>
|
|
149
|
+
</array>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
3. **Host `apple-app-site-association`**: Serve the following JSON (without a `.json` extension) at `https://yourdomain.com/.well-known/apple-app-site-association`.
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"applinks": {
|
|
157
|
+
"apps": [],
|
|
158
|
+
"details": [
|
|
159
|
+
{
|
|
160
|
+
"appIDs": ["TEAM_ID.com.yourcompany.yourapp"],
|
|
161
|
+
"paths": ["*"],
|
|
162
|
+
"components": [{ "/": "/*" }]
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Validation Loop
|
|
170
|
+
|
|
171
|
+
Run validator -> review errors -> fix.
|
|
172
|
+
|
|
173
|
+
- **Android**: Test using ADB.
|
|
174
|
+
```bash
|
|
175
|
+
adb shell 'am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://yourdomain.com/details/123"' com.yourcompany.yourapp
|
|
176
|
+
```
|
|
177
|
+
- **iOS**: Test using `xcrun` on a booted simulator.
|
|
178
|
+
```bash
|
|
179
|
+
xcrun simctl openurl booted https://yourdomain.com/details/123
|
|
180
|
+
```
|
|
79
181
|
|
|
80
182
|
## Workflow: Implementing Nested Navigation
|
|
81
183
|
|
|
82
|
-
Use `StatefulShellRoute
|
|
184
|
+
Use `StatefulShellRoute` to implement persistent UI shells (like a bottom navigation bar) that maintain the state of their child routes.
|
|
185
|
+
|
|
186
|
+
### Task Progress
|
|
187
|
+
|
|
188
|
+
- [ ] Define `StatefulShellRoute.indexedStack` in the `GoRouter` configuration.
|
|
189
|
+
- [ ] Create `StatefulShellBranch` instances for each navigation tab.
|
|
190
|
+
- [ ] Implement the shell widget using `StatefulNavigationShell`.
|
|
83
191
|
|
|
84
192
|
```dart
|
|
85
193
|
final GoRouter _router = GoRouter(
|
|
@@ -90,12 +198,22 @@ final GoRouter _router = GoRouter(
|
|
|
90
198
|
return ScaffoldWithNavBar(navigationShell: navigationShell);
|
|
91
199
|
},
|
|
92
200
|
branches: [
|
|
93
|
-
StatefulShellBranch(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
201
|
+
StatefulShellBranch(
|
|
202
|
+
routes: [
|
|
203
|
+
GoRoute(
|
|
204
|
+
path: '/home',
|
|
205
|
+
builder: (context, state) => const HomeScreen(),
|
|
206
|
+
),
|
|
207
|
+
],
|
|
208
|
+
),
|
|
209
|
+
StatefulShellBranch(
|
|
210
|
+
routes: [
|
|
211
|
+
GoRoute(
|
|
212
|
+
path: '/settings',
|
|
213
|
+
builder: (context, state) => const SettingsScreen(),
|
|
214
|
+
),
|
|
215
|
+
],
|
|
216
|
+
),
|
|
99
217
|
],
|
|
100
218
|
),
|
|
101
219
|
],
|
|
@@ -104,25 +222,25 @@ final GoRouter _router = GoRouter(
|
|
|
104
222
|
|
|
105
223
|
## Examples
|
|
106
224
|
|
|
107
|
-
###
|
|
108
|
-
|
|
109
|
-
```dart
|
|
110
|
-
context.go('/details/123'); // Replace current stack
|
|
111
|
-
context.push('/details/123'); // Push onto stack
|
|
112
|
-
context.goNamed('details', pathParameters: {'id': '123'});
|
|
113
|
-
context.pop();
|
|
114
|
-
```
|
|
225
|
+
### High-Fidelity Shell Widget Implementation
|
|
115
226
|
|
|
116
|
-
|
|
227
|
+
Implement the UI shell that consumes the `StatefulNavigationShell` to handle branch switching.
|
|
117
228
|
|
|
118
229
|
```dart
|
|
119
230
|
class ScaffoldWithNavBar extends StatelessWidget {
|
|
120
|
-
const ScaffoldWithNavBar({
|
|
231
|
+
const ScaffoldWithNavBar({
|
|
232
|
+
required this.navigationShell,
|
|
233
|
+
super.key,
|
|
234
|
+
});
|
|
235
|
+
|
|
121
236
|
final StatefulNavigationShell navigationShell;
|
|
122
237
|
|
|
123
238
|
void _goBranch(int index) {
|
|
124
|
-
navigationShell.goBranch(
|
|
125
|
-
|
|
239
|
+
navigationShell.goBranch(
|
|
240
|
+
index,
|
|
241
|
+
// Support navigating to the initial location when tapping the active tab.
|
|
242
|
+
initialLocation: index == navigationShell.currentIndex,
|
|
243
|
+
);
|
|
126
244
|
}
|
|
127
245
|
|
|
128
246
|
@override
|
|
@@ -142,6 +260,24 @@ class ScaffoldWithNavBar extends StatelessWidget {
|
|
|
142
260
|
}
|
|
143
261
|
```
|
|
144
262
|
|
|
263
|
+
### Programmatic Navigation
|
|
264
|
+
|
|
265
|
+
Use the `context.go()` and `context.push()` extension methods provided by `go_router`.
|
|
266
|
+
|
|
267
|
+
```dart
|
|
268
|
+
// Replaces the current route stack with the target route (Declarative)
|
|
269
|
+
context.go('/details/123');
|
|
270
|
+
|
|
271
|
+
// Pushes the target route onto the existing stack (Imperative)
|
|
272
|
+
context.push('/details/123');
|
|
273
|
+
|
|
274
|
+
// Navigates using a named route and path parameters
|
|
275
|
+
context.goNamed('details', pathParameters: {'id': '123'});
|
|
276
|
+
|
|
277
|
+
// Pops the current route
|
|
278
|
+
context.pop();
|
|
279
|
+
```
|
|
280
|
+
|
|
145
281
|
## Flutter Ultra Integration
|
|
146
282
|
|
|
147
283
|
After configuring routes, test navigation in the running app:
|