@@ -16,6 +16,7 @@ import '../api/model/model.dart';
1616import  '../api/route/events.dart' ;
1717import  '../api/route/messages.dart' ;
1818import  '../api/backoff.dart' ;
19+ import  '../api/route/realm.dart' ;
1920import  '../log.dart' ;
2021import  '../notifications/receive.dart' ;
2122import  'autocomplete.dart' ;
@@ -345,6 +346,15 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess
345346      emojiType:  emojiType, emojiCode:  emojiCode, emojiName:  emojiName);
346347  }
347348
349+   @override 
350+   Map <String , List <String >>?  get  debugServerEmojiData =>  _emoji.debugServerEmojiData;
351+ 
352+   @override 
353+   void  setServerEmojiData (ServerEmojiData  data) {
354+     _emoji.setServerEmojiData (data);
355+     notifyListeners ();
356+   }
357+ 
348358  EmojiStoreImpl  _emoji;
349359
350360  //////////////////////////////// 
@@ -746,6 +756,7 @@ class UpdateMachine {
746756    final  updateMachine =  UpdateMachine .fromInitialSnapshot (
747757      store:  store, initialSnapshot:  initialSnapshot);
748758    updateMachine.poll ();
759+     unawaited (updateMachine.fetchEmojiData (initialSnapshot.serverEmojiDataUrl));
749760    // TODO do registerNotificationToken before registerQueue: 
750761    //   https://github.com/zulip/zulip-flutter/pull/325#discussion_r1365982807 
751762    unawaited (updateMachine.registerNotificationToken ());
@@ -772,6 +783,43 @@ class UpdateMachine {
772783    }
773784  }
774785
786+   /// Fetch emoji data from the server, and update the store with the result. 
787+   /// 
788+   /// This functions a lot like [registerQueue]  and the surrounding logic 
789+   /// in [load]  above, but it's unusual in that we've separated it out. 
790+   /// Effectively it's data that *would have* been in the [registerQueue]  
791+   /// response, except that we pulled it out to its own endpoint as part of 
792+   /// a caching strategy, because the data changes infrequently. 
793+   /// 
794+   /// Conveniently (a) this deferred fetch doesn't cause any fetch/event race, 
795+   /// because this data doesn't get updated by events anyway (it can change 
796+   /// only on a server restart); and (b) we don't need this data for displaying 
797+   /// messages or anything else, only for certain UIs like the emoji picker, 
798+   /// so it's fine that we go without it for a while. 
799+ Future <void > fetchEmojiData (Uri  serverEmojiDataUrl) async  {
800+     if  (! debugEnableFetchEmojiData) return ;
801+     BackoffMachine ?  backoffMachine;
802+     ServerEmojiData  data;
803+     while  (true ) {
804+       try  {
805+         data =  await  fetchServerEmojiData (store.connection,
806+           emojiDataUrl:  serverEmojiDataUrl);
807+         assert (debugLog ('Got emoji data: ${data .codeToNames .length } emoji' ));
808+         break ;
809+       } catch  (e) {
810+         assert (debugLog ('Error fetching emoji data: $e \n '  // TODO(log) 
811+           'Backing off, then will retry…' ));
812+         // The emoji data is a lot less urgent than the initial fetch, 
813+         // or even the event-queue poll request.  So wait longer. 
814+         backoffMachine ?? =  BackoffMachine (firstBound:  const  Duration (seconds:  2 ),
815+                                           maxBound:  const  Duration (minutes:  2 ));
816+         await  backoffMachine.wait ();
817+       }
818+     }
819+ 
820+     store.setServerEmojiData (data);
821+   }
822+ 
775823  Completer <void >?  _debugLoopSignal;
776824
777825  /// In debug mode, causes the polling loop to pause before the next 
@@ -890,6 +938,26 @@ class UpdateMachine {
890938    NotificationService .instance.token.removeListener (_registerNotificationToken);
891939  }
892940
941+   /// In debug mode, controls whether [fetchEmojiData]  should 
942+   /// have its normal effect. 
943+   /// 
944+   /// Outside of debug mode, this is always true and the setter has no effect. 
945+ static  bool  get  debugEnableFetchEmojiData {
946+     bool  result =  true ;
947+     assert (() {
948+       result =  _debugEnableFetchEmojiData;
949+       return  true ;
950+     }());
951+     return  result;
952+   }
953+   static  bool  _debugEnableFetchEmojiData =  true ;
954+   static  set  debugEnableFetchEmojiData (bool  value) {
955+     assert (() {
956+       _debugEnableFetchEmojiData =  value;
957+       return  true ;
958+     }());
959+   }
960+ 
893961  /// In debug mode, controls whether [registerNotificationToken]  should 
894962  /// have its normal effect. 
895963  /// 
0 commit comments