22// Use of this source code is governed by a BSD-style license that can be
33// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
44
5+ import 'package:collection/collection.dart' show ListExtensions;
56import 'package:devtools_app_shared/ui.dart' ;
67import 'package:devtools_app_shared/utils.dart' ;
78import 'package:flutter/material.dart' ;
@@ -12,28 +13,26 @@ import '../../../../shared/analytics/constants.dart' as gac;
1213import '../../../../shared/primitives/utils.dart' show SortDirection;
1314import '../../../../shared/table/table.dart' show FlatTable;
1415import '../../../../shared/table/table_data.dart' ;
15- import '../../../../shared/ui/common_widgets.dart' show RefreshButton;
16+ import '../../../../shared/ui/common_widgets.dart'
17+ show CenteredMessage, RefreshButton;
1618import 'queued_microtasks_controller.dart' ;
1719
1820class RefreshQueuedMicrotasksButton extends StatelessWidget {
19- const RefreshQueuedMicrotasksButton ({
20- super .key,
21- required QueuedMicrotasksController controller,
22- }) : _controller = controller;
21+ const RefreshQueuedMicrotasksButton ({super .key, required this .controller});
2322
24- final QueuedMicrotasksController _controller ;
23+ final QueuedMicrotasksController controller ;
2524
2625 @override
2726 Widget build (BuildContext context) {
2827 return ValueListenableBuilder <QueuedMicrotasksControllerStatus >(
29- valueListenable: _controller .status,
28+ valueListenable: controller .status,
3029 builder: (_, status, _) {
3130 return RefreshButton (
3231 iconOnly: true ,
3332 outlined: false ,
3433 onPressed: status == QueuedMicrotasksControllerStatus .refreshing
3534 ? null
36- : _controller .refresh,
35+ : controller .refresh,
3736 tooltip:
3837 "Take a new snapshot of the selected isolate's microtask queue." ,
3938 gaScreen: gac.performance,
@@ -44,23 +43,6 @@ class RefreshQueuedMicrotasksButton extends StatelessWidget {
4443 }
4544}
4645
47- class QueuedMicrotasksTabControls extends StatelessWidget {
48- const QueuedMicrotasksTabControls ({
49- super .key,
50- required QueuedMicrotasksController controller,
51- }) : _controller = controller;
52-
53- final QueuedMicrotasksController _controller;
54-
55- @override
56- Widget build (BuildContext context) {
57- return Row (
58- mainAxisAlignment: MainAxisAlignment .end,
59- children: [RefreshQueuedMicrotasksButton (controller: _controller)],
60- );
61- }
62- }
63-
6446class RefreshQueuedMicrotasksInstructions extends StatelessWidget {
6547 const RefreshQueuedMicrotasksInstructions ({super .key});
6648
@@ -85,60 +67,52 @@ class RefreshQueuedMicrotasksInstructions extends StatelessWidget {
8567 }
8668}
8769
88- // In the response returned by the VM Service, microtasks are sorted in
89- // ascending order of when they will be dequeued, i.e. the microtask that will
90- // run earliest is at index 0 of the returned list. We use those indices of the
91- // returned list to sort the entries of the microtask selector, so that they
92- // they also appear in ascending order of when they will be dequeued.
93- typedef IndexedMicrotask = (int , Microtask );
70+ /// In the response returned by the VM Service, microtasks are sorted in
71+ /// ascending order of when they will be dequeued, i.e. the microtask that will
72+ /// run earliest is at index 0 of the returned list. We use those indices of the
73+ /// returned list to sort the entries of the microtask selector, so that they
74+ /// they also appear in ascending order of when they will be dequeued.
75+ typedef IndexedMicrotask = ({ int index , Microtask microtask} );
9476
9577class _MicrotaskIdColumn extends ColumnData <IndexedMicrotask > {
9678 _MicrotaskIdColumn ()
9779 : super .wide ('Microtask ID' , alignment: ColumnAlignment .center);
9880
9981 @override
100- int getValue (IndexedMicrotask indexedMicrotask) => indexedMicrotask.$1 ;
82+ int getValue (IndexedMicrotask indexedMicrotask) => indexedMicrotask.index ;
10183
10284 @override
10385 String getDisplayValue (IndexedMicrotask indexedMicrotask) =>
104- indexedMicrotask.$2 .id! .toString ();
86+ indexedMicrotask.microtask .id! .toString ();
10587}
10688
10789class QueuedMicrotaskSelector extends StatelessWidget {
10890 const QueuedMicrotaskSelector ({
10991 super .key,
11092 required List <IndexedMicrotask > indexedMicrotasks,
111- required void Function (Microtask ? ) setSelectedMicrotask ,
93+ required void Function (Microtask ? ) onMicrotaskSelected ,
11294 }) : _indexedMicrotasks = indexedMicrotasks,
113- _setSelectedMicrotask = setSelectedMicrotask ;
95+ _setSelectedMicrotask = onMicrotaskSelected ;
11496
11597 static final _idColumn = _MicrotaskIdColumn ();
11698 final List <IndexedMicrotask > _indexedMicrotasks;
11799 final void Function (Microtask ? ) _setSelectedMicrotask;
118100
119101 @override
120- Widget build (BuildContext context) => Column (
121- crossAxisAlignment: CrossAxisAlignment .start,
122- children: [
123- Expanded (
124- child: FlatTable <IndexedMicrotask >(
125- keyFactory: (IndexedMicrotask microtask) =>
126- ValueKey <int >(microtask.$1),
127- data: _indexedMicrotasks,
128- dataKey: 'queued-microtask-selector' ,
129- columns: [_idColumn],
130- defaultSortColumn: _idColumn,
131- defaultSortDirection: SortDirection .ascending,
132- onItemSelected: (indexedMicrotask) =>
133- _setSelectedMicrotask (indexedMicrotask? .$2),
134- ),
135- ),
136- ],
102+ Widget build (BuildContext context) => FlatTable <IndexedMicrotask >(
103+ keyFactory: (IndexedMicrotask microtask) => ValueKey <int >(microtask.index),
104+ data: _indexedMicrotasks,
105+ dataKey: 'queued-microtask-selector' ,
106+ columns: [_idColumn],
107+ defaultSortColumn: _idColumn,
108+ defaultSortDirection: SortDirection .ascending,
109+ onItemSelected: (indexedMicrotask) =>
110+ _setSelectedMicrotask (indexedMicrotask? .microtask),
137111 );
138112}
139113
140- class StackTraceView extends StatelessWidget {
141- const StackTraceView ({super .key, required selectedMicrotask})
114+ class MicrotaskStackTraceView extends StatelessWidget {
115+ const MicrotaskStackTraceView ({super .key, required selectedMicrotask})
142116 : _selectedMicrotask = selectedMicrotask;
143117
144118 final Microtask ? _selectedMicrotask;
@@ -149,14 +123,11 @@ class StackTraceView extends StatelessWidget {
149123
150124 return Column (
151125 children: [
152- SizedBox .fromSize (
153- size: Size .fromHeight (defaultHeaderHeight),
154- child: Container (
155- decoration: BoxDecoration (
156- border: Border (bottom: defaultBorderSide (theme)),
157- ),
158- padding: const EdgeInsets .only (left: defaultSpacing),
159- alignment: Alignment .centerLeft,
126+ Container (
127+ height: defaultHeaderHeight,
128+ padding: const EdgeInsets .only (left: defaultSpacing),
129+ alignment: Alignment .centerLeft,
130+ child: OutlineDecoration .onlyBottom (
160131 child: const Row (
161132 children: [
162133 Text ('Stack trace captured when microtask was enqueued' ),
@@ -207,20 +178,20 @@ class _QueuedMicrotasksTabViewState extends State<QueuedMicrotasksTabView>
207178 if (status == QueuedMicrotasksControllerStatus .empty) {
208179 return const RefreshQueuedMicrotasksInstructions ();
209180 } else if (status == QueuedMicrotasksControllerStatus .refreshing) {
210- return Center (
211- child: Text (
212- style: Theme .of (context).regularTextStyle,
213- 'Refreshing...' ,
214- ),
215- );
181+ return const CenteredMessage (message: 'Refreshing...' );
216182 } else {
217183 return ValueListenableBuilder (
218184 valueListenable: widget.controller.queuedMicrotasks,
219185 builder: (_, queuedMicrotasks, _) {
220186 assert (queuedMicrotasks != null );
221-
222- final indexedMicrotasks = queuedMicrotasks! .microtasks! .indexed
223- .cast <IndexedMicrotask >()
187+ if (queuedMicrotasks == null ) {
188+ return const CenteredMessage (message: 'Unexpected null value' );
189+ }
190+
191+ final indexedMicrotasks = queuedMicrotasks.microtasks!
192+ .mapIndexed (
193+ (index, microtask) => (index: index, microtask: microtask),
194+ )
224195 .toList ();
225196 final formattedTimestamp = _dateTimeFormat.format (
226197 DateTime .fromMicrosecondsSinceEpoch (
@@ -244,25 +215,28 @@ class _QueuedMicrotasksTabViewState extends State<QueuedMicrotasksTabView>
244215 axis: Axis .horizontal,
245216 initialFractions: const [0.15 , 0.85 ],
246217 children: [
247- QueuedMicrotaskSelector (
248- indexedMicrotasks: indexedMicrotasks,
249- setSelectedMicrotask:
250- widget.controller.setSelectedMicrotask,
218+ OutlineDecoration (
219+ child: QueuedMicrotaskSelector (
220+ indexedMicrotasks: indexedMicrotasks,
221+ onMicrotaskSelected:
222+ widget.controller.setSelectedMicrotask,
223+ ),
251224 ),
252225 ValueListenableBuilder (
253226 valueListenable: widget.controller.selectedMicrotask,
254227 builder: (_, selectedMicrotask, _) =>
255- selectedMicrotask == null
256- ? const Center (
257- child: Text (
258- 'Select a microtask ID on the left '
259- 'to see information about the '
260- 'corresponding microtask.' ,
261- ),
262- )
263- : StackTraceView (
264- selectedMicrotask: selectedMicrotask,
265- ),
228+ OutlineDecoration (
229+ child: selectedMicrotask == null
230+ ? const CenteredMessage (
231+ message:
232+ 'Select a microtask ID on the left '
233+ 'to see information about the '
234+ 'corresponding microtask.' ,
235+ )
236+ : MicrotaskStackTraceView (
237+ selectedMicrotask: selectedMicrotask,
238+ ),
239+ ),
266240 ),
267241 ],
268242 ),
0 commit comments