🐛 Fixes in chat subscribe
This commit is contained in:
@@ -7,6 +7,7 @@ import "package:island/pods/chat/chat_room.dart";
|
|||||||
import "package:island/pods/lifecycle.dart";
|
import "package:island/pods/lifecycle.dart";
|
||||||
import "package:island/pods/chat/messages_notifier.dart";
|
import "package:island/pods/chat/messages_notifier.dart";
|
||||||
import "package:island/pods/websocket.dart";
|
import "package:island/pods/websocket.dart";
|
||||||
|
import "package:island/talker.dart";
|
||||||
import "package:island/widgets/chat/call_button.dart";
|
import "package:island/widgets/chat/call_button.dart";
|
||||||
import "package:riverpod_annotation/riverpod_annotation.dart";
|
import "package:riverpod_annotation/riverpod_annotation.dart";
|
||||||
|
|
||||||
@@ -35,6 +36,22 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
Timer? _typingCooldownTimer;
|
Timer? _typingCooldownTimer;
|
||||||
Timer? _periodicSubscribeTimer;
|
Timer? _periodicSubscribeTimer;
|
||||||
StreamSubscription? _wsSubscription;
|
StreamSubscription? _wsSubscription;
|
||||||
|
Function? _sendMessage;
|
||||||
|
|
||||||
|
void _cleanupResources() {
|
||||||
|
if (_wsSubscription != null) {
|
||||||
|
_wsSubscription!.cancel();
|
||||||
|
_wsSubscription = null;
|
||||||
|
}
|
||||||
|
if (_typingCleanupTimer != null) {
|
||||||
|
_typingCleanupTimer!.cancel();
|
||||||
|
_typingCleanupTimer = null;
|
||||||
|
}
|
||||||
|
if (_periodicSubscribeTimer != null) {
|
||||||
|
_periodicSubscribeTimer!.cancel();
|
||||||
|
_periodicSubscribeTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<SnChatMember> build(String roomId) {
|
List<SnChatMember> build(String roomId) {
|
||||||
@@ -43,6 +60,8 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
final chatIdentityAsync = ref.watch(chatRoomIdentityProvider(roomId));
|
final chatIdentityAsync = ref.watch(chatRoomIdentityProvider(roomId));
|
||||||
_messagesNotifier = ref.watch(messagesProvider(roomId).notifier);
|
_messagesNotifier = ref.watch(messagesProvider(roomId).notifier);
|
||||||
|
|
||||||
|
_cleanupResources();
|
||||||
|
|
||||||
if (chatRoomAsync.isLoading || chatIdentityAsync.isLoading) {
|
if (chatRoomAsync.isLoading || chatIdentityAsync.isLoading) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -56,7 +75,9 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
|
|
||||||
// Subscribe to messages
|
// Subscribe to messages
|
||||||
final wsState = ref.read(websocketStateProvider.notifier);
|
final wsState = ref.read(websocketStateProvider.notifier);
|
||||||
wsState.sendMessage(
|
_sendMessage = wsState.sendMessage;
|
||||||
|
talker.info('[MessageSubscriber] Subscribing room $roomId');
|
||||||
|
_sendMessage!(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(
|
WebSocketPacket(
|
||||||
type: 'messages.subscribe',
|
type: 'messages.subscribe',
|
||||||
@@ -93,7 +114,7 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
|
|
||||||
// Set up periodic subscribe timer (every 5 minutes)
|
// Set up periodic subscribe timer (every 5 minutes)
|
||||||
_periodicSubscribeTimer = Timer.periodic(const Duration(minutes: 5), (_) {
|
_periodicSubscribeTimer = Timer.periodic(const Duration(minutes: 5), (_) {
|
||||||
wsState.sendMessage(
|
_sendMessage!(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(
|
WebSocketPacket(
|
||||||
type: 'messages.subscribe',
|
type: 'messages.subscribe',
|
||||||
@@ -104,14 +125,13 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen to app lifecycle changes
|
|
||||||
ref.listen(appLifecycleStateProvider, (previous, next) {
|
ref.listen(appLifecycleStateProvider, (previous, next) {
|
||||||
final lifecycleState = next.value;
|
final lifecycleState = next.value;
|
||||||
if (lifecycleState == AppLifecycleState.paused ||
|
if (lifecycleState == AppLifecycleState.paused ||
|
||||||
lifecycleState == AppLifecycleState.inactive) {
|
lifecycleState == AppLifecycleState.inactive) {
|
||||||
// Unsubscribe when app goes to background
|
// Unsubscribe when app goes to background
|
||||||
final wsState = ref.read(websocketStateProvider.notifier);
|
talker.info('[MessageSubscriber] Unsubscribing room $roomId');
|
||||||
wsState.sendMessage(
|
_sendMessage!(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(
|
WebSocketPacket(
|
||||||
type: 'messages.unsubscribe',
|
type: 'messages.unsubscribe',
|
||||||
@@ -122,8 +142,8 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
);
|
);
|
||||||
} else if (lifecycleState == AppLifecycleState.resumed) {
|
} else if (lifecycleState == AppLifecycleState.resumed) {
|
||||||
// Resubscribe when app comes back to foreground
|
// Resubscribe when app comes back to foreground
|
||||||
final wsState = ref.read(websocketStateProvider.notifier);
|
talker.info('[MessageSubscriber] Subscribing room $roomId');
|
||||||
wsState.sendMessage(
|
_sendMessage!(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(
|
WebSocketPacket(
|
||||||
type: 'messages.subscribe',
|
type: 'messages.subscribe',
|
||||||
@@ -135,22 +155,44 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cleanup on dispose
|
final subscribedNotifier = ref.watch(
|
||||||
ref.onDispose(() {
|
currentSubscribedChatIdProvider.notifier,
|
||||||
ref.read(currentSubscribedChatIdProvider.notifier).set(null);
|
);
|
||||||
wsState.sendMessage(
|
|
||||||
jsonEncode(
|
ref.onCancel(() {
|
||||||
WebSocketPacket(
|
talker.info('[MessageSubscriber] Unsubscribing room $roomId');
|
||||||
type: 'messages.unsubscribe',
|
subscribedNotifier.set(null);
|
||||||
data: {'chat_room_id': roomId},
|
try {
|
||||||
endpoint: 'messager',
|
_sendMessage!(
|
||||||
|
jsonEncode(
|
||||||
|
WebSocketPacket(
|
||||||
|
type: 'messages.unsubscribe',
|
||||||
|
data: {'chat_room_id': roomId},
|
||||||
|
endpoint: 'messager',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
} catch (e, stackTrace) {
|
||||||
_wsSubscription?.cancel();
|
talker.error(
|
||||||
_typingCleanupTimer?.cancel();
|
'[MessageSubscriber] Error sending unsubscribe message for room $roomId: $e\n$stackTrace',
|
||||||
_typingCooldownTimer?.cancel();
|
);
|
||||||
_periodicSubscribeTimer?.cancel();
|
}
|
||||||
|
try {
|
||||||
|
_cleanupResources();
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
talker.error(
|
||||||
|
'[MessageSubscriber] Error during cleanup for room $roomId: $e\n$stackTrace',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (_typingCooldownTimer != null) {
|
||||||
|
_typingCooldownTimer!.cancel();
|
||||||
|
}
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
talker.error(
|
||||||
|
'[MessageSubscriber] Error cancelling typing cooldown timer for room $roomId: $e\n$stackTrace',
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return _typingStatuses;
|
return _typingStatuses;
|
||||||
@@ -201,8 +243,8 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
|
|
||||||
void sendReadReceipt() {
|
void sendReadReceipt() {
|
||||||
// Send websocket packet
|
// Send websocket packet
|
||||||
final wsState = ref.read(websocketStateProvider.notifier);
|
if (_sendMessage == null) return;
|
||||||
wsState.sendMessage(
|
_sendMessage!(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(
|
WebSocketPacket(
|
||||||
type: 'messages.read',
|
type: 'messages.read',
|
||||||
@@ -218,8 +260,8 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
|
|||||||
if (_typingCooldownTimer != null) return;
|
if (_typingCooldownTimer != null) return;
|
||||||
|
|
||||||
// Send typing status immediately
|
// Send typing status immediately
|
||||||
final wsState = ref.read(websocketStateProvider.notifier);
|
if (_sendMessage == null) return;
|
||||||
wsState.sendMessage(
|
_sendMessage!(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
WebSocketPacket(
|
WebSocketPacket(
|
||||||
type: 'messages.typing',
|
type: 'messages.typing',
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ final class ChatSubscribeNotifierProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$chatSubscribeNotifierHash() =>
|
String _$chatSubscribeNotifierHash() =>
|
||||||
r'a05739450e6d23eb3d8c0a96078887b2b58ffd10';
|
r'7d720afd7e9f1bc4cc0e4308415e60a4781157db';
|
||||||
|
|
||||||
final class ChatSubscribeNotifierFamily extends $Family
|
final class ChatSubscribeNotifierFamily extends $Family
|
||||||
with
|
with
|
||||||
|
|||||||
Reference in New Issue
Block a user