成员列表
This commit is contained in:
@@ -663,12 +663,13 @@ class UIRenderer {
|
||||
|
||||
const participantsMap = participants || {};
|
||||
const participantCount = Object.keys(participantsMap).length;
|
||||
// Host端使用participants计数,Participant端使用remoteUser状态
|
||||
const isHost = participantCount > 0;
|
||||
const userCount = isHost ? (1 + participantCount) : (remoteUser.status !== 'offline' ? 2 : 1);
|
||||
|
||||
// 通话成员总数 = 本地用户(1) + participants中的条目数
|
||||
// Host端participants只含其他participant;Participant端participants含host+其他participant
|
||||
const userCount = 1 + participantCount;
|
||||
|
||||
// 更新通话成员总数显示
|
||||
const userCountElement = this.elements.userList.closest('div').querySelector('h3.text-sm.font-medium.text-gray-400');
|
||||
const userCountElement = this.elements.userCountDisplay;
|
||||
if (userCountElement) {
|
||||
userCountElement.textContent = `通话成员 (${userCount})`;
|
||||
}
|
||||
@@ -676,20 +677,27 @@ class UIRenderer {
|
||||
// 清空列表并重新渲染
|
||||
this.elements.userList.innerHTML = '';
|
||||
|
||||
// 1. 渲染本地用户(主持人)
|
||||
// 1. 渲染本地用户
|
||||
// 判断当前用户角色:Host端localUser是主持人;Participant端localUser是参与者
|
||||
this.elements.userList.appendChild(this.createLocalUserEntry(localUser));
|
||||
|
||||
// 2. Host端:渲染所有participants;Participant端:渲染单一remoteUser
|
||||
if (isHost) {
|
||||
// 2. 渲染远端成员
|
||||
if (participantCount > 0) {
|
||||
// 有participants数据(Host端或Participant端收到participants-sync后)
|
||||
for (const [pid, p] of Object.entries(participantsMap)) {
|
||||
this.elements.userList.appendChild(this.createParticipantEntry(pid, p));
|
||||
if (p.role === 'host') {
|
||||
this.elements.userList.appendChild(this.createHostEntry(pid, p));
|
||||
} else {
|
||||
this.elements.userList.appendChild(this.createParticipantEntry(pid, p));
|
||||
}
|
||||
}
|
||||
} else if (remoteUser.status !== 'offline') {
|
||||
// 兼容:Participant端未收到participants-sync时,使用remoteUser显示Host
|
||||
this.elements.userList.appendChild(this.createRemoteUserEntry(remoteUser));
|
||||
}
|
||||
}
|
||||
|
||||
// 创建本地用户条目(主持人)
|
||||
// 创建本地用户条目
|
||||
createLocalUserEntry(localUser) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'flex items-center gap-3 p-2 rounded-lg hover:bg-white/5';
|
||||
@@ -701,12 +709,18 @@ class UIRenderer {
|
||||
? '<i class="fas fa-microphone-slash text-gray-500 text-xs"></i>'
|
||||
: '';
|
||||
|
||||
// 根据是否为Host显示不同角色标签
|
||||
const isHost = localUser.isHost;
|
||||
const roleTag = isHost
|
||||
? '<span class="text-xs bg-indigo-500 px-1.5 rounded ml-1">主持人</span>'
|
||||
: '<span class="text-xs bg-purple-500 px-1.5 rounded ml-1">参与者</span>';
|
||||
|
||||
div.innerHTML = `
|
||||
<img src="${localUser.avatar}" class="w-10 h-10 rounded-full object-cover">
|
||||
<div class="flex-1">
|
||||
<div class="text-sm font-medium">
|
||||
${localUser.name}
|
||||
<span class="text-xs bg-indigo-500 px-1.5 rounded ml-1">主持人</span>
|
||||
${roleTag}
|
||||
</div>
|
||||
<div class="${mediaStatusClass}" data-field="localUser.mediaStatus">${mediaStatusText}</div>
|
||||
</div>
|
||||
@@ -715,7 +729,36 @@ class UIRenderer {
|
||||
return div;
|
||||
}
|
||||
|
||||
// 创建远程用户条目(Participant端显示Host用)
|
||||
// 创建Host条目(Participant端显示Host用)
|
||||
createHostEntry(hostId, hostInfo) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'flex items-center gap-3 p-2 rounded-lg bg-white/5';
|
||||
div.dataset.userId = `host_${hostId}`;
|
||||
|
||||
const mediaStatusText = !hostInfo.mediaState.audio ? '静音中' : (!hostInfo.mediaState.video ? '视频关闭' : '在线');
|
||||
const mediaStatusClass = (!hostInfo.mediaState.audio || !hostInfo.mediaState.video) ? 'text-xs text-gray-500' : 'text-xs text-green-400';
|
||||
const muteIconHtml = !hostInfo.mediaState.audio
|
||||
? '<i class="fas fa-microphone-slash text-gray-500 text-xs"></i>'
|
||||
: '';
|
||||
|
||||
div.innerHTML = `
|
||||
<div class="relative">
|
||||
<img src="${hostInfo.avatar}" class="w-10 h-10 rounded-full object-cover">
|
||||
<div class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-slate-900"></div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-sm font-medium">
|
||||
${hostInfo.name}
|
||||
<span class="text-xs bg-indigo-500 px-1.5 rounded ml-1">主持人</span>
|
||||
</div>
|
||||
<div class="${mediaStatusClass}">${mediaStatusText}</div>
|
||||
</div>
|
||||
${muteIconHtml}
|
||||
`;
|
||||
return div;
|
||||
}
|
||||
|
||||
// 创建远程用户条目(兼容回退:Participant端未收到participants-sync时显示Host)
|
||||
createRemoteUserEntry(remoteUser) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'flex items-center gap-3 p-2 rounded-lg bg-white/5';
|
||||
@@ -726,9 +769,6 @@ class UIRenderer {
|
||||
const muteIconHtml = !remoteUser.mediaState.audio
|
||||
? '<i class="fas fa-microphone-slash text-gray-500 text-xs"></i>'
|
||||
: '';
|
||||
const speakingHtml = (remoteUser.mediaState.isSpeaking && remoteUser.mediaState.audio)
|
||||
? '<div class="audio-wave w-6"><span></span><span></span><span></span><span></span><span></span></div>'
|
||||
: '';
|
||||
|
||||
div.innerHTML = `
|
||||
<div class="relative">
|
||||
@@ -736,13 +776,13 @@ class UIRenderer {
|
||||
<div class="absolute -bottom-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-slate-900"></div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-sm font-medium">${remoteUser.name}</div>
|
||||
<div class="text-sm font-medium">
|
||||
${remoteUser.name}
|
||||
<span class="text-xs bg-indigo-500 px-1.5 rounded ml-1">主持人</span>
|
||||
</div>
|
||||
<div class="${mediaStatusClass}">${mediaStatusText}</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
${muteIconHtml}
|
||||
${speakingHtml}
|
||||
</div>
|
||||
${muteIconHtml}
|
||||
`;
|
||||
return div;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user