@@ -83,22 +83,33 @@ class MessageListOutboxMessageItem extends MessageListMessageBaseItem {
8383 ]);
8484}
8585
86- /// The status of outstanding or recent fetch requests from a [MessageListView] .
87- enum FetchingStatus {
88- /// The model has not made any fetch requests (since its last reset, if any).
86+ /// The status of outstanding or recent `fetchInitial` request from a [MessageListView] .
87+ enum FetchingInitialStatus {
88+ /// The model has not made a `fetchInitial` request (since its last reset, if any).
8989 unstarted,
9090
9191 /// The model has made a `fetchInitial` request, which hasn't succeeded.
92- fetchInitial ,
92+ fetching ,
9393
94- /// The model made a successful `fetchInitial` request,
95- /// and has no outstanding requests or backoff.
94+ /// The model made a successful `fetchInitial` request.
9695 idle,
96+ }
97+
98+ /// The status of outstanding or recent "fetch more" request from a [MessageListView] .
99+ ///
100+ /// By a "fetch more" request we mean a `fetchOlder` or a `fetchNewer` request.
101+ enum FetchingMoreStatus {
102+ /// The model has not made the "fetch more" request (since its last reset, if any).
103+ unstarted,
104+
105+ /// The model has made the "fetch more" request, which hasn't succeeded.
106+ fetching,
97107
98- /// The model has an active `fetchOlder` or `fetchNewer` request.
99- fetchingMore,
108+ /// The model made a successful "fetch more" request,
109+ /// and has no outstanding request of the same kind or backoff.
110+ idle,
100111
101- /// The model is in a backoff period from a failed request.
112+ /// The model is in a backoff period from the failed "fetch more" request.
102113 backoff,
103114}
104115
@@ -125,7 +136,7 @@ mixin _MessageSequence {
125136 ///
126137 /// This may or may not represent all the message history that
127138 /// conceptually belongs in this message list.
128- /// That information is expressed in [fetched ] , [haveOldest] , [haveNewest] .
139+ /// That information is expressed in [initialFetched ] , [haveOldest] , [haveNewest] .
129140 ///
130141 /// This also may or may not represent all the message history that
131142 /// conceptually belongs in this narrow because some messages might be
@@ -165,12 +176,15 @@ mixin _MessageSequence {
165176 int ? get newMessageId => _newMessageId;
166177 int ? _newMessageId;
167178
168- /// Whether [messages] and [items] represent the results of a fetch .
179+ /// Whether the first batch of messages for this narrow is fetched yet .
169180 ///
170- /// This allows the UI to distinguish "still working on fetching messages"
171- /// from "there are in fact no messages here".
172- bool get fetched => switch (_status) {
173- FetchingStatus .unstarted || FetchingStatus .fetchInitial => false ,
181+ /// Some or all of the fetched messages may not make it to [messages]
182+ /// and [items] if they're muted in one way or another.
183+ ///
184+ /// This allows the UI to distinguish "still working on fetching first batch
185+ /// of messages" from "there are in fact no messages here".
186+ bool get initialFetched => switch (_fetchInitialStatus) {
187+ .unstarted || .fetching => false ,
174188 _ => true ,
175189 };
176190
@@ -188,18 +202,37 @@ mixin _MessageSequence {
188202
189203 /// Whether this message list is currently busy when it comes to
190204 /// fetching more messages.
205+ bool get busyFetchingMore => busyFetchingOlder || busyFetchingNewer;
206+
207+ /// Whether this message list is currently busy when it comes to
208+ /// fetching older messages.
209+ ///
210+ /// Here "busy" means a new call to fetch older messages would do nothing,
211+ /// rather than make any request to the server,
212+ /// as a result of an existing recent request.
213+ /// This is true both when the recent request is still outstanding,
214+ /// and when it failed and the backoff from that is still in progress.
215+ bool get busyFetchingOlder => switch (_fetchOlderStatus) {
216+ .fetching || .backoff => true ,
217+ _ => false ,
218+ };
219+
220+ /// Whether this message list is currently busy when it comes to
221+ /// fetching newer messages.
191222 ///
192- /// Here "busy" means a new call to fetch more messages would do nothing,
223+ /// Here "busy" means a new call to fetch older messages would do nothing,
193224 /// rather than make any request to the server,
194225 /// as a result of an existing recent request.
195226 /// This is true both when the recent request is still outstanding,
196227 /// and when it failed and the backoff from that is still in progress.
197- bool get busyFetchingMore => switch (_status ) {
198- FetchingStatus .fetchingMore || FetchingStatus .backoff => true ,
228+ bool get busyFetchingNewer => switch (_fetchNewerStatus ) {
229+ .fetching || .backoff => true ,
199230 _ => false ,
200231 };
201232
202- FetchingStatus _status = FetchingStatus .unstarted;
233+ FetchingInitialStatus _fetchInitialStatus = .unstarted;
234+ FetchingMoreStatus _fetchOlderStatus = .unstarted;
235+ FetchingMoreStatus _fetchNewerStatus = .unstarted;
203236
204237 BackoffMachine ? _fetchBackoffMachine;
205238
@@ -434,7 +467,9 @@ mixin _MessageSequence {
434467 outboxMessages.clear ();
435468 _haveOldest = false ;
436469 _haveNewest = false ;
437- _status = FetchingStatus .unstarted;
470+ _fetchInitialStatus = .unstarted;
471+ _fetchOlderStatus = .unstarted;
472+ _fetchNewerStatus = .unstarted;
438473 _fetchBackoffMachine = null ;
439474 contents.clear ();
440475 items.clear ();
@@ -786,16 +821,28 @@ class MessageListView with ChangeNotifier, _MessageSequence {
786821 }
787822 }
788823
789- void _setStatus (FetchingStatus value, {FetchingStatus ? was}) {
790- assert (was == null || _status == was);
791- _status = value;
792- if (! fetched) return ;
824+ void _setInitialStatus (FetchingInitialStatus value, {FetchingInitialStatus ? was}) {
825+ assert (was == null || _fetchInitialStatus == was);
826+ _fetchInitialStatus = value;
827+ if (! initialFetched) return ;
828+ notifyListeners ();
829+ }
830+
831+ void _setOlderStatus (FetchingMoreStatus value, {FetchingMoreStatus ? was}) {
832+ assert (was == null || _fetchOlderStatus == was);
833+ _fetchOlderStatus = value;
834+ notifyListeners ();
835+ }
836+
837+ void _setNewerStatus (FetchingMoreStatus value, {FetchingMoreStatus ? was}) {
838+ assert (was == null || _fetchNewerStatus == was);
839+ _fetchNewerStatus = value;
793840 notifyListeners ();
794841 }
795842
796843 /// Fetch messages, starting from scratch.
797844 Future <void > fetchInitial () async {
798- assert (! fetched && ! haveOldest && ! haveNewest && ! busyFetchingMore);
845+ assert (! initialFetched && ! haveOldest && ! haveNewest && ! busyFetchingMore);
799846 assert (messages.isEmpty && contents.isEmpty);
800847 assert (oldMessageId == null && newMessageId == null );
801848
@@ -805,11 +852,11 @@ class MessageListView with ChangeNotifier, _MessageSequence {
805852 // probably better if the UI code doesn't take it to this point.
806853 _haveOldest = true ;
807854 _haveNewest = true ;
808- _setStatus ( FetchingStatus .idle, was: FetchingStatus .unstarted);
855+ _setInitialStatus ( .idle, was: .unstarted);
809856 return ;
810857 }
811858
812- _setStatus ( FetchingStatus .fetchInitial , was: FetchingStatus .unstarted);
859+ _setInitialStatus (.fetching , was: .unstarted);
813860 // TODO schedule all this in another isolate
814861 final generation = this .generation;
815862 final result = await getMessages (store.connection,
@@ -850,7 +897,7 @@ class MessageListView with ChangeNotifier, _MessageSequence {
850897 _syncOutboxMessagesFromStore ();
851898 }
852899
853- _setStatus ( FetchingStatus .idle, was: FetchingStatus .fetchInitial );
900+ _setInitialStatus ( .idle, was: .fetching );
854901 }
855902
856903 /// Update [narrow] for the result of a "with" narrow (topic permalink) fetch.
@@ -888,22 +935,23 @@ class MessageListView with ChangeNotifier, _MessageSequence {
888935 /// Fetch the next batch of older messages, if applicable.
889936 ///
890937 /// If there are no older messages to fetch (i.e. if [haveOldest] ),
891- /// or if this message list is already busy fetching more messages
892- /// (i.e. if [busyFetchingMore ] , which includes backoff from failed requests),
938+ /// or if this message list is already busy fetching older messages
939+ /// (i.e. if [busyFetchingOlder ] , which includes backoff from failed requests),
893940 /// then this method does nothing and immediately returns.
894941 /// That makes this method suitable to call frequently, e.g. every frame,
895- /// whenever it looks likely to be useful to have more messages.
942+ /// whenever it looks likely to be useful to have older messages.
896943 Future <void > fetchOlder () async {
897944 int visibleMessageCount = 0 ;
898945 do {
899946 if (haveOldest) return ;
900- if (busyFetchingMore ) return ;
901- assert (fetched );
947+ if (busyFetchingOlder ) return ;
948+ assert (initialFetched );
902949 assert (oldMessageId != null );
903950 await _fetchMore (
904951 anchor: NumericAnchor (oldMessageId! ),
905952 numBefore: kMessageListFetchBatchSize,
906953 numAfter: 0 ,
954+ setStatus: _setOlderStatus,
907955 processResult: (result) {
908956 _oldMessageId = result.messages.firstOrNull? .id ?? oldMessageId;
909957 store.reconcileMessages (result.messages);
@@ -923,22 +971,23 @@ class MessageListView with ChangeNotifier, _MessageSequence {
923971 /// Fetch the next batch of newer messages, if applicable.
924972 ///
925973 /// If there are no newer messages to fetch (i.e. if [haveNewest] ),
926- /// or if this message list is already busy fetching more messages
927- /// (i.e. if [busyFetchingMore ] , which includes backoff from failed requests),
974+ /// or if this message list is already busy fetching newer messages
975+ /// (i.e. if [busyFetchingNewer ] , which includes backoff from failed requests),
928976 /// then this method does nothing and immediately returns.
929977 /// That makes this method suitable to call frequently, e.g. every frame,
930- /// whenever it looks likely to be useful to have more messages.
978+ /// whenever it looks likely to be useful to have newer messages.
931979 Future <void > fetchNewer () async {
932980 int visibleMessageCount = 0 ;
933981 do {
934982 if (haveNewest) return ;
935- if (busyFetchingMore ) return ;
936- assert (fetched );
983+ if (busyFetchingNewer ) return ;
984+ assert (initialFetched );
937985 assert (newMessageId != null );
938986 await _fetchMore (
939987 anchor: NumericAnchor (newMessageId! ),
940988 numBefore: 0 ,
941989 numAfter: kMessageListFetchBatchSize,
990+ setStatus: _setNewerStatus,
942991 processResult: (result) {
943992 _newMessageId = result.messages.lastOrNull? .id ?? newMessageId;
944993 store.reconcileMessages (result.messages);
@@ -963,12 +1012,13 @@ class MessageListView with ChangeNotifier, _MessageSequence {
9631012 required Anchor anchor,
9641013 required int numBefore,
9651014 required int numAfter,
1015+ required void Function (FetchingMoreStatus value, {FetchingMoreStatus ? was}) setStatus,
9661016 required void Function (GetMessagesResult ) processResult,
9671017 }) async {
9681018 assert (narrow is ! TopicNarrow
9691019 // We only intend to send "with" in [fetchInitial]; see there.
9701020 || (narrow as TopicNarrow ).with_ == null );
971- _setStatus ( FetchingStatus .fetchingMore, was : FetchingStatus .idle );
1021+ setStatus (.fetching );
9721022 final generation = this .generation;
9731023 bool hasFetchError = false ;
9741024 try {
@@ -989,14 +1039,14 @@ class MessageListView with ChangeNotifier, _MessageSequence {
9891039 } finally {
9901040 if (this .generation == generation) {
9911041 if (hasFetchError) {
992- _setStatus ( FetchingStatus .backoff, was: FetchingStatus .fetchingMore );
1042+ setStatus ( .backoff, was: .fetching );
9931043 unawaited ((_fetchBackoffMachine ?? = BackoffMachine ())
9941044 .wait ().then ((_) {
9951045 if (this .generation != generation) return ;
996- _setStatus ( FetchingStatus .idle, was: FetchingStatus .backoff);
1046+ setStatus ( .idle, was: .backoff);
9971047 }));
9981048 } else {
999- _setStatus ( FetchingStatus .idle, was: FetchingStatus .fetchingMore );
1049+ setStatus ( .idle, was: .fetching );
10001050 _fetchBackoffMachine = null ;
10011051 }
10021052 }
@@ -1008,7 +1058,7 @@ class MessageListView with ChangeNotifier, _MessageSequence {
10081058 /// This will set [anchor] to [AnchorCode.newest] ,
10091059 /// and cause messages to be re-fetched from scratch.
10101060 void jumpToEnd () {
1011- assert (fetched );
1061+ assert (initialFetched );
10121062 assert (! haveNewest);
10131063 assert (anchor != AnchorCode .newest);
10141064 _anchor = AnchorCode .newest;
@@ -1090,7 +1140,7 @@ class MessageListView with ChangeNotifier, _MessageSequence {
10901140 // TODO get the newly-unmuted messages from the message store
10911141 // For now, we simplify the task by just refetching this message list
10921142 // from scratch.
1093- if (fetched ) {
1143+ if (initialFetched ) {
10941144 _reset ();
10951145 notifyListeners ();
10961146 fetchInitial ();
@@ -1118,7 +1168,7 @@ class MessageListView with ChangeNotifier, _MessageSequence {
11181168 // TODO get the newly-unmuted messages from the message store
11191169 // For now, we simplify the task by just refetching this message list
11201170 // from scratch.
1121- if (fetched ) {
1171+ if (initialFetched ) {
11221172 _reset ();
11231173 notifyListeners ();
11241174 fetchInitial ();
0 commit comments