Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ import '../../../shared/analytics/constants.dart' as gac;
import '../../../shared/globals.dart';
import '../../../shared/primitives/utils.dart';
import '../../../shared/server/server.dart' as server;
import '../../../shared/ui/common_widgets.dart';
import '../deep_links_controller.dart';
import '../deep_links_model.dart';
import 'root_selector.dart';

const _kLinearProgressIndicatorWidth = 280.0;

enum DeepLinksTarget { android, ios }

/// A view for selecting a Flutter project.
class SelectProjectView extends StatefulWidget {
const SelectProjectView({super.key});
Expand Down Expand Up @@ -131,7 +134,7 @@ class _SelectProjectViewState extends State<SelectProjectView> {
gac.deeplink,
gac.AnalyzeFlutterProject.flutterInvalidProjectSelected.name,
);
await showNonFlutterProjectDialog();
await _showFlutterProjectMissingBuildOptionsDialog(directory);
return;
}
controller.selectedProject.value = FlutterProject(
Expand All @@ -144,6 +147,119 @@ class _SelectProjectViewState extends State<SelectProjectView> {
});
}

Future<void> _showFlutterProjectMissingBuildOptionsDialog(
String appPath,
) async {
await showDialog(
context: context,
builder: (_) {
final theme = Theme.of(context);
return DevToolsDialog(
title: const Text('No iOS or Android build options found.'),
content: SizedBox(
width: defaultDialogWidth,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'DevTools could not verify the build options for this project.',
),
const SizedBox(height: largeSpacing),
..._deepLinksInstructions(
theme: theme,
appPath: appPath,
target: DeepLinksTarget.android,
),
const SizedBox(height: largeSpacing),
..._deepLinksInstructions(
theme: theme,
appPath: appPath,
target: DeepLinksTarget.ios,
),
],
),
),
actions: const [DialogCloseButton()],
);
},
);
setState(() {
_retrievingFlutterProject = false;
});
}

List<Widget> _deepLinksInstructions({
required ThemeData theme,
required String appPath,
required DeepLinksTarget target,
}) {
final commandStyle = theme.subtleTextStyle.copyWith(
fontFamily: 'RobotoMono',
);
const commandPadding = EdgeInsets.symmetric(
horizontal: denseSpacing,
vertical: densePadding,
);
final title = switch (target) {
DeepLinksTarget.android => 'Android',
DeepLinksTarget.ios => 'iOS',
};
final directory = switch (target) {
DeepLinksTarget.android => '/android',
DeepLinksTarget.ios => '/ios',
};
final documentationUrl = switch (target) {
DeepLinksTarget.android => 'https://docs.flutter.dev/deployment/android',
DeepLinksTarget.ios => 'https://docs.flutter.dev/deployment/ios',
};
final command = switch (target) {
DeepLinksTarget.android =>
'flutter analyze --android --list-build-variants',
DeepLinksTarget.ios => 'flutter analyze --ios --list-build-options',
};

return [
Text('For $title', style: theme.textTheme.titleMedium),
const SizedBox(height: intermediateSpacing),
RichText(
text: TextSpan(
style: theme.regularTextStyle,
children: [
TextSpan(
text:
'These are configured in the $directory directory. Please refer to the ',
),
GaLinkTextSpan(
link: GaLink(
display: 'Flutter documentation',
url: documentationUrl,
),
context: context,
),
const TextSpan(text: ' for more information.'),
],
),
),
const SizedBox(height: intermediateSpacing),
const Text(
'To confirm your setup, run the following command in your terminal:',
),
const SizedBox(height: denseSpacing),
Card(
child: Padding(
padding: commandPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: Text('$command $appPath', style: commandStyle)),
CopyToClipboardControl(dataProvider: () => '$command $appPath'),
],
),
),
),
];
}

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
Expand All @@ -156,7 +272,7 @@ class _SelectProjectViewState extends State<SelectProjectView> {
Padding(
padding: const EdgeInsets.all(extraLargeSpacing),
child: Text(
'Select a local flutter project to check the status of all deep links.',
'Select a local Flutter project to check the status of all deep links.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
),
Expand Down
4 changes: 3 additions & 1 deletion packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ TODO: Remove this section if there are not any general updates.

## Deep links tool updates

TODO: Remove this section if there are not any general updates.
- Added more informative dialog if Deep Links tool is unable to find build
options for the iOS or Android app. -
[#9571](https://github.com/flutter/devtools/pull/9571)

## VS Code Sidebar updates

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void main() {
) async {
await pumpSelectProjectView(tester);
expect(
find.textContaining('Select a local flutter project to check'),
find.textContaining('Select a local Flutter project to check'),
findsOneWidget,
);
expect(find.byType(ProjectRootsDropdown), findsOneWidget);
Expand Down Expand Up @@ -95,7 +95,7 @@ void main() {
(WidgetTester tester) async {
await pumpSelectProjectView(tester);
expect(
find.textContaining('Select a local flutter project to check'),
find.textContaining('Select a local Flutter project to check'),
findsOneWidget,
);
expect(find.byType(ProjectRootsDropdown), findsOneWidget);
Expand Down