Commit 96eea437 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Declare locals final where not reassigned (gallery) (#8571)

parent aa07d147
......@@ -139,7 +139,7 @@ class CalcExpression {
/// in the calculator's display panel.
@override
String toString() {
StringBuffer buffer = new StringBuffer('');
final StringBuffer buffer = new StringBuffer('');
buffer.writeAll(_list);
return buffer.toString();
}
......@@ -162,12 +162,12 @@ class CalcExpression {
newToken = new IntToken('-$digit');
break;
case ExpressionState.Number:
ExpressionToken last = outList.removeLast();
final ExpressionToken last = outList.removeLast();
newToken = new IntToken('${last.stringRep}$digit');
break;
case ExpressionState.Point:
case ExpressionState.NumberWithPoint:
ExpressionToken last = outList.removeLast();
final ExpressionToken last = outList.removeLast();
newState = ExpressionState.NumberWithPoint;
newToken = new FloatToken('${last.stringRep}$digit');
break;
......@@ -191,7 +191,7 @@ class CalcExpression {
break;
case ExpressionState.LeadingNeg:
case ExpressionState.Number:
ExpressionToken last = outList.removeLast();
final ExpressionToken last = outList.removeLast();
newToken = new FloatToken(last.stringRep + '.');
break;
case ExpressionState.Point:
......@@ -282,14 +282,14 @@ class CalcExpression {
// We make a copy of _list because CalcExpressions are supposed to
// be immutable.
List<ExpressionToken> list = _list.toList();
final List<ExpressionToken> list = _list.toList();
// We obey order-of-operations by computing the sum of the 'terms',
// where a "term" is defined to be a sequence of numbers separated by
// multiplcation or division symbols.
num currentTermValue = removeNextTerm(list);
while (list.isNotEmpty) {
OperationToken opToken = list.removeAt(0);
num nextTermValue = removeNextTerm(list);
final OperationToken opToken = list.removeAt(0);
final num nextTermValue = removeNextTerm(list);
switch (opToken.operation) {
case Operation.Addition:
currentTermValue += nextTermValue;
......@@ -317,7 +317,7 @@ class CalcExpression {
num currentValue = firstNumToken.number;
while (list.isNotEmpty) {
bool isDivision = false;
OperationToken nextOpToken = list.first;
final OperationToken nextOpToken = list.first;
switch (nextOpToken.operation) {
case Operation.Addition:
case Operation.Subtraction:
......@@ -332,7 +332,7 @@ class CalcExpression {
list.removeAt(0);
// Remove the next number token.
final NumberToken nextNumToken = list.removeAt(0);
num nextNumber = nextNumToken.number;
final num nextNumber = nextNumToken.number;
if (isDivision)
currentValue /= nextNumber;
else
......
......@@ -82,7 +82,7 @@ class ColorSwatchTabView extends StatelessWidget {
final TextTheme textTheme = Theme.of(context).textTheme;
final TextStyle whiteTextStyle = textTheme.body1.copyWith(color: Colors.white);
final TextStyle blackTextStyle = textTheme.body1.copyWith(color: Colors.black);
List<Widget> colorItems = swatch.colors.keys.map((int index) {
final List<Widget> colorItems = swatch.colors.keys.map((int index) {
return new DefaultTextStyle(
style: index > swatch.threshold ? whiteTextStyle : blackTextStyle,
child: new ColorItem(index: index, color: swatch.colors[index]),
......
......@@ -49,10 +49,10 @@ class _ContactItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
List<Widget> columnChildren = lines.sublist(0, lines.length - 1).map((String line) => new Text(line)).toList();
final List<Widget> columnChildren = lines.sublist(0, lines.length - 1).map((String line) => new Text(line)).toList();
columnChildren.add(new Text(lines.last, style: themeData.textTheme.caption));
List<Widget> rowChildren = <Widget>[
final List<Widget> rowChildren = <Widget>[
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
......
......@@ -49,7 +49,7 @@ class ButtonsDemo extends StatefulWidget {
class _ButtonsDemoState extends State<ButtonsDemo> {
@override
Widget build(BuildContext context) {
List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
final List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
new ComponentDemoTabData(
tabName: 'RAISED',
description: _raisedText,
......
......@@ -45,9 +45,9 @@ class TravelDestinationItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
TextStyle titleStyle = theme.textTheme.headline.copyWith(color: Colors.white);
TextStyle descriptionStyle = theme.textTheme.subhead;
final ThemeData theme = Theme.of(context);
final TextStyle titleStyle = theme.textTheme.headline.copyWith(color: Colors.white);
final TextStyle descriptionStyle = theme.textTheme.subhead;
return new SizedBox(
height: height,
......
......@@ -22,7 +22,7 @@ class _ChipDemoState extends State<ChipDemo> {
@override
Widget build(BuildContext context) {
List<Widget> chips = <Widget>[
final List<Widget> chips = <Widget>[
new Chip(
label: new Text('Apple')
),
......
......@@ -61,7 +61,7 @@ class _DateTimePicker extends StatelessWidget {
final ValueChanged<TimeOfDay> selectTime;
Future<Null> _selectDate(BuildContext context) async {
DateTime picked = await showDatePicker(
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: new DateTime(2015, 8),
......@@ -72,7 +72,7 @@ class _DateTimePicker extends StatelessWidget {
}
Future<Null> _selectTime(BuildContext context) async {
TimeOfDay picked = await showTimePicker(
final TimeOfDay picked = await showTimePicker(
context: context,
initialTime: selectedTime
);
......
......@@ -185,7 +185,7 @@ class GridDemoPhotoItem extends StatelessWidget {
)
);
IconData icon = photo.isFavorite ? Icons.star : Icons.star_border;
final IconData icon = photo.isFavorite ? Icons.star : Icons.star_border;
switch(tileStyle) {
case GridDemoTileStyle.imageOnly:
......
......@@ -77,7 +77,7 @@ class LeaveBehindDemoState extends State<LeaveBehindDemo> {
}
void handleUndo(LeaveBehindItem item) {
int insertionIndex = lowerBound(leaveBehindItems, item);
final int insertionIndex = lowerBound(leaveBehindItems, item);
setState(() {
leaveBehindItems.insert(insertionIndex, item);
});
......
......@@ -25,7 +25,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
];
Future<Null> _handleRefresh() {
Completer<Null> completer = new Completer<Null>();
final Completer<Null> completer = new Completer<Null>();
new Timer(const Duration(seconds: 3), () { completer.complete(null); });
return completer.future.then((_) {
_scaffoldKey.currentState?.showSnackBar(new SnackBar(
......@@ -63,7 +63,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
padding: const EdgeInsets.all(8.0),
itemCount: _items.length,
itemBuilder: (BuildContext context, int index) {
String item = _items[index];
final String item = _items[index];
return new ListItem(
isThreeLine: true,
leading: new CircleAvatar(child: new Text(item)),
......
......@@ -10,7 +10,7 @@ class _PageSelector extends StatelessWidget {
final List<IconData> icons;
void _handleArrowButtonPress(BuildContext context, int delta) {
TabController controller = DefaultTabController.of(context);
final TabController controller = DefaultTabController.of(context);
if (!controller.indexIsChanging)
controller.animateTo(controller.index + delta);
}
......
......@@ -62,7 +62,7 @@ class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> with Sing
}
Widget _buildIndicators(BuildContext context, Widget child) {
List<Widget> indicators = <Widget>[
final List<Widget> indicators = <Widget>[
new SizedBox(
width: 200.0,
child: new LinearProgressIndicator()
......
......@@ -35,7 +35,7 @@ class SelectionControlsDemo extends StatefulWidget {
class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
@override
Widget build(BuildContext context) {
List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
final List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
new ComponentDemoTabData(
tabName: "CHECKBOX",
description: _checkboxText,
......
......@@ -37,7 +37,7 @@ class TextFieldDemoState extends State<TextFieldDemo> {
GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
GlobalKey<FormFieldState<InputValue>> _passwordFieldKey = new GlobalKey<FormFieldState<InputValue>>();
void _handleSubmitted() {
FormState form = _formKey.currentState;
final FormState form = _formKey.currentState;
if (!form.validate()) {
_autovalidate = true; // Start validating on every change.
showInSnackBar('Please fix the errors in red before submitting.');
......@@ -51,7 +51,7 @@ class TextFieldDemoState extends State<TextFieldDemo> {
_formWasEdited = true;
if (value.text.isEmpty)
return 'Name is required.';
RegExp nameExp = new RegExp(r'^[A-za-z ]+$');
final RegExp nameExp = new RegExp(r'^[A-za-z ]+$');
if (!nameExp.hasMatch(value.text))
return 'Please enter only alphabetical characters.';
return null;
......@@ -59,7 +59,7 @@ class TextFieldDemoState extends State<TextFieldDemo> {
String _validatePhoneNumber(InputValue value) {
_formWasEdited = true;
RegExp phoneExp = new RegExp(r'^\d\d\d-\d\d\d\-\d\d\d\d$');
final RegExp phoneExp = new RegExp(r'^\d\d\d-\d\d\d\-\d\d\d\d$');
if (!phoneExp.hasMatch(value.text))
return '###-###-#### - Please enter a valid phone number.';
return null;
......@@ -67,7 +67,7 @@ class TextFieldDemoState extends State<TextFieldDemo> {
String _validatePassword(InputValue value) {
_formWasEdited = true;
FormFieldState<InputValue> passwordField = _passwordFieldKey.currentState;
final FormFieldState<InputValue> passwordField = _passwordFieldKey.currentState;
if (passwordField.value == null || passwordField.value.text.isEmpty)
return 'Please choose a password.';
if (passwordField.value.text != value.text)
......
......@@ -147,7 +147,7 @@ class _RecipeGridPageState extends State<RecipeGridPage> {
),
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
Recipe recipe = config.recipes[index];
final Recipe recipe = config.recipes[index];
return new RecipeCard(
recipe: recipe,
onTap: () { showRecipePage(context, recipe); },
......
......@@ -149,7 +149,7 @@ class _OrderPageState extends State<OrderPage> {
}
void updateOrder({ int quantity, bool inCart }) {
Order newOrder = currentOrder.copyWith(quantity: quantity, inCart: inCart);
final Order newOrder = currentOrder.copyWith(quantity: quantity, inCart: inCart);
if (currentOrder != newOrder) {
setState(() {
config.shoppingCart[newOrder.product] = newOrder;
......
......@@ -41,7 +41,7 @@ class ShrinePageState extends State<ShrinePage> {
int _appBarElevation = 0;
bool _handleScrollNotification(ScrollNotification notification) {
int elevation = notification.metrics.extentBefore <= 0.0 ? 0 : 1;
final int elevation = notification.metrics.extentBefore <= 0.0 ? 0 : 1;
if (elevation != _appBarElevation) {
setState(() {
_appBarElevation = elevation;
......
......@@ -24,7 +24,7 @@ class ComponentDemoTabData {
bool operator==(Object other) {
if (other.runtimeType != runtimeType)
return false;
ComponentDemoTabData typedOther = other;
final ComponentDemoTabData typedOther = other;
return typedOther.tabName == tabName && typedOther.description == description;
}
......@@ -42,7 +42,7 @@ class TabbedComponentDemoScaffold extends StatelessWidget {
final String title;
void _showExampleCode(BuildContext context) {
String tag = demos[DefaultTabController.of(context).index].exampleCodeTag;
final String tag = demos[DefaultTabController.of(context).index].exampleCodeTag;
if (tag != null) {
Navigator.push(context, new MaterialPageRoute<FullScreenCodeDialog>(
builder: (BuildContext context) => new FullScreenCodeDialog(exampleCodeTag: tag)
......
......@@ -93,7 +93,7 @@ class DartSyntaxHighlighter extends SyntaxHighlighter {
if (_generateSpans()) {
// Successfully parsed the code
List<TextSpan> formattedText = <TextSpan>[];
final List<TextSpan> formattedText = <TextSpan>[];
int currentPosition = 0;
for (_HighlightSpan span in _spans) {
......@@ -134,7 +134,7 @@ class DartSyntaxHighlighter extends SyntaxHighlighter {
// Line comments
if (_scanner.scan("//")) {
int startComment = _scanner.lastMatch.start;
final int startComment = _scanner.lastMatch.start;
bool eof = false;
int endComment;
......@@ -310,7 +310,7 @@ class DartSyntaxHighlighter extends SyntaxHighlighter {
bool _firstLetterIsUpperCase(String str) {
if (str.isNotEmpty) {
String first = str.substring(0, 1);
final String first = str.substring(0, 1);
return first == first.toUpperCase();
}
return false;
......
......@@ -37,9 +37,9 @@ class UpdaterState extends State<Updater> {
}
_lastUpdateCheck = new DateTime.now();
String updateUrl = await config.updateUrlFetcher();
final String updateUrl = await config.updateUrlFetcher();
if (updateUrl != null) {
bool wantsUpdate = await showDialog(context: context, child: _buildDialog());
final bool wantsUpdate = await showDialog(context: context, child: _buildDialog());
if (wantsUpdate != null && wantsUpdate)
UrlLauncher.launch(updateUrl);
}
......
......@@ -7,7 +7,7 @@ import 'package:flutter_gallery/demo/calculator_demo.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
if (binding is LiveTestWidgetsFlutterBinding)
binding.allowAllFrames = true;
......@@ -16,10 +16,10 @@ void main() {
testWidgets('Flutter calculator app smoke test', (WidgetTester tester) async {
await tester.pumpWidget(new CalculatorDemo());
Finder oneButton = find.widgetWithText(InkResponse, '1');
final Finder oneButton = find.widgetWithText(InkResponse, '1');
expect(oneButton, findsOneWidget);
Finder twoButton = find.widgetWithText(InkResponse, '2');
final Finder twoButton = find.widgetWithText(InkResponse, '2');
expect(twoButton, findsOneWidget);
await tester.tap(oneButton);
......@@ -28,7 +28,7 @@ void main() {
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // Wait until it has finished.
Finder display = find.widgetWithText(Expanded, '12');
final Finder display = find.widgetWithText(Expanded, '12');
expect(display, findsOneWidget);
});
}
......@@ -7,7 +7,7 @@ import 'package:flutter_gallery/gallery/app.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
if (binding is LiveTestWidgetsFlutterBinding)
binding.allowAllFrames = true;
......
......@@ -11,12 +11,12 @@ import 'package:test/test.dart';
void main() {
test('Flutter gallery example code parser test', () async {
TestAssetBundle bundle = new TestAssetBundle();
final TestAssetBundle bundle = new TestAssetBundle();
String codeSnippet0 = await getExampleCode('test_0', bundle);
final String codeSnippet0 = await getExampleCode('test_0', bundle);
expect(codeSnippet0, 'test 0 0\ntest 0 1');
String codeSnippet1 = await getExampleCode('test_1', bundle);
final String codeSnippet1 = await getExampleCode('test_1', bundle);
expect(codeSnippet1, 'test 1 0\ntest 1 1');
});
}
......
......@@ -7,7 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_gallery/gallery/app.dart';
void main() {
TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
if (binding is LiveTestWidgetsFlutterBinding)
binding.allowAllFrames = true;
......
......@@ -7,7 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_gallery/main.dart' as flutter_gallery_main;
void main() {
TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
if (binding is LiveTestWidgetsFlutterBinding)
binding.allowAllFrames = true;
......@@ -16,7 +16,7 @@ void main() {
await tester.pump(); // see https://github.com/flutter/flutter/issues/1865
await tester.pump(); // triggers a frame
Finder finder = find.byWidgetPredicate((Widget widget) {
final Finder finder = find.byWidgetPredicate((Widget widget) {
return widget is Tooltip && widget.message == 'Open navigation menu';
});
expect(finder, findsOneWidget);
......
......@@ -32,16 +32,16 @@ void reportToStringError(String name, String route, int lineNumber, List<String>
// If you're on line 12, then it has index 11.
// If you want 1 line before and 1 line after, then you want lines with index 10, 11, and 12.
// That's (lineNumber-1)-margin .. (lineNumber-1)+margin, or lineNumber-(margin+1) .. lineNumber+(margin-1)
int margin = 5;
int firstLine = math.max(0, lineNumber - margin);
int lastLine = math.min(lines.length, lineNumber + margin);
final int margin = 5;
final int firstLine = math.max(0, lineNumber - margin);
final int lastLine = math.min(lines.length, lineNumber + margin);
print('$name : $route : line $lineNumber of ${lines.length} : $message; nearby lines were:\n ${lines.sublist(firstLine, lastLine).join("\n ")}');
errors += 1;
}
void verifyToStringOutput(String name, String route, String testString) {
int lineNumber = 0;
List<String> lines = testString.split('\n');
final List<String> lines = testString.split('\n');
if (!testString.endsWith('\n'))
reportToStringError(name, route, lines.length, lines, 'does not end with a line feed');
for (String line in lines) {
......@@ -103,7 +103,7 @@ Future<Null> smokeDemo(WidgetTester tester, String routeName) async {
await tester.pump(const Duration(milliseconds: 400));
// Go back
Finder backButton = find.byTooltip('Back');
final Finder backButton = find.byTooltip('Back');
expect(backButton, findsOneWidget);
await tester.tap(backButton);
await tester.pump(); // Start the pop "back" operation.
......@@ -125,7 +125,7 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
expect(find.text(kCaption), findsOneWidget);
for (String routeName in routeNames) {
Finder finder = findGalleryItemByRouteName(tester, routeName);
final Finder finder = findGalleryItemByRouteName(tester, routeName);
Scrollable.ensureVisible(tester.element(finder), alignment: 0.5);
await tester.pump();
await tester.pumpUntilNoTransientCallbacks();
......@@ -135,7 +135,7 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
expect(errors, 0);
Finder navigationMenuButton = find.byTooltip('Open navigation menu');
final Finder navigationMenuButton = find.byTooltip('Open navigation menu');
expect(navigationMenuButton, findsOneWidget);
await tester.tap(navigationMenuButton);
await tester.pump(); // Start opening drawer.
......
......@@ -11,7 +11,7 @@ Future<String> mockUpdateUrlFetcher() {
}
void main() {
TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
if (binding is LiveTestWidgetsFlutterBinding) binding.allowAllFrames = true;
// Regression test for https://github.com/flutter/flutter/pull/5168
......@@ -29,7 +29,7 @@ void main() {
await tester.pump(); // Launch shrine
await tester.pump(const Duration(seconds: 1)); // transition is complete
Finder backButton = find.byTooltip('Back');
final Finder backButton = find.byTooltip('Back');
expect(backButton, findsOneWidget);
await tester.tap(backButton);
await tester.pump(); // Start the pop "back" operation.
......
......@@ -18,9 +18,9 @@ void main() {
});
test('navigation', () async {
Completer<Null> completer = new Completer<Null>();
final Completer<Null> completer = new Completer<Null>();
bool scroll = true;
SerializableFinder menuItem = find.text('Text fields');
final SerializableFinder menuItem = find.text('Text fields');
driver.waitFor(menuItem).then<Null>((Null value) async {
scroll = false;
await new Future<Null>.delayed(kWaitBetweenActions);
......
......@@ -21,9 +21,9 @@ void main() {
});
test('measure', () async {
Timeline timeline = await driver.traceAction(() async {
final Timeline timeline = await driver.traceAction(() async {
// Find the scrollable stock list
SerializableFinder stockList = find.byValueKey('Gallery List');
final SerializableFinder stockList = find.byValueKey('Gallery List');
expect(stockList, isNotNull);
await driver.tap(find.text('Demos'));
......
......@@ -91,7 +91,7 @@ Future<Null> saveDurationsHistogram(List<Map<String, dynamic>> events, String ou
// Verify that the durations data is valid.
if (durations.keys.isEmpty)
throw 'no "Start Transition" timeline events found';
Map<String, int> unexpectedValueCounts = <String, int>{};
final Map<String, int> unexpectedValueCounts = <String, int>{};
durations.forEach((String routeName, List<int> values) {
if (values.length != 2) {
unexpectedValueCounts[routeName] = values.length;
......@@ -99,21 +99,21 @@ Future<Null> saveDurationsHistogram(List<Map<String, dynamic>> events, String ou
});
if (unexpectedValueCounts.isNotEmpty) {
StringBuffer error = new StringBuffer('Some routes recorded wrong number of values (expected 2 values/route):\n\n');
final StringBuffer error = new StringBuffer('Some routes recorded wrong number of values (expected 2 values/route):\n\n');
unexpectedValueCounts.forEach((String routeName, int count) {
error.writeln(' - $routeName recorded $count values.');
});
error.writeln('\nFull event sequence:');
Iterator<Map<String, dynamic>> eventIter = events.iterator;
final Iterator<Map<String, dynamic>> eventIter = events.iterator;
String lastEventName = '';
String lastRouteName = '';
while(eventIter.moveNext()) {
String eventName = eventIter.current['name'];
final String eventName = eventIter.current['name'];
if (!<String>['Start Transition', 'Frame'].contains(eventName))
continue;
String routeName = eventName == 'Start Transition'
final String routeName = eventName == 'Start Transition'
? eventIter.current['args']['to']
: '';
......@@ -147,12 +147,12 @@ void main() {
});
test('all demos', () async {
Timeline timeline = await driver.traceAction(() async {
final Timeline timeline = await driver.traceAction(() async {
// Scroll each demo menu item into view, launch the demo and
// return to the demo menu 2x.
for(String demoTitle in demoTitles) {
print('Testing "$demoTitle" demo');
SerializableFinder menuItem = find.text(demoTitle);
final SerializableFinder menuItem = find.text(demoTitle);
await driver.scrollIntoView(menuItem, alignment: 0.5);
await new Future<Null>.delayed(kWaitBetweenActions);
......@@ -180,9 +180,9 @@ void main() {
// Save the duration (in microseconds) of the first timeline Frame event
// that follows a 'Start Transition' event. The Gallery app adds a
// 'Start Transition' event when a demo is launched (see GalleryItem).
TimelineSummary summary = new TimelineSummary.summarize(timeline);
final TimelineSummary summary = new TimelineSummary.summarize(timeline);
await summary.writeSummaryToFile('transitions', pretty: true);
String histogramPath = path.join(testOutputsDirectory, 'transition_durations.timeline.json');
final String histogramPath = path.join(testOutputsDirectory, 'transition_durations.timeline.json');
await saveDurationsHistogram(timeline.json['traceEvents'], histogramPath);
}, timeout: const Timeout(const Duration(minutes: 5)));
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment