From 1bb19bb9d421e3b9e8f4309bdab2fd0bf08665ed Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Tue, 8 Oct 2024 17:02:52 -0700 Subject: [PATCH] Refactor logging code (#8418) * Refactor logging code * fix import --- .../logging_screen_v2/logging_table_row.dart | 146 +----------------- .../lib/src/screens/logging/metadata.dart | 146 ++++++++++++++++++ .../src/screens/logging/shared/constants.dart | 4 + .../logging_table_row_test.dart | 1 + 4 files changed, 154 insertions(+), 143 deletions(-) create mode 100644 packages/devtools_app/lib/src/screens/logging/metadata.dart diff --git a/packages/devtools_app/lib/src/screens/logging/logging_screen_v2/logging_table_row.dart b/packages/devtools_app/lib/src/screens/logging/logging_screen_v2/logging_table_row.dart index 25439d68391..fc6aa17854f 100644 --- a/packages/devtools_app/lib/src/screens/logging/logging_screen_v2/logging_table_row.dart +++ b/packages/devtools_app/lib/src/screens/logging/logging_screen_v2/logging_table_row.dart @@ -7,15 +7,12 @@ import 'dart:math'; import 'package:devtools_app_shared/ui.dart'; import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; import '../../../shared/globals.dart'; -import '../../../shared/ui/icons.dart'; import '../../../shared/ui/utils.dart'; +import '../metadata.dart'; import 'log_data.dart'; -final loggingTableTimeFormat = DateFormat('HH:mm:ss.SSS'); - class LoggingTableRow extends StatefulWidget { const LoggingTableRow({ super.key, @@ -57,18 +54,17 @@ class LoggingTableRow extends StatefulWidget { return [ if (data.timestamp != null) WhenMetaDataChip( - data: data, + timestamp: data.timestamp, maxWidth: maxWidth, ), KindMetaDataChip( - data: data, + kind: data.kind, maxWidth: maxWidth, icon: kindIcon.icon, iconAsset: kindIcon.iconAsset, ), if (elapsedFrameTimeAsString != null) FrameElapsedMetaDataChip( - data: data, maxWidth: maxWidth, elapsedTimeDisplay: elapsedFrameTimeAsString, ), @@ -171,139 +167,3 @@ class _LoggingTableRowState extends State { ); } } - -@visibleForTesting -abstract class MetadataChip extends StatelessWidget { - const MetadataChip({ - super.key, - required this.data, - required this.maxWidth, - required this.text, - this.icon, - this.iconAsset, - this.includeLeadingPadding = true, - }); - - final LogDataV2 data; - final double maxWidth; - final IconData? icon; - final String? iconAsset; - final String text; - final bool includeLeadingPadding; - - static const horizontalPadding = denseSpacing; - static const verticalPadding = densePadding; - static const iconPadding = densePadding; - - /// Estimates the size of this single metadata chip. - /// - /// If the [build] method is changed then this may need to be updated - Size estimateSize() { - final horizontalPaddingCount = includeLeadingPadding ? 2 : 1; - final maxWidthInsidePadding = - max(0.0, maxWidth - horizontalPadding * horizontalPaddingCount); - final iconSize = Size.square(defaultIconSize); - final textSize = calculateTextSpanSize( - _buildValueText(), - maxWidth: maxWidthInsidePadding, - ); - return Size( - ((icon != null || iconAsset != null) - ? iconSize.width + iconPadding - : 0.0) + - textSize.width + - horizontalPadding * horizontalPaddingCount, - max(iconSize.height, textSize.height) + verticalPadding * 2, - ); - } - - /// If this build method is changed then you may need to modify [estimateSize()] - @override - Widget build(BuildContext context) { - return Container( - constraints: BoxConstraints(maxWidth: maxWidth), - padding: EdgeInsets.fromLTRB( - includeLeadingPadding ? horizontalPadding : 0, - verticalPadding, - horizontalPadding, - verticalPadding, - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (icon != null || iconAsset != null) ...[ - DevToolsIcon( - icon: icon, - iconAsset: iconAsset, - size: defaultIconSize, - color: Theme.of(context).colorScheme.subtleTextColor, - ), - const SizedBox(width: iconPadding), - ] else - // Include an empty SizedBox to ensure a consistent height for the - // chips, regardless of whether the chip includes an icon. - SizedBox(height: defaultIconSize), - RichText( - text: _buildValueText(), - ), - ], - ), - ); - } - - TextSpan _buildValueText() { - return TextSpan( - text: text, - style: LoggingTableRow.metadataStyle, - ); - } -} - -@visibleForTesting -class WhenMetaDataChip extends MetadataChip { - WhenMetaDataChip({ - super.key, - required super.data, - required super.maxWidth, - }) : super( - icon: null, - text: data.timestamp == null - ? '' - : loggingTableTimeFormat - .format(DateTime.fromMillisecondsSinceEpoch(data.timestamp!)), - includeLeadingPadding: false, - ); -} - -@visibleForTesting -class KindMetaDataChip extends MetadataChip { - KindMetaDataChip({ - super.key, - required super.data, - required super.maxWidth, - super.icon, - super.iconAsset, - }) : super(text: data.kind); - - static ({IconData? icon, String? iconAsset}) generateIcon(String kind) { - IconData? kindIcon = Icons.list_rounded; - String? kindIconAsset; - if (kind == 'stdout' || kind == 'stderr') { - kindIcon = Icons.terminal_rounded; - } else if (RegExp(r'^flutter\..*$').hasMatch(kind)) { - kindIconAsset = 'icons/flutter.png'; - kindIcon = null; - } - return (icon: kindIcon, iconAsset: kindIconAsset); - } -} - -@visibleForTesting -class FrameElapsedMetaDataChip extends MetadataChip { - const FrameElapsedMetaDataChip({ - super.key, - required super.data, - required super.maxWidth, - required String elapsedTimeDisplay, - }) : super(icon: Icons.timer, text: elapsedTimeDisplay); -} diff --git a/packages/devtools_app/lib/src/screens/logging/metadata.dart b/packages/devtools_app/lib/src/screens/logging/metadata.dart new file mode 100644 index 00000000000..08bbb4c7f62 --- /dev/null +++ b/packages/devtools_app/lib/src/screens/logging/metadata.dart @@ -0,0 +1,146 @@ +// 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:math'; + +import 'package:devtools_app_shared/ui.dart'; +import 'package:flutter/material.dart'; + +import '../../shared/ui/icons.dart'; +import '../../shared/ui/utils.dart'; +import 'logging_screen_v2/logging_table_row.dart'; +import 'shared/constants.dart'; + +// TODO(kenz): remove dependency on Logging V2 references. + +abstract class MetadataChip extends StatelessWidget { + const MetadataChip({ + super.key, + required this.maxWidth, + required this.text, + this.icon, + this.iconAsset, + this.includeLeadingPadding = true, + }); + + final double maxWidth; + final IconData? icon; + final String? iconAsset; + final String text; + final bool includeLeadingPadding; + + static const horizontalPadding = denseSpacing; + static const verticalPadding = densePadding; + static const iconPadding = densePadding; + + /// Estimates the size of this single metadata chip. + /// + /// If the [build] method is changed then this may need to be updated + Size estimateSize() { + final horizontalPaddingCount = includeLeadingPadding ? 2 : 1; + final maxWidthInsidePadding = + max(0.0, maxWidth - horizontalPadding * horizontalPaddingCount); + final iconSize = Size.square(defaultIconSize); + final textSize = calculateTextSpanSize( + _buildValueText(), + maxWidth: maxWidthInsidePadding, + ); + return Size( + ((icon != null || iconAsset != null) + ? iconSize.width + iconPadding + : 0.0) + + textSize.width + + horizontalPadding * horizontalPaddingCount, + max(iconSize.height, textSize.height) + verticalPadding * 2, + ); + } + + /// If this build method is changed then you may need to modify [estimateSize()] + @override + Widget build(BuildContext context) { + return Container( + constraints: BoxConstraints(maxWidth: maxWidth), + padding: EdgeInsets.fromLTRB( + includeLeadingPadding ? horizontalPadding : 0, + verticalPadding, + horizontalPadding, + verticalPadding, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (icon != null || iconAsset != null) ...[ + DevToolsIcon( + icon: icon, + iconAsset: iconAsset, + size: defaultIconSize, + color: Theme.of(context).colorScheme.subtleTextColor, + ), + const SizedBox(width: iconPadding), + ] else + // Include an empty SizedBox to ensure a consistent height for the + // chips, regardless of whether the chip includes an icon. + SizedBox(height: defaultIconSize), + RichText( + text: _buildValueText(), + ), + ], + ), + ); + } + + TextSpan _buildValueText() { + return TextSpan( + text: text, + style: LoggingTableRow.metadataStyle, + ); + } +} + +@visibleForTesting +class WhenMetaDataChip extends MetadataChip { + WhenMetaDataChip({ + super.key, + required int? timestamp, + required super.maxWidth, + }) : super( + icon: null, + text: timestamp == null + ? '' + : loggingTableTimeFormat + .format(DateTime.fromMillisecondsSinceEpoch(timestamp)), + includeLeadingPadding: false, + ); +} + +class KindMetaDataChip extends MetadataChip { + const KindMetaDataChip({ + super.key, + required String kind, + required super.maxWidth, + super.icon, + super.iconAsset, + }) : super(text: kind); + + static ({IconData? icon, String? iconAsset}) generateIcon(String kind) { + IconData? kindIcon = Icons.list_rounded; + String? kindIconAsset; + if (kind == 'stdout' || kind == 'stderr') { + kindIcon = Icons.terminal_rounded; + } else if (RegExp(r'^flutter\..*$').hasMatch(kind)) { + kindIconAsset = 'icons/flutter.png'; + kindIcon = null; + } + return (icon: kindIcon, iconAsset: kindIconAsset); + } +} + +@visibleForTesting +class FrameElapsedMetaDataChip extends MetadataChip { + const FrameElapsedMetaDataChip({ + super.key, + required super.maxWidth, + required String elapsedTimeDisplay, + }) : super(icon: Icons.timer, text: elapsedTimeDisplay); +} diff --git a/packages/devtools_app/lib/src/screens/logging/shared/constants.dart b/packages/devtools_app/lib/src/screens/logging/shared/constants.dart index 20c02803cd7..74c92dd67cb 100644 --- a/packages/devtools_app/lib/src/screens/logging/shared/constants.dart +++ b/packages/devtools_app/lib/src/screens/logging/shared/constants.dart @@ -2,4 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:intl/intl.dart'; + const loggingMinVerboseWidth = 650.0; + +final loggingTableTimeFormat = DateFormat('HH:mm:ss.SSS'); diff --git a/packages/devtools_app/test/logging/logging_screen_v2/logging_table_row_test.dart b/packages/devtools_app/test/logging/logging_screen_v2/logging_table_row_test.dart index b21d7e8dad1..d7dad146f0c 100644 --- a/packages/devtools_app/test/logging/logging_screen_v2/logging_table_row_test.dart +++ b/packages/devtools_app/test/logging/logging_screen_v2/logging_table_row_test.dart @@ -4,6 +4,7 @@ import 'package:devtools_app/devtools_app.dart'; import 'package:devtools_app/src/screens/logging/logging_screen_v2/logging_table_row.dart'; +import 'package:devtools_app/src/screens/logging/metadata.dart'; import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; import 'package:devtools_test/devtools_test.dart';