共享屏幕小弹窗优化

This commit is contained in:
yj 2025-10-15 10:46:57 +08:00
parent 1f0cfc9a70
commit 5a99ec21a0
2 changed files with 120 additions and 42 deletions

View File

@ -105,17 +105,47 @@
top: 0;
z-index: 3000;
.meetingAbsoluteLoading {
background: black;
.meetingAbsoluteVideoView {
position: absolute;
left: 0;
top: 0;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
left: 0;
top: 0;
>div {
height: 160px;
position: relative;
.meetingAbsoluteUser {
position: absolute;
left: 0;
bottom: 0;
font-size: 13px;
color: #EEEEEE;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
background-color: rgba(0, 0, 0, 0.62);
z-index: 1;
padding: 2px 4px;
box-sizing: border-box;
width: 100%;
}
.meetingAbsoluteLoading {
background: black;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
}
}
}
.meetingAbsoluteText {
@ -234,7 +264,6 @@
#videoView {
position: relative;
border: 1px red solid;
}
.standardModeIcon {

View File

@ -1164,13 +1164,25 @@ const Meeting: React.FC = () => {
useEffect(() => {
if (isScreenCapture) {
agora.setupLocalVideo({
uid: Number(user.uid),
view: document.getElementById(`meetingAbsoluteVideo`) as HTMLElement,
channelId: state.channelId,
sourceType: VideoSourceType.VideoSourceCameraPrimary,
type: true
})
roomUserList
.filter((item: any) => item.isRoom && item.isAdmin).forEach(async (item: any) => {
if (user.uid === item.uid) {
await agora.setupLocalVideo({
uid: Number(user.uid),
view: document.getElementById(`meetingAbsoluteVideo`) as HTMLElement,
channelId: state.channelId,
sourceType: VideoSourceType.VideoSourceCameraPrimary,
type: true
})
} else {
await agora.setupRemoteVideoJoin({
uid: Number(item.uid),
view: document.getElementById(`meeting-absolute-video-${item.uid}`),
channelId: state.channelId,
renderMode: RenderModeType.RenderModeHidden,
})
}
});
}
}, [isScreenCapture]);
@ -1283,26 +1295,27 @@ const Meeting: React.FC = () => {
}, [applyUserList]);
useEffect(() => {
const elements = document.querySelectorAll('.intersectionObserver-view');
if (elements.length && currentVideoId) {
elements.forEach(element => {
observer?.unobserve(element);
});
const observerObject = new IntersectionObserver(async (entries: IntersectionObserverEntry[], _observer: IntersectionObserver) => {
setIsScreenCapture((bool: boolean) => {
entries.forEach(async (entry) => {
if (entry.target.id !== user.uid) {
await agora.muteRemoteVideoStreamEx(Number(entry.target.id), bool ? true : !entry.isIntersecting)
const className = isScreenCapture ? '.intersectionAbsoluteObserver-view' : '.intersectionObserver-view';
const rootId = isScreenCapture ? 'meetingAbsoluteVideoView' : 'videoView';
const rootElement = document.getElementById(rootId);
const elements = document.querySelectorAll(className);
elements.forEach(element => {
observer?.unobserve(element);
});
observer?.disconnect();
if (elements.length && currentVideoId && rootElement) {
const observerObject = new IntersectionObserver(
(entries: IntersectionObserverEntry[]) => {
entries.forEach(entry => {
const dataUid = (entry.target as HTMLElement).getAttribute('data-uid');
if (dataUid !== user.uid) {
agora.muteRemoteVideoStreamEx(Number(dataUid), !entry.isIntersecting);
}
});
return bool
})
setIsScreenCapture((bool: boolean) => {
agora.muteRemoteVideoStreamEx(Number(currentVideoId), bool)
return bool
})
}, { threshold: 0, root: document.getElementById('videoView') });
setObserver(observerObject)
},
{ threshold: 0, root: rootElement }
);
setObserver(observerObject);
elements.forEach(element => {
observerObject.observe(element);
});
@ -1334,7 +1347,7 @@ const Meeting: React.FC = () => {
});
observer?.disconnect();
}
}, [roomUserList, currentVideoId, footerList]);
}, [roomUserList, currentVideoId, footerList, isScreenCapture]);
// 声网初始化
const agoraInit = async () => {
@ -1397,6 +1410,17 @@ const Meeting: React.FC = () => {
return res
})
}, 1000);
setIsScreenCapture(bool => {
if (bool) {
agora.setupRemoteVideoJoin({
uid: Number(remoteUid),
view: document.getElementById(`meeting-absolute-video-${remoteUid}`),
channelId: connection.channelId,
renderMode: RenderModeType.RenderModeHidden,
})
}
return bool
})
}
}
},
@ -2140,6 +2164,7 @@ const Meeting: React.FC = () => {
const isOpen = await getKeyOpenChildWindow('shareScreenWindow')
setIsScreenCapture(true)
if (!isOpen) {
setIsExpand(false)
window.electron.createChildWindow('show')
setKeyOpenChildWindow('shareScreenWindow', true)
window.electron.setMainWindowSize({
@ -2206,6 +2231,9 @@ const Meeting: React.FC = () => {
// 停止共享
const stopScreenCapture = async (): Promise<void> => {
await agora.destroyRendererByView(`meetingAbsoluteVideo`)
roomUserList.forEach(async (item: any) => {
await agora.destroyRendererByConfig(Number(item.uid), state.channelId)
});
const footerListTemplate = [...footerList]
await agora.leaveChannelEx(userInfo.screenShareId)
agora.stopScreenCapture()
@ -2699,18 +2727,39 @@ const Meeting: React.FC = () => {
}
setIsNetworkQuality(false)
}}>
{isScreenCapture ? <div className={`${styles.meetingAbsolute}`} id='meetingAbsoluteVideo'>
{isScreenCapture ? <div className={`${styles.meetingAbsolute}`}>
<div style={{ top: '0px' }} className={`${styles.meetingAbsoluteText}`}>{currentSpeakUser.length ? '正在说话:' + currentSpeakUser.join(';') : '正在说话:'}</div>
{footerList[0][1].active ? <div className={styles.meetingAbsoluteLoading}>
<Avatar name={user.userName} />
</div> : null}
<div className={`${styles.meetingAbsoluteVideoView}`} id='meetingAbsoluteVideoView' style={{ overflowY: roomUserList.filter((item: any) => item.isRoom).length > 4 && isExpand ? 'auto' : 'hidden' }}>
<div id='meetingAbsoluteVideo' style={{
margin: !isExpand ? '0' : '0 auto 5px',
width: !isExpand ? '100%' : '96%',
}}>
{footerList[0][1].active ? <div className={styles.meetingAbsoluteLoading}>
<Avatar name={user.userName} />
</div> : null}
{!footerList[0][1].active && isExpand ? <div className={styles.meetingAbsoluteUser}>{user.userName}</div> : null}
</div>
{roomUserList
.filter((item: any) => item.isRoom && item.isAdmin && item.uid !== user.uid)
.map((item: any) => (
<div id={`meeting-absolute-video-${item.uid}`} style={{
margin: !isExpand ? '0' : '0 auto 5px',
width: !isExpand ? '100%' : '96%',
}} data-uid={item.uid} className={`intersectionAbsoluteObserver-view`}>
{item.enableCamera && isExpand ? <div className={styles.meetingAbsoluteUser}>{item.userName}</div> : null}
{item.enableCamera ? null : <div className={styles.meetingAbsoluteLoading}>
<Avatar name={item.userName} />
</div>}
</div>
))}
</div>
<div style={{ bottom: '0px' }} className={`${styles.meetingAbsoluteText} drag`} onClick={() => {
setIsExpand(!isExpand)
window.electron.setChildWindow({
height: isExpand ? 160 : 40,
height: !isExpand ? 4 * 160 + 15 : 160,
key: 'main'
})
}}><span>{isExpand ? '展开' : '收起'}</span></div>
}}><span>{isExpand ? '收起' : '查看参会者'}</span></div>
</div> : null}
{contextMenu ? <div className={styles.meetingContentSwiperCardPopover} style={
{
@ -2919,7 +2968,7 @@ const Meeting: React.FC = () => {
<div className={getMeetingContentBodyLeftModeClass(isAdmin)} id='videoView' style={meetingMode === 'SpeakerMode' && isVideoFullScreen ? { width: '0' } : {}}>
{roomUserList.map((item: any, index: number) => {
return (item.isRoom && item.isAdmin ? <div
id={item.uid}
data-uid={item.uid}
className={`${styles.meetingContentSwiperCard} intersectionObserver-view`}
key={index}
onClick={() => {