Commit 1aac53a5 authored by Hans Muller's avatar Hans Muller

showSnackBar() returns a Future, clears its placeholder

TransitionRoute completer is now optional.
parent 145b53f1
...@@ -77,10 +77,14 @@ class _BottomSheetRoute extends OverlayRoute { ...@@ -77,10 +77,14 @@ class _BottomSheetRoute extends OverlayRoute {
} }
void didPop(dynamic result) { void didPop(dynamic result) {
completer.complete(result); void finish() {
performance.reverse().then((_) {
super.didPop(result); // clear the overlay entries super.didPop(result); // clear the overlay entries
}); completer.complete(result);
}
if (performance.isDismissed)
finish();
else
performance.reverse().then((_) { finish(); });
} }
String get debugLabel => '$runtimeType'; String get debugLabel => '$runtimeType';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:flutter/animation.dart'; import 'package:flutter/animation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -92,12 +94,15 @@ class _SnackBar extends StatelessComponent { ...@@ -92,12 +94,15 @@ class _SnackBar extends StatelessComponent {
} }
class _SnackBarRoute extends TransitionRoute { class _SnackBarRoute extends TransitionRoute {
_SnackBarRoute({ Completer completer }) : super(completer: completer);
bool get opaque => false; bool get opaque => false;
Duration get transitionDuration => const Duration(milliseconds: 200); Duration get transitionDuration => const Duration(milliseconds: 200);
} }
void showSnackBar({ BuildContext context, GlobalKey<PlaceholderState> placeholderKey, Widget content, List<SnackBarAction> actions }) { Future showSnackBar({ BuildContext context, GlobalKey<PlaceholderState> placeholderKey, Widget content, List<SnackBarAction> actions }) {
_SnackBarRoute route = new _SnackBarRoute(); final Completer completer = new Completer();
_SnackBarRoute route = new _SnackBarRoute(completer: completer);
_SnackBar snackBar = new _SnackBar( _SnackBar snackBar = new _SnackBar(
route: route, route: route,
content: content, content: content,
...@@ -105,4 +110,7 @@ void showSnackBar({ BuildContext context, GlobalKey<PlaceholderState> placeholde ...@@ -105,4 +110,7 @@ void showSnackBar({ BuildContext context, GlobalKey<PlaceholderState> placeholde
); );
placeholderKey.currentState.child = snackBar; placeholderKey.currentState.child = snackBar;
Navigator.of(context).pushEphemeral(route); Navigator.of(context).pushEphemeral(route);
return completer.future.then((_) {
placeholderKey.currentState.child = null;
});
} }
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:flutter/animation.dart'; import 'package:flutter/animation.dart';
import 'basic.dart'; import 'basic.dart';
...@@ -46,6 +48,10 @@ class OverlayRoute extends Route { ...@@ -46,6 +48,10 @@ class OverlayRoute extends Route {
// TODO(abarth): Should we add a type for the result? // TODO(abarth): Should we add a type for the result?
abstract class TransitionRoute extends OverlayRoute { abstract class TransitionRoute extends OverlayRoute {
TransitionRoute({ this.completer });
final Completer completer;
Duration get transitionDuration; Duration get transitionDuration;
bool get opaque; bool get opaque;
...@@ -86,6 +92,9 @@ abstract class TransitionRoute extends OverlayRoute { ...@@ -86,6 +92,9 @@ abstract class TransitionRoute extends OverlayRoute {
void didPop(dynamic result) { void didPop(dynamic result) {
_result = result; _result = result;
if (completer != null)
_performance.reverse().then((_) { completer.complete(_result); });
else
_performance.reverse(); _performance.reverse();
} }
......
...@@ -8,6 +8,8 @@ void main() { ...@@ -8,6 +8,8 @@ void main() {
test('Verify that a tap dismisses a modal BottomSheet', () { test('Verify that a tap dismisses a modal BottomSheet', () {
testWidgets((WidgetTester tester) { testWidgets((WidgetTester tester) {
BuildContext context; BuildContext context;
bool showBottomSheetThenCalled = false;
tester.pumpWidget(new MaterialApp( tester.pumpWidget(new MaterialApp(
routes: <String, RouteBuilder>{ routes: <String, RouteBuilder>{
'/': (RouteArguments args) { '/': (RouteArguments args) {
...@@ -20,7 +22,10 @@ void main() { ...@@ -20,7 +22,10 @@ void main() {
tester.pump(); tester.pump();
expect(tester.findText('BottomSheet'), isNull); expect(tester.findText('BottomSheet'), isNull);
showModalBottomSheet(context: context, child: new Text('BottomSheet')); showModalBottomSheet(context: context, child: new Text('BottomSheet')).then((_) {
showBottomSheetThenCalled = true;
});
tester.pump(); // bottom sheet show animation starts tester.pump(); // bottom sheet show animation starts
tester.pump(new Duration(seconds: 1)); // animation done tester.pump(new Duration(seconds: 1)); // animation done
expect(tester.findText('BottomSheet'), isNotNull); expect(tester.findText('BottomSheet'), isNotNull);
...@@ -29,7 +34,8 @@ void main() { ...@@ -29,7 +34,8 @@ void main() {
tester.tap(tester.findText('BottomSheet')); tester.tap(tester.findText('BottomSheet'));
tester.pump(); // bottom sheet dismiss animation starts tester.pump(); // bottom sheet dismiss animation starts
tester.pump(new Duration(seconds: 1)); // animation done tester.pump(new Duration(seconds: 1)); // animation done
tester.pump(new Duration(seconds: 2)); // rebuild frame tester.pump(new Duration(seconds: 1)); // rebuild frame
expect(showBottomSheetThenCalled, isTrue);
expect(tester.findText('BottomSheet'), isNull); expect(tester.findText('BottomSheet'), isNull);
showModalBottomSheet(context: context, child: new Text('BottomSheet')); showModalBottomSheet(context: context, child: new Text('BottomSheet'));
...@@ -41,7 +47,7 @@ void main() { ...@@ -41,7 +47,7 @@ void main() {
tester.tapAt(new Point(20.0, 20.0)); tester.tapAt(new Point(20.0, 20.0));
tester.pump(); // bottom sheet dismiss animation starts tester.pump(); // bottom sheet dismiss animation starts
tester.pump(new Duration(seconds: 1)); // animation done tester.pump(new Duration(seconds: 1)); // animation done
tester.pump(new Duration(seconds: 2)); // rebuild frame tester.pump(new Duration(seconds: 1)); // rebuild frame
expect(tester.findText('BottomSheet'), isNull); expect(tester.findText('BottomSheet'), isNull);
}); });
}); });
...@@ -50,6 +56,8 @@ void main() { ...@@ -50,6 +56,8 @@ void main() {
testWidgets((WidgetTester tester) { testWidgets((WidgetTester tester) {
GlobalKey<PlaceholderState> _bottomSheetPlaceholderKey = new GlobalKey<PlaceholderState>(); GlobalKey<PlaceholderState> _bottomSheetPlaceholderKey = new GlobalKey<PlaceholderState>();
BuildContext context; BuildContext context;
bool showBottomSheetThenCalled = false;
tester.pumpWidget(new MaterialApp( tester.pumpWidget(new MaterialApp(
routes: <String, RouteBuilder>{ routes: <String, RouteBuilder>{
'/': (RouteArguments args) { '/': (RouteArguments args) {
...@@ -69,7 +77,9 @@ void main() { ...@@ -69,7 +77,9 @@ void main() {
context: context, context: context,
child: new Container(child: new Text('BottomSheet'), margin: new EdgeDims.all(40.0)), child: new Container(child: new Text('BottomSheet'), margin: new EdgeDims.all(40.0)),
placeholderKey: _bottomSheetPlaceholderKey placeholderKey: _bottomSheetPlaceholderKey
); ).then((_) {
showBottomSheetThenCalled = true;
});
expect(_bottomSheetPlaceholderKey.currentState.child, isNotNull); expect(_bottomSheetPlaceholderKey.currentState.child, isNotNull);
tester.pump(); // bottom sheet show animation starts tester.pump(); // bottom sheet show animation starts
...@@ -79,7 +89,8 @@ void main() { ...@@ -79,7 +89,8 @@ void main() {
tester.fling(tester.findText('BottomSheet'), const Offset(0.0, 20.0), 1000.0); tester.fling(tester.findText('BottomSheet'), const Offset(0.0, 20.0), 1000.0);
tester.pump(); // bottom sheet dismiss animation starts tester.pump(); // bottom sheet dismiss animation starts
tester.pump(new Duration(seconds: 1)); // animation done tester.pump(new Duration(seconds: 1)); // animation done
tester.pump(new Duration(seconds: 2)); // rebuild frame without the bottom sheet tester.pump(new Duration(seconds: 1)); // rebuild frame without the bottom sheet
expect(showBottomSheetThenCalled, isTrue);
expect(tester.findText('BottomSheet'), isNull); expect(tester.findText('BottomSheet'), isNull);
expect(_bottomSheetPlaceholderKey.currentState.child, isNull); expect(_bottomSheetPlaceholderKey.currentState.child, isNull);
}); });
......
...@@ -9,17 +9,22 @@ void main() { ...@@ -9,17 +9,22 @@ void main() {
String helloSnackBar = 'Hello SnackBar'; String helloSnackBar = 'Hello SnackBar';
GlobalKey<PlaceholderState> placeholderKey = new GlobalKey<PlaceholderState>(); GlobalKey<PlaceholderState> placeholderKey = new GlobalKey<PlaceholderState>();
Key tapTarget = new Key('tap-target'); Key tapTarget = new Key('tap-target');
BuildContext context;
bool showSnackBarThenCalled = false;
tester.pumpWidget(new MaterialApp( tester.pumpWidget(new MaterialApp(
routes: <String, RouteBuilder>{ routes: <String, RouteBuilder>{
'/': (RouteArguments args) { '/': (RouteArguments args) {
context = args.context;
return new GestureDetector( return new GestureDetector(
onTap: () { onTap: () {
showSnackBar( showSnackBar(
context: args.context, context: args.context,
placeholderKey: placeholderKey, placeholderKey: placeholderKey,
content: new Text(helloSnackBar) content: new Text(helloSnackBar)
); ).then((_) {
showSnackBarThenCalled = true;
});
}, },
child: new Container( child: new Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
...@@ -36,10 +41,16 @@ void main() { ...@@ -36,10 +41,16 @@ void main() {
)); ));
tester.tap(tester.findElementByKey(tapTarget)); tester.tap(tester.findElementByKey(tapTarget));
expect(tester.findText(helloSnackBar), isNull); expect(tester.findText(helloSnackBar), isNull);
tester.pump(); tester.pump();
expect(tester.findText(helloSnackBar), isNotNull); expect(tester.findText(helloSnackBar), isNotNull);
Navigator.of(context).pop();
expect(tester.findText(helloSnackBar), isNotNull);
tester.pump(new Duration(seconds: 1));
expect(showSnackBarThenCalled, isTrue);
expect(tester.findText(helloSnackBar), isNull);
expect(placeholderKey.currentState.child, isNull);
}); });
}); });
} }
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