Skip to content

Commit

Permalink
Refactor logging controls (#8425)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenzieschmoll authored Oct 9, 2024
1 parent 76b4c9c commit bcf5cb1
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 111 deletions.
123 changes: 123 additions & 0 deletions packages/devtools_app/lib/src/screens/logging/logging_controls.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:devtools_app_shared/ui.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../../service/service_extension_widgets.dart';
import '../../shared/analytics/constants.dart' as gac;
import '../../shared/common_widgets.dart';
import '../../shared/primitives/utils.dart';
import '../../shared/ui/filter.dart';
import '../../shared/ui/search.dart';
import 'logging_controller.dart';
import 'shared/constants.dart';

class LoggingControls extends StatelessWidget {
const LoggingControls({super.key});

static const filterQueryInstructions = '''
Type a filter query to show or hide specific logs.
Any text that is not paired with an available filter key below will be queried against all categories (kind, message).
Available filters:
'kind', 'k' (e.g. 'k:flutter.frame', '-k:gc,stdout')
Example queries:
'my log message k:stdout,stdin'
'flutter -k:gc'
''';

@override
Widget build(BuildContext context) {
final controller = Provider.of<LoggingController>(context);
final hasData = controller.filteredData.value.isNotEmpty;
return Row(
children: [
ClearButton(
onPressed: controller.clear,
gaScreen: gac.logging,
gaSelection: gac.clear,
minScreenWidthForTextBeforeScaling: loggingMinVerboseWidth,
),
const Spacer(),
const SizedBox(width: denseSpacing),
// TODO(kenz): fix focus issue when state is refreshed
SearchField<LoggingController>(
searchFieldWidth: isScreenWiderThan(context, loggingMinVerboseWidth)
? wideSearchFieldWidth
: defaultSearchFieldWidth,
searchController: controller,
searchFieldEnabled: hasData,
),
const SizedBox(width: denseSpacing),
DevToolsFilterButton(
onPressed: () {
unawaited(
showDialog(
context: context,
builder: (context) => FilterDialog<LogData>(
controller: controller,
queryInstructions: filterQueryInstructions,
),
),
);
},
isFilterActive: controller.isFilterActive,
),
const SizedBox(width: denseSpacing),
CopyToClipboardControl(
dataProvider: () => controller.filteredData.value
.map((e) => '${e.timestamp} [${e.kind}] ${e.prettyPrinted()}')
.joinWithTrailing('\n'),
tooltip: 'Copy filtered logs',
),
const SizedBox(width: denseSpacing),
SettingsOutlinedButton(
gaScreen: gac.logging,
gaSelection: gac.loggingSettings,
tooltip: 'Logging Settings',
onPressed: () {
unawaited(
showDialog(
context: context,
builder: (context) => const LoggingSettingsDialog(),
),
);
},
),
],
);
}
}

class LoggingSettingsDialog extends StatelessWidget {
const LoggingSettingsDialog({super.key});

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return DevToolsDialog(
title: const DialogTitleText('Logging Settings'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...dialogSubHeader(
theme,
'General',
),
const StructuredErrorsToggle(),
],
),
actions: const [
DialogCloseButton(),
],
);
}
}
113 changes: 2 additions & 111 deletions packages/devtools_app/lib/src/screens/logging/logging_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:devtools_app_shared/ui.dart';
import 'package:devtools_app_shared/utils.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../../service/service_extension_widgets.dart';
import '../../shared/analytics/analytics.dart' as ga;
import '../../shared/analytics/constants.dart' as gac;
import '../../shared/common_widgets.dart';
import '../../shared/primitives/utils.dart';
import '../../shared/screen.dart';
import '../../shared/ui/filter.dart';
import '../../shared/ui/search.dart';
import '../../shared/utils.dart';
import '_log_details.dart';
import '_logs_table.dart';
import 'logging_controller.dart';
import 'shared/constants.dart';
import 'logging_controls.dart';

/// Presents logs from the connected app.
class LoggingScreen extends Screen {
Expand Down Expand Up @@ -52,19 +45,6 @@ class LoggingScreen extends Screen {
class LoggingScreenBody extends StatefulWidget {
const LoggingScreenBody({super.key});

static const filterQueryInstructions = '''
Type a filter query to show or hide specific logs.
Any text that is not paired with an available filter key below will be queried against all categories (kind, message).
Available filters:
'kind', 'k' (e.g. 'k:flutter.frame', '-k:gc,stdout')
Example queries:
'my log message k:stdout,stdin'
'flutter -k:gc'
''';

@override
State<LoggingScreenBody> createState() => _LoggingScreenState();
}
Expand Down Expand Up @@ -92,7 +72,7 @@ class _LoggingScreenState extends State<LoggingScreenBody>
Widget build(BuildContext context) {
return Column(
children: [
_buildLoggingControls(),
const LoggingControls(),
const SizedBox(height: intermediateSpacing),
Expanded(
child: _buildLoggingBody(),
Expand All @@ -101,57 +81,6 @@ class _LoggingScreenState extends State<LoggingScreenBody>
);
}

// TODO(kenz): replace with helper widget
Widget _buildLoggingControls() {
final hasData = controller.filteredData.value.isNotEmpty;
return Row(
children: [
ClearButton(
onPressed: controller.clear,
gaScreen: gac.logging,
gaSelection: gac.clear,
minScreenWidthForTextBeforeScaling: loggingMinVerboseWidth,
),
const Spacer(),
const SizedBox(width: denseSpacing),
// TODO(kenz): fix focus issue when state is refreshed
SearchField<LoggingController>(
searchFieldWidth: isScreenWiderThan(context, loggingMinVerboseWidth)
? wideSearchFieldWidth
: defaultSearchFieldWidth,
searchController: controller,
searchFieldEnabled: hasData,
),
const SizedBox(width: denseSpacing),
DevToolsFilterButton(
onPressed: _showFilterDialog,
isFilterActive: controller.isFilterActive,
),
const SizedBox(width: denseSpacing),
CopyToClipboardControl(
dataProvider: () => controller.filteredData.value
.map((e) => '${e.timestamp} [${e.kind}] ${e.prettyPrinted()}')
.joinWithTrailing('\n'),
tooltip: 'Copy filtered logs',
),
const SizedBox(width: denseSpacing),
SettingsOutlinedButton(
gaScreen: gac.logging,
gaSelection: gac.loggingSettings,
tooltip: 'Logging Settings',
onPressed: () {
unawaited(
showDialog(
context: context,
builder: (context) => const LoggingSettingsDialog(),
),
);
},
),
],
);
}

// TODO(kenz): replace with helper widget.
Widget _buildLoggingBody() {
return SplitPane(
Expand Down Expand Up @@ -179,42 +108,4 @@ class _LoggingScreenState extends State<LoggingScreenBody>
],
);
}

void _showFilterDialog() {
unawaited(
showDialog(
context: context,
builder: (context) => FilterDialog<LogData>(
controller: controller,
queryInstructions: LoggingScreenBody.filterQueryInstructions,
),
),
);
}
}

class LoggingSettingsDialog extends StatelessWidget {
const LoggingSettingsDialog({super.key});

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return DevToolsDialog(
title: const DialogTitleText('Logging Settings'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...dialogSubHeader(
theme,
'General',
),
const StructuredErrorsToggle(),
],
),
actions: const [
DialogCloseButton(),
],
);
}
}

0 comments on commit bcf5cb1

Please sign in to comment.