@@ -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,12 @@ class UpdateMachine {
746756    final  updateMachine =  UpdateMachine .fromInitialSnapshot (
747757      store:  store, initialSnapshot:  initialSnapshot);
748758    updateMachine.poll ();
759+     if  (initialSnapshot.serverEmojiDataUrl !=  null ) {
760+       // TODO(server-6): If the server is ancient, just skip trying to have 
761+       //   a list of its emoji.  (The old servers that don't provide 
762+       //   serverEmojiDataUrl are already unsupported at time of writing.) 
763+       unawaited (updateMachine.fetchEmojiData (initialSnapshot.serverEmojiDataUrl! ));
764+     }
749765    // TODO do registerNotificationToken before registerQueue: 
750766    //   https://github.com/zulip/zulip-flutter/pull/325#discussion_r1365982807 
751767    unawaited (updateMachine.registerNotificationToken ());
@@ -772,6 +788,43 @@ class UpdateMachine {
772788    }
773789  }
774790
791+   /// Fetch emoji data from the server, and update the store with the result. 
792+   /// 
793+   /// This functions a lot like [registerQueue]  and the surrounding logic 
794+   /// in [load]  above, but it's unusual in that we've separated it out. 
795+   /// Effectively it's data that *would have* been in the [registerQueue]  
796+   /// response, except that we pulled it out to its own endpoint as part of 
797+   /// a caching strategy, because the data changes infrequently. 
798+   /// 
799+   /// Conveniently (a) this deferred fetch doesn't cause any fetch/event race, 
800+   /// because this data doesn't get updated by events anyway (it can change 
801+   /// only on a server restart); and (b) we don't need this data for displaying 
802+   /// messages or anything else, only for certain UIs like the emoji picker, 
803+   /// so it's fine that we go without it for a while. 
804+ Future <void > fetchEmojiData (Uri  serverEmojiDataUrl) async  {
805+     if  (! debugEnableFetchEmojiData) return ;
806+     BackoffMachine ?  backoffMachine;
807+     ServerEmojiData  data;
808+     while  (true ) {
809+       try  {
810+         data =  await  fetchServerEmojiData (store.connection,
811+           emojiDataUrl:  serverEmojiDataUrl);
812+         assert (debugLog ('Got emoji data: ${data .codeToNames .length } emoji' ));
813+         break ;
814+       } catch  (e) {
815+         assert (debugLog ('Error fetching emoji data: $e \n '  // TODO(log) 
816+           'Backing off, then will retry…' ));
817+         // The emoji data is a lot less urgent than the initial fetch, 
818+         // or even the event-queue poll request.  So wait longer. 
819+         backoffMachine ?? =  BackoffMachine (firstBound:  const  Duration (seconds:  2 ),
820+                                           maxBound:  const  Duration (minutes:  2 ));
821+         await  backoffMachine.wait ();
822+       }
823+     }
824+ 
825+     store.setServerEmojiData (data);
826+   }
827+ 
775828  Completer <void >?  _debugLoopSignal;
776829
777830  /// In debug mode, causes the polling loop to pause before the next 
@@ -890,6 +943,26 @@ class UpdateMachine {
890943    NotificationService .instance.token.removeListener (_registerNotificationToken);
891944  }
892945
946+   /// In debug mode, controls whether [fetchEmojiData]  should 
947+   /// have its normal effect. 
948+   /// 
949+   /// Outside of debug mode, this is always true and the setter has no effect. 
950+ static  bool  get  debugEnableFetchEmojiData {
951+     bool  result =  true ;
952+     assert (() {
953+       result =  _debugEnableFetchEmojiData;
954+       return  true ;
955+     }());
956+     return  result;
957+   }
958+   static  bool  _debugEnableFetchEmojiData =  true ;
959+   static  set  debugEnableFetchEmojiData (bool  value) {
960+     assert (() {
961+       _debugEnableFetchEmojiData =  value;
962+       return  true ;
963+     }());
964+   }
965+ 
893966  /// In debug mode, controls whether [registerNotificationToken]  should 
894967  /// have its normal effect. 
895968  /// 
0 commit comments