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;
 | 
						|
  }
 | 
						|
}
 |