🐛 Add well defined mounted check in messages notifier

This commit is contained in:
2026-01-11 12:53:57 +08:00
parent eec181da55
commit bf59108569

View File

@@ -128,7 +128,7 @@ class MessagesNotifier extends _$MessagesNotifier {
uniqueMessages.add(message);
}
}
state = AsyncValue.data(uniqueMessages);
if (ref.mounted) state = AsyncValue.data(uniqueMessages);
} finally {
_isUpdatingState = false;
}
@@ -350,7 +350,7 @@ class MessagesNotifier extends _$MessagesNotifier {
offset: 0,
take: _pageSize,
);
state = AsyncValue.data(newMessages);
if (ref.mounted) state = AsyncValue.data(newMessages);
return;
}
@@ -408,7 +408,9 @@ class MessagesNotifier extends _$MessagesNotifier {
} finally {
talker.log('Finished message sync');
// Always reset global syncing state, regardless of disposal
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(false));
Future.microtask(() {
if (ref.mounted) ref.read(chatSyncingProvider.notifier).set(false);
});
_isSyncing = false;
}
}
@@ -498,7 +500,7 @@ class MessagesNotifier extends _$MessagesNotifier {
_hasMore = messages.length == _pageSize;
state = AsyncValue.data(messages);
if (ref.mounted) state = AsyncValue.data(messages);
}
Future<void> loadMore() async {
@@ -509,7 +511,7 @@ class MessagesNotifier extends _$MessagesNotifier {
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(true));
}
try {
final currentMessages = state.value ?? [];
final currentMessages = (ref.mounted ? state.value : null) ?? [];
final offset = currentMessages.length;
final newMessages = await listMessages(offset: offset, take: _pageSize);
@@ -518,9 +520,11 @@ class MessagesNotifier extends _$MessagesNotifier {
_hasMore = false;
}
if (ref.mounted) {
state = AsyncValue.data(
_sortMessages([...currentMessages, ...newMessages]),
);
}
} catch (err, stackTrace) {
talker.log(
'Error loading more messages',
@@ -531,12 +535,14 @@ class MessagesNotifier extends _$MessagesNotifier {
showErrorAlert(err);
} finally {
// Always reset global syncing state, regardless of disposal
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(false));
Future.microtask(() {
if (ref.mounted) ref.read(chatSyncingProvider.notifier).set(false);
});
}
}
Future<void> sendMessage(
WidgetRef ref,
WidgetRef outerRef,
String content,
List<UniversalFile> attachments, {
SnPoll? poll,
@@ -569,14 +575,14 @@ class MessagesNotifier extends _$MessagesNotifier {
_fileUploadProgress[localMessage.id] = {};
await _database.saveMessageWithSender(localMessage);
final currentMessages = state.value ?? [];
final currentMessages = (ref.mounted ? state.value : null) ?? [];
state = AsyncValue.data([localMessage, ...currentMessages]);
try {
var cloudAttachments = List.empty(growable: true);
for (var idx = 0; idx < attachments.length; idx++) {
final cloudFile = await FileUploader.createCloudFile(
ref: ref,
ref: outerRef,
fileData: attachments[idx],
onProgress: (progress, _) {
_fileUploadProgress[localMessage.id]?[idx] = progress ?? 0.0;
@@ -619,6 +625,7 @@ class MessagesNotifier extends _$MessagesNotifier {
await _database.deleteMessage(localMessage.id);
await _database.saveMessageWithSender(updatedMessage);
if (ref.mounted) {
final currentMessages = state.value ?? [];
if (editingTo != null) {
final newMessages = currentMessages
@@ -637,6 +644,8 @@ class MessagesNotifier extends _$MessagesNotifier {
}).toList();
state = AsyncValue.data(newMessages);
}
}
talker.log('Message with nonce $nonce sent successfully');
} catch (e, stackTrace) {
talker.log(
@@ -651,6 +660,7 @@ class MessagesNotifier extends _$MessagesNotifier {
localMessage.id,
MessageStatus.failed,
);
if (ref.mounted) {
final newMessages = (state.value ?? []).map((m) {
if (m.id == localMessage.id) {
return m..status = MessageStatus.failed;
@@ -658,6 +668,7 @@ class MessagesNotifier extends _$MessagesNotifier {
return m;
}).toList();
state = AsyncValue.data(newMessages);
}
showErrorAlert(e);
}
}
@@ -698,6 +709,7 @@ class MessagesNotifier extends _$MessagesNotifier {
await _database.deleteMessage(pendingMessageId);
await _database.saveMessageWithSender(updatedMessage);
if (ref.mounted) {
final newMessages = (state.value ?? []).map((m) {
if (m.id == pendingMessageId) {
return updatedMessage;
@@ -705,6 +717,7 @@ class MessagesNotifier extends _$MessagesNotifier {
return m;
}).toList();
state = AsyncValue.data(newMessages);
}
} catch (e, stackTrace) {
talker.log(
'Failed to retry message $pendingMessageId',
@@ -718,6 +731,7 @@ class MessagesNotifier extends _$MessagesNotifier {
pendingMessageId,
MessageStatus.failed,
);
if (ref.mounted) {
final newMessages = (state.value ?? []).map((m) {
if (m.id == pendingMessageId) {
return m..status = MessageStatus.failed;
@@ -725,6 +739,7 @@ class MessagesNotifier extends _$MessagesNotifier {
return m;
}).toList();
state = AsyncValue.data(_sortMessages(newMessages));
}
showErrorAlert(e);
}
}
@@ -756,13 +771,14 @@ class MessagesNotifier extends _$MessagesNotifier {
if (!isSilentMessage) {
await _database.saveMessageWithSender(localMessage);
final currentMessages = state.value ?? [];
final currentMessages = (ref.mounted ? state.value : null) ?? [];
final existingIndex = currentMessages.indexWhere(
(m) =>
m.id == localMessage.id ||
(localMessage.nonce != null && m.nonce == localMessage.nonce),
);
if (ref.mounted) {
if (existingIndex >= 0) {
final newList = [...currentMessages];
newList[existingIndex] = localMessage;
@@ -773,6 +789,7 @@ class MessagesNotifier extends _$MessagesNotifier {
);
}
}
}
switch (remoteMessage.type) {
case "messages.delete":
@@ -837,15 +854,17 @@ class MessagesNotifier extends _$MessagesNotifier {
await _database.updateMessage(_database.messageToCompanion(updatedMessage));
final currentMessages = state.value ?? [];
final currentMessages = (ref.mounted ? state.value : null) ?? [];
final index = currentMessages.indexWhere((m) => m.id == updatedMessage.id);
if (ref.mounted) {
if (index >= 0) {
final newList = [...currentMessages];
newList[index] = updatedMessage;
state = AsyncValue.data(_sortMessages(newList));
}
}
}
Future<void> receiveMessageDeletion(String messageId) async {
// Block message deletions during jumps to prevent list resets
@@ -857,7 +876,7 @@ class MessagesNotifier extends _$MessagesNotifier {
talker.log('Received message deletion $messageId');
_pendingMessages.remove(messageId);
final currentMessages = state.value ?? [];
final currentMessages = (ref.mounted ? state.value : null) ?? [];
final messageIndex = currentMessages.indexWhere((m) => m.id == messageId);
LocalChatMessage? messageToUpdate;
@@ -883,12 +902,14 @@ class MessagesNotifier extends _$MessagesNotifier {
await _database.saveMessageWithSender(deletedMessage);
if (ref.mounted) {
if (messageIndex != -1) {
final newList = [...currentMessages];
newList[messageIndex] = deletedMessage;
state = AsyncValue.data(newList);
}
}
}
Future<void> deleteMessage(String messageId) async {
talker.log('Deleting message $messageId');
@@ -907,7 +928,7 @@ class MessagesNotifier extends _$MessagesNotifier {
_pendingMessages.remove(messageId);
await _database.deleteMessage(messageId);
final currentMessages = state.value ?? [];
final currentMessages = (ref.mounted ? state.value : null) ?? [];
final newMessages = currentMessages
.where((m) => m.id != messageId)
.toList();
@@ -1063,7 +1084,7 @@ class MessagesNotifier extends _$MessagesNotifier {
}
// Check if message is already in current state to avoid duplicate loading
final currentMessages = state.value ?? [];
final currentMessages = (ref.mounted ? state.value : null) ?? [];
final existingIndex = currentMessages.indexWhere(
(m) => m.id == messageId,
);