|
|
@@ -38,17 +38,29 @@ export type UserInfo = {
|
|
|
isVideoVisible?: boolean,
|
|
|
isScreenVisible?: boolean,
|
|
|
userRole?: TUIRole,
|
|
|
+ // 是否在麦上
|
|
|
onSeat?: boolean,
|
|
|
isChatMutedByMasterOrAdmin?: boolean,
|
|
|
+ // 是否正在请求用户打开麦克风
|
|
|
isRequestingUserOpenMic?: boolean,
|
|
|
+ // 请求用户打开麦克风的 requestId
|
|
|
requestUserOpenMicRequestId?: string,
|
|
|
+ // 是否正在请求用户打开摄像头
|
|
|
isRequestingUserOpenCamera?: boolean,
|
|
|
+ // 请求用户打开摄像头的 requestId
|
|
|
requestUserOpenCameraRequestId?: string,
|
|
|
+ // 用户是否正在申请上麦
|
|
|
isUserApplyingToAnchor?: boolean,
|
|
|
+ // 用户申请上麦的 requestId
|
|
|
applyToAnchorRequestId?: string,
|
|
|
+ // 用户申请上麦的时间点
|
|
|
applyToAnchorTimestamp?: number,
|
|
|
+ // 是否正在邀请用户上麦
|
|
|
isInvitingUserToAnchor?: boolean,
|
|
|
+ // 邀请用户上麦的 requestId
|
|
|
inviteToAnchorRequestId?: string,
|
|
|
+ // cameraStreamInfo 和 screenStreamInfo 存在的意义时,流渲染保持使用同一个引用传递的数据
|
|
|
+ // 避免出现大窗口和实际数据显示不一致的问题
|
|
|
cameraStreamInfo: StreamInfo,
|
|
|
screenStreamInfo: StreamInfo,
|
|
|
}
|
|
|
@@ -59,6 +71,7 @@ interface RoomState {
|
|
|
userVolumeObj: Record<string, number>,
|
|
|
isDefaultOpenCamera: boolean,
|
|
|
isDefaultOpenMicrophone: boolean,
|
|
|
+ // 主持人全员禁麦,但是单独取消某个用户音视频禁止状态的时候,是可以自己 unmute audio/video 的
|
|
|
canControlSelfAudio: boolean,
|
|
|
canControlSelfVideo: boolean,
|
|
|
localVideoQuality: TUIVideoQuality,
|
|
|
@@ -75,6 +88,8 @@ interface RoomState {
|
|
|
isSeatEnabled: boolean,
|
|
|
seatMode: TUISeatMode,
|
|
|
maxMembersCount: number,
|
|
|
+ maxSeatCount: number,
|
|
|
+ roomName: string,
|
|
|
hasVideoStreamObject: Record<string, UserInfo>,
|
|
|
currentStreamIdListInVisibleView: string[],
|
|
|
hasOtherScreenShare: boolean,
|
|
|
@@ -129,8 +144,11 @@ export const useRoomStore = defineStore('room', {
|
|
|
isMessageDisableForAllUser: false,
|
|
|
isSeatEnabled: false,
|
|
|
seatMode: TUISeatMode.kFreeToTake,
|
|
|
- maxMembersCount: 5,
|
|
|
+ maxMembersCount: 5, // 包含本地流和屏幕分享,超过该数目后续都播放小流
|
|
|
+ maxSeatCount: 20,
|
|
|
+ roomName: '',
|
|
|
hasVideoStreamObject: {},
|
|
|
+ // 可视区域用户流列表
|
|
|
currentStreamIdListInVisibleView: [],
|
|
|
hasOtherScreenShare: false,
|
|
|
isOnStateTabActive: true,
|
|
|
@@ -145,6 +163,7 @@ export const useRoomStore = defineStore('room', {
|
|
|
isGeneralUser(state) {
|
|
|
return state.localUser.userRole === TUIRole.kGeneralUser;
|
|
|
},
|
|
|
+ // 当前用户是否在麦上
|
|
|
isAnchor(state) {
|
|
|
if (this.isFreeSpeakMode) {
|
|
|
return true;
|
|
|
@@ -153,6 +172,7 @@ export const useRoomStore = defineStore('room', {
|
|
|
return state.localUser.onSeat;
|
|
|
}
|
|
|
},
|
|
|
+ // 当前用户是否是在麦下
|
|
|
isAudience(state) {
|
|
|
if (this.isFreeSpeakMode) {
|
|
|
return false;
|
|
|
@@ -168,10 +188,12 @@ export const useRoomStore = defineStore('room', {
|
|
|
return !this.isSeatEnabled;
|
|
|
},
|
|
|
isLocalAudioIconDisable(): boolean {
|
|
|
+ // 全员禁麦状态
|
|
|
const micForbidden = this.isGeneralUser && !this.canControlSelfAudio;
|
|
|
return micForbidden as any || this.isAudience;
|
|
|
},
|
|
|
isLocalVideoIconDisable(): boolean {
|
|
|
+ // 全员禁画状态
|
|
|
const cameraForbidden = this.isGeneralUser && !this.canControlSelfVideo;
|
|
|
return cameraForbidden as any || this.isAudience;
|
|
|
},
|
|
|
@@ -315,6 +337,7 @@ export const useRoomStore = defineStore('room', {
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
+ // 远端用户进入房间(IM事件)
|
|
|
addRemoteUser(userInfo: TUIUserInfo) {
|
|
|
const { userId } = userInfo;
|
|
|
const basicStore = useBasicStore();
|
|
|
@@ -363,6 +386,9 @@ export const useRoomStore = defineStore('room', {
|
|
|
};
|
|
|
});
|
|
|
},
|
|
|
+ // 更新 seatList 的变更
|
|
|
+ // 进入房间后会立即通知 onSeatListChanged, onUserVideoAvailable,onUserAudioAvailable 事件,因此先更新到 userMap 中
|
|
|
+ // 等待 getUserList 获取到全部用户列表后再做更新
|
|
|
updateOnSeatList(seatedList: TUISeatInfo[], leftList: TUISeatInfo[]) {
|
|
|
seatedList.forEach((seat) => {
|
|
|
const { userId } = seat;
|
|
|
@@ -397,6 +423,7 @@ export const useRoomStore = defineStore('room', {
|
|
|
updateUserVideoState(userId: string, streamType: TUIVideoStreamType, hasVideo: boolean) {
|
|
|
const basicStore = useBasicStore();
|
|
|
let user = userId === basicStore.userId ? this.localUser : this.remoteUserObj[userId];
|
|
|
+ // 需要判断 hasVideo 是否为 true,避免视频取消事件在 onRemoteUserLeaveRoom 之后抛出的情况
|
|
|
if (!user && hasVideo) {
|
|
|
user = this.getNewUserInfo(userId);
|
|
|
if (isVue3) {
|
|
|
@@ -438,6 +465,7 @@ export const useRoomStore = defineStore('room', {
|
|
|
updateUserAudioState(userId: string, hasAudio: boolean) {
|
|
|
const basicStore = useBasicStore();
|
|
|
let user = userId === basicStore.userId ? this.localUser : this.remoteUserObj[userId];
|
|
|
+ // 需要判断 hasAudio 是否为 true,避免音频取消事件在 onRemoteUserLeaveRoom 之后抛出的情况
|
|
|
if (!user && hasAudio) {
|
|
|
user = this.getNewUserInfo(userId);
|
|
|
if (isVue3) {
|
|
|
@@ -482,6 +510,7 @@ export const useRoomStore = defineStore('room', {
|
|
|
user.isScreenVisible = true;
|
|
|
}
|
|
|
});
|
|
|
+ // 在新的 streamIdList 里面没有的流, isVideoVisible 要设置为 false
|
|
|
this.currentStreamIdListInVisibleView.forEach((item: string) => {
|
|
|
const userId = item.slice(0, item.length - 2);
|
|
|
const streamType = Number(item.slice(-1)) as TUIVideoStreamType;
|
|
|
@@ -544,7 +573,7 @@ export const useRoomStore = defineStore('room', {
|
|
|
const {
|
|
|
roomOwner, isMicrophoneDisableForAllUser,
|
|
|
isCameraDisableForAllUser, isMessageDisableForAllUser,
|
|
|
- isSeatEnabled, seatMode,
|
|
|
+ isSeatEnabled, seatMode, maxSeatCount, roomName,
|
|
|
} = roomInfo;
|
|
|
if (this.localUser.userId === roomOwner) {
|
|
|
this.localUser.userRole = TUIRole.kRoomOwner;
|
|
|
@@ -558,6 +587,8 @@ export const useRoomStore = defineStore('room', {
|
|
|
this.seatMode = seatMode;
|
|
|
this.canControlSelfAudio = !this.isMicrophoneDisableForAllUser;
|
|
|
this.canControlSelfVideo = !this.isCameraDisableForAllUser;
|
|
|
+ this.maxSeatCount = maxSeatCount;
|
|
|
+ this.roomName = roomName;
|
|
|
},
|
|
|
setDisableMicrophoneForAllUserByAdmin(isDisable: boolean) {
|
|
|
this.isMicrophoneDisableForAllUser = isDisable;
|
|
|
@@ -588,10 +619,12 @@ export const useRoomStore = defineStore('room', {
|
|
|
this.setCurrentSpeakerId(defaultSpeakerId);
|
|
|
roomEngine.instance?.setCurrentSpeakerDevice({ deviceId: defaultSpeakerId });
|
|
|
}
|
|
|
+ // 如果已经开启全员禁言/当前为申请发言模式,则忽略默认打开麦克风的设置
|
|
|
if (this.isMaster || (!this.isMicrophoneDisableForAllUser
|
|
|
&& this.isFreeSpeakMode)) {
|
|
|
typeof isOpenMicrophone === 'boolean' && (this.isDefaultOpenMicrophone = isOpenMicrophone);
|
|
|
}
|
|
|
+ // 如果已经开启全员禁画/当前为申请发言模式,则忽略默认打开摄像头的设置
|
|
|
if (this.isMaster || (!this.isCameraDisableForAllUser
|
|
|
&& this.isFreeSpeakMode)) {
|
|
|
typeof isOpenCamera === 'boolean' && (this.isDefaultOpenCamera = isOpenCamera);
|
|
|
@@ -639,12 +672,15 @@ export const useRoomStore = defineStore('room', {
|
|
|
this.setCurrentSpeakerId(deviceList[0].deviceId);
|
|
|
}
|
|
|
},
|
|
|
+ // 全员禁麦/取消禁麦时设置所有人的禁麦状态
|
|
|
setMicrophoneDisableState(isDisable: boolean) {
|
|
|
this.isMicrophoneDisableForAllUser = isDisable;
|
|
|
},
|
|
|
+ // 全员禁画/取消禁画时设置所有人的禁画状态
|
|
|
setCameraDisableState(isDisable: boolean) {
|
|
|
this.isCameraDisableForAllUser = isDisable;
|
|
|
},
|
|
|
+ // 主持人单个修改用户的发文字消息 mute 状态
|
|
|
setMuteUserChat(userId: string, muted: boolean) {
|
|
|
const remoteUserInfo = this.remoteUserObj[userId];
|
|
|
if (remoteUserInfo) {
|
|
|
@@ -764,6 +800,8 @@ export const useRoomStore = defineStore('room', {
|
|
|
this.hasVideoStreamObject = {};
|
|
|
this.hasOtherScreenShare = false;
|
|
|
this.isOnStateTabActive = true;
|
|
|
+ this.maxSeatCount = 20;
|
|
|
+ this.roomName = '';
|
|
|
},
|
|
|
},
|
|
|
});
|