@@ -6,6 +6,7 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
66import 'package:url_launcher/url_launcher.dart' as url_launcher;
77
88import '../host/android_notifications.dart' ;
9+ import '../log.dart' ;
910import '../widgets/store.dart' ;
1011import 'store.dart' ;
1112
@@ -66,6 +67,20 @@ abstract class ZulipBinding {
6667 _instance = this ;
6768 }
6869
70+ /// Provides device and operating system information,
71+ /// via package:device_info_plus.
72+ ///
73+ /// The returned Future resolves to null if an error is
74+ /// encountered while fetching the data.
75+ Future <BaseDeviceInfo ?> get deviceInfo;
76+
77+ /// Provides device and operating system information,
78+ /// via package:device_info_plus.
79+ ///
80+ /// May return null if prefetching hasn't completed yet,
81+ /// or an error occured while fetching the data.
82+ BaseDeviceInfo ? get maybeDeviceInfo;
83+
6984 /// Prepare the app's [GlobalStore] , loading the necessary data.
7085 ///
7186 /// Generally the app should call this function only once.
@@ -98,12 +113,6 @@ abstract class ZulipBinding {
98113 /// This wraps [url_launcher.closeInAppWebView] .
99114 Future <void > closeInAppWebView ();
100115
101- /// Provides device and operating system information,
102- /// via package:device_info_plus.
103- ///
104- /// This wraps [device_info_plus.DeviceInfoPlugin.deviceInfo] .
105- Future <BaseDeviceInfo > deviceInfo ();
106-
107116 /// Initialize Firebase, to use for notifications.
108117 ///
109118 /// This wraps [firebase_core.Firebase.initializeApp] .
@@ -164,11 +173,35 @@ class LiveZulipBinding extends ZulipBinding {
164173 /// Initialize the binding if necessary, and ensure it is a [LiveZulipBinding] .
165174 static LiveZulipBinding ensureInitialized () {
166175 if (ZulipBinding ._instance == null ) {
167- LiveZulipBinding ();
176+ final binding = LiveZulipBinding ();
177+ binding._deviceInfo = binding._prefetchDeviceInfo ();
168178 }
169179 return ZulipBinding .instance as LiveZulipBinding ;
170180 }
171181
182+ @override
183+ Future <BaseDeviceInfo ?> get deviceInfo => _deviceInfo;
184+ late Future <BaseDeviceInfo ?> _deviceInfo;
185+
186+ @override
187+ BaseDeviceInfo ? get maybeDeviceInfo => _maybeDeviceInfo;
188+ BaseDeviceInfo ? _maybeDeviceInfo;
189+
190+ Future <BaseDeviceInfo ?> _prefetchDeviceInfo () async {
191+ try {
192+ final info = await device_info_plus.DeviceInfoPlugin ().deviceInfo;
193+ _maybeDeviceInfo = switch (info) {
194+ device_info_plus.AndroidDeviceInfo (: var version) => AndroidDeviceInfo (sdkInt: version.sdkInt),
195+ device_info_plus.IosDeviceInfo (: var systemVersion) => IosDeviceInfo (systemVersion: systemVersion),
196+ _ => throw UnimplementedError (),
197+ };
198+ } catch (e) {
199+ assert (debugLog ('Failed to prefetch device info: $e ' ));
200+ // TODO(log)
201+ }
202+ return _maybeDeviceInfo;
203+ }
204+
172205 @override
173206 Future <GlobalStore > loadGlobalStore () {
174207 return LiveGlobalStore .load ();
@@ -195,16 +228,6 @@ class LiveZulipBinding extends ZulipBinding {
195228 return url_launcher.closeInAppWebView ();
196229 }
197230
198- @override
199- Future <BaseDeviceInfo > deviceInfo () async {
200- final deviceInfo = await device_info_plus.DeviceInfoPlugin ().deviceInfo;
201- return switch (deviceInfo) {
202- device_info_plus.AndroidDeviceInfo (: var version) => AndroidDeviceInfo (sdkInt: version.sdkInt),
203- device_info_plus.IosDeviceInfo (: var systemVersion) => IosDeviceInfo (systemVersion: systemVersion),
204- _ => throw UnimplementedError (),
205- };
206- }
207-
208231 @override
209232 Future <void > firebaseInitializeApp ({
210233 required firebase_core.FirebaseOptions options}) {
0 commit comments