Skip to content

Commit 86e3a95

Browse files
gnpricePIG208
authored andcommitted
app: add ZulipApp.scaffoldMessenger.
Because static extensions are not supported, we cannot create app_checks.dart for ZulipApp.ready or ZulipApp.scaffoldMessenger. See: dart-lang/language#723
1 parent 69e19aa commit 86e3a95

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

lib/widgets/app.dart

+16
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,22 @@ class ZulipApp extends StatefulWidget {
6363
/// to be mounted.
6464
static final navigatorKey = GlobalKey<NavigatorState>();
6565

66+
/// The [ScaffoldMessengerState] for the app.
67+
///
68+
/// This is null during the app's early startup, while [ready] is still false.
69+
///
70+
/// For code that exists entirely outside the widget tree and has no natural
71+
/// [BuildContext] of its own, this enables controlling snack bars.
72+
/// Where a relevant [BuildContext] does exist, prefer using that instead,
73+
/// with [ScaffoldMessenger.of].
74+
static ScaffoldMessengerState? get scaffoldMessenger {
75+
final context = navigatorKey.currentContext;
76+
if (context == null) return null;
77+
// Not maybeOf; we use MaterialApp, which provides ScaffoldMessenger,
78+
// so it's a bug if navigatorKey is mounted somewhere lacking that.
79+
return ScaffoldMessenger.of(context);
80+
}
81+
6682
/// Reset the state of [ZulipApp] statics, for testing.
6783
///
6884
/// TODO refactor this better, perhaps unify with ZulipBinding

test/flutter_checks.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
library;
33

44
import 'package:checks/checks.dart';
5+
import 'package:flutter/foundation.dart';
56
import 'package:flutter/material.dart';
67
import 'package:flutter/services.dart';
78

@@ -51,7 +52,7 @@ extension RouteSettingsChecks<T> on Subject<RouteSettings> {
5152
Subject<Object?> get arguments => has((s) => s.arguments, 'arguments');
5253
}
5354

54-
extension ValueNotifierChecks<T> on Subject<ValueNotifier<T>> {
55+
extension ValueListenableChecks<T> on Subject<ValueListenable<T>> {
5556
Subject<T> get value => has((c) => c.value, 'value');
5657
}
5758

test/widgets/app_test.dart

+11
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,15 @@ void main() {
154154
..bottom.isLessThan(2 / 3 * screenHeight);
155155
});
156156
});
157+
158+
group('scaffoldMessenger', () {
159+
testWidgets('scaffoldMessenger becomes non-null after startup', (tester) async {
160+
await tester.pumpWidget(const ZulipApp());
161+
check(ZulipApp.scaffoldMessenger).isNull();
162+
check(ZulipApp.ready).value.isFalse();
163+
await tester.pump();
164+
check(ZulipApp.scaffoldMessenger).isNotNull();
165+
check(ZulipApp.ready).value.isTrue();
166+
});
167+
});
157168
}

0 commit comments

Comments
 (0)