Compare commits
17 Commits
60f2311570
...
9e6a862d49
| Author | SHA1 | Date |
|---|---|---|
|
|
9e6a862d49 | |
|
|
b6775f8e40 | |
|
|
6cc27d8020 | |
|
|
b45d2fdfa6 | |
|
|
2faafe8647 | |
|
|
26ae33e0aa | |
|
|
76e37eff1d | |
|
|
883525787d | |
|
|
58542e80b3 | |
|
|
c2ce66ed0d | |
|
|
15233cf8de | |
|
|
621ef06aba | |
|
|
2c11b8e726 | |
|
|
3ad59ff992 | |
|
|
016dcf6e09 | |
|
|
2598ecbcea | |
|
|
f24150af42 |
|
|
@ -6,6 +6,7 @@
|
|||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
|
||||
<meta name="build-time" content="<%- buildTime%>" id="build-time">
|
||||
<!-- <meta http-equiv="Content-Security-Policy"
|
||||
content="script-src 'self' https://www.google-analytics.com; style-src 'self' https://animate.style"> -->
|
||||
<title></title>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -53,6 +53,7 @@
|
|||
"electron-builder": "^23.1.0",
|
||||
"typescript": "^4.5.4",
|
||||
"vite": "^2.8.0",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-resolve": "^2.5.1"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 317 B |
|
|
@ -53,14 +53,14 @@ const SpeakerModeModal = forwardRef((props: any, ref: any) => {
|
|||
})
|
||||
|
||||
const FreedomMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||
// 自由者模式
|
||||
// 宫格模式
|
||||
return (
|
||||
<>
|
||||
<div className={styles.freedomMode} onClick={onClick}>
|
||||
<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>)}
|
||||
</div>
|
||||
<span>自由者模式</span>
|
||||
<span>宫格模式</span>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@
|
|||
|
||||
>div:nth-child(1) {
|
||||
color: #ccc;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ const Home: React.FC = () => {
|
|||
]);
|
||||
const [userInfo, setUserInfo] = useState<any>({})
|
||||
const [version, setVersion] = useState<string>('')
|
||||
const [buildTime, setBuildTime] = useState<string>('0')
|
||||
const [update, setUpdate] = useState(false)
|
||||
const [dateInfo, setDateInfo] = useState<{
|
||||
work: string;
|
||||
|
|
@ -60,6 +61,13 @@ const Home: React.FC = () => {
|
|||
window.electron.getVersion().then(res => {
|
||||
setVersion(res)
|
||||
})
|
||||
try {
|
||||
const buildStr = document.getElementById('build-time')?.getAttribute('content');
|
||||
const formattedTime = dayjs(Number(buildStr)).format('YYYYMMDDHHmm');
|
||||
setBuildTime(formattedTime)
|
||||
} catch {
|
||||
|
||||
}
|
||||
const updateTime = () => {
|
||||
setDateInfo({
|
||||
work: dayjs().format('ddd'),
|
||||
|
|
@ -136,7 +144,9 @@ const Home: React.FC = () => {
|
|||
</div>
|
||||
<div className='drag'>
|
||||
<div>
|
||||
<span>版本号:{version}</span>
|
||||
<span>V{version}-
|
||||
<span style={{ fontSize: '12px', color: 'gray' }}>{buildTime}</span>
|
||||
</span>
|
||||
{update ? <span>new</span> : null}
|
||||
</div>
|
||||
{update ? <div>
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@
|
|||
flex-shrink: 0;
|
||||
color: #ccc;
|
||||
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 { ExclamationCircleFilled } from '@ant-design/icons';
|
||||
import { isVersion } from '@/utils/package/public';
|
||||
import dayjs from 'dayjs';
|
||||
const { confirm } = Modal;
|
||||
const Login: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -39,6 +40,7 @@ const Login: React.FC = () => {
|
|||
nickName: '',
|
||||
roomNum: '',
|
||||
})
|
||||
const [buildTime, setBuildTime] = useState<string>('0')
|
||||
const [nameModal, setNameModal] = useState(false)
|
||||
const [env, setEnv] = useState('')
|
||||
useEffect(() => {
|
||||
|
|
@ -50,6 +52,13 @@ const Login: React.FC = () => {
|
|||
window.electron.getEnv().then(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')) {
|
||||
const login = JSON.parse(storage.getItem('login') as string);
|
||||
const data = {
|
||||
|
|
@ -319,7 +328,8 @@ const Login: React.FC = () => {
|
|||
><img src={ImageUrl.icon3} alt="" /></div>
|
||||
</div>
|
||||
<div>
|
||||
版本号:{version}
|
||||
V{version}-
|
||||
<span style={{ fontSize: '12px', color: 'gray' }}>{buildTime}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
.meetingContentUserName {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #0000009E;
|
||||
background-color: rgba(0, 0, 0, 0.62);
|
||||
border-radius: 6px;
|
||||
height: 24px;
|
||||
padding: 0 4px;
|
||||
|
|
@ -285,14 +285,126 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 宫格模式
|
||||
// 1
|
||||
.meetingContentBodyLeftFreedomModeOne {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// 自由者模式
|
||||
.meetingContentBodyLeftFreedomMode {
|
||||
.meetingContentSwiperCard {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 2
|
||||
.meetingContentBodyLeftFreedomModeTwo {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
.meetingContentSwiperCard {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 4
|
||||
.meetingContentBodyLeftFreedomModeThree {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
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 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.meetingContentSwiperCard {
|
||||
height: 160px;
|
||||
}
|
||||
}
|
||||
|
|
@ -888,40 +997,72 @@
|
|||
}
|
||||
|
||||
.modePopover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
>div {
|
||||
width: 140px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 8px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
>span {
|
||||
color: #EEEEEE;
|
||||
>div {
|
||||
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 {
|
||||
height: 16px;
|
||||
margin-right: 10px;
|
||||
>div {
|
||||
background-color: #101418;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten(#101418, 4%);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: darken(#101418, 4%);
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin: 0;
|
||||
.active {
|
||||
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 {
|
||||
background-color: #101418;
|
||||
>span {
|
||||
margin-top: 4px;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten(#101418, 4%);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: darken(#101418, 4%);
|
||||
>span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ const Meeting: React.FC = () => {
|
|||
const [isClickLock, setIsClickLock] = useState(false)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [modeOpen, setModeOpen] = useState(false)
|
||||
const [meetingMode, setMeetingMode] = useState('')
|
||||
const [meetingMode, setMeetingMode] = useState('FreedomMode')
|
||||
const [userSearchValue, setUserSearchValue] = useState('')
|
||||
const [noViewChatList, setNoViewChatList] = useState(0)
|
||||
const [currentLookUserAccount, setCurrentLookUserAccount] = useState<any>('')
|
||||
|
|
@ -216,6 +216,7 @@ const Meeting: React.FC = () => {
|
|||
}
|
||||
});
|
||||
const [isVideoFullScreen, setIsVideoFullScreen] = useState<boolean>(false)
|
||||
const [_freedomModeStatus, setFreedomModeStatus] = useState<boolean>(false)
|
||||
const [observer, setObserver] = useState<IntersectionObserver>()
|
||||
const [_activeSpeaker, setActiveSpeaker] = useState('')
|
||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||
|
|
@ -234,7 +235,6 @@ const Meeting: React.FC = () => {
|
|||
}
|
||||
})
|
||||
setKeyOpenChildWindow('shareScreenWindow', false)
|
||||
setMeetingMode('StandardMode');
|
||||
agoraInit()
|
||||
storage.setItem('noViewChatList', 0)
|
||||
window.addEventListener('customStorageChange', handleCustomStorageChange);
|
||||
|
|
@ -638,18 +638,36 @@ const Meeting: React.FC = () => {
|
|||
if (isShare) {
|
||||
const item = roomUserList.find((item: any) => item.screenShareId === String(isShare))
|
||||
setIsShareUser(item || null)
|
||||
setMeetingMode('StandardMode')
|
||||
}
|
||||
}, [isShare, roomUserList]);
|
||||
|
||||
useEffect(() => {
|
||||
setFreedomModeStatus((res: boolean) => {
|
||||
if (meetingMode === 'FreedomMode') {
|
||||
return true
|
||||
} else {
|
||||
if (res) {
|
||||
getShowUser(true)
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
}, [meetingMode]);
|
||||
|
||||
useEffect(() => {
|
||||
roomUserList.forEach(async (item: any) => {
|
||||
if (item.uid === currentVideoId) {
|
||||
if (meetingMode === "FreedomMode") {
|
||||
await agora.setRemoteVideoStreamType(item.uid, VideoStreamType.VideoStreamHigh, true)
|
||||
} 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(() => {
|
||||
let item = roomUserList.find((item: any) => currentVideoId == item.uid)
|
||||
|
|
@ -722,7 +740,13 @@ const Meeting: React.FC = () => {
|
|||
break;
|
||||
// 扩展操作
|
||||
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;
|
||||
|
|
@ -738,7 +762,7 @@ const Meeting: React.FC = () => {
|
|||
break;
|
||||
// 更新视图模式
|
||||
case 'RefreshView':
|
||||
setMeetingMode(item.type)
|
||||
|
||||
break;
|
||||
// 全员看他
|
||||
case 'ShowUser':
|
||||
|
|
@ -987,7 +1011,7 @@ const Meeting: React.FC = () => {
|
|||
uid: temp.uid,
|
||||
enableMicr: temp.enableMicr
|
||||
})
|
||||
} else {
|
||||
} else if (temp.type === 'video') {
|
||||
await PostOpenCamera({
|
||||
roomNum: temp.roomNum,
|
||||
uid: temp.uid,
|
||||
|
|
@ -1583,7 +1607,11 @@ const Meeting: React.FC = () => {
|
|||
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
|
||||
})
|
||||
}
|
||||
|
|
@ -1715,16 +1743,18 @@ const Meeting: React.FC = () => {
|
|||
})
|
||||
}
|
||||
// 渲染视频
|
||||
const renderVideo = async (uid: string = ''): Promise<void> => {
|
||||
if (isClickLock) {
|
||||
return
|
||||
}
|
||||
if (uid) {
|
||||
if (currentVideoId === uid || currentVideoUid === uid) {
|
||||
const renderVideo = async (uid: string = '', bool: boolean = false): Promise<void> => {
|
||||
if (!bool) {
|
||||
if (isClickLock) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
uid = userInfo.uid
|
||||
if (uid) {
|
||||
if (currentVideoId === uid || currentVideoUid === uid) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
uid = userInfo.uid
|
||||
}
|
||||
}
|
||||
await agora.destroyRendererByView(`video-source-camera-primary`)
|
||||
await agora.destroyRendererByView(`video-source-screen`)
|
||||
|
|
@ -1762,11 +1792,11 @@ const Meeting: React.FC = () => {
|
|||
}, 500);
|
||||
}
|
||||
// 全员观看
|
||||
const getShowUser = async (): Promise<void> => {
|
||||
const getShowUser = async (bool: boolean = false): Promise<void> => {
|
||||
if (location.href.indexOf('/meeting') !== -1) {
|
||||
await GetShowUser(state.channelId).then(async (res) => {
|
||||
if (res.code === 200 && res.data) {
|
||||
renderVideo(res.data)
|
||||
renderVideo(res.data, bool)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -2142,6 +2172,14 @@ const Meeting: React.FC = () => {
|
|||
await PostStopSharedScreen(state.channelId)
|
||||
} else {
|
||||
await PostShowUser(state.channelId, uid, name)
|
||||
await window.electron.onInvoke('sendOper', {
|
||||
roomNum: state.channelId,
|
||||
contentString: JSON.stringify({
|
||||
mode: 'StandardMode',
|
||||
type: 'mode',
|
||||
msg: false
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
// 设置发言人
|
||||
|
|
@ -2454,10 +2492,37 @@ const Meeting: React.FC = () => {
|
|||
})
|
||||
}
|
||||
// 获取当前模式样式
|
||||
const getMeetingContentBodyLeftModeClass = (): string => {
|
||||
const getMeetingContentBodyLeftModeClass = (people: Number): string => {
|
||||
switch (meetingMode) {
|
||||
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':
|
||||
return styles.meetingContentBodyLeftStandardMode
|
||||
case 'SpeakerMode':
|
||||
|
|
@ -2472,10 +2537,10 @@ const Meeting: React.FC = () => {
|
|||
return ''
|
||||
}
|
||||
// 获取当前模式文字
|
||||
const getMeetingContentBodyLeftModeText = (): string => {
|
||||
switch (meetingMode) {
|
||||
const getMeetingContentBodyLeftModeText = (mode?: string): string => {
|
||||
switch (mode || meetingMode) {
|
||||
case 'FreedomMode':
|
||||
return '自由者模式'
|
||||
return '宫格模式'
|
||||
case 'StandardMode':
|
||||
return '标准模式'
|
||||
case 'SpeakerMode':
|
||||
|
|
@ -2573,6 +2638,31 @@ const Meeting: React.FC = () => {
|
|||
}
|
||||
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 = () => {
|
||||
let element = document.getElementById('videoView') as HTMLDivElement
|
||||
|
|
@ -2602,6 +2692,9 @@ const Meeting: React.FC = () => {
|
|||
<>
|
||||
<div className={styles.meeting} onClick={() => {
|
||||
setContextMenu('')
|
||||
if (modeOpen) {
|
||||
setModeOpen(false)
|
||||
}
|
||||
setIsNetworkQuality(false)
|
||||
}}>
|
||||
{isScreenCapture ? <div className={`${styles.meetingAbsolute}`} id='meetingAbsoluteVideo'>
|
||||
|
|
@ -2771,28 +2864,33 @@ const Meeting: React.FC = () => {
|
|||
<span className='drag' style={{ marginTop: '2px', marginLeft: '4px' }}><Code roomNum={state.channelId}></Code></span>
|
||||
</div>
|
||||
<div className='drag'>
|
||||
<Popover
|
||||
{role.ID.includes(userInfo.roleId) ? <Popover
|
||||
content={
|
||||
<div className='modePopover'>
|
||||
<div onClick={() => {
|
||||
setModeOpen(false)
|
||||
storage.setItem('meetingMode', 'StandardMode')
|
||||
}}>
|
||||
<img src={ImageUrl.icon43} alt="" />
|
||||
<span>标准模式</span>
|
||||
</div>
|
||||
<div onClick={() => {
|
||||
setModeOpen(false)
|
||||
storage.setItem('meetingMode', 'SpeakerMode')
|
||||
}}>
|
||||
<img src={ImageUrl.icon44} alt="" />
|
||||
<span>演讲模式</span>
|
||||
</div>
|
||||
<div onClick={() => {
|
||||
setModeOpen(false)
|
||||
}}>
|
||||
<span>取消</span>
|
||||
<div>
|
||||
<div className={meetingMode === 'FreedomMode' ? 'active' : ''} onClick={() => {
|
||||
setSyncView('FreedomMode')
|
||||
}}>
|
||||
<img src={ImageUrl.icon57} alt="" />
|
||||
<span>宫格模式</span>
|
||||
</div>
|
||||
<div className={meetingMode === 'StandardMode' ? 'active' : ''} onClick={() => {
|
||||
setSyncView('StandardMode')
|
||||
}}>
|
||||
<img src={ImageUrl.icon43} alt="" />
|
||||
<span>标准模式</span>
|
||||
</div>
|
||||
<div className={meetingMode === 'SpeakerMode' ? 'active' : ''} onClick={() => {
|
||||
setSyncView('SpeakerMode')
|
||||
}}>
|
||||
<img src={ImageUrl.icon44} alt="" />
|
||||
<span>演讲模式</span>
|
||||
</div>
|
||||
</div>
|
||||
<span>
|
||||
<ExclamationCircleFilled />
|
||||
<span>改变布局将对所有成员生效</span>
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
title=""
|
||||
|
|
@ -2801,10 +2899,14 @@ const Meeting: React.FC = () => {
|
|||
onOpenChange={() => setModeOpen(true)}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
</Popover>
|
||||
</Popover> : null}
|
||||
<Operation></Operation>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -2812,7 +2914,7 @@ const Meeting: React.FC = () => {
|
|||
<div className={styles.meetingContentBody}>
|
||||
<div className={`${styles.meetingContentBodyLeft} drag`}>
|
||||
{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) => {
|
||||
return (item.isRoom && item.isAdmin ? <div
|
||||
id={item.uid}
|
||||
|
|
@ -2937,7 +3039,13 @@ const Meeting: React.FC = () => {
|
|||
</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={() => {
|
||||
const container = document.getElementById('videoView') as HTMLElement;
|
||||
container.scrollLeft -= 100
|
||||
|
|
@ -2961,7 +3069,7 @@ const Meeting: React.FC = () => {
|
|||
<CaretDownOutlined />
|
||||
</div>}
|
||||
</div> : null}
|
||||
{currentLookUserStatus === 0 ?
|
||||
{meetingMode !== "FreedomMode" && currentLookUserStatus === 0 ?
|
||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
||||
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||
|
|
@ -2972,7 +3080,7 @@ const Meeting: React.FC = () => {
|
|||
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
||||
{meetingContentUser(currentLookUserAccount, true)}
|
||||
</div> : null}
|
||||
{currentLookUserStatus === 1 ?
|
||||
{meetingMode !== "FreedomMode" && currentLookUserStatus === 1 ?
|
||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
||||
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||
|
|
@ -2984,7 +3092,7 @@ const Meeting: React.FC = () => {
|
|||
{meetingContentUser(currentLookUserAccount, true)}
|
||||
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentLookUserAccount)}
|
||||
</div> : null}
|
||||
{currentLookUserStatus === 2 ?
|
||||
{meetingMode !== "FreedomMode" && currentLookUserStatus === 2 ?
|
||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-screen'>
|
||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||
|
|
@ -2995,7 +3103,7 @@ const Meeting: React.FC = () => {
|
|||
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
||||
{meetingContentUser(currentLookUserAccount, true)}
|
||||
</div> : null}
|
||||
{currentLookUserStatus === 3 ?
|
||||
{meetingMode !== "FreedomMode" && currentLookUserStatus === 3 ?
|
||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-screen'>
|
||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||
|
|
@ -3006,7 +3114,7 @@ const Meeting: React.FC = () => {
|
|||
<FullscreenOutlined className={styles.meetingContentSwiperCardFullScreenIcon} title='全屏' onClick={() => setIsVideoFullScreen(true)} />}
|
||||
{meetingContentUser(currentLookUserAccount, true)}
|
||||
</div> : null}
|
||||
{currentLookUserStatus === 4 ?
|
||||
{meetingMode !== "FreedomMode" && currentLookUserStatus === 4 ?
|
||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass()} ${setMeetingContentSwiperCardFullScreenClass()}`}>
|
||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-camera'>
|
||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ import icon54 from '@/assets/icon54.png'
|
|||
import icon55 from '@/assets/icon55.png'
|
||||
import icon56 from '@/assets/icon56.png'
|
||||
import icon56Active from '@/assets/icon56-active.png'
|
||||
import icon57 from '@/assets/icon57.png'
|
||||
export default {
|
||||
loading,
|
||||
icon,
|
||||
|
|
@ -174,5 +175,6 @@ export default {
|
|||
icon54,
|
||||
icon55,
|
||||
icon56,
|
||||
icon56Active
|
||||
icon56Active,
|
||||
icon57,
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import react from '@vitejs/plugin-react'
|
|||
import pxtovw from 'postcss-px-to-viewport-8-plugin'
|
||||
import { resolve as resolvePath } from 'path'
|
||||
import resolve from 'vite-plugin-resolve';
|
||||
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||
const loder_pxtovw = pxtovw({
|
||||
viewportWidth: 1900,
|
||||
viewportUnit: 'vw',
|
||||
|
|
@ -51,6 +52,20 @@ export default defineConfig({
|
|||
base: './', // 这里更改打包相对绝对路径
|
||||
plugins: [
|
||||
react(),
|
||||
createHtmlPlugin({
|
||||
minify: false,
|
||||
pages: [
|
||||
{
|
||||
template: 'index.html',
|
||||
filename: 'index.html',
|
||||
injectOptions: {
|
||||
data: {
|
||||
buildTime: +new Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}),
|
||||
resolve({
|
||||
'agora-electron-sdk': `
|
||||
const {
|
||||
|
|
|
|||
Loading…
Reference in New Issue