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
2 changes: 1 addition & 1 deletion packages/devtools_app/lib/devtools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
/// Note: a regexp in the `dt update-version' command logic matches the constant
/// declaration `const version =`. If you change the declaration you must also
/// modify the regex in the `dt update-version' command logic.
const version = '2.56.0';
const version = '2.57.0-dev.0';
104 changes: 84 additions & 20 deletions packages/devtools_app/lib/src/screens/app_size/app_size_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,14 @@ class _AppSizeBodyState extends State<AppSizeBody>
testAppSizeFile = await server.requestTestAppSizeFile(testFilePath);
}

// TODO(kenz): add error handling if the files are null
final errorMessages = <String>[
if (baseAppSizeFile == null) 'base app size file: $baseFilePath',
if (testAppSizeFile == null) 'test app size file: $testFilePath',
];
if (errorMessages.isNotEmpty) {
_pushErrorMessage('Failed to load ${errorMessages.join(' and ')}.');
}

if (baseAppSizeFile != null) {
if (testAppSizeFile != null) {
controller.loadDiffTreeFromJsonFiles(
Expand Down Expand Up @@ -306,15 +313,78 @@ class DiffTreeTypeDropdown extends StatelessWidget {
}
}

enum ImportInstructionType { analysis, diffOld, diffNew }

class _ImportInstructions extends StatelessWidget {
const _ImportInstructions({this.type = ImportInstructionType.analysis});

final ImportInstructionType type;

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);

List<InlineSpan> buildInstructionText() {
final article = type == ImportInstructionType.diffNew ? 'a' : 'an';
final boldText = type == ImportInstructionType.diffOld
? 'original (old)'
: type == ImportInstructionType.diffNew
? 'modified (new)'
: null;

return [
TextSpan(
text: 'Drag and drop $article ',
style: theme.regularTextStyle,
),
if (boldText != null)
TextSpan(text: boldText, style: theme.boldTextStyle),
TextSpan(
text:
'${boldText != null ? ' ' : ''}AOT snapshot or size analysis file'
' for debugging, or click "Open file".',
style: theme.regularTextStyle,
),
];
}

return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
RichText(
textAlign: TextAlign.center,
text: TextSpan(children: buildInstructionText()),
),
const SizedBox(height: densePadding),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
TextSpan(text: 'Read ', style: theme.regularTextStyle),
LinkTextSpan(
link: const Link(
display: 'documentation',
url:
'https://docs.flutter.dev/tools/devtools/app-size#generating-size-files',
),
context: context,
),
TextSpan(
text: ' to learn how to generate these files.',
style: theme.regularTextStyle,
),
],
),
),
],
);
}
}

class AnalysisView extends StatefulWidget {
const AnalysisView({super.key});

// TODO(kenz): add links to documentation on how to generate these files, and
// mention the import file button once it is hooked up to a file picker.
static const importInstructions =
'Drag and drop an AOT snapshot or'
' size analysis file for debugging';

@override
State<AnalysisView> createState() => _AnalysisViewState();
}
Expand Down Expand Up @@ -382,7 +452,7 @@ class _AnalysisViewState extends State<AnalysisView> with AutoDisposeMixin {
children: [
Flexible(
child: FileImportContainer(
instructions: AnalysisView.importInstructions,
instructionsWidget: const _ImportInstructions(),
actionText: 'Analyze Size',
gaScreen: gac.appSize,
gaSelectionImport: gac.importFileSingle,
Expand All @@ -407,15 +477,6 @@ class _AnalysisViewState extends State<AnalysisView> with AutoDisposeMixin {
class DiffView extends StatefulWidget {
const DiffView({super.key});

// TODO(kenz): add links to documentation on how to generate these files, and
// mention the import file button once it is hooked up to a file picker.
static const importOldInstructions =
'Drag and drop an original (old) AOT '
'snapshot or size analysis file for debugging';
static const importNewInstructions =
'Drag and drop a modified (new) AOT '
'snapshot or size analysis file for debugging';

@override
State<DiffView> createState() => _DiffViewState();
}
Expand Down Expand Up @@ -490,9 +551,12 @@ class _DiffViewState extends State<DiffView> with AutoDisposeMixin {
child: DualFileImportContainer(
firstFileTitle: 'Old',
secondFileTitle: 'New',
// TODO(kenz): perhaps bold "original" and "modified".
firstInstructions: DiffView.importOldInstructions,
secondInstructions: DiffView.importNewInstructions,
firstInstructionsWidget: const _ImportInstructions(
type: ImportInstructionType.diffOld,
),
secondInstructionsWidget: const _ImportInstructions(
type: ImportInstructionType.diffNew,
),
actionText: 'Analyze Diff',
gaScreen: gac.appSize,
gaSelectionImportFirst: gac.importFileDiffFirst,
Expand Down
28 changes: 20 additions & 8 deletions packages/devtools_app/lib/src/shared/ui/file_import.dart
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,10 @@ class __DropdownSaveButtonState extends State<_DropdownSaveButton> {

class FileImportContainer extends StatefulWidget {
const FileImportContainer({
required this.instructions,
required this.gaScreen,
required this.gaSelectionImport,
this.instructions,
this.instructionsWidget,
this.title,
this.backgroundColor,
this.gaSelectionAction,
Expand All @@ -230,13 +231,15 @@ class FileImportContainer extends StatefulWidget {
this.onFileCleared,
this.extensions = const ['json'],
super.key,
});
}) : assert((instructions == null) != (instructionsWidget == null));

final String? title;

final Color? backgroundColor;

final String instructions;
final String? instructions;

final Widget? instructionsWidget;

/// The title of the action button.
final String? actionText;
Expand Down Expand Up @@ -276,7 +279,10 @@ class _FileImportContainerState extends State<FileImportContainer> {
Text(title, style: const TextStyle(fontSize: 18.0)),
const SizedBox(height: extraLargeSpacing),
],
CenteredMessage(message: widget.instructions),
if (widget.instructionsWidget != null)
widget.instructionsWidget!
else if (widget.instructions != null)
CenteredMessage(message: widget.instructions),
const SizedBox(height: denseSpacing),
_buildImportFileRow(),
if (widget.actionText != null && widget.onAction != null)
Expand Down Expand Up @@ -477,8 +483,10 @@ class DualFileImportContainer extends StatefulWidget {
super.key,
required this.firstFileTitle,
required this.secondFileTitle,
required this.firstInstructions,
required this.secondInstructions,
this.firstInstructions,
this.secondInstructions,
this.firstInstructionsWidget,
this.secondInstructionsWidget,
required this.actionText,
required this.onAction,
required this.gaScreen,
Expand All @@ -489,8 +497,10 @@ class DualFileImportContainer extends StatefulWidget {

final String firstFileTitle;
final String secondFileTitle;
final String firstInstructions;
final String secondInstructions;
final String? firstInstructions;
final String? secondInstructions;
final Widget? firstInstructionsWidget;
final Widget? secondInstructionsWidget;
final String gaScreen;
final String gaSelectionImportFirst;
final String gaSelectionImportSecond;
Expand Down Expand Up @@ -525,6 +535,7 @@ class _DualFileImportContainerState extends State<DualFileImportContainer> {
title: widget.firstFileTitle,
backgroundColor: backgroundColor,
instructions: widget.firstInstructions,
instructionsWidget: widget.firstInstructionsWidget,
onFileSelected: onFirstFileSelected,
onFileCleared: onFirstFileCleared,
gaScreen: widget.gaScreen,
Expand All @@ -539,6 +550,7 @@ class _DualFileImportContainerState extends State<DualFileImportContainer> {
title: widget.secondFileTitle,
backgroundColor: backgroundColor,
instructions: widget.secondInstructions,
instructionsWidget: widget.secondInstructionsWidget,
onFileSelected: onSecondFileSelected,
onFileCleared: onSecondFileCleared,
gaScreen: widget.gaScreen,
Expand Down
2 changes: 1 addition & 1 deletion packages/devtools_app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish_to: none

# Note: this version should only be updated by running the 'dt update-version'
# command that updates the version here and in 'devtools.dart'.
version: 2.56.0
version: 2.57.0-dev.0

repository: https://github.com/flutter/devtools/tree/master/packages/devtools_app

Expand Down
11 changes: 6 additions & 5 deletions packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ found in the LICENSE file or at https://developers.google.com/open-source/licens
This is a draft for future release notes that are going to land on
[the Flutter website](https://docs.flutter.dev/tools/devtools/release-notes).

# DevTools 2.56.0 release notes
# DevTools 2.57.0 release notes

The 2.56.0 release of the Dart and Flutter DevTools
The 2.57.0 release of the Dart and Flutter DevTools
includes the following changes among other general improvements.
To learn more about DevTools, check out the
[DevTools overview](/tools/devtools).
Expand Down Expand Up @@ -39,15 +39,16 @@ TODO: Remove this section if there are not any updates.

## Network profiler updates

- Fix crash in the Network tab when viewing binary multipart request or response bodies (#9978)
- Fix crash in the Network tab when viewing binary multipart request or
response bodies. [#9680](https://github.com/flutter/devtools/pull/9680)

## Logging updates

TODO: Remove this section if there are not any updates.

## App size tool updates

TODO: Remove this section if there are not any updates.
- Added documentation links and improved handling for null files. [#9689](https://github.com/flutter/devtools/pull/9689)

## Deep links tool updates

Expand All @@ -68,4 +69,4 @@ TODO: Remove this section if there are not any updates.
## Full commit history

To find a complete list of changes in this release, check out the
[DevTools git log](https://github.com/flutter/devtools/tree/v2.56.0).
[DevTools git log](https://github.com/flutter/devtools/tree/v2.57.0).
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ void main() {
expect(find.byType(ClearButton), findsOneWidget);

expect(find.byType(FileImportContainer), findsOneWidget);
expect(find.text(AnalysisView.importInstructions), findsOneWidget);
const importInstructions =
'Drag and drop an AOT snapshot or size analysis file for debugging, or click "Open file".';
expect(find.richText(importInstructions), findsOneWidget);
expect(find.text('No File Selected'), findsOneWidget);

appSizeController.loadTreeFromJsonFile(
Expand All @@ -227,7 +229,7 @@ void main() {
await tester.pumpAndSettle();

expect(find.byType(FileImportContainer), findsNothing);
expect(find.text(AnalysisView.importInstructions), findsNothing);
expect(find.richText(importInstructions), findsNothing);
expect(find.text('No File Selected'), findsNothing);
expect(find.byType(AnalysisView), findsOneWidget);
expect(
Expand Down Expand Up @@ -261,7 +263,9 @@ void main() {
await tester.pumpAndSettle();

expect(find.byType(FileImportContainer), findsOneWidget);
expect(find.text(AnalysisView.importInstructions), findsOneWidget);
const importInstructions =
'Drag and drop an AOT snapshot or size analysis file for debugging, or click "Open file".';
expect(find.richText(importInstructions), findsOneWidget);
expect(find.text('No File Selected'), findsOneWidget);
});
});
Expand Down Expand Up @@ -302,8 +306,12 @@ void main() {

expect(find.byType(DualFileImportContainer), findsOneWidget);
expect(find.byType(FileImportContainer), findsNWidgets(2));
expect(find.text(DiffView.importOldInstructions), findsOneWidget);
expect(find.text(DiffView.importNewInstructions), findsOneWidget);
const importOldInstructions =
'Drag and drop an original (old) AOT snapshot or size analysis file for debugging, or click "Open file".';
const importNewInstructions =
'Drag and drop a modified (new) AOT snapshot or size analysis file for debugging, or click "Open file".';
expect(find.richText(importOldInstructions), findsOneWidget);
expect(find.richText(importNewInstructions), findsOneWidget);
expect(find.text('No File Selected'), findsNWidgets(2));
});

Expand All @@ -323,8 +331,12 @@ void main() {
await tester.pumpAndSettle();

expect(find.byType(FileImportContainer), findsNothing);
expect(find.text(DiffView.importOldInstructions), findsNothing);
expect(find.text(DiffView.importNewInstructions), findsNothing);
const importOldInstructions =
'Drag and drop an original (old) AOT snapshot or size analysis file for debugging, or click "Open file".';
const importNewInstructions =
'Drag and drop a modified (new) AOT snapshot or size analysis file for debugging, or click "Open file".';
expect(find.richText(importOldInstructions), findsNothing);
expect(find.richText(importNewInstructions), findsNothing);
expect(find.text('No File Selected'), findsNothing);

expect(find.byType(DiffView), findsOneWidget);
Expand Down Expand Up @@ -393,8 +405,12 @@ void main() {

expect(find.byType(DualFileImportContainer), findsOneWidget);
expect(find.byType(FileImportContainer), findsNWidgets(2));
expect(find.text(DiffView.importOldInstructions), findsOneWidget);
expect(find.text(DiffView.importNewInstructions), findsOneWidget);
const importOldInstructions =
'Drag and drop an original (old) AOT snapshot or size analysis file for debugging, or click "Open file".';
const importNewInstructions =
'Drag and drop a modified (new) AOT snapshot or size analysis file for debugging, or click "Open file".';
expect(find.richText(importOldInstructions), findsOneWidget);
expect(find.richText(importNewInstructions), findsOneWidget);
expect(find.text('No File Selected'), findsNWidgets(2));
});
});
Expand Down
Loading