diff --git a/desktop/renderer-app/src/pages/BigClassPage/index.tsx b/desktop/renderer-app/src/pages/BigClassPage/index.tsx index d2ee5348a42..ff0bc333b6b 100644 --- a/desktop/renderer-app/src/pages/BigClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/BigClassPage/index.tsx @@ -330,7 +330,7 @@ export const BigClassPage = observer(function BigClassPage() > } isShow={isRealtimeSideOpen} - isVideoOn={true} + isVideoOn={classRoomStore.isJoinedRTC} videoSlot={
(function OneToOnePage() > } isShow={isRealtimeSideOpen} - isVideoOn={true} + isVideoOn={classRoomStore.isJoinedRTC} videoSlot={
(function SmallClassP className="small-class-realtime-avatars-wrap" style={{ maxWidth: `${whiteboardStore.smallClassAvatarWrapMaxWidth}px` }} > -
- - {classRoomStore.users.joiners.map(renderAvatar)} -
+ {classRoomStore.isJoinedRTC && ( +
+ + {classRoomStore.users.joiners.map(renderAvatar)} +
+ )}
); } diff --git a/desktop/renderer-app/src/stores/class-room-store.ts b/desktop/renderer-app/src/stores/class-room-store.ts index 3954b2410ef..3c13f020c03 100644 --- a/desktop/renderer-app/src/stores/class-room-store.ts +++ b/desktop/renderer-app/src/stores/class-room-store.ts @@ -77,6 +77,7 @@ export class ClassRoomStore { public isRecording = false; /** is RTC on, for UI */ public isCalling = false; + public isJoinedRTC = false; /** is user login on other device */ public isRemoteLogin = false; @@ -308,6 +309,7 @@ export class ClassRoomStore { shareScreenUID: globalStore.rtcShareScreen?.uid || -1, shareScreenToken: globalStore.rtcShareScreen?.token || "", }); + this.updateIsJoinedRTC(true); } catch (e) { console.error(e); this.updateCalling(false); @@ -338,6 +340,7 @@ export class ClassRoomStore { try { this.rtc.leaveRoom(); + this.updateIsJoinedRTC(false); } catch (e) { console.error(e); this.updateCalling(true); @@ -1068,6 +1071,10 @@ export class ClassRoomStore { this.isCalling = isCalling; }); + private updateIsJoinedRTC = action("updateIsJoinedRTC", (isJoinedRTC: boolean): void => { + this.isJoinedRTC = isJoinedRTC; + }); + private updateBanStatus = (isBan: boolean): void => { this.isBan = isBan; }; diff --git a/packages/flat-components/src/components/ClassroomPage/VideoAvatar/index.tsx b/packages/flat-components/src/components/ClassroomPage/VideoAvatar/index.tsx index d2caab88bf5..be93223d7c6 100644 --- a/packages/flat-components/src/components/ClassroomPage/VideoAvatar/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/VideoAvatar/index.tsx @@ -36,6 +36,7 @@ export const VideoAvatar: React.FC = ({ }) => { const isCameraCtrlDisable = avatarUser.userUUID !== userUUID && (!isCreator || !avatarUser.camera); + console.log(avatarUser.userUUID, userUUID, isCreator, avatarUser.camera); const isMicCtrlDisable = avatarUser.userUUID !== userUUID && (!isCreator || !avatarUser.mic); diff --git a/packages/flat-components/src/components/ClassroomPage/VideoAvatar/style.less b/packages/flat-components/src/components/ClassroomPage/VideoAvatar/style.less index 05e623fa04e..564468e90af 100644 --- a/packages/flat-components/src/components/ClassroomPage/VideoAvatar/style.less +++ b/packages/flat-components/src/components/ClassroomPage/VideoAvatar/style.less @@ -4,6 +4,7 @@ position: relative; overflow: hidden; user-select: none; + background: #000; &::after { content: ''; diff --git a/services/rtc/flat-rtc-agora-electron/src/flat-rtc-agora-electron.ts b/services/rtc/flat-rtc-agora-electron/src/flat-rtc-agora-electron.ts index d7bf35f6dc5..574926eb6b2 100644 --- a/services/rtc/flat-rtc-agora-electron/src/flat-rtc-agora-electron.ts +++ b/services/rtc/flat-rtc-agora-electron/src/flat-rtc-agora-electron.ts @@ -239,7 +239,10 @@ export class FlatRTCAgoraElectron extends FlatRTC< this.shareScreen.setParams(null); } - public getAvatar(uid?: FlatRTCAgoraElectronUIDType): FlatRTCAvatar { + public getAvatar(uid?: FlatRTCAgoraElectronUIDType): FlatRTCAvatar | undefined { + if (!this.isJoinedRoom) { + return; + } if (!uid || this.uid === uid) { return this.localAvatar; } diff --git a/services/rtc/flat-rtc-agora-web/src/flat-rtc-agora-web.ts b/services/rtc/flat-rtc-agora-web/src/flat-rtc-agora-web.ts index d5a57421bd3..a71e7dcc45b 100644 --- a/services/rtc/flat-rtc-agora-web/src/flat-rtc-agora-web.ts +++ b/services/rtc/flat-rtc-agora-web/src/flat-rtc-agora-web.ts @@ -178,7 +178,10 @@ export class FlatRTCAgoraWeb extends FlatRTC { this.shareScreen.setParams(null); } - public getAvatar(uid?: FlatRTCAgoraWebUIDType): FlatRTCAvatar { + public getAvatar(uid?: FlatRTCAgoraWebUIDType): FlatRTCAvatar | undefined { + if (!this.isJoinedRoom) { + return; + } if (!uid || this.uid === uid) { return this.localAvatar; } @@ -187,7 +190,8 @@ export class FlatRTCAgoraWeb extends FlatRTC { } let remoteAvatar = this._remoteAvatars.get(uid); if (!remoteAvatar) { - remoteAvatar = new RTCRemoteAvatar(); + const rtcRemoteUser = this.client?.remoteUsers.find(user => user.uid === uid); + remoteAvatar = new RTCRemoteAvatar({ rtcRemoteUser }); this._remoteAvatars.set(uid, remoteAvatar); } return remoteAvatar; @@ -361,16 +365,18 @@ export class FlatRTCAgoraWeb extends FlatRTC { console.error(e); } - const uid = user.uid as FlatRTCAgoraWebUIDType; - if (uid === this.shareScreenUID) { - this.shareScreen.setRemoteUser(null); - return; - } - - const avatar = this._remoteAvatars.get(uid); - if (avatar) { - avatar.destroy(); - this._remoteAvatars.delete(uid); + if (!user.videoTrack && !user.audioTrack) { + const uid = user.uid as FlatRTCAgoraWebUIDType; + if (uid === this.shareScreenUID) { + this.shareScreen.setRemoteUser(null); + return; + } + + const avatar = this._remoteAvatars.get(uid); + if (avatar) { + avatar.destroy(); + this._remoteAvatars.delete(uid); + } } }; client.on("user-unpublished", handler); diff --git a/services/rtc/flat-rtc/src/rtc.ts b/services/rtc/flat-rtc/src/rtc.ts index ffddc1bb6be..3f284751e3c 100644 --- a/services/rtc/flat-rtc/src/rtc.ts +++ b/services/rtc/flat-rtc/src/rtc.ts @@ -34,7 +34,7 @@ export abstract class FlatRTC< public abstract setRole(role: FlatRTCRole): void; /** @returns local avatar if uid is not provided, throws error if uid == shareScreenUID */ - public abstract getAvatar(uid?: TUid): FlatRTCAvatar; + public abstract getAvatar(uid?: TUid): FlatRTCAvatar | undefined; public abstract getVolumeLevel(uid?: TUid): number; public abstract setCameraID(deviceId: string): Promise; diff --git a/web/flat-web/src/components/RTCAvatar/AvatarCanvas.tsx b/web/flat-web/src/components/RTCAvatar/AvatarCanvas.tsx index bba10ee1495..4e6035ceb60 100644 --- a/web/flat-web/src/components/RTCAvatar/AvatarCanvas.tsx +++ b/web/flat-web/src/components/RTCAvatar/AvatarCanvas.tsx @@ -25,8 +25,6 @@ export const AvatarCanvas = observer< const [canvasEl, setCanvasEl] = useState(null); - useEffect(() => () => rtcAvatar?.destroy(), [rtcAvatar]); - const getVolumeLevel = useCallback((): number => { return rtcAvatar?.getVolumeLevel() || 0; }, [rtcAvatar]); diff --git a/web/flat-web/src/pages/BigClassPage/index.tsx b/web/flat-web/src/pages/BigClassPage/index.tsx index 8a31787ab49..25c63f801c9 100644 --- a/web/flat-web/src/pages/BigClassPage/index.tsx +++ b/web/flat-web/src/pages/BigClassPage/index.tsx @@ -276,7 +276,7 @@ export const BigClassPage = observer(function BigClassPage() > } isShow={isRealtimeSideOpen} - isVideoOn={true} + isVideoOn={classRoomStore.isJoinedRTC} videoSlot={
(function OneToOnePage() > } isShow={isRealtimeSideOpen} - isVideoOn={true} + isVideoOn={classRoomStore.isJoinedRTC} videoSlot={
(function SmallClassP className="small-class-realtime-avatars-wrap" style={{ maxWidth: `${whiteboardStore.smallClassAvatarWrapMaxWidth}px` }} > -
- - {classRoomStore.users.joiners.map(renderAvatar)} -
+ {classRoomStore.isJoinedRTC && ( +
+ + {classRoomStore.users.joiners.map(renderAvatar)} +
+ )}
); } diff --git a/web/flat-web/src/stores/class-room-store.ts b/web/flat-web/src/stores/class-room-store.ts index cf0f2020483..ae410544d5f 100644 --- a/web/flat-web/src/stores/class-room-store.ts +++ b/web/flat-web/src/stores/class-room-store.ts @@ -75,8 +75,10 @@ export class ClassRoomStore { public isBan = false; /** is Cloud Recording on */ public isRecording = false; - /** is RTC on */ + /** is RTC UI on */ public isCalling = false; + /** is RTC joined room */ + public isJoinedRTC = false; /** is user login on other device */ public isRemoteLogin = false; @@ -265,6 +267,7 @@ export class ClassRoomStore { shareScreenUID: globalStore.rtcShareScreen?.uid || -1, shareScreenToken: globalStore.rtcShareScreen?.token || "", }); + this.updateIsJoinedRTC(true); } catch (e) { console.error(e); this.updateCalling(false); @@ -281,6 +284,7 @@ export class ClassRoomStore { } this.updateCalling(false); + this.updateIsJoinedRTC(false); }; public toggleCloudStoragePanel = (visible: boolean): void => { @@ -1029,6 +1033,10 @@ export class ClassRoomStore { this.isCalling = isCalling; }); + private updateIsJoinedRTC = action("updateIsJoinedRTC", (isJoinedRTC: boolean): void => { + this.isJoinedRTC = isJoinedRTC; + }); + private updateBanStatus = (isBan: boolean): void => { this.isBan = isBan; };