[ermine] Use FutureBuilder to wait for locale to load.

TEST: Updated App widget unittest.
Change-Id: Ia0c29b1e3bf40ad228babc9bc8e7a11be9a481e9
diff --git a/session_shells/ermine/shell/lib/main.dart b/session_shells/ermine/shell/lib/main.dart
index 796f429..44c61d1 100644
--- a/session_shells/ermine/shell/lib/main.dart
+++ b/session_shells/ermine/shell/lib/main.dart
@@ -13,8 +13,6 @@
   setupLogger(name: 'ermine');
 
   final model = AppModel();
-  await model.init();
-
   final app = App(model: model);
 
   runApp(app);
diff --git a/session_shells/ermine/shell/lib/src/models/app_model.dart b/session_shells/ermine/shell/lib/src/models/app_model.dart
index 28f72a6..db40a84 100644
--- a/session_shells/ermine/shell/lib/src/models/app_model.dart
+++ b/session_shells/ermine/shell/lib/src/models/app_model.dart
@@ -57,8 +57,8 @@
   ValueNotifier<bool> helpVisibility = ValueNotifier(false);
   ValueNotifier<bool> peekNotifier = ValueNotifier(false);
   ValueNotifier<bool> recentsVisibility = ValueNotifier(false);
+  Stream<Locale> _localeStream;
   KeyboardShortcuts _keyboardShortcuts;
-  Locale _initialLocale;
   StatusModel status;
   TopbarModel topbarModel;
   String keyboardShortcuts = 'Help Me!';
@@ -75,6 +75,7 @@
         .connectToService(_shortcutRegistry);
 
     StartupContext.fromStartupInfo().incoming.connectToService(_intl);
+    _localeStream = LocaleSource(_intl).stream().asBroadcastStream();
 
     sessionShell = SessionShell(
       startupContext: _startupContext,
@@ -96,19 +97,11 @@
     status = StatusModel.fromStartupContext(_startupContext, onLogout);
   }
 
-  /// Performs initialization before the [App] widget are created.
-  Future<void> init() async {
-    /// Read the initial [Locale].
-    _initialLocale = await localeStream.asBroadcastStream().first;
-  }
-
   SuggestionService get suggestions => SuggestionService(_suggestionsService);
 
   modular.PuppetMaster get puppetMaster => _puppetMaster;
 
-  Stream<Locale> get localeStream => LocaleSource(_intl).stream();
-
-  Locale get initialLocale => _initialLocale;
+  Stream<Locale> get localeStream => _localeStream;
 
   bool get isFullscreen => clustersModel.fullscreenStory != null;
 
diff --git a/session_shells/ermine/shell/lib/src/widgets/app.dart b/session_shells/ermine/shell/lib/src/widgets/app.dart
index a462f46..630443e 100644
--- a/session_shells/ermine/shell/lib/src/widgets/app.dart
+++ b/session_shells/ermine/shell/lib/src/widgets/app.dart
@@ -28,8 +28,11 @@
   Widget build(BuildContext context) {
     return StreamBuilder<Locale>(
         stream: model.localeStream,
-        initialData: model.initialLocale,
         builder: (context, snapshot) {
+          // Check if [Locale] is loaded.
+          if (!snapshot.hasData) {
+            return Offstage();
+          }
           final locale = snapshot.data;
           // Needed to set the locale for anything that depends on the Intl
           // package.
diff --git a/session_shells/ermine/shell/test/app_widget_test.dart b/session_shells/ermine/shell/test/app_widget_test.dart
index af50658..fc19e94 100644
--- a/session_shells/ermine/shell/test/app_widget_test.dart
+++ b/session_shells/ermine/shell/test/app_widget_test.dart
@@ -21,11 +21,14 @@
     final swissFrench = Locale('fr', 'CH');
 
     final model = MockAppModel();
-    when(model.initialLocale).thenReturn(swissFrench);
+    when(model.localeStream).thenAnswer(
+        (_) => Stream<Locale>.value(swissFrench).asBroadcastStream());
     when(model.overviewVisibility).thenReturn(ValueNotifier<bool>(false));
 
     final app = App(model: model);
     await tester.pumpWidget(app);
+    // Pump widget for StreamBuilder<Locale>.
+    await tester.pump();
     expect(Intl.defaultLocale, swissFrench.toString());
   });
 }