51 lines
1.6 KiB
Dart
51 lines
1.6 KiB
Dart
import 'dart:async';
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:island/pods/network.dart';
|
|
import 'package:island/pods/websocket.dart';
|
|
import 'package:island/models/account.dart';
|
|
|
|
part 'chat_online_count.g.dart';
|
|
|
|
@riverpod
|
|
class ChatOnlineCountNotifier extends _$ChatOnlineCountNotifier {
|
|
@override
|
|
Future<int> build(String chatroomId) async {
|
|
final apiClient = ref.watch(apiClientProvider);
|
|
final ws = ref.watch(websocketProvider);
|
|
|
|
// Fetch initial online count
|
|
final response = await apiClient.get(
|
|
'/sphere/chat/$chatroomId/members/online',
|
|
);
|
|
final initialCount = response.data as int;
|
|
|
|
// Listen for websocket status updates
|
|
final subscription = ws.dataStream.listen((WebSocketPacket packet) {
|
|
if (packet.type == 'accounts.status.update') {
|
|
final data = packet.data;
|
|
if (data != null && data['chat_room_id'] == chatroomId) {
|
|
final status = SnAccountStatus.fromJson(data['status']);
|
|
var delta = status.isOnline ? 1 : -1;
|
|
if (status.clearedAt != null &&
|
|
status.clearedAt!.isBefore(DateTime.now())) {
|
|
if (status.isInvisible) delta = 1;
|
|
}
|
|
// Update count based on online status
|
|
state.whenData((currentCount) {
|
|
final newCount = currentCount + delta;
|
|
state = AsyncData(
|
|
newCount.clamp(0, double.infinity).toInt(),
|
|
); // Ensure non-negative
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
ref.onDispose(() {
|
|
subscription.cancel();
|
|
});
|
|
|
|
return initialCount;
|
|
}
|
|
}
|