diff --git a/packages/devtools_app/lib/src/screens/network/network_screen.dart b/packages/devtools_app/lib/src/screens/network/network_screen.dart index 88f71a9fba3..cd526324e2f 100644 --- a/packages/devtools_app/lib/src/screens/network/network_screen.dart +++ b/packages/devtools_app/lib/src/screens/network/network_screen.dart @@ -206,72 +206,115 @@ class _NetworkProfilerControlsState extends State<_NetworkProfilerControls> final screenWidth = ScreenSize(context).width; final hasRequests = controller.filteredData.value.isNotEmpty; - return Row( + return Column( children: [ - StartStopRecordingButton( - recording: _recording, - onPressed: () async => await controller.togglePolling(!_recording), - tooltipOverride: _recording - ? 'Stop recording network traffic' - : 'Resume recording network traffic', - minScreenWidthForText: double.infinity, - gaScreen: gac.network, - gaSelection: _recording ? gac.pause : gac.resume, - ), - const SizedBox(width: denseSpacing), - ClearButton( - minScreenWidthForText: _NetworkProfilerControls._includeTextWidth, - gaScreen: gac.network, - gaSelection: gac.clear, - onPressed: controller.clear, + Row( + children: [ + StartStopRecordingButton( + recording: _recording, + onPressed: () async => + await controller.togglePolling(!_recording), + tooltipOverride: _recording + ? 'Stop recording network traffic' + : 'Resume recording network traffic', + minScreenWidthForText: double.infinity, + gaScreen: gac.network, + gaSelection: _recording ? gac.pause : gac.resume, + ), + const SizedBox(width: denseSpacing), + ClearButton( + minScreenWidthForText: _NetworkProfilerControls._includeTextWidth, + gaScreen: gac.network, + gaSelection: gac.clear, + onPressed: controller.clear, + ), + const SizedBox(width: denseSpacing), + // TODO(kenz): fix focus issue when state is refreshed + Expanded( + child: SearchField( + searchController: controller, + searchFieldEnabled: hasRequests, + searchFieldWidth: screenWidth <= MediaSize.xs + ? defaultSearchFieldWidth + : wideSearchFieldWidth, + ), + ), + const SizedBox(width: denseSpacing), + Expanded( + child: StandaloneFilterField( + controller: controller, + filteredItem: 'request', + ), + ), + const SizedBox(width: denseSpacing), + if (FeatureFlags.networkSaveLoad.isEnabled) + OpenSaveButtonGroup( + screenId: ScreenMetaData.network.id, + saveFormats: const [SaveFormat.devtools, SaveFormat.har], + gaItemForSaveFormatSelection: (SaveFormat format) => + switch (format) { + SaveFormat.devtools => gac.saveFile, + SaveFormat.har => gac.NetworkEvent.downloadAsHar.name, + }, + onSave: (SaveFormat format) async { + switch (format) { + case SaveFormat.devtools: + await controller.fetchFullDataBeforeExport(); + controller.exportData(); + case SaveFormat.har: + await controller.exportAsHarFile(); + } + }, + ) + else + DownloadButton( + tooltip: 'Download as .har file', + minScreenWidthForText: + _NetworkProfilerControls._includeTextWidth, + onPressed: controller.exportAsHarFile, + gaScreen: gac.network, + gaSelection: gac.NetworkEvent.downloadAsHar.name, + ), + ], ), - const SizedBox(width: denseSpacing), - // TODO(kenz): fix focus issue when state is refreshed - Expanded( - child: SearchField( - searchController: controller, - searchFieldEnabled: hasRequests, - searchFieldWidth: screenWidth <= MediaSize.xs - ? defaultSearchFieldWidth - : wideSearchFieldWidth, + if (!_recording) + const Padding( + padding: EdgeInsets.only(top: intermediateSpacing), + child: _RecordingPausedBanner(), ), + ], + ); + } +} + +class _RecordingPausedBanner extends StatelessWidget { + const _RecordingPausedBanner(); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + return Card( + color: theme.colorScheme.secondaryContainer, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: densePadding, + horizontal: denseSpacing, ), - const SizedBox(width: denseSpacing), - Expanded( - child: StandaloneFilterField( - controller: controller, - filteredItem: 'request', - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + 'Network traffic recording is paused. Click the resume button ' + 'to continue.', + style: theme.regularTextStyle.copyWith( + color: theme.colorScheme.onSecondaryContainer, + ), + ), + ), + ], ), - const SizedBox(width: denseSpacing), - if (FeatureFlags.networkSaveLoad.isEnabled) - OpenSaveButtonGroup( - screenId: ScreenMetaData.network.id, - saveFormats: const [SaveFormat.devtools, SaveFormat.har], - gaItemForSaveFormatSelection: (SaveFormat format) => - switch (format) { - SaveFormat.devtools => gac.saveFile, - SaveFormat.har => gac.NetworkEvent.downloadAsHar.name, - }, - onSave: (SaveFormat format) async { - switch (format) { - case SaveFormat.devtools: - await controller.fetchFullDataBeforeExport(); - controller.exportData(); - case SaveFormat.har: - await controller.exportAsHarFile(); - } - }, - ) - else - DownloadButton( - tooltip: 'Download as .har file', - minScreenWidthForText: _NetworkProfilerControls._includeTextWidth, - onPressed: controller.exportAsHarFile, - gaScreen: gac.network, - gaSelection: gac.NetworkEvent.downloadAsHar.name, - ), - ], + ), ); } } diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index 526a25cdede..71b86952a6f 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -42,9 +42,12 @@ TODO: Remove this section if there are not any general updates. ## Network profiler updates -* Fixed layout of the "error count" badge in the tab name. -* Fix display of "Response Headers" and "Request Headers" when there are no - headers. +* Fixed layout of the "error count" badge in the tab name. - + [#9470](https://github.com/flutter/devtools/pull/9470) +* Fixed display of "Response Headers" and "Request Headers" when there are no + headers. - [#9492](https://github.com/flutter/devtools/pull/9492) +* Added a banner to clearly indicate when DevTools is not logging network + requests. - [#9495](https://github.com/flutter/devtools/pull/9495) ## Logging updates