From e20666160fe9abb89058a3d15576a2145fb1ae48 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 25 May 2025 20:48:47 +0800 Subject: [PATCH] :sparkles: Now the JoinResponse include ChatMember details --- .../Chat/Realtime/LivekitService.cs | 47 +++++++++++++------ .../Chat/RealtimeCallController.cs | 26 +++++++--- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/DysonNetwork.Sphere/Chat/Realtime/LivekitService.cs b/DysonNetwork.Sphere/Chat/Realtime/LivekitService.cs index 63a9399..63a3219 100644 --- a/DysonNetwork.Sphere/Chat/Realtime/LivekitService.cs +++ b/DysonNetwork.Sphere/Chat/Realtime/LivekitService.cs @@ -315,32 +315,49 @@ public class LivekitRealtimeService : IRealtimeService .Where(c => c.SessionId == roomName && c.EndedAt == null) .Select(c => new { c.RoomId, c.Id }) .FirstOrDefaultAsync(); - + if (roomInfo == null) { _logger.LogWarning("Could not find room info for session: {SessionName}", roomName); return; } - + // Get current participants - var participants = await GetRoomParticipantsAsync(roomName); - + var livekitParticipants = await GetRoomParticipantsAsync(roomName); + // Get all room members who should receive this update var roomMembers = await _db.ChatMembers .Where(m => m.ChatRoomId == roomInfo.RoomId && m.LeaveAt == null) .Select(m => m.AccountId) .ToListAsync(); - - // Create the update packet - var participantsDto = participants.Select(p => new + + // Get member profiles for participants who have account IDs + var accountIds = livekitParticipants + .Where(p => p.AccountId.HasValue) + .Select(p => p.AccountId!.Value) + .ToList(); + + var memberProfiles = new Dictionary(); + if (accountIds.Any()) { - p.Identity, - p.Name, - p.AccountId, - State = p.State.ToString(), - p.JoinedAt + memberProfiles = await _db.ChatMembers + .Where(m => m.ChatRoomId == roomInfo.RoomId && accountIds.Contains(m.AccountId)) + .ToDictionaryAsync(m => m.AccountId, m => m); + } + + // Convert to CallParticipant objects + var participants = livekitParticipants.Select(p => new CallParticipant + { + Identity = p.Identity, + Name = p.Name, + AccountId = p.AccountId, + JoinedAt = p.JoinedAt, + Profile = p.AccountId.HasValue && memberProfiles.TryGetValue(p.AccountId.Value, out var profile) + ? profile + : null }).ToList(); - + + // Create the update packet with CallParticipant objects var updatePacket = new WebSocketPacket { Type = WebSocketPacketType.CallParticipantsUpdate, @@ -348,10 +365,10 @@ public class LivekitRealtimeService : IRealtimeService { { "room_id", roomInfo.RoomId }, { "call_id", roomInfo.Id }, - { "participants", participantsDto } + { "participants", participants } } }; - + // Send the update to all members foreach (var accountId in roomMembers) { diff --git a/DysonNetwork.Sphere/Chat/RealtimeCallController.cs b/DysonNetwork.Sphere/Chat/RealtimeCallController.cs index dac62ee..e23c8b9 100644 --- a/DysonNetwork.Sphere/Chat/RealtimeCallController.cs +++ b/DysonNetwork.Sphere/Chat/RealtimeCallController.cs @@ -97,18 +97,32 @@ public class RealtimeCallController( var endpoint = _config.Endpoint ?? throw new InvalidOperationException("LiveKit endpoint configuration is missing"); + // Inject the ChatRoomService + var chatRoomService = HttpContext.RequestServices.GetRequiredService(); + // Get current participants from the LiveKit service var participants = new List(); if (realtime is LivekitRealtimeService livekitService) { var roomParticipants = await livekitService.GetRoomParticipantsAsync(ongoingCall.SessionId); - participants = roomParticipants.Select(p => new CallParticipant + participants = new List(); + + foreach (var p in roomParticipants) { - Identity = p.Identity, - Name = p.Name, - AccountId = p.AccountId, - JoinedAt = p.JoinedAt - }).ToList(); + var participant = new CallParticipant + { + Identity = p.Identity, + Name = p.Name, + AccountId = p.AccountId, + JoinedAt = p.JoinedAt + }; + + // Fetch the ChatMember profile if we have an account ID + if (p.AccountId.HasValue) + participant.Profile = await chatRoomService.GetChannelMember(p.AccountId.Value, roomId); + + participants.Add(participant); + } } // Create the response model