成员列表
This commit is contained in:
parent
49d73bedce
commit
ad07bd753f
22
main.js
22
main.js
|
|
@ -325,9 +325,18 @@ app.on('ready', () => {
|
||||||
});
|
});
|
||||||
// 关闭子窗口
|
// 关闭子窗口
|
||||||
ipcMain.handle('closeChildWindow', (event, key) => {
|
ipcMain.handle('closeChildWindow', (event, key) => {
|
||||||
childWindow[key].close()
|
if (key === 'shareScreenWindow') {
|
||||||
childWindow[key] = ""
|
for (const k in childWindow) {
|
||||||
mainWindowCenter()
|
if (childWindow[k]){
|
||||||
|
childWindow[k].close()
|
||||||
|
childWindow[k] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainWindowCenter()
|
||||||
|
} else {
|
||||||
|
childWindow[key].close()
|
||||||
|
childWindow[key] = ""
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// 隐藏主窗口
|
// 隐藏主窗口
|
||||||
ipcMain.handle('mainWindowHide', () => {
|
ipcMain.handle('mainWindowHide', () => {
|
||||||
|
|
@ -408,16 +417,13 @@ function quitAndInstall() {
|
||||||
|
|
||||||
function windowOperation(config) {
|
function windowOperation(config) {
|
||||||
const child = childWindow[config.key];
|
const child = childWindow[config.key];
|
||||||
|
child.setResizable(false)
|
||||||
|
if (env === 'development') child.webContents.openDevTools();
|
||||||
if (config.key === 'shareScreenWindow') {
|
if (config.key === 'shareScreenWindow') {
|
||||||
const display = screen.getDisplayMatching({ ...child.getBounds() });
|
const display = screen.getDisplayMatching({ ...child.getBounds() });
|
||||||
const x = Math.round((display.workArea.width - child.getSize()[0]) / 2);
|
const x = Math.round((display.workArea.width - child.getSize()[0]) / 2);
|
||||||
child.setPosition(x, 0);
|
child.setPosition(x, 0);
|
||||||
child.setResizable(false)
|
|
||||||
child.setMovable(false)
|
|
||||||
mainWindowHide()
|
mainWindowHide()
|
||||||
if (env === 'development') {
|
|
||||||
child.webContents.openDevTools()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 主窗口居中
|
// 主窗口居中
|
||||||
|
|
|
||||||
10
src/App.tsx
10
src/App.tsx
|
|
@ -18,7 +18,8 @@ import { agora } from "@/utils/package/agora";
|
||||||
import QuitTips from "@/components/QuitTips";
|
import QuitTips from "@/components/QuitTips";
|
||||||
import { GetLeave } from "@/api/Meeting";
|
import { GetLeave } from "@/api/Meeting";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import ShareScreenWindow from "./page/ShareScreenWindow";
|
import ShareScreenWindow from "@/page/Meeting/ShareScreenWindow";
|
||||||
|
import UserListWindow from "@/page/Meeting/UserListWindow";
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
|
|
@ -33,7 +34,8 @@ const App: React.FC = () => {
|
||||||
});
|
});
|
||||||
const [spinning, setSpinning] = useState(false);
|
const [spinning, setSpinning] = useState(false);
|
||||||
const [isState, setIsState] = useState(true);
|
const [isState, setIsState] = useState(true);
|
||||||
if (location.hash.indexOf('shareScreenWindow') == -1) {
|
const urlHashArr = ['#/userListWindow', '#/shareScreenWindow']
|
||||||
|
if (urlHashArr.indexOf(location.hash) == -1) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
let loginInfo = JSON.parse(storage.getItem('login') as string)
|
let loginInfo = JSON.parse(storage.getItem('login') as string)
|
||||||
|
|
@ -122,6 +124,9 @@ const App: React.FC = () => {
|
||||||
aINoiseReduction: 1, // 降噪模式
|
aINoiseReduction: 1, // 降噪模式
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
if (!storage.getItem('openChildWindow')) {
|
||||||
|
storage.setItem('openChildWindow', JSON.stringify({}))
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isState) {
|
if (isState) {
|
||||||
|
|
@ -243,6 +248,7 @@ const App: React.FC = () => {
|
||||||
<Route path='/login' element={<Login />} />
|
<Route path='/login' element={<Login />} />
|
||||||
<Route path='/meeting' element={<Meeting />} />
|
<Route path='/meeting' element={<Meeting />} />
|
||||||
<Route path='/shareScreenWindow' element={<ShareScreenWindow />} />
|
<Route path='/shareScreenWindow' element={<ShareScreenWindow />} />
|
||||||
|
<Route path='/userListWindow' element={<UserListWindow />} />
|
||||||
<Route path='*' element={<NotFound />} />
|
<Route path='*' element={<NotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
<Spin spinning={spinning} fullscreen />
|
<Spin spinning={spinning} fullscreen />
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import styles from '@/components/EquipmentManagement/index.module.scss'
|
import styles from '@/components/EquipmentManagement/index.module.scss'
|
||||||
|
import { getKeyOpenChildWindow } from '@/utils/package/public';
|
||||||
import { onInvoke } from '@/utils/package/signalr';
|
import { onInvoke } from '@/utils/package/signalr';
|
||||||
import { Button, Modal, Select, Slider, message } from 'antd';
|
import { Button, Modal, Select, Slider, message } from 'antd';
|
||||||
import { useState, useImperativeHandle, forwardRef } from "react";
|
import { useState, useImperativeHandle, forwardRef } from "react";
|
||||||
|
|
@ -21,6 +22,13 @@ const EquipmentManagement = forwardRef((_props: any, ref: any) => {
|
||||||
const [callerUid, setCallerUid] = useState('')
|
const [callerUid, setCallerUid] = useState('')
|
||||||
const [deviceInfo, setDeviceInfo] = useState<any>({})
|
const [deviceInfo, setDeviceInfo] = useState<any>({})
|
||||||
const [userName, setUserName] = useState<any>({})
|
const [userName, setUserName] = useState<any>({})
|
||||||
|
const handleWindowsChange = async (): Promise<void> => {
|
||||||
|
const isOpen = await getKeyOpenChildWindow('shareScreenWindow')
|
||||||
|
if (isOpen) {
|
||||||
|
window.electron.mainWindowHide()
|
||||||
|
}
|
||||||
|
setEquipmentManagementModal(false)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
|
|
@ -30,7 +38,7 @@ const EquipmentManagement = forwardRef((_props: any, ref: any) => {
|
||||||
centered
|
centered
|
||||||
width={'500px'}
|
width={'500px'}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setEquipmentManagementModal(false)
|
handleWindowsChange()
|
||||||
}}>
|
}}>
|
||||||
<div className={styles.equipmentManagement}>
|
<div className={styles.equipmentManagement}>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -87,12 +95,12 @@ const EquipmentManagement = forwardRef((_props: any, ref: any) => {
|
||||||
uid: callerUid,
|
uid: callerUid,
|
||||||
driversJsonString: JSON.stringify(deviceInfo)
|
driversJsonString: JSON.stringify(deviceInfo)
|
||||||
})
|
})
|
||||||
setEquipmentManagementModal(false)
|
handleWindowsChange()
|
||||||
message.success('设置成功')
|
message.success('设置成功')
|
||||||
}}>确定</Button>
|
}}>确定</Button>
|
||||||
<Button type="primary"
|
<Button type="primary"
|
||||||
style={{ backgroundColor: '#31353A', marginLeft: '10px' }}
|
style={{ backgroundColor: '#31353A', marginLeft: '10px' }}
|
||||||
onClick={() => setEquipmentManagementModal(false)}>取消</Button>
|
onClick={() => handleWindowsChange()}>取消</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal >
|
</Modal >
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { agora } from '@/utils/package/agora'
|
||||||
import { CloseOutlined, LoadingOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
import { CloseOutlined, LoadingOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { getKeyOpenChildWindow } from '@/utils/package/public';
|
||||||
|
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
|
|
@ -95,13 +96,13 @@ const StupWizard = forwardRef((props: any, ref: any) => {
|
||||||
top: '16px',
|
top: '16px',
|
||||||
cursor: 'pointer'
|
cursor: 'pointer'
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
if (location.hash.indexOf('/meeting') === -1) {
|
if (location.hash.indexOf('/meeting') === -1) {
|
||||||
agora.release()
|
agora.release()
|
||||||
}
|
}
|
||||||
if (storage.getItem('isOpenChildWindow') === 'true') {
|
const isOpen = await getKeyOpenChildWindow('shareScreenWindow')
|
||||||
|
if (isOpen) {
|
||||||
window.electron.mainWindowHide()
|
window.electron.mainWindowHide()
|
||||||
storage.setItem('isOpenChildWindow', false)
|
|
||||||
}
|
}
|
||||||
setIsStupWizard(false)
|
setIsStupWizard(false)
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import { GetRoomUser, GetRoomUserItem } from '@/api/Meeting';
|
import { GetRoomUser, GetRoomUserItem } from '@/api/Meeting';
|
||||||
import { role } from '@/config/role';
|
import { role } from '@/config/role';
|
||||||
import styles from '@/page/ShareScreenWindow/index.module.scss'
|
import styles from '@/page/Meeting/ShareScreenWindow/index.module.scss'
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
import ImageUrl from '@/utils/package/imageUrl';
|
import ImageUrl from '@/utils/package/imageUrl';
|
||||||
|
import { getKeyOpenChildWindow, setKeyOpenChildWindow } from '@/utils/package/public';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
const ShareScreenWindow: React.FC = () => {
|
const ShareScreenWindow: React.FC = () => {
|
||||||
|
|
@ -54,7 +55,7 @@ const ShareScreenWindow: React.FC = () => {
|
||||||
const [time, setTime] = useState('')
|
const [time, setTime] = useState('')
|
||||||
const [roomUserLists, setRoomUserLists] = useState<any>([])
|
const [roomUserLists, setRoomUserLists] = useState<any>([])
|
||||||
const channel = new BroadcastChannel('meeting_channel');
|
const channel = new BroadcastChannel('meeting_channel');
|
||||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
const userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRoomUser()
|
getRoomUser()
|
||||||
channel.onmessage = function (event) {
|
channel.onmessage = function (event) {
|
||||||
|
|
@ -106,14 +107,14 @@ const ShareScreenWindow: React.FC = () => {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={`${styles.shareScreenWindow} drag`}>
|
<div className={styles.shareScreenWindow}>
|
||||||
<div className={styles.shareScreenWindowTitle}>{time} 共享中</div>
|
<div className={styles.shareScreenWindowTitle}>{time} 共享中</div>
|
||||||
<div className={styles.shareScreenWindowContent}>
|
<div className={`${styles.shareScreenWindowContent} drag`}>
|
||||||
<div className={styles.shareScreenWindowContentList}>
|
<div className={styles.shareScreenWindowContentList}>
|
||||||
{footerLists.map((item: any, index: number) => {
|
{footerLists.map((item: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
switch (item.title) {
|
switch (item.title) {
|
||||||
case '静音':
|
case '静音':
|
||||||
case '解除静音':
|
case '解除静音':
|
||||||
|
|
@ -122,15 +123,27 @@ const ShareScreenWindow: React.FC = () => {
|
||||||
case '录制':
|
case '录制':
|
||||||
case '录制中':
|
case '录制中':
|
||||||
channel.postMessage({
|
channel.postMessage({
|
||||||
type: 'footerListsTitle',
|
type: 'shareScreenWindowfooterListsTitle',
|
||||||
footerListsTitle: item.title
|
shareScreenWindowfooterListsTitle: item.title
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case '设置':
|
case '设置':
|
||||||
channel.postMessage({
|
channel.postMessage({
|
||||||
type: 'setting'
|
type: 'shareScreenWindowSetting'
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case '成员列表':
|
||||||
|
const isOpen = await getKeyOpenChildWindow('userListWindow')
|
||||||
|
if (!isOpen) {
|
||||||
|
window.electron.createChildWindow({
|
||||||
|
url: location.origin + `/#/userListWindow`,
|
||||||
|
width: 340,
|
||||||
|
height: 540,
|
||||||
|
key: 'userListWindow',
|
||||||
|
})
|
||||||
|
setKeyOpenChildWindow('userListWindow', true)
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
key={index}>
|
key={index}>
|
||||||
|
|
@ -142,13 +155,13 @@ const ShareScreenWindow: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
<Button type="primary" style={{ backgroundColor: '#FF5219', marginRight: '14px' }} onClick={() => {
|
<Button type="primary" style={{ backgroundColor: '#FF5219', marginRight: '14px' }} onClick={() => {
|
||||||
channel.postMessage({
|
channel.postMessage({
|
||||||
type: 'closeShareScreen'
|
type: 'shareScreenWindowClose'
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
结束共享
|
结束共享
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div >
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
.userListWindow {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #16191E;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 10px 0;
|
||||||
|
|
||||||
|
>div {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.userListWindowTitle {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
>span {
|
||||||
|
color: #EEEEEE;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
>img {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.userListWindowContent {
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 0px;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
>div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 4px 10px;
|
||||||
|
|
||||||
|
>div:nth-child(1) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
>span {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #F3F3F5;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
>div {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
>div:nth-child(2) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
>div {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
>img {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgb(52, 52, 52);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.userListWindowFooter {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
>div {
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #31353A;
|
||||||
|
color: #EEEEEE;
|
||||||
|
width: 104px;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten(#31353A, 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: darken(#31353A, 4%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
import { role } from '@/config/role';
|
||||||
|
import styles from '@/page/Meeting/UserListWindow/index.module.scss'
|
||||||
|
import ImageUrl from '@/utils/package/imageUrl';
|
||||||
|
import { EllipsisOutlined, ExclamationCircleFilled, SearchOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Input, Modal, Popover } from 'antd';
|
||||||
|
import Avatar from '@/components/Avatar';
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { storage } from '@/utils';
|
||||||
|
import { GetRoomUser } from '@/api/Meeting';
|
||||||
|
import { setKeyOpenChildWindow } from '@/utils/package/public';
|
||||||
|
const { confirm } = Modal;
|
||||||
|
|
||||||
|
const UserListWindow: React.FC = () => {
|
||||||
|
const [userSearchValue, setUserSearchValue] = useState('')
|
||||||
|
const [user, setUser] = useState<any>({});
|
||||||
|
const [roomUserList, setRoomUserList] = useState<any>([])
|
||||||
|
const channel = new BroadcastChannel('meeting_channel');
|
||||||
|
const userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
|
useEffect(() => {
|
||||||
|
setUser(userInfo)
|
||||||
|
getRoomUser()
|
||||||
|
channel.onmessage = function (event) {
|
||||||
|
const { type, roomUserList } = event.data;
|
||||||
|
switch (type) {
|
||||||
|
case 'roomUserList':
|
||||||
|
setRoomUserList(roomUserList)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
// 获取房间用户
|
||||||
|
const getRoomUser = async (): Promise<void> => {
|
||||||
|
const data = JSON.parse(storage.getItem('stateInfo') as string)
|
||||||
|
GetRoomUser(data.channelId).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
res.data.forEach((item: any) => {
|
||||||
|
item.isShow = true;
|
||||||
|
item.isRoom = true;
|
||||||
|
item.isAdmin = role.ID.includes(item.roleId) || item.isRoomManager
|
||||||
|
})
|
||||||
|
setRoomUserList(res.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={`${styles.userListWindow}`}>
|
||||||
|
<div className={styles.userListWindowTitle}>
|
||||||
|
<span>成员列表</span>
|
||||||
|
<img src={ImageUrl.icon18} className='drag' alt="" onClick={() => {
|
||||||
|
window.electron.closeChildWindow('userListWindow')
|
||||||
|
setKeyOpenChildWindow('userListWindow', false)
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
<div className='drag' style={{ padding: '0 10px' }}>
|
||||||
|
<Input
|
||||||
|
placeholder="请输入用户名"
|
||||||
|
prefix={<SearchOutlined style={{ color: 'white' }} />}
|
||||||
|
value={userSearchValue}
|
||||||
|
onChange={(e) => {
|
||||||
|
setUserSearchValue(e.target.value)
|
||||||
|
const newRoomUserList = [...roomUserList]
|
||||||
|
newRoomUserList.forEach(row => {
|
||||||
|
if (e.target.value) {
|
||||||
|
if (row.userName.indexOf(e.target.value) !== -1) {
|
||||||
|
row.isShow = true;
|
||||||
|
} else {
|
||||||
|
row.isShow = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
row.isShow = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setRoomUserList(newRoomUserList)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={`${styles.userListWindowContent} drag`}>
|
||||||
|
{roomUserList.map((item: any, index: number) => {
|
||||||
|
return (
|
||||||
|
item.isShow && item.isRoom ? <div key={index + item.uid}>
|
||||||
|
<div>
|
||||||
|
<div><Avatar name={item.userName} /></div>
|
||||||
|
<span>
|
||||||
|
{item.userName}{item.uid === user.uid ? '(我)' : ''}
|
||||||
|
{role.ID.includes(item.roleId) || item.isRoomManager ?
|
||||||
|
<span style={{ color: '#02B188', marginLeft: '4px' }}>
|
||||||
|
{role.ID.includes(item.roleId) ? '管理员' : '发言人'}
|
||||||
|
</span>
|
||||||
|
: null}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{role.ID.includes(item.roleId) || item.isRoomManager ? <div>
|
||||||
|
<img src={item.enableMicr ? ImageUrl.icon22 : ImageUrl.icon22Active} alt="" onClick={() => {
|
||||||
|
channel.postMessage({
|
||||||
|
type: 'userListWindowPostOpenMicr',
|
||||||
|
userListWindowPostOpenMicr: {
|
||||||
|
enableMicr: !item.enableMicr,
|
||||||
|
uid: item.uid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}} title={item.enableMicr ? '静音' : '解除声音'} />
|
||||||
|
</div> : null}
|
||||||
|
{role.ID.includes(item.roleId) || item.isRoomManager ? <div>
|
||||||
|
<img src={item.enableCamera ? ImageUrl.icon23 : ImageUrl.icon23Active} alt="" onClick={() => {
|
||||||
|
channel.postMessage({
|
||||||
|
type: 'userListWindowPostOpenCamera',
|
||||||
|
userListWindowPostOpenCamera: {
|
||||||
|
enableCamera: !item.enableCamera,
|
||||||
|
uid: item.uid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}} title={item.enableCamera ? '关闭视频' : '开启视频'} />
|
||||||
|
</div> : null}
|
||||||
|
{item.uid !== user.uid && role.ID.includes(user.roleId) ? <div>
|
||||||
|
<Popover placement="left" title={''} content={
|
||||||
|
<div style={{ width: '100px' }}>
|
||||||
|
{!role.ID.includes(item.roleId) ? <Button
|
||||||
|
type="primary"
|
||||||
|
className='m-ant-btn'
|
||||||
|
style={{ marginBottom: '10px', width: '100%' }}
|
||||||
|
size={'small'}
|
||||||
|
onClick={() => {
|
||||||
|
if (item.isRoomManager) {
|
||||||
|
channel.postMessage({
|
||||||
|
type: 'userListWindowDeleteRoomManager',
|
||||||
|
userListWindowDeleteRoomManager: {
|
||||||
|
uid: item.uid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
channel.postMessage({
|
||||||
|
type: 'userListWindowPostRoomManager',
|
||||||
|
userListWindowPostRoomManager: {
|
||||||
|
uid: item.uid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>{item.isRoomManager ? '取消发言人' : '设为发言人'}</Button> : null}
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
className='m-ant-btn'
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
size={'small'}
|
||||||
|
onClick={() => {
|
||||||
|
channel.postMessage({
|
||||||
|
type: 'shareScreenWindowEquipmentManagement',
|
||||||
|
shareScreenWindowEquipmentManagement: {
|
||||||
|
uid: item.uid,
|
||||||
|
userName: item.userName,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
window.electron.closeChildWindow('userListWindow')
|
||||||
|
setKeyOpenChildWindow('userListWindow', false)
|
||||||
|
}}
|
||||||
|
>设备管理</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
style={{ backgroundColor: '#EC3C3C', width: '100%', marginTop: '10px' }}
|
||||||
|
size={'small'}
|
||||||
|
onClick={() => {
|
||||||
|
confirm({
|
||||||
|
title: '移出会议',
|
||||||
|
icon: <ExclamationCircleFilled />,
|
||||||
|
content: `确定将用户${item.userName}移出会议?`,
|
||||||
|
centered: true,
|
||||||
|
okText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
async onOk() {
|
||||||
|
channel.postMessage({
|
||||||
|
type: 'userListWindowGetRoomKickout',
|
||||||
|
userListWindowGetRoomKickout: {
|
||||||
|
uid: item.uid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>移出会议</Button>
|
||||||
|
</div>
|
||||||
|
}>
|
||||||
|
<EllipsisOutlined style={{
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: '20px'
|
||||||
|
}} />
|
||||||
|
</Popover>
|
||||||
|
</div> : null}
|
||||||
|
</div>
|
||||||
|
</div> : null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className={`${styles.userListWindowFooter}`}>
|
||||||
|
<div className='drag' onClick={() => {
|
||||||
|
channel.postMessage({
|
||||||
|
type: 'userListWindowAllPostOpenMicr'
|
||||||
|
});
|
||||||
|
}}>全员静音</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserListWindow
|
||||||
|
|
@ -22,6 +22,7 @@ import EquipmentManagement from '@/components/EquipmentManagement';
|
||||||
import UserVideo from '@/components/UserVideo';
|
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';
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
|
|
@ -201,38 +202,77 @@ const Meeting: React.FC = () => {
|
||||||
const container = document.getElementById('videoView') as HTMLElement;
|
const container = document.getElementById('videoView') as HTMLElement;
|
||||||
container.addEventListener('wheel', handleWheelChange);
|
container.addEventListener('wheel', handleWheelChange);
|
||||||
channel.onmessage = async function (event) {
|
channel.onmessage = async function (event) {
|
||||||
const { type, footerListsTitle } = event.data;
|
const {
|
||||||
|
type,
|
||||||
|
shareScreenWindowfooterListsTitle,
|
||||||
|
userListWindowPostOpenMicr,
|
||||||
|
userListWindowPostOpenCamera,
|
||||||
|
userListWindowDeleteRoomManager,
|
||||||
|
userListWindowPostRoomManager,
|
||||||
|
userListWindowGetRoomKickout,
|
||||||
|
shareScreenWindowEquipmentManagement
|
||||||
|
} = event.data;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'closeShareScreen':
|
case 'shareScreenWindowClose':
|
||||||
await stopScreenCapture()
|
await stopScreenCapture()
|
||||||
await allUserLook(userInfo.uid, userInfo.userName)
|
await allUserLook(userInfo.uid, userInfo.userName)
|
||||||
break;
|
break;
|
||||||
case 'setting':
|
case 'shareScreenWindowSetting':
|
||||||
stupWizardRef.current.changeModal(3);
|
stupWizardRef.current.changeModal(3);
|
||||||
window.electron.mainWindowCenter()
|
window.electron.mainWindowCenter()
|
||||||
break;
|
break;
|
||||||
case 'footerListsTitle':
|
case 'shareScreenWindowfooterListsTitle':
|
||||||
switch (footerListsTitle) {
|
switch (shareScreenWindowfooterListsTitle) {
|
||||||
case '静音':
|
case '静音':
|
||||||
case '解除静音':
|
case '解除静音':
|
||||||
changeStatusList({
|
changeStatusList({
|
||||||
title: footerListsTitle
|
title: shareScreenWindowfooterListsTitle
|
||||||
}, 0, 1)
|
}, 0, 1)
|
||||||
break;
|
break;
|
||||||
case '关闭视频':
|
case '关闭视频':
|
||||||
case '开启视频':
|
case '开启视频':
|
||||||
changeStatusList({
|
changeStatusList({
|
||||||
title: footerListsTitle
|
title: shareScreenWindowfooterListsTitle
|
||||||
}, 0, 2)
|
}, 0, 2)
|
||||||
break;
|
break;
|
||||||
case '录制':
|
case '录制':
|
||||||
case '录制中':
|
case '录制中':
|
||||||
changeStatusList({
|
changeStatusList({
|
||||||
title: footerListsTitle
|
title: shareScreenWindowfooterListsTitle
|
||||||
}, 1, 3)
|
}, 1, 3)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'userListWindowPostOpenMicr':
|
||||||
|
postOpenMicr(userListWindowPostOpenMicr.enableMicr, userListWindowPostOpenMicr.uid)
|
||||||
|
break;
|
||||||
|
case 'userListWindowPostOpenCamera':
|
||||||
|
postOpenCamera(userListWindowPostOpenCamera.enableCamera, userListWindowPostOpenCamera.uid)
|
||||||
|
break;
|
||||||
|
case 'userListWindowDeleteRoomManager':
|
||||||
|
DeleteRoomManager({
|
||||||
|
roomId: state.roomId,
|
||||||
|
roomNum: state.channelId,
|
||||||
|
userId: userListWindowDeleteRoomManager.uid
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'userListWindowPostRoomManager':
|
||||||
|
postRoomManager({
|
||||||
|
roomId: state.roomId,
|
||||||
|
roomNum: state.channelId,
|
||||||
|
userId: userListWindowPostRoomManager.uid
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'userListWindowGetRoomKickout':
|
||||||
|
GetRoomKickout(state.channelId, userListWindowGetRoomKickout.uid)
|
||||||
|
break;
|
||||||
|
case 'userListWindowAllPostOpenMicr':
|
||||||
|
postOpenMicr(false, userInfo.id, true)
|
||||||
|
break;
|
||||||
|
case 'shareScreenWindowEquipmentManagement':
|
||||||
|
equipmentManagement(shareScreenWindowEquipmentManagement.uid, shareScreenWindowEquipmentManagement.userName)
|
||||||
|
window.electron.mainWindowCenter()
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time = setInterval(() => {
|
time = setInterval(() => {
|
||||||
|
|
@ -1307,13 +1347,16 @@ const Meeting: React.FC = () => {
|
||||||
setIsSharedScreenModal(false)
|
setIsSharedScreenModal(false)
|
||||||
await agora.setDesktopCapturerVideo(sharedScreenItem, isComputerAudio, isFluencyPriority)
|
await agora.setDesktopCapturerVideo(sharedScreenItem, isComputerAudio, isFluencyPriority)
|
||||||
await allUserLook(user.screenShareId, user.userName)
|
await allUserLook(user.screenShareId, user.userName)
|
||||||
// window.electron.createChildWindow({
|
const isOpen = await getKeyOpenChildWindow('shareScreenWindow')
|
||||||
// url: location.origin + `/#/shareScreenWindow`,
|
if (!isOpen) {
|
||||||
// width: 540,
|
window.electron.createChildWindow({
|
||||||
// height: 70,
|
url: location.origin + `/#/shareScreenWindow`,
|
||||||
// key: 'shareScreenWindow',
|
width: 540,
|
||||||
// })
|
height: 70,
|
||||||
// storage.setItem('isOpenChildWindow', true)
|
key: 'shareScreenWindow',
|
||||||
|
})
|
||||||
|
setKeyOpenChildWindow('shareScreenWindow', true)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
message.error('请选择应用!')
|
message.error('请选择应用!')
|
||||||
}
|
}
|
||||||
|
|
@ -1357,6 +1400,7 @@ const Meeting: React.FC = () => {
|
||||||
footerListTemplate[1][0].title = '共享屏幕'
|
footerListTemplate[1][0].title = '共享屏幕'
|
||||||
setFooterList(footerListTemplate)
|
setFooterList(footerListTemplate)
|
||||||
window.electron.closeChildWindow('shareScreenWindow')
|
window.electron.closeChildWindow('shareScreenWindow')
|
||||||
|
setKeyOpenChildWindow('shareScreenWindow', false)
|
||||||
}
|
}
|
||||||
// 获取房间用户
|
// 获取房间用户
|
||||||
const getRoomUser = async (): Promise<void> => {
|
const getRoomUser = async (): Promise<void> => {
|
||||||
|
|
@ -2015,7 +2059,7 @@ const Meeting: React.FC = () => {
|
||||||
</div> : null}
|
</div> : null}
|
||||||
{item.uid !== user.uid && role.ID.includes(user.roleId) ? <div>
|
{item.uid !== user.uid && role.ID.includes(user.roleId) ? <div>
|
||||||
<Popover placement="left" title={''} content={
|
<Popover placement="left" title={''} content={
|
||||||
<div>
|
<div style={{ width: '100px' }}>
|
||||||
{!role.ID.includes(item.roleId) ? <Button
|
{!role.ID.includes(item.roleId) ? <Button
|
||||||
type="primary"
|
type="primary"
|
||||||
className='m-ant-btn'
|
className='m-ant-btn'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import storage from "./storage";
|
||||||
|
export const setKeyOpenChildWindow = async (key: string, bool: boolean) => {
|
||||||
|
const openChildWindow = await JSON.parse(storage.getItem('openChildWindow') as string)
|
||||||
|
openChildWindow[key] = bool;
|
||||||
|
if (key === 'shareScreenWindow' && !bool) {
|
||||||
|
for (const k in openChildWindow) {
|
||||||
|
openChildWindow[k] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storage.setItem('openChildWindow', JSON.stringify(openChildWindow))
|
||||||
|
};
|
||||||
|
export const getKeyOpenChildWindow = async (key: string): Promise<boolean> => {
|
||||||
|
const openChildWindow = await JSON.parse(storage.getItem('openChildWindow') as string)
|
||||||
|
return openChildWindow[key]
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue