聊天界面优化

This commit is contained in:
2026-04-25 16:53:50 +08:00
parent 85f80d9f59
commit f6694839f2
2 changed files with 243 additions and 139 deletions

View File

@@ -20,7 +20,8 @@ class CallStateManager {
},
localStream: null, // MediaStream 对象
remoteStream: null, // 单路远端流兼容旧逻辑participant端使用
remoteStreams: {} // 多路远端流 Map: { connectionId: MediaStream }host端使用
remoteStreams: {}, // 多路远端流 Map: { connectionId: MediaStream }host端使用
participants: {} // 多Participant用户信息 Map: { participantId: { id, name, avatar, mediaState, status } }host端使用
};
// 监听器数组
@@ -372,6 +373,21 @@ class CallStateManager {
this.hangUp(); // 房间已关闭,挂断连接
};
// participant加入回调host收到新participant加入房间
this.renderstreaming.onParticipantJoined = (participantId) => {
console.log(`Participant joined: ${participantId}`);
if (!this.state.participants[participantId]) {
this.state.participants[participantId] = {
id: '',
name: '参与者',
avatar: '/images/p2.png',
mediaState: { audio: false, video: false, isSpeaking: false },
status: 'online'
};
}
this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
};
// participant离开回调host收到房间仍然存在
this.renderstreaming.onParticipantLeft = (participantId) => {
console.log(`Participant left: ${participantId}, room still active`);
@@ -387,8 +403,11 @@ class CallStateManager {
this.state.remoteStream.getTracks().forEach(track => track.stop());
this.state.remoteStream = null;
}
// 清理该 participant 的用户信息
delete this.state.participants[participantId];
// 通知UI更新用participantId作为connectionId传给renderer
this.notify({ type: 'PARTICIPANT_LEFT', connectionId: participantId });
this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
};
// 轨道事件回调
@@ -424,6 +443,18 @@ class CallStateManager {
targetStream.addTrack(data.track);
console.log('Added new track:', data.track.kind, 'for participant:', trackParticipantId);
// Host端兜底确保participants中有该participant条目
if (isHost && !this.state.participants[trackParticipantId]) {
this.state.participants[trackParticipantId] = {
id: '',
name: '参与者',
avatar: '/images/p2.png',
mediaState: { audio: false, video: false, isSpeaking: false },
status: 'online'
};
this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
}
// 通知UI远程流已更新
this.notify({
type: 'REMOTE_STREAM_OBTAINED',
@@ -467,32 +498,72 @@ class CallStateManager {
// 处理聊天
// 添加到列表并更新UI
chatMessage.handleChatMessage(data.message);
// 从消息中提取用户信息并更新remoteUser
if (data.message && data.message.senderId !== this.state.session.localUser.id) {
this.state.session.remoteUser = {
...this.state.session.remoteUser,
id: data.message.senderId,
name: data.message.senderName,
avatar: data.message.senderAvatar
};
this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState: this.state.session.remoteUser.mediaState });
// Host端按participantId更新对应用户信息
if (data.participantId && this.role === 'host' && this.state.participants[data.participantId]) {
this.state.participants[data.participantId].id = data.message.senderId;
if (data.message.senderName) {
this.state.participants[data.participantId].name = data.message.senderName;
}
if (data.message.senderAvatar) {
this.state.participants[data.participantId].avatar = data.message.senderAvatar;
}
this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
}
// Participant端从消息中提取Host用户信息并更新remoteUser
if (!this.role || this.role !== 'host') {
if (data.message && data.message.senderId !== this.state.session.localUser.id) {
this.state.session.remoteUser = {
...this.state.session.remoteUser,
id: data.message.senderId,
name: data.message.senderName,
avatar: data.message.senderAvatar
};
this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState: this.state.session.remoteUser.mediaState });
}
}
} else if (data.type === 'media-state-changed') {
// 处理媒体状态变化
console.log('收到媒体状态变化:', data.data, 'from participant:', data.participantId);
// 更新远程用户的媒体状态传递participantId以便精准定位
// Host端同步更新participants中对应participant的mediaState
if (data.participantId && this.role === 'host' && this.state.participants[data.participantId]) {
this.state.participants[data.participantId].mediaState = {
...this.state.participants[data.participantId].mediaState,
...data.data
};
}
// 更新远端媒体状态兼容Participant端
this.updateRemoteMedia(data.data, data.participantId);
// 通知UI更新participants
this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
} else if (data.type === 'user-info') {
// 处理用户信息更新
console.log('收到用户信息:', data.data);
console.log('收到用户信息:', data.data, 'from participant:', data.participantId);
if (data.data) {
this.state.session.remoteUser = {
...this.state.session.remoteUser,
id: data.data.id || this.state.session.remoteUser.id,
name: data.data.name || this.state.session.remoteUser.name,
avatar: data.data.avatar || this.state.session.remoteUser.avatar
};
this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState: this.state.session.remoteUser.mediaState });
if (data.participantId && this.role === 'host') {
// Host端按participantId存储到participants Map
if (!this.state.participants[data.participantId]) {
this.state.participants[data.participantId] = {
id: '',
name: '参与者',
avatar: '/images/p2.png',
mediaState: { audio: false, video: false, isSpeaking: false },
status: 'online'
};
}
this.state.participants[data.participantId].id = data.data.id || '';
this.state.participants[data.participantId].name = data.data.name || '参与者';
this.state.participants[data.participantId].avatar = data.data.avatar || '/images/p2.png';
this.notify({ type: 'PARTICIPANTS_UPDATE', participants: this.state.participants });
} else {
// Participant端更新单一remoteUserHost的信息
this.state.session.remoteUser = {
...this.state.session.remoteUser,
id: data.data.id || this.state.session.remoteUser.id,
name: data.data.name || this.state.session.remoteUser.name,
avatar: data.data.avatar || this.state.session.remoteUser.avatar
};
this.notify({ type: 'REMOTE_MEDIA_CHANGE', mediaState: this.state.session.remoteUser.mediaState });
}
}
}
@@ -552,6 +623,8 @@ class CallStateManager {
// 更新远程用户状态为离线
this.updateRemoteUserStatus('offline');
this.updateRemoteUserNetworkQuality('no_signal');
// 清理participants
this.state.participants = {};
this.connectionId = null;
this.role = null;
this.state.session.status = 'ended';