Skip to content

Commit 12e96da

Browse files
committed
feat: make kind chip clickable to filter logs by kind
1 parent 05507a2 commit 12e96da

2 files changed

Lines changed: 65 additions & 42 deletions

File tree

packages/devtools_app/lib/src/screens/logging/_message_column.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'package:devtools_app_shared/ui.dart';
66
import 'package:flutter/material.dart';
77

8+
import '../../shared/globals.dart';
89
import '../../shared/primitives/utils.dart';
910
import '../../shared/table/table.dart';
1011
import '../../shared/table/table_data.dart';
@@ -92,7 +93,14 @@ class MessageColumn extends ColumnData<LogData>
9293
padding: const EdgeInsets.symmetric(vertical: densePadding),
9394
child: LayoutBuilder(
9495
builder: (context, constraints) {
95-
return MetadataChips(data: data);
96+
return MetadataChips(
97+
data: data,
98+
onKindTapped: (kind) {
99+
final controller = screenControllers
100+
.lookup<LoggingController>();
101+
controller.setActiveFilter(query: 'k:$kind');
102+
},
103+
);
96104
},
97105
),
98106
),

packages/devtools_app/lib/src/screens/logging/metadata.dart

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ import '../../shared/primitives/utils.dart';
1414
import 'logging_controller.dart';
1515

1616
class MetadataChips extends StatelessWidget {
17-
const MetadataChips({super.key, required this.data});
17+
const MetadataChips({super.key, required this.data, this.onKindTapped});
1818

1919
final LogData data;
20+
final void Function(String kind)? onKindTapped;
2021

2122
@override
2223
Widget build(BuildContext context) {
@@ -91,6 +92,7 @@ class MetadataChips extends StatelessWidget {
9192
iconAsset: kindIcon.iconAsset,
9293
backgroundColor: kindColors.background,
9394
foregroundColor: kindColors.foreground,
95+
onTap: onKindTapped != null ? () => onKindTapped!(data.kind) : null,
9496
),
9597
logLevelChip,
9698
if (elapsedFrameTimeAsString != null)
@@ -115,6 +117,7 @@ abstract class MetadataChip extends StatelessWidget {
115117
this.foregroundColor,
116118
this.outlined = false,
117119
this.includeLeadingMargin = true,
120+
this.onTap,
118121
});
119122

120123
final IconData? icon;
@@ -125,6 +128,7 @@ abstract class MetadataChip extends StatelessWidget {
125128
final Color? foregroundColor;
126129
final bool outlined;
127130
final bool includeLeadingMargin;
131+
final VoidCallback? onTap;
128132

129133
static const horizontalPadding = densePadding;
130134
static const verticalPadding = borderPadding;
@@ -140,50 +144,60 @@ abstract class MetadataChip extends StatelessWidget {
140144
final foregroundColor =
141145
this.foregroundColor ?? theme.colorScheme.onSecondaryContainer;
142146

143-
return maybeWrapWithTooltip(
144-
tooltip: tooltip,
145-
child: Container(
146-
decoration: BoxDecoration(
147-
color: backgroundColor,
148-
borderRadius: BorderRadius.circular(_borderRadius),
149-
border: outlined
150-
? Border.all(color: theme.colorScheme.subtleTextColor)
151-
: null,
152-
),
153-
margin: includeLeadingMargin
154-
? const EdgeInsets.only(left: denseSpacing)
147+
Widget chip = Container(
148+
decoration: BoxDecoration(
149+
color: backgroundColor,
150+
borderRadius: BorderRadius.circular(_borderRadius),
151+
border: outlined
152+
? Border.all(color: theme.colorScheme.subtleTextColor)
155153
: null,
156-
padding: const EdgeInsets.symmetric(
157-
horizontal: horizontalPadding,
158-
vertical: verticalPadding,
159-
),
160-
child: Row(
161-
mainAxisSize: MainAxisSize.min,
162-
children: [
163-
if (icon != null || iconAsset != null) ...[
164-
DevToolsIcon(
165-
icon: icon,
166-
iconAsset: iconAsset,
167-
size: _metadataIconSize,
168-
color: foregroundColor,
169-
),
170-
const SizedBox(width: iconPadding),
171-
] else
172-
// Include an empty SizedBox to ensure a consistent height for the
173-
// chips, regardless of whether the chip includes an icon.
174-
const SizedBox(height: _metadataIconSize),
175-
RichText(
176-
text: TextSpan(
177-
text: text,
178-
style: theme
179-
.regularTextStyleWithColor(foregroundColor)
180-
.copyWith(fontSize: smallFontSize),
181-
),
154+
),
155+
margin: includeLeadingMargin
156+
? const EdgeInsets.only(left: denseSpacing)
157+
: null,
158+
padding: const EdgeInsets.symmetric(
159+
horizontal: horizontalPadding,
160+
vertical: verticalPadding,
161+
),
162+
child: Row(
163+
mainAxisSize: MainAxisSize.min,
164+
children: [
165+
if (icon != null || iconAsset != null) ...[
166+
DevToolsIcon(
167+
icon: icon,
168+
iconAsset: iconAsset,
169+
size: _metadataIconSize,
170+
color: foregroundColor,
182171
),
183-
],
184-
),
172+
const SizedBox(width: iconPadding),
173+
] else
174+
// Include an empty SizedBox to ensure a consistent height for the
175+
// chips, regardless of whether the chip includes an icon.
176+
const SizedBox(height: _metadataIconSize),
177+
RichText(
178+
text: TextSpan(
179+
text: text,
180+
style: theme
181+
.regularTextStyleWithColor(foregroundColor)
182+
.copyWith(fontSize: smallFontSize),
183+
),
184+
),
185+
],
185186
),
186187
);
188+
189+
if (onTap != null) {
190+
chip = MouseRegion(
191+
cursor: SystemMouseCursors.click,
192+
child: GestureDetector(
193+
onTap: onTap,
194+
behavior: HitTestBehavior.opaque,
195+
child: chip,
196+
),
197+
);
198+
}
199+
200+
return maybeWrapWithTooltip(tooltip: tooltip, child: chip);
187201
}
188202
}
189203

@@ -195,6 +209,7 @@ class KindMetaDataChip extends MetadataChip {
195209
super.iconAsset,
196210
super.backgroundColor,
197211
super.foregroundColor,
212+
super.onTap,
198213
}) : super(text: kind, includeLeadingMargin: false);
199214

200215
static ({IconData? icon, String? iconAsset}) generateIcon(String kind) {

0 commit comments

Comments
 (0)