Ian Hickson d7fb51a551 Hot reload UI polish (#5193)
* General improvoments to the loader app:
   * Show a message after 8 seconds if no connection comes in.
   * Show a progress bar as files are being uploaded.
   * Hide the spinner just before launching the application.

* General improvements to the "flutter run" UI:
   * Add "?" key as a silent alias for "h".
   * Make the help text bold so it doesn't get mixed with the logs.
   * Make "R" do a cold restart when hot reload is enabled.

* Supporting features and bug fixes:
   * Add support for string service extensions.

* Other bug fixes:
   * Expose debugDumpRenderTree() outside debug mode.
   * Logger.supportsColor was missing a getter.
   * Mention in the usage docs that --hot requires --resident.
   * Trivial style fixes.
2016-08-02 16:52:57 -07:00

104 lines
3.2 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
String message = 'Flutter Debug Loader';
String explanation = 'Please stand by...';
double progress = 0.0;
double progressMax = 0.0;
StateSetter setState = (VoidCallback fn) => fn();
Timer connectionTimeout;
void main() {
new LoaderBinding();
runApp(
new MaterialApp(
title: 'Flutter Debug Loader',
debugShowCheckedModeBanner: false,
home: new Scaffold(
body: new StatefulBuilder(
builder: (BuildContext context, StateSetter setStateRef) {
setState = setStateRef;
return new Column(
children: <Widget>[
new Flexible(
child: new Container() // TODO(ianh): replace this with our logo in a Center box
),
new Flexible(
child: new Builder(
builder: (BuildContext context) {
List<Widget> children = <Widget>[];
children.add(new Text(
message,
style: new TextStyle(fontSize: 24.0),
textAlign: TextAlign.center
));
if (progressMax >= 0.0) {
children.add(new SizedBox(height: 18.0));
children.add(new Center(child: new CircularProgressIndicator(value: progressMax > 0 ? progress / progressMax : null)));
}
return new Block(children: children);
}
)
),
new Flexible(
child: new Block(
padding: new EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[ new Text(explanation, textAlign: TextAlign.center) ]
)
),
]
);
}
)
)
)
);
connectionTimeout = new Timer(const Duration(seconds: 8), () {
setState(() {
explanation =
'This is a hot-reload-enabled debug-mode Flutter application. '
'To launch this application, please use the "flutter run" command. '
'To be able to launch a Flutter application in debug mode from the '
'device, please use "flutter run --no-hot". To install a release '
'mode build of this application on your device, use "flutter install".';
progressMax = -1.0;
});
});
}
class LoaderBinding extends WidgetsFlutterBinding {
@override
void initServiceExtensions() {
super.initServiceExtensions();
registerStringServiceExtension(
name: 'loaderShowMessage',
getter: () => message,
setter: (String value) {
connectionTimeout?.cancel();
connectionTimeout = null;
setState(() {
message = value;
});
}
);
registerNumericServiceExtension(
name: 'loaderSetProgress',
getter: () => progress,
setter: (double value) {
setState(() {
progress = value;
});
}
);
registerNumericServiceExtension(
name: 'loaderSetProgressMax',
getter: () => progressMax,
setter: (double value) {
setState(() {
progressMax = value;
});
}
);
}
}