@@ -445,6 +445,8 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess
445
445
// End of data.
446
446
////////////////////////////////////////////////////////////////
447
447
448
+ bool _disposed = false ;
449
+
448
450
/// Called when the app is reassembled during debugging, e.g. for hot reload.
449
451
///
450
452
/// This will redo from scratch any computations we can, such as parsing
@@ -456,15 +458,19 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess
456
458
457
459
@override
458
460
void dispose () {
461
+ assert (! _disposed);
459
462
recentDmConversationsView.dispose ();
460
463
unreads.dispose ();
461
464
_messages.dispose ();
462
465
typingStatus.dispose ();
463
466
updateMachine? .dispose ();
467
+ _disposed = true ;
464
468
super .dispose ();
465
469
}
466
470
467
471
Future <void > handleEvent (Event event) async {
472
+ assert (! _disposed);
473
+
468
474
switch (event) {
469
475
case HeartbeatEvent ():
470
476
assert (debugLog ("server event: heartbeat" ));
@@ -606,6 +612,8 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess
606
612
}
607
613
608
614
Future <void > sendMessage ({required MessageDestination destination, required String content}) {
615
+ assert (! _disposed);
616
+
609
617
// TODO implement outbox; see design at
610
618
// https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M3881.20Sending.20outbox.20messages.20is.20fraught.20with.20issues/near/1405739
611
619
return _apiSendMessage (connection,
@@ -790,6 +798,8 @@ class UpdateMachine {
790
798
final String queueId;
791
799
int lastEventId;
792
800
801
+ bool _disposed = false ;
802
+
793
803
static Future <InitialSnapshot > _registerQueueWithRetry (
794
804
ApiConnection connection) async {
795
805
BackoffMachine ? backoffMachine;
@@ -876,11 +886,15 @@ class UpdateMachine {
876
886
}());
877
887
}
878
888
889
+ if (_disposed) return ;
890
+
879
891
final GetEventsResult result;
880
892
try {
881
893
result = await getEvents (store.connection,
882
894
queueId: queueId, lastEventId: lastEventId);
883
895
} catch (e) {
896
+ if (_disposed) return ;
897
+
884
898
store.isLoading = true ;
885
899
switch (e) {
886
900
case ZulipApiException (code: 'BAD_EVENT_QUEUE_ID' ):
@@ -908,6 +922,8 @@ class UpdateMachine {
908
922
}
909
923
}
910
924
925
+ if (_disposed) return ;
926
+
911
927
// After one successful request, we reset backoff to its initial state.
912
928
// That way if the user is off the network and comes back on, the app
913
929
// doesn't wind up in a state where it's slow to recover the next time
@@ -929,6 +945,7 @@ class UpdateMachine {
929
945
final events = result.events;
930
946
for (final event in events) {
931
947
await store.handleEvent (event);
948
+ if (_disposed) return ;
932
949
}
933
950
if (events.isNotEmpty) {
934
951
lastEventId = events.last.id;
@@ -944,6 +961,8 @@ class UpdateMachine {
944
961
// TODO(#322) save acked token, to dedupe updating it on the server
945
962
// TODO(#323) track the addFcmToken/etc request, warn if not succeeding
946
963
Future <void > registerNotificationToken () async {
964
+ if (_disposed) return ;
965
+
947
966
if (! debugEnableRegisterNotificationToken) {
948
967
return ;
949
968
}
@@ -957,12 +976,14 @@ class UpdateMachine {
957
976
await NotificationService .registerToken (store.connection, token: token);
958
977
}
959
978
960
- /// Cleans up resources.
979
+ /// Cleans up resources and tells the instance not to make new API requests .
961
980
///
962
981
/// After this is called, the instance is not in a usable state
963
982
/// and should be abandoned.
964
983
void dispose () { // TODO abort long-poll and close ApiConnection
984
+ assert (! _disposed);
965
985
NotificationService .instance.token.removeListener (_registerNotificationToken);
986
+ _disposed = true ;
966
987
}
967
988
968
989
/// In debug mode, controls whether [fetchEmojiData] should
0 commit comments