Compare commits
22 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
5db98e2b46 | |
|
|
431bad2b9a | |
|
|
ed33bf6fa6 | |
|
|
c7189dd63e | |
|
|
9e6a862d49 | |
|
|
b6775f8e40 | |
|
|
6cc27d8020 | |
|
|
b45d2fdfa6 | |
|
|
2faafe8647 | |
|
|
26ae33e0aa | |
|
|
76e37eff1d | |
|
|
883525787d | |
|
|
58542e80b3 | |
|
|
c2ce66ed0d | |
|
|
15233cf8de | |
|
|
621ef06aba | |
|
|
2c11b8e726 | |
|
|
3ad59ff992 | |
|
|
60f2311570 | |
|
|
14e90cab7e | |
|
|
9924d7d14e | |
|
|
3a43f75c91 |
|
|
@ -0,0 +1,15 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const indexPath = path.resolve(__dirname, 'dist/index.html');
|
||||||
|
let indexHtml = fs.readFileSync(indexPath, 'utf-8');
|
||||||
|
const timestamp = new Date().getTime();
|
||||||
|
|
||||||
|
// 正则表达式匹配JS文件引用并添加时间戳
|
||||||
|
indexHtml = indexHtml.replace(/<script type="module" crossorigin src="([^"]+)">/g, (match, p1) => {
|
||||||
|
if (p1.endsWith('.js')) {
|
||||||
|
return `<script type="module" crossorigin src="${p1}?t=${timestamp}"></script>`;
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
fs.writeFileSync(indexPath, indexHtml);
|
||||||
|
|
@ -6,6 +6,10 @@
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
|
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
|
||||||
|
<meta name="build-time" content="<%- buildTime%>" id="build-time">
|
||||||
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||||
|
<meta http-equiv="Pragma" content="no-cache">
|
||||||
|
<meta http-equiv="Expires" content="0">
|
||||||
<!-- <meta http-equiv="Content-Security-Policy"
|
<!-- <meta http-equiv="Content-Security-Policy"
|
||||||
content="script-src 'self' https://www.google-analytics.com; style-src 'self' https://animate.style"> -->
|
content="script-src 'self' https://www.google-analytics.com; style-src 'self' https://animate.style"> -->
|
||||||
<title></title>
|
<title></title>
|
||||||
|
|
|
||||||
43
main.js
43
main.js
|
|
@ -24,6 +24,7 @@ const cancellationToken = new CancellationToken()
|
||||||
app.allowRendererProcessReuse = false;
|
app.allowRendererProcessReuse = false;
|
||||||
let mainWindow = null;
|
let mainWindow = null;
|
||||||
let childWindow = {}
|
let childWindow = {}
|
||||||
|
let customizeChildWindow = {}
|
||||||
let isMaximized = false;
|
let isMaximized = false;
|
||||||
let env = 'development'; //development production xy
|
let env = 'development'; //development production xy
|
||||||
let regKey;
|
let regKey;
|
||||||
|
|
@ -624,6 +625,48 @@ app.on('ready', () => {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// 创建自定义子窗口
|
||||||
|
ipcMain.handle('customizeCreateChildWindow', (event, config) => {
|
||||||
|
if (config.open) {
|
||||||
|
customizeChildWindow[config.key].show()
|
||||||
|
customizeChildWindow[config.key].focus()
|
||||||
|
} else {
|
||||||
|
const customizeChild = new BrowserWindow({
|
||||||
|
webPreferences: {
|
||||||
|
contextIsolation: false,
|
||||||
|
nodeIntegration: true,
|
||||||
|
enableRemoteModule: true,
|
||||||
|
nodeIntegrationInWorker: true,
|
||||||
|
allowMediaDevices: true,
|
||||||
|
},
|
||||||
|
frame: true,
|
||||||
|
width: config.width,
|
||||||
|
height: config.height,
|
||||||
|
minWidth: config.width,
|
||||||
|
minHeight: config.height,
|
||||||
|
title: '会议监控',
|
||||||
|
})
|
||||||
|
customizeChildWindow[config.key] = customizeChild;
|
||||||
|
customizeChild.loadURL(config.url)
|
||||||
|
customizeChild.once('ready-to-show', () => {
|
||||||
|
customizeChild.show()
|
||||||
|
customizeChild.setMenuBarVisibility(false)
|
||||||
|
})
|
||||||
|
customizeChild.on('close', () => {
|
||||||
|
customizeChildWindow[config.key] = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 判断自定义窗口是否打开
|
||||||
|
ipcMain.handle('isCustomizeCreateChildOpen', (event, key) => {
|
||||||
|
return customizeChildWindow[key] ? true : false
|
||||||
|
})
|
||||||
|
// 关闭自定义窗口
|
||||||
|
ipcMain.handle('closeCustomizeCreateChildWindow', (event, key) => {
|
||||||
|
if (customizeChildWindow[key]) {
|
||||||
|
customizeChildWindow[key].close()
|
||||||
|
}
|
||||||
|
})
|
||||||
// 创建子窗口
|
// 创建子窗口
|
||||||
ipcMain.handle('createChildWindow', (event, config) => {
|
ipcMain.handle('createChildWindow', (event, config) => {
|
||||||
const child = new BrowserWindow({
|
const child = new BrowserWindow({
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -9,9 +9,9 @@
|
||||||
"dev": "concurrently \"electron .\" \"cross-env BROWSER=none vite\"",
|
"dev": "concurrently \"electron .\" \"cross-env BROWSER=none vite\"",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build:dev": "vite build & electron-builder -w --config=./config/development.json",
|
"build:dev": "vite build & node build.js & electron-builder -w --config=./config/development.json",
|
||||||
"build:prod": "vite build & electron-builder -w --config=./config/production.json",
|
"build:prod": "vite build & node build.js & electron-builder -w --config=./config/production.json",
|
||||||
"build:xy": "vite build & electron-builder -w --config=./config/xy.json"
|
"build:xy": "vite build & node build.js & electron-builder -w --config=./config/xy.json"
|
||||||
},
|
},
|
||||||
"agora_electron": {
|
"agora_electron": {
|
||||||
"platform": "win32",
|
"platform": "win32",
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
"electron-builder": "^23.1.0",
|
"electron-builder": "^23.1.0",
|
||||||
"typescript": "^4.5.4",
|
"typescript": "^4.5.4",
|
||||||
"vite": "^2.8.0",
|
"vite": "^2.8.0",
|
||||||
|
"vite-plugin-html": "^3.2.2",
|
||||||
"vite-plugin-resolve": "^2.5.1"
|
"vite-plugin-resolve": "^2.5.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
12
preload.js
12
preload.js
|
|
@ -123,6 +123,18 @@ window.electron = {
|
||||||
setRegistry: (uuid) => {
|
setRegistry: (uuid) => {
|
||||||
ipcRenderer.invoke('setRegistry', uuid)
|
ipcRenderer.invoke('setRegistry', uuid)
|
||||||
},
|
},
|
||||||
|
// 创建自定义子窗口
|
||||||
|
customizeCreateChildWindow: (config) => {
|
||||||
|
ipcRenderer.invoke('customizeCreateChildWindow', config)
|
||||||
|
},
|
||||||
|
// 判断自定义窗口是否打开
|
||||||
|
isCustomizeCreateChildOpen: (key) => {
|
||||||
|
return ipcRenderer.invoke('isCustomizeCreateChildOpen', key)
|
||||||
|
},
|
||||||
|
// 关闭自定义窗口
|
||||||
|
closeCustomizeCreateChildWindow: (key) => {
|
||||||
|
ipcRenderer.invoke('closeCustomizeCreateChildWindow', key)
|
||||||
|
},
|
||||||
// 创建子窗口
|
// 创建子窗口
|
||||||
createChildWindow: (str) => {
|
createChildWindow: (str) => {
|
||||||
switch (str) {
|
switch (str) {
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 317 B |
|
|
@ -83,11 +83,10 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const getRoomRtcToken = async (roomNum: string, callBack: Function): Promise<void> => {
|
const getRoomRtcToken = async (roomNum: string, callBack: Function): Promise<void> => {
|
||||||
Promise.all([GetRoomRtcToken(roomNum), GetRoomRtcToken(roomNum + 'a')]).then(res => {
|
GetRoomRtcToken(roomNum).then(res => {
|
||||||
if (res[0].code === 200 && res[1].code === 200) {
|
if (res.code === 200) {
|
||||||
callBack({
|
callBack({
|
||||||
token: res[0].data,
|
token: res.data,
|
||||||
tokenA: res[1].data,
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
storage.setItem('loading', false)
|
storage.setItem('loading', false)
|
||||||
|
|
@ -213,7 +212,6 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
||||||
state: {
|
state: {
|
||||||
channelId: roomNumber,
|
channelId: roomNumber,
|
||||||
token: options.token,
|
token: options.token,
|
||||||
tokenA: options.tokenA,
|
|
||||||
roomId: res.data.id,
|
roomId: res.data.id,
|
||||||
roomName: res.data.roomName,
|
roomName: res.data.roomName,
|
||||||
enableMicr: joinRoomSettingForm[0].active,
|
enableMicr: joinRoomSettingForm[0].active,
|
||||||
|
|
|
||||||
|
|
@ -53,14 +53,14 @@ const SpeakerModeModal = forwardRef((props: any, ref: any) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const FreedomMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
const FreedomMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||||
// 自由者模式
|
// 宫格模式
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.freedomMode} onClick={onClick}>
|
<div className={styles.freedomMode} onClick={onClick}>
|
||||||
<div className={`${meetingMode === 'FreedomMode' ? styles.active : ''}`}>
|
<div className={`${meetingMode === 'FreedomMode' ? styles.active : ''}`}>
|
||||||
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].map(item => <div key={item}></div>)}
|
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].map(item => <div key={item}></div>)}
|
||||||
</div>
|
</div>
|
||||||
<span>自由者模式</span>
|
<span>宫格模式</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ const VideoComponents = () => {
|
||||||
}, [darkLightEnhancement]);
|
}, [darkLightEnhancement]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof virtualBackground.sourceIndex === 'number') {
|
if (typeof virtualBackground.sourceIndex === 'number') {
|
||||||
window.electron.getEnv().then(res=>{
|
window.electron.getEnv().then(res => {
|
||||||
if (res === 'development') {
|
if (res === 'development') {
|
||||||
window.electron.getAppPath().then((res: string) => {
|
window.electron.getAppPath().then((res: string) => {
|
||||||
const imagePath = path.join(res, 'src', 'assets', 'virtualBackground', `${virtualBackground.sourceIndex + 1}.png`);
|
const imagePath = path.join(res, 'src', 'assets', 'virtualBackground', `${virtualBackground.sourceIndex + 1}.png`);
|
||||||
|
|
@ -730,7 +730,6 @@ const AudioComponents = () => {
|
||||||
ecordingVolume: e,
|
ecordingVolume: e,
|
||||||
})
|
})
|
||||||
}} disabled={!audioDeviceManager.ecordingItem} />
|
}} disabled={!audioDeviceManager.ecordingItem} />
|
||||||
{/* || audioDeviceManager.autoEcordingVolume */}
|
|
||||||
</div>
|
</div>
|
||||||
{/* <div style={{ marginBottom: '10px' }}>
|
{/* <div style={{ marginBottom: '10px' }}>
|
||||||
<Checkbox onChange={async (e) => {
|
<Checkbox onChange={async (e) => {
|
||||||
|
|
|
||||||
|
|
@ -111,11 +111,10 @@ const Index: React.FC = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const getRoomRtcToken = async (roomNum: string, callBack: Function): Promise<void> => {
|
const getRoomRtcToken = async (roomNum: string, callBack: Function): Promise<void> => {
|
||||||
Promise.all([GetRoomRtcToken(roomNum), GetRoomRtcToken(roomNum + 'a')]).then(res => {
|
GetRoomRtcToken(roomNum).then(res => {
|
||||||
if (res[0].code === 200 && res[1].code === 200) {
|
if (res.code === 200) {
|
||||||
callBack({
|
callBack({
|
||||||
token: res[0].data,
|
token: res.data,
|
||||||
tokenA: res[1].data,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
|
|
@ -334,7 +333,6 @@ const Index: React.FC = () => {
|
||||||
state: {
|
state: {
|
||||||
channelId: item.roomNum,
|
channelId: item.roomNum,
|
||||||
token: options.token,
|
token: options.token,
|
||||||
tokenA: options.tokenA,
|
|
||||||
roomId: item.id,
|
roomId: item.id,
|
||||||
roomName: item.roomName,
|
roomName: item.roomName,
|
||||||
enableMicr: false,
|
enableMicr: false,
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@
|
||||||
|
|
||||||
>div:nth-child(1) {
|
>div:nth-child(1) {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ const Home: React.FC = () => {
|
||||||
]);
|
]);
|
||||||
const [userInfo, setUserInfo] = useState<any>({})
|
const [userInfo, setUserInfo] = useState<any>({})
|
||||||
const [version, setVersion] = useState<string>('')
|
const [version, setVersion] = useState<string>('')
|
||||||
|
const [buildTime, setBuildTime] = useState<string>('0')
|
||||||
const [update, setUpdate] = useState(false)
|
const [update, setUpdate] = useState(false)
|
||||||
const [dateInfo, setDateInfo] = useState<{
|
const [dateInfo, setDateInfo] = useState<{
|
||||||
work: string;
|
work: string;
|
||||||
|
|
@ -60,6 +61,13 @@ const Home: React.FC = () => {
|
||||||
window.electron.getVersion().then(res => {
|
window.electron.getVersion().then(res => {
|
||||||
setVersion(res)
|
setVersion(res)
|
||||||
})
|
})
|
||||||
|
try {
|
||||||
|
const buildStr = document.getElementById('build-time')?.getAttribute('content');
|
||||||
|
const formattedTime = dayjs(Number(buildStr)).format('YYYYMMDDHHmm');
|
||||||
|
setBuildTime(formattedTime)
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
const updateTime = () => {
|
const updateTime = () => {
|
||||||
setDateInfo({
|
setDateInfo({
|
||||||
work: dayjs().format('ddd'),
|
work: dayjs().format('ddd'),
|
||||||
|
|
@ -136,7 +144,9 @@ const Home: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className='drag'>
|
<div className='drag'>
|
||||||
<div>
|
<div>
|
||||||
<span>版本号:{version}</span>
|
<span>V{version}-
|
||||||
|
<span style={{ fontSize: '12px', color: 'gray' }}>{buildTime}</span>
|
||||||
|
</span>
|
||||||
{update ? <span>new</span> : null}
|
{update ? <span>new</span> : null}
|
||||||
</div>
|
</div>
|
||||||
{update ? <div>
|
{update ? <div>
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||||
import { GetCheckoutRoomNum, GetRoomInfo, GetRoomRtcToken } from '@/api/Home/Index';
|
import { GetCheckoutRoomNum, GetRoomInfo, GetRoomRtcToken } from '@/api/Home/Index';
|
||||||
import { ExclamationCircleFilled } from '@ant-design/icons';
|
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||||
import { isVersion } from '@/utils/package/public';
|
import { isVersion } from '@/utils/package/public';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
const Login: React.FC = () => {
|
const Login: React.FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -39,6 +40,7 @@ const Login: React.FC = () => {
|
||||||
nickName: '',
|
nickName: '',
|
||||||
roomNum: '',
|
roomNum: '',
|
||||||
})
|
})
|
||||||
|
const [buildTime, setBuildTime] = useState<string>('0')
|
||||||
const [nameModal, setNameModal] = useState(false)
|
const [nameModal, setNameModal] = useState(false)
|
||||||
const [env, setEnv] = useState('')
|
const [env, setEnv] = useState('')
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -50,6 +52,13 @@ const Login: React.FC = () => {
|
||||||
window.electron.getEnv().then(res => {
|
window.electron.getEnv().then(res => {
|
||||||
setEnv(res)
|
setEnv(res)
|
||||||
})
|
})
|
||||||
|
try {
|
||||||
|
const buildStr = document.getElementById('build-time')?.getAttribute('content');
|
||||||
|
const formattedTime = dayjs(Number(buildStr)).format('YYYYMMDDHHmm');
|
||||||
|
setBuildTime(formattedTime)
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
if (storage.getItem('login')) {
|
if (storage.getItem('login')) {
|
||||||
const login = JSON.parse(storage.getItem('login') as string);
|
const login = JSON.parse(storage.getItem('login') as string);
|
||||||
const data = {
|
const data = {
|
||||||
|
|
@ -319,7 +328,8 @@ const Login: React.FC = () => {
|
||||||
><img src={ImageUrl.icon3} alt="" /></div>
|
><img src={ImageUrl.icon3} alt="" /></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
版本号:{version}
|
V{version}-
|
||||||
|
<span style={{ fontSize: '12px', color: 'gray' }}>{buildTime}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
.meetingContentUserName {
|
.meetingContentUserName {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #0000009E;
|
background-color: rgba(0, 0, 0, 0.62);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
|
|
@ -285,14 +285,126 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 宫格模式
|
||||||
|
// 1
|
||||||
|
.meetingContentBodyLeftFreedomModeOne {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
// 自由者模式
|
.meetingContentSwiperCard {
|
||||||
.meetingContentBodyLeftFreedomMode {
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2
|
||||||
|
.meetingContentBodyLeftFreedomModeTwo {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3 4
|
||||||
|
.meetingContentBodyLeftFreedomModeThree {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
overflow-y: auto;
|
justify-content: center;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//5 6
|
||||||
|
.meetingContentBodyLeftFreedomModeFour {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: calc(100% / 3);
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7
|
||||||
|
.meetingContentBodyLeftFreedomModeFive {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: calc(100% / 4);
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//8 9
|
||||||
|
.meetingContentBodyLeftFreedomModeSix {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: calc(100% / 3);
|
||||||
|
height: calc(100% / 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10 11 12
|
||||||
|
.meetingContentBodyLeftFreedomModeSeven {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: calc(100% / 4);
|
||||||
|
height: calc(100% / 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 13 14 15 16
|
||||||
|
.meetingContentBodyLeftFreedomModeEight {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: calc(100% / 4);
|
||||||
|
height: calc(100% / 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 17 18 19 20
|
||||||
|
.meetingContentBodyLeftFreedomModeNine {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.meetingContentSwiperCard {
|
||||||
|
width: calc(100% / 5);
|
||||||
|
height: calc(100% / 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 标准模式
|
// 标准模式
|
||||||
|
|
@ -309,9 +421,6 @@
|
||||||
|
|
||||||
.meetingContentSwiperCard {
|
.meetingContentSwiperCard {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
|
||||||
|
|
||||||
.meetingContentSwiperCard {
|
|
||||||
height: 160px;
|
height: 160px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -741,38 +850,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.meetingUserVideoList {
|
|
||||||
padding: 10px 10px 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #16191E;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.meetingUserVideoListTitle {
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
|
|
||||||
>span {
|
|
||||||
color: #EEEEEE;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
>img {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.meetingUserVideoListContent {
|
|
||||||
flex-grow: 1;
|
|
||||||
height: 0px;
|
|
||||||
overflow-y: auto;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -920,40 +997,72 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.modePopover {
|
.modePopover {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
>div {
|
>div {
|
||||||
width: 140px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
>span {
|
>div {
|
||||||
color: #EEEEEE;
|
width: 100px;
|
||||||
|
padding: 10px 0;
|
||||||
|
line-height: 30px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20px;
|
||||||
|
|
||||||
|
>span {
|
||||||
|
color: #EEEEEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
>img {
|
||||||
|
height: 30px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
>img {
|
>div {
|
||||||
height: 16px;
|
background-color: #101418;
|
||||||
margin-right: 10px;
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten(#101418, 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: darken(#101418, 4%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
.active {
|
||||||
margin: 0;
|
background-color: lighten(#101418, 8%);
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten(#101418, 8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: lighten(#101418, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:last-child {
|
||||||
|
margin-right: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
>div {
|
>span {
|
||||||
background-color: #101418;
|
margin-top: 4px;
|
||||||
|
color: white;
|
||||||
|
|
||||||
&:hover {
|
>span {
|
||||||
background-color: lighten(#101418, 4%);
|
margin-left: 4px;
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: darken(#101418, 4%);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import Avatar from '@/components/Avatar';
|
||||||
import SharedFilesModel from '@/components/SharedFilesModel';
|
import SharedFilesModel from '@/components/SharedFilesModel';
|
||||||
import StupWizard from '@/components/StupWizard';
|
import StupWizard from '@/components/StupWizard';
|
||||||
import EquipmentManagement from '@/components/EquipmentManagement';
|
import EquipmentManagement from '@/components/EquipmentManagement';
|
||||||
import UserVideo from '@/components/UserVideo';
|
|
||||||
import { role } from '@/config/role';
|
import { role } from '@/config/role';
|
||||||
import { fixWebmDuration } from "webm-duration-fix-buffer";
|
import { fixWebmDuration } from "webm-duration-fix-buffer";
|
||||||
import { getKeyOpenChildWindow, setKeyOpenChildWindow } from '@/utils/package/public';
|
import { getKeyOpenChildWindow, setKeyOpenChildWindow } from '@/utils/package/public';
|
||||||
|
|
@ -47,8 +46,7 @@ const Meeting: React.FC = () => {
|
||||||
const [isClickedMediaSteam, setIsClickedMediaSteam] = useState(false);
|
const [isClickedMediaSteam, setIsClickedMediaSteam] = useState(false);
|
||||||
const [statusList, setStatusList] = useState({
|
const [statusList, setStatusList] = useState({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: false,
|
userChatList: false
|
||||||
userVideo: false,
|
|
||||||
})
|
})
|
||||||
const [isSharedScreenModal, setIsSharedScreenModal] = useState(false);
|
const [isSharedScreenModal, setIsSharedScreenModal] = useState(false);
|
||||||
const [quitMeetingModal, setQuitMeetingModal] = useState(false);
|
const [quitMeetingModal, setQuitMeetingModal] = useState(false);
|
||||||
|
|
@ -171,6 +169,7 @@ const Meeting: React.FC = () => {
|
||||||
const [currentVideoUid, setCurrentVideoUid] = useState('')
|
const [currentVideoUid, setCurrentVideoUid] = useState('')
|
||||||
let [currentSeconds, setCurrentSeconds] = useState(0)
|
let [currentSeconds, setCurrentSeconds] = useState(0)
|
||||||
const [isNetworkQuality, setIsNetworkQuality] = useState(false)
|
const [isNetworkQuality, setIsNetworkQuality] = useState(false)
|
||||||
|
const [userVideoWindow, _setUserVideoWindow] = useState(false)
|
||||||
const [currentEffective, setCurrentEffective] = useState(3)
|
const [currentEffective, setCurrentEffective] = useState(3)
|
||||||
const [networkQuality, setNetworkQuality] = useState({
|
const [networkQuality, setNetworkQuality] = useState({
|
||||||
level: '佳',
|
level: '佳',
|
||||||
|
|
@ -184,7 +183,7 @@ const Meeting: React.FC = () => {
|
||||||
const [isClickLock, setIsClickLock] = useState(false)
|
const [isClickLock, setIsClickLock] = useState(false)
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [modeOpen, setModeOpen] = useState(false)
|
const [modeOpen, setModeOpen] = useState(false)
|
||||||
const [meetingMode, setMeetingMode] = useState('')
|
const [meetingMode, setMeetingMode] = useState('FreedomMode')
|
||||||
const [userSearchValue, setUserSearchValue] = useState('')
|
const [userSearchValue, setUserSearchValue] = useState('')
|
||||||
const [noViewChatList, setNoViewChatList] = useState(0)
|
const [noViewChatList, setNoViewChatList] = useState(0)
|
||||||
const [currentLookUserAccount, setCurrentLookUserAccount] = useState<any>('')
|
const [currentLookUserAccount, setCurrentLookUserAccount] = useState<any>('')
|
||||||
|
|
@ -217,6 +216,7 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const [isVideoFullScreen, setIsVideoFullScreen] = useState<boolean>(false)
|
const [isVideoFullScreen, setIsVideoFullScreen] = useState<boolean>(false)
|
||||||
|
const [_freedomModeStatus, setFreedomModeStatus] = useState<boolean>(false)
|
||||||
const [observer, setObserver] = useState<IntersectionObserver>()
|
const [observer, setObserver] = useState<IntersectionObserver>()
|
||||||
const [_activeSpeaker, setActiveSpeaker] = useState('')
|
const [_activeSpeaker, setActiveSpeaker] = useState('')
|
||||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
|
|
@ -235,7 +235,6 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setKeyOpenChildWindow('shareScreenWindow', false)
|
setKeyOpenChildWindow('shareScreenWindow', false)
|
||||||
setMeetingMode('StandardMode');
|
|
||||||
agoraInit()
|
agoraInit()
|
||||||
storage.setItem('noViewChatList', 0)
|
storage.setItem('noViewChatList', 0)
|
||||||
window.addEventListener('customStorageChange', handleCustomStorageChange);
|
window.addEventListener('customStorageChange', handleCustomStorageChange);
|
||||||
|
|
@ -639,18 +638,36 @@ const Meeting: React.FC = () => {
|
||||||
if (isShare) {
|
if (isShare) {
|
||||||
const item = roomUserList.find((item: any) => item.screenShareId === String(isShare))
|
const item = roomUserList.find((item: any) => item.screenShareId === String(isShare))
|
||||||
setIsShareUser(item || null)
|
setIsShareUser(item || null)
|
||||||
|
setMeetingMode('StandardMode')
|
||||||
}
|
}
|
||||||
}, [isShare, roomUserList]);
|
}, [isShare, roomUserList]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFreedomModeStatus((res: boolean) => {
|
||||||
|
if (meetingMode === 'FreedomMode') {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
if (res) {
|
||||||
|
getShowUser(true)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [meetingMode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
roomUserList.forEach(async (item: any) => {
|
roomUserList.forEach(async (item: any) => {
|
||||||
if (item.uid === currentVideoId) {
|
if (meetingMode === "FreedomMode") {
|
||||||
await agora.setRemoteVideoStreamType(item.uid, VideoStreamType.VideoStreamHigh, true)
|
await agora.setRemoteVideoStreamType(item.uid, VideoStreamType.VideoStreamHigh, true)
|
||||||
} else {
|
} else {
|
||||||
await agora.setRemoteVideoStreamType(item.uid, VideoStreamType.VideoStreamLow, true)
|
if (item.uid === currentVideoId) {
|
||||||
|
await agora.setRemoteVideoStreamType(item.uid, VideoStreamType.VideoStreamHigh, true)
|
||||||
|
} else {
|
||||||
|
await agora.setRemoteVideoStreamType(item.uid, VideoStreamType.VideoStreamLow, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [currentVideoId, roomUserList]);
|
}, [currentVideoId, roomUserList, meetingMode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let item = roomUserList.find((item: any) => currentVideoId == item.uid)
|
let item = roomUserList.find((item: any) => currentVideoId == item.uid)
|
||||||
|
|
@ -723,7 +740,13 @@ const Meeting: React.FC = () => {
|
||||||
break;
|
break;
|
||||||
// 扩展操作
|
// 扩展操作
|
||||||
case 'Operation':
|
case 'Operation':
|
||||||
switch (item.contentString) {
|
try {
|
||||||
|
const temp = JSON.parse(item.contentString)
|
||||||
|
if (temp.type === 'mode') {
|
||||||
|
temp.msg ? message.success(`管理员已将会议室显示模式更新为${getMeetingContentBodyLeftModeText(temp.mode)}`) : null;
|
||||||
|
setMeetingMode(temp.mode)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -739,7 +762,7 @@ const Meeting: React.FC = () => {
|
||||||
break;
|
break;
|
||||||
// 更新视图模式
|
// 更新视图模式
|
||||||
case 'RefreshView':
|
case 'RefreshView':
|
||||||
setMeetingMode(item.type)
|
|
||||||
break;
|
break;
|
||||||
// 全员看他
|
// 全员看他
|
||||||
case 'ShowUser':
|
case 'ShowUser':
|
||||||
|
|
@ -797,7 +820,7 @@ const Meeting: React.FC = () => {
|
||||||
setAllUserListData('ManagerRefresh', item, async () => {
|
setAllUserListData('ManagerRefresh', item, async () => {
|
||||||
if (item.user.uid === item.uid) {
|
if (item.user.uid === item.uid) {
|
||||||
if (item.user.uid === userInfo.uid) {
|
if (item.user.uid === userInfo.uid) {
|
||||||
await agora.allLeaveChannelEx()
|
await agora.allJoinChannelEx(item.user, false)
|
||||||
message.success(`操作成功`)
|
message.success(`操作成功`)
|
||||||
await agora.updateChannelMediaOptions(item.user.isRoomManager)
|
await agora.updateChannelMediaOptions(item.user.isRoomManager)
|
||||||
await postOpenMicrApi(item.user.isRoomManager, userInfo.uid, false)
|
await postOpenMicrApi(item.user.isRoomManager, userInfo.uid, false)
|
||||||
|
|
@ -808,9 +831,7 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (item.user.uid === userInfo.uid) {
|
if (item.user.uid === userInfo.uid) {
|
||||||
if (item.user.isRoomManager) {
|
await agora.allJoinChannelEx(item.user, false)
|
||||||
await agora.allLeaveChannelEx()
|
|
||||||
}
|
|
||||||
message.success(`管理员${item.user.isRoomManager ? '设置' : '取消'}您为发言人`)
|
message.success(`管理员${item.user.isRoomManager ? '设置' : '取消'}您为发言人`)
|
||||||
await agora.updateChannelMediaOptions(item.user.isRoomManager)
|
await agora.updateChannelMediaOptions(item.user.isRoomManager)
|
||||||
setCurrentRequestSpeakType(res => {
|
setCurrentRequestSpeakType(res => {
|
||||||
|
|
@ -846,15 +867,15 @@ const Meeting: React.FC = () => {
|
||||||
case 'Watch':
|
case 'Watch':
|
||||||
if (!role.ID.includes(userInfo.roleId)) {
|
if (!role.ID.includes(userInfo.roleId)) {
|
||||||
let userId = item.watchUids.find((uid: any) => uid === userInfo.uid)
|
let userId = item.watchUids.find((uid: any) => uid === userInfo.uid)
|
||||||
if (userId) {
|
setRoomUserList((res: any) => {
|
||||||
GetRoomRtcToken(state.channelId + 'a').then(async res => {
|
let userRow = res.find((row: any) => row.uid === userId)
|
||||||
if (res.code === 200) {
|
if (userId) {
|
||||||
await agora.allJoinChannelEx(false, res.data)
|
agora.allJoinChannelEx(userRow, true)
|
||||||
}
|
} else {
|
||||||
})
|
agora.allJoinChannelEx(userRow, false)
|
||||||
} else {
|
}
|
||||||
await agora.allLeaveChannelEx()
|
return res
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// 设备列表
|
// 设备列表
|
||||||
|
|
@ -990,7 +1011,7 @@ const Meeting: React.FC = () => {
|
||||||
uid: temp.uid,
|
uid: temp.uid,
|
||||||
enableMicr: temp.enableMicr
|
enableMicr: temp.enableMicr
|
||||||
})
|
})
|
||||||
} else {
|
} else if (temp.type === 'video') {
|
||||||
await PostOpenCamera({
|
await PostOpenCamera({
|
||||||
roomNum: temp.roomNum,
|
roomNum: temp.roomNum,
|
||||||
uid: temp.uid,
|
uid: temp.uid,
|
||||||
|
|
@ -1406,6 +1427,11 @@ const Meeting: React.FC = () => {
|
||||||
const percentage = (item.volume / 255) * 100
|
const percentage = (item.volume / 255) * 100
|
||||||
if (domMe) {
|
if (domMe) {
|
||||||
domMe.style.height = `${percentage}%`
|
domMe.style.height = `${percentage}%`
|
||||||
|
// if (item.volume > 180) {
|
||||||
|
// agora.adjustRecordingSignalVolume(60)
|
||||||
|
// } else {
|
||||||
|
// agora.adjustRecordingSignalVolume(100)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
window.electron.windowHandleMessage({
|
window.electron.windowHandleMessage({
|
||||||
key: 'shareScreenWindow',
|
key: 'shareScreenWindow',
|
||||||
|
|
@ -1581,7 +1607,11 @@ const Meeting: React.FC = () => {
|
||||||
item.isShow = true;
|
item.isShow = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setIsAdmin(res.filter((item: any) => (role.ID.includes(item.roleId) || item.isRoomManager) && item.isRoom).length)
|
const peoPleLength = res.filter((item: any) => (role.ID.includes(item.roleId) || item.isRoomManager) && item.isRoom).length
|
||||||
|
setIsAdmin(peoPleLength)
|
||||||
|
if (peoPleLength > 6) {
|
||||||
|
setMeetingMode('StandardMode')
|
||||||
|
}
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1713,16 +1743,18 @@ const Meeting: React.FC = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 渲染视频
|
// 渲染视频
|
||||||
const renderVideo = async (uid: string = ''): Promise<void> => {
|
const renderVideo = async (uid: string = '', bool: boolean = false): Promise<void> => {
|
||||||
if (isClickLock) {
|
if (!bool) {
|
||||||
return
|
if (isClickLock) {
|
||||||
}
|
|
||||||
if (uid) {
|
|
||||||
if (currentVideoId === uid || currentVideoUid === uid) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
if (uid) {
|
||||||
uid = userInfo.uid
|
if (currentVideoId === uid || currentVideoUid === uid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uid = userInfo.uid
|
||||||
|
}
|
||||||
}
|
}
|
||||||
await agora.destroyRendererByView(`video-source-camera-primary`)
|
await agora.destroyRendererByView(`video-source-camera-primary`)
|
||||||
await agora.destroyRendererByView(`video-source-screen`)
|
await agora.destroyRendererByView(`video-source-screen`)
|
||||||
|
|
@ -1760,11 +1792,11 @@ const Meeting: React.FC = () => {
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
// 全员观看
|
// 全员观看
|
||||||
const getShowUser = async (): Promise<void> => {
|
const getShowUser = async (bool: boolean = false): Promise<void> => {
|
||||||
if (location.href.indexOf('/meeting') !== -1) {
|
if (location.href.indexOf('/meeting') !== -1) {
|
||||||
await GetShowUser(state.channelId).then(async (res) => {
|
await GetShowUser(state.channelId).then(async (res) => {
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
renderVideo(res.data)
|
renderVideo(res.data, bool)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1832,14 +1864,12 @@ const Meeting: React.FC = () => {
|
||||||
setStatusList({
|
setStatusList({
|
||||||
userList: statusList.userList ? false : true,
|
userList: statusList.userList ? false : true,
|
||||||
userChatList: false,
|
userChatList: false,
|
||||||
userVideo: false,
|
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case '聊天':
|
case '聊天':
|
||||||
setStatusList({
|
setStatusList({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: statusList.userChatList ? false : true,
|
userChatList: statusList.userChatList ? false : true,
|
||||||
userVideo: false,
|
|
||||||
})
|
})
|
||||||
storage.setItem('noViewChatList', 0)
|
storage.setItem('noViewChatList', 0)
|
||||||
setNoViewChatList(0)
|
setNoViewChatList(0)
|
||||||
|
|
@ -2012,22 +2042,20 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '会议监控':
|
case '会议监控':
|
||||||
if (!statusList.userVideo) {
|
window.electron.isCustomizeCreateChildOpen('meetingMonitoring').then((req: boolean) => {
|
||||||
GetRoomRtcToken(state.channelId + 'a').then(async res => {
|
window.electron.getWindowSize().then((res: any) => {
|
||||||
if (res.code === 200) {
|
window.electron.customizeCreateChildWindow({
|
||||||
await agora.allJoinChannelEx(true, res.data)
|
url: location.hostname.includes('meeting-api.23544.com') ?
|
||||||
}
|
`http://192.168.2.9:8828?uid=${Number('1' + userInfo.screenShareId)}&channel=${state.channelId}&token=${userInfo.token}` :
|
||||||
|
`http://192.168.2.9:8828?uid=${Number('1' + userInfo.screenShareId)}&channel=${state.channelId}&token=${userInfo.token}`,
|
||||||
|
key: 'meetingMonitoring',
|
||||||
|
title: '会议监控',
|
||||||
|
width: Math.ceil(res.width / 1.5),
|
||||||
|
height: Math.ceil(res.height / 1.3),
|
||||||
|
open: req,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
await agora.allLeaveChannelEx()
|
|
||||||
}
|
|
||||||
setStatusList({
|
|
||||||
userVideo: statusList.userVideo ? false : true,
|
|
||||||
userChatList: false,
|
|
||||||
userList: false,
|
|
||||||
})
|
})
|
||||||
storage.setItem('noViewChatList', 0)
|
|
||||||
setNoViewChatList(0)
|
|
||||||
break;
|
break;
|
||||||
case '签到':
|
case '签到':
|
||||||
singInRef.current.changeModal()
|
singInRef.current.changeModal()
|
||||||
|
|
@ -2144,6 +2172,14 @@ const Meeting: React.FC = () => {
|
||||||
await PostStopSharedScreen(state.channelId)
|
await PostStopSharedScreen(state.channelId)
|
||||||
} else {
|
} else {
|
||||||
await PostShowUser(state.channelId, uid, name)
|
await PostShowUser(state.channelId, uid, name)
|
||||||
|
await window.electron.onInvoke('sendOper', {
|
||||||
|
roomNum: state.channelId,
|
||||||
|
contentString: JSON.stringify({
|
||||||
|
mode: 'StandardMode',
|
||||||
|
type: 'mode',
|
||||||
|
msg: false
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 设置发言人
|
// 设置发言人
|
||||||
|
|
@ -2456,10 +2492,37 @@ const Meeting: React.FC = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 获取当前模式样式
|
// 获取当前模式样式
|
||||||
const getMeetingContentBodyLeftModeClass = (): string => {
|
const getMeetingContentBodyLeftModeClass = (people: Number): string => {
|
||||||
switch (meetingMode) {
|
switch (meetingMode) {
|
||||||
case 'FreedomMode':
|
case 'FreedomMode':
|
||||||
return styles.meetingContentBodyLeftFreedomMode
|
switch (people) {
|
||||||
|
case 1:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeOne;
|
||||||
|
case 2:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeTwo;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeThree;
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeFour;
|
||||||
|
case 7:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeFive;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeSix;
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeSeven;
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
case 16:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeEight;
|
||||||
|
default:
|
||||||
|
return styles.meetingContentBodyLeftFreedomModeNine;
|
||||||
|
}
|
||||||
case 'StandardMode':
|
case 'StandardMode':
|
||||||
return styles.meetingContentBodyLeftStandardMode
|
return styles.meetingContentBodyLeftStandardMode
|
||||||
case 'SpeakerMode':
|
case 'SpeakerMode':
|
||||||
|
|
@ -2474,10 +2537,10 @@ const Meeting: React.FC = () => {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
// 获取当前模式文字
|
// 获取当前模式文字
|
||||||
const getMeetingContentBodyLeftModeText = (): string => {
|
const getMeetingContentBodyLeftModeText = (mode?: string): string => {
|
||||||
switch (meetingMode) {
|
switch (mode || meetingMode) {
|
||||||
case 'FreedomMode':
|
case 'FreedomMode':
|
||||||
return '自由者模式'
|
return '宫格模式'
|
||||||
case 'StandardMode':
|
case 'StandardMode':
|
||||||
return '标准模式'
|
return '标准模式'
|
||||||
case 'SpeakerMode':
|
case 'SpeakerMode':
|
||||||
|
|
@ -2575,6 +2638,31 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
message.success('操作成功')
|
message.success('操作成功')
|
||||||
}
|
}
|
||||||
|
// 设置模式
|
||||||
|
const setSyncView = (mode: string) => {
|
||||||
|
if (meetingMode === mode) {
|
||||||
|
setModeOpen(false)
|
||||||
|
return message.error(`${getMeetingContentBodyLeftModeText(mode)}已开启,请勿重复操作!`)
|
||||||
|
}
|
||||||
|
if (isAdmin > 6 && mode === 'FreedomMode') {
|
||||||
|
setModeOpen(false)
|
||||||
|
return message.error('发言人数超过6人,无法使用宫格模式!')
|
||||||
|
}
|
||||||
|
if (isShare && mode === 'FreedomMode') {
|
||||||
|
setModeOpen(false)
|
||||||
|
return message.error('共享中,无法切换模式')
|
||||||
|
}
|
||||||
|
window.electron.onInvoke('sendOper', {
|
||||||
|
roomNum: state.channelId,
|
||||||
|
contentString: JSON.stringify({
|
||||||
|
mode,
|
||||||
|
type: 'mode',
|
||||||
|
msg: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
setModeOpen(false)
|
||||||
|
storage.setItem('meetingMode', mode)
|
||||||
|
}
|
||||||
// 判断是否出现滚动条
|
// 判断是否出现滚动条
|
||||||
const hasScrollbar = () => {
|
const hasScrollbar = () => {
|
||||||
let element = document.getElementById('videoView') as HTMLDivElement
|
let element = document.getElementById('videoView') as HTMLDivElement
|
||||||
|
|
@ -2604,6 +2692,9 @@ const Meeting: React.FC = () => {
|
||||||
<>
|
<>
|
||||||
<div className={styles.meeting} onClick={() => {
|
<div className={styles.meeting} onClick={() => {
|
||||||
setContextMenu('')
|
setContextMenu('')
|
||||||
|
if (modeOpen) {
|
||||||
|
setModeOpen(false)
|
||||||
|
}
|
||||||
setIsNetworkQuality(false)
|
setIsNetworkQuality(false)
|
||||||
}}>
|
}}>
|
||||||
{isScreenCapture ? <div className={`${styles.meetingAbsolute}`} id='meetingAbsoluteVideo'>
|
{isScreenCapture ? <div className={`${styles.meetingAbsolute}`} id='meetingAbsoluteVideo'>
|
||||||
|
|
@ -2773,28 +2864,33 @@ const Meeting: React.FC = () => {
|
||||||
<span className='drag' style={{ marginTop: '2px', marginLeft: '4px' }}><Code roomNum={state.channelId}></Code></span>
|
<span className='drag' style={{ marginTop: '2px', marginLeft: '4px' }}><Code roomNum={state.channelId}></Code></span>
|
||||||
</div>
|
</div>
|
||||||
<div className='drag'>
|
<div className='drag'>
|
||||||
<Popover
|
{role.ID.includes(userInfo.roleId) ? <Popover
|
||||||
content={
|
content={
|
||||||
<div className='modePopover'>
|
<div className='modePopover'>
|
||||||
<div onClick={() => {
|
<div>
|
||||||
setModeOpen(false)
|
<div className={meetingMode === 'FreedomMode' ? 'active' : ''} onClick={() => {
|
||||||
storage.setItem('meetingMode', 'StandardMode')
|
setSyncView('FreedomMode')
|
||||||
}}>
|
}}>
|
||||||
<img src={ImageUrl.icon43} alt="" />
|
<img src={ImageUrl.icon57} alt="" />
|
||||||
<span>标准模式</span>
|
<span>宫格模式</span>
|
||||||
</div>
|
</div>
|
||||||
<div onClick={() => {
|
<div className={meetingMode === 'StandardMode' ? 'active' : ''} onClick={() => {
|
||||||
setModeOpen(false)
|
setSyncView('StandardMode')
|
||||||
storage.setItem('meetingMode', 'SpeakerMode')
|
}}>
|
||||||
}}>
|
<img src={ImageUrl.icon43} alt="" />
|
||||||
<img src={ImageUrl.icon44} alt="" />
|
<span>标准模式</span>
|
||||||
<span>演讲模式</span>
|
</div>
|
||||||
</div>
|
<div className={meetingMode === 'SpeakerMode' ? 'active' : ''} onClick={() => {
|
||||||
<div onClick={() => {
|
setSyncView('SpeakerMode')
|
||||||
setModeOpen(false)
|
}}>
|
||||||
}}>
|
<img src={ImageUrl.icon44} alt="" />
|
||||||
<span>取消</span>
|
<span>演讲模式</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<span>
|
||||||
|
<ExclamationCircleFilled />
|
||||||
|
<span>改变布局将对所有成员生效</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
title=""
|
title=""
|
||||||
|
|
@ -2803,10 +2899,14 @@ const Meeting: React.FC = () => {
|
||||||
onOpenChange={() => setModeOpen(true)}
|
onOpenChange={() => setModeOpen(true)}
|
||||||
>
|
>
|
||||||
<div className={styles.meetingGrayButton}>
|
<div className={styles.meetingGrayButton}>
|
||||||
{meetingMode === 'StandardMode' ? <img src={ImageUrl.icon43} alt="" /> : <img src={ImageUrl.icon44} alt="" />}
|
{meetingMode === 'StandardMode' ?
|
||||||
|
<img src={ImageUrl.icon43} alt="" /> :
|
||||||
|
meetingMode === 'FreedomMode' ?
|
||||||
|
<img src={ImageUrl.icon57} alt="" /> :
|
||||||
|
<img src={ImageUrl.icon44} alt="" />}
|
||||||
<span>{getMeetingContentBodyLeftModeText()}</span>
|
<span>{getMeetingContentBodyLeftModeText()}</span>
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover> : null}
|
||||||
<Operation></Operation>
|
<Operation></Operation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2814,7 +2914,7 @@ const Meeting: React.FC = () => {
|
||||||
<div className={styles.meetingContentBody}>
|
<div className={styles.meetingContentBody}>
|
||||||
<div className={`${styles.meetingContentBodyLeft} drag`}>
|
<div className={`${styles.meetingContentBodyLeft} drag`}>
|
||||||
{isAdmin && currentLookUserAccount ? getSettingIcon() : null}
|
{isAdmin && currentLookUserAccount ? getSettingIcon() : null}
|
||||||
<div className={getMeetingContentBodyLeftModeClass()} id='videoView' style={meetingMode === 'SpeakerMode' && isVideoFullScreen ? { width: '0' } : {}}>
|
<div className={getMeetingContentBodyLeftModeClass(isAdmin)} id='videoView' style={meetingMode === 'SpeakerMode' && isVideoFullScreen ? { width: '0' } : {}}>
|
||||||
{roomUserList.map((item: any, index: number) => {
|
{roomUserList.map((item: any, index: number) => {
|
||||||
return (item.isRoom && item.isAdmin ? <div
|
return (item.isRoom && item.isAdmin ? <div
|
||||||
id={item.uid}
|
id={item.uid}
|
||||||
|
|
@ -2939,7 +3039,13 @@ const Meeting: React.FC = () => {
|
||||||
</div> : null)
|
</div> : null)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
{hasScrollbar() ? <div>
|
{/* <div className={`${styles.meetingContentSwiperCard}`}>
|
||||||
|
<div className={`${styles.meetingContentSwiperCardVdeio}`}>
|
||||||
|
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
{meetingMode !== "FreedomMode" && hasScrollbar() ? <div>
|
||||||
{meetingMode === "StandardMode" ? <div className={`${styles.meetingContentSwiperCaret}`} style={{ left: '20px', top: '66px' }} onClick={() => {
|
{meetingMode === "StandardMode" ? <div className={`${styles.meetingContentSwiperCaret}`} style={{ left: '20px', top: '66px' }} onClick={() => {
|
||||||
const container = document.getElementById('videoView') as HTMLElement;
|
const container = document.getElementById('videoView') as HTMLElement;
|
||||||
container.scrollLeft -= 100
|
container.scrollLeft -= 100
|
||||||
|
|
@ -2963,7 +3069,7 @@ const Meeting: React.FC = () => {
|
||||||
<CaretDownOutlined />
|
<CaretDownOutlined />
|
||||||
</div>}
|
</div>}
|
||||||
</div> : null}
|
</div> : null}
|
||||||
{currentLookUserStatus === 0 ?
|
{meetingMode !== "FreedomMode" && currentLookUserStatus === 0 ?
|
||||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
||||||
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
|
|
@ -2974,7 +3080,7 @@ const Meeting: React.FC = () => {
|
||||||
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
||||||
{meetingContentUser(currentLookUserAccount, true)}
|
{meetingContentUser(currentLookUserAccount, true)}
|
||||||
</div> : null}
|
</div> : null}
|
||||||
{currentLookUserStatus === 1 ?
|
{meetingMode !== "FreedomMode" && currentLookUserStatus === 1 ?
|
||||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
||||||
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
|
|
@ -2986,7 +3092,7 @@ const Meeting: React.FC = () => {
|
||||||
{meetingContentUser(currentLookUserAccount, true)}
|
{meetingContentUser(currentLookUserAccount, true)}
|
||||||
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentLookUserAccount)}
|
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentLookUserAccount)}
|
||||||
</div> : null}
|
</div> : null}
|
||||||
{currentLookUserStatus === 2 ?
|
{meetingMode !== "FreedomMode" && currentLookUserStatus === 2 ?
|
||||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-screen'>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-screen'>
|
||||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
|
|
@ -2997,7 +3103,7 @@ const Meeting: React.FC = () => {
|
||||||
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
||||||
{meetingContentUser(currentLookUserAccount, true)}
|
{meetingContentUser(currentLookUserAccount, true)}
|
||||||
</div> : null}
|
</div> : null}
|
||||||
{currentLookUserStatus === 3 ?
|
{meetingMode !== "FreedomMode" && currentLookUserStatus === 3 ?
|
||||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-screen'>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-screen'>
|
||||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
|
|
@ -3008,7 +3114,7 @@ const Meeting: React.FC = () => {
|
||||||
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
||||||
{meetingContentUser(currentLookUserAccount, true)}
|
{meetingContentUser(currentLookUserAccount, true)}
|
||||||
</div> : null}
|
</div> : null}
|
||||||
{currentLookUserStatus === 4 ?
|
{meetingMode !== "FreedomMode" && currentLookUserStatus === 4 ?
|
||||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-camera'>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-camera'>
|
||||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
|
|
@ -3026,7 +3132,7 @@ const Meeting: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
(statusList.userList || statusList.userChatList || statusList.userVideo) ? (
|
(statusList.userList || statusList.userChatList) ? (
|
||||||
<div className={`${styles.meetingContentBodyRight} drag`}>
|
<div className={`${styles.meetingContentBodyRight} drag`}>
|
||||||
{statusList.userList ?
|
{statusList.userList ?
|
||||||
<div className={styles.meetingUserList}>
|
<div className={styles.meetingUserList}>
|
||||||
|
|
@ -3036,7 +3142,6 @@ const Meeting: React.FC = () => {
|
||||||
setStatusList({
|
setStatusList({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: false,
|
userChatList: false,
|
||||||
userVideo: false,
|
|
||||||
})
|
})
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3182,7 +3287,6 @@ const Meeting: React.FC = () => {
|
||||||
setStatusList({
|
setStatusList({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: false,
|
userChatList: false,
|
||||||
userVideo: false,
|
|
||||||
})
|
})
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3345,22 +3449,7 @@ const Meeting: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div className={styles.meetingUserVideoList} style={{ width: statusList.userVideo ? '500px' : '500px' }}>
|
null
|
||||||
<div className={styles.meetingUserVideoListTitle}>
|
|
||||||
<span>会议监控</span>
|
|
||||||
<img src={ImageUrl.icon18} alt="" onClick={async () => {
|
|
||||||
await agora.allLeaveChannelEx()
|
|
||||||
setStatusList({
|
|
||||||
userList: false,
|
|
||||||
userChatList: false,
|
|
||||||
userVideo: false,
|
|
||||||
})
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
<div className={styles.meetingUserVideoListContent}>
|
|
||||||
<UserVideo />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
) : null
|
) : null
|
||||||
|
|
@ -3466,7 +3555,7 @@ const Meeting: React.FC = () => {
|
||||||
onMouseUp={() => changeFooterListSelect(row, itemIndex, rowIndex, false)}
|
onMouseUp={() => changeFooterListSelect(row, itemIndex, rowIndex, false)}
|
||||||
onMouseLeave={() => changeFooterListSelect(row, itemIndex, rowIndex, false)}
|
onMouseLeave={() => changeFooterListSelect(row, itemIndex, rowIndex, false)}
|
||||||
key={rowIndex}>
|
key={rowIndex}>
|
||||||
{statusList.userVideo ? <img src={row.iconSelect} alt="" /> : row.select ? <img src={row.iconSelect} alt="" /> : <img src={row.active ? row.iconActive : row.icon} alt="" />}
|
{userVideoWindow ? <img src={row.iconSelect} alt="" /> : row.select ? <img src={row.iconSelect} alt="" /> : <img src={row.active ? row.iconActive : row.icon} alt="" />}
|
||||||
<span>{row.title}</span>
|
<span>{row.title}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ export interface IElectronAPI {
|
||||||
setRegistry: (uuid: string) => any;
|
setRegistry: (uuid: string) => any;
|
||||||
getRegistry: () => any;
|
getRegistry: () => any;
|
||||||
createChildWindow: (str: string) => void;
|
createChildWindow: (str: string) => void;
|
||||||
|
isCustomizeCreateChildOpen: (str: string) => Promise<boolean>;
|
||||||
|
closeCustomizeCreateChildWindow: (str: string) => void;
|
||||||
|
customizeCreateChildWindow: (config: any) => void;
|
||||||
setChildWindow: (config: any) => void;
|
setChildWindow: (config: any) => void;
|
||||||
setChildWindowShow: (config: any) => void;
|
setChildWindowShow: (config: any) => void;
|
||||||
closeChildWindow: (key: string) => void;
|
closeChildWindow: (key: string) => void;
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,7 @@ export const agora = {
|
||||||
})
|
})
|
||||||
agora.stopScreenCapture()
|
agora.stopScreenCapture()
|
||||||
agora.release()
|
agora.release()
|
||||||
|
window.electron.closeCustomizeCreateChildWindow('meetingMonitoring')
|
||||||
},
|
},
|
||||||
// 加入频道
|
// 加入频道
|
||||||
joinChannel: async () => {
|
joinChannel: async () => {
|
||||||
|
|
@ -346,34 +347,20 @@ export const agora = {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// 所有用户加入的第二个房间
|
// 监控
|
||||||
allJoinChannelEx: async (bool: boolean = false, token: string) => {
|
allJoinChannelEx: async (user: any, bool: boolean) => {
|
||||||
const user = await JSON.parse(storage.getItem('user') as string)
|
if (!role.ID.includes(user.roleId) || !user.isRoomManager) {
|
||||||
await agora.startCameraCapture(true)
|
await rtcEngine.updateChannelMediaOptions({
|
||||||
await rtcEngine.joinChannelEx(
|
clientRoleType: bool ? ClientRoleType.ClientRoleBroadcaster : ClientRoleType.ClientRoleAudience, //用户角色 ClientRoleBroadcaster 主播 ClientRoleAudience 观众
|
||||||
token,
|
|
||||||
{ channelId: option.channelId + 'a', localUid: Number('1' + option.screenShareId) },
|
|
||||||
{
|
|
||||||
clientRoleType: bool ? ClientRoleType.ClientRoleAudience : ClientRoleType.ClientRoleBroadcaster, //用户角色 ClientRoleBroadcaster 主播 ClientRoleAudience 观众
|
|
||||||
autoSubscribeAudio: false,//设置是否自动订阅所有音频流
|
autoSubscribeAudio: false,//设置是否自动订阅所有音频流
|
||||||
autoSubscribeVideo: role.ID.includes(user.roleId) ? true : false,//设置是否自动订阅所有视频流
|
autoSubscribeVideo: false,//设置是否自动订阅所有视频流
|
||||||
publishMicrophoneTrack: false,//设置是否发布麦克风采集到的音频
|
publishMicrophoneTrack: false,//设置是否发布麦克风采集到的音频
|
||||||
publishCameraTrack: true,//设置是否发布摄像头采集的视频
|
publishCameraTrack: true,//设置是否发布摄像头采集的视频
|
||||||
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
||||||
audienceLatencyLevel: bool ? AudienceLatencyLevelType.AudienceLatencyLevelLowLatency : AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency,
|
audienceLatencyLevel: bool ? AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency : AudienceLatencyLevelType.AudienceLatencyLevelLowLatency,
|
||||||
}
|
})
|
||||||
);
|
bool ? agora.startCameraCapture() : agora.stopCameraCapture()
|
||||||
await rtcEngine.setDualStreamModeEx(
|
}
|
||||||
SimulcastStreamMode.EnableSimulcastStream,
|
|
||||||
{
|
|
||||||
dimensions: {
|
|
||||||
width: 320,
|
|
||||||
height: 180
|
|
||||||
},
|
|
||||||
framerate: 5,
|
|
||||||
},
|
|
||||||
{ channelId: option.channelId + 'a', localUid: Number('1' + option.screenShareId) }
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
// 退出第二个房间
|
// 退出第二个房间
|
||||||
allLeaveChannelEx: async () => {
|
allLeaveChannelEx: async () => {
|
||||||
|
|
@ -604,4 +591,13 @@ export const agora = {
|
||||||
greenCapacity: 1
|
greenCapacity: 1
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// 调节音频采集信号音量。
|
||||||
|
adjustRecordingSignalVolume: async (number: number) => {
|
||||||
|
const setting = await JSON.parse(storage.getItem('setting') as string)
|
||||||
|
if (setting.autoEcordingVolume) {
|
||||||
|
await rtcEngine.adjustRecordingSignalVolume(number)
|
||||||
|
} else {
|
||||||
|
await rtcEngine.adjustRecordingSignalVolume(100)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -86,6 +86,7 @@ import icon54 from '@/assets/icon54.png'
|
||||||
import icon55 from '@/assets/icon55.png'
|
import icon55 from '@/assets/icon55.png'
|
||||||
import icon56 from '@/assets/icon56.png'
|
import icon56 from '@/assets/icon56.png'
|
||||||
import icon56Active from '@/assets/icon56-active.png'
|
import icon56Active from '@/assets/icon56-active.png'
|
||||||
|
import icon57 from '@/assets/icon57.png'
|
||||||
export default {
|
export default {
|
||||||
loading,
|
loading,
|
||||||
icon,
|
icon,
|
||||||
|
|
@ -174,5 +175,6 @@ export default {
|
||||||
icon54,
|
icon54,
|
||||||
icon55,
|
icon55,
|
||||||
icon56,
|
icon56,
|
||||||
icon56Active
|
icon56Active,
|
||||||
|
icon57,
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ import react from '@vitejs/plugin-react'
|
||||||
import pxtovw from 'postcss-px-to-viewport-8-plugin'
|
import pxtovw from 'postcss-px-to-viewport-8-plugin'
|
||||||
import { resolve as resolvePath } from 'path'
|
import { resolve as resolvePath } from 'path'
|
||||||
import resolve from 'vite-plugin-resolve';
|
import resolve from 'vite-plugin-resolve';
|
||||||
|
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||||
const loder_pxtovw = pxtovw({
|
const loder_pxtovw = pxtovw({
|
||||||
viewportWidth: 1900,
|
viewportWidth: 1900,
|
||||||
viewportUnit: 'vw',
|
viewportUnit: 'vw',
|
||||||
|
|
@ -51,6 +52,20 @@ export default defineConfig({
|
||||||
base: './', // 这里更改打包相对绝对路径
|
base: './', // 这里更改打包相对绝对路径
|
||||||
plugins: [
|
plugins: [
|
||||||
react(),
|
react(),
|
||||||
|
createHtmlPlugin({
|
||||||
|
minify: false,
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
template: 'index.html',
|
||||||
|
filename: 'index.html',
|
||||||
|
injectOptions: {
|
||||||
|
data: {
|
||||||
|
buildTime: +new Date()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}),
|
||||||
resolve({
|
resolve({
|
||||||
'agora-electron-sdk': `
|
'agora-electron-sdk': `
|
||||||
const {
|
const {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue