This commit is contained in:
parent
d3977ea0ae
commit
704d79b0f7
2
main.js
2
main.js
|
|
@ -98,7 +98,7 @@ function createNotification(user) {
|
||||||
const notification = new Notification({
|
const notification = new Notification({
|
||||||
title: `${user.name} 邀请你加入`,
|
title: `${user.name} 邀请你加入`,
|
||||||
body: user.body,
|
body: user.body,
|
||||||
icon: path.join(`${__dirname}/src/assets/avatar.png`)
|
// icon: path.join(`${__dirname}/src/assets/avatar.png`)
|
||||||
});
|
});
|
||||||
notification.show();
|
notification.show();
|
||||||
mainWindow.focus();
|
mainWindow.focus();
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
"@microsoft/signalr": "^8.0.0",
|
"@microsoft/signalr": "^8.0.0",
|
||||||
"@types/node": "^20.14.9",
|
"@types/node": "^20.14.9",
|
||||||
"agora-electron-sdk": "^4.3.2",
|
"agora-electron-sdk": "^4.3.2",
|
||||||
|
"animate.css": "^4.1.1",
|
||||||
"antd": "^5.18.2",
|
"antd": "^5.18.2",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
|
|
@ -2686,6 +2687,11 @@
|
||||||
"ajv": "^6.9.1"
|
"ajv": "^6.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/animate.css": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/animate.css/-/animate.css-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
|
||||||
|
},
|
||||||
"node_modules/ansi-colors": {
|
"node_modules/ansi-colors": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-1.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-1.1.0.tgz",
|
||||||
|
|
@ -13827,6 +13833,11 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
|
"animate.css": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/animate.css/-/animate.css-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
|
||||||
|
},
|
||||||
"ansi-colors": {
|
"ansi-colors": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-1.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-1.1.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
"@microsoft/signalr": "^8.0.0",
|
"@microsoft/signalr": "^8.0.0",
|
||||||
"@types/node": "^20.14.9",
|
"@types/node": "^20.14.9",
|
||||||
"agora-electron-sdk": "^4.3.2",
|
"agora-electron-sdk": "^4.3.2",
|
||||||
|
"animate.css": "^4.1.1",
|
||||||
"antd": "^5.18.2",
|
"antd": "^5.18.2",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
|
|
|
||||||
49
src/App.tsx
49
src/App.tsx
|
|
@ -12,6 +12,8 @@ import { storage } from '@/utils'
|
||||||
import { Spin } from "antd";
|
import { Spin } from "antd";
|
||||||
import { onInvitation } from "@/utils/package/signalr";
|
import { onInvitation } from "@/utils/package/signalr";
|
||||||
import JoinMeetingModal from "./components/JoinMeetingModal";
|
import JoinMeetingModal from "./components/JoinMeetingModal";
|
||||||
|
import * as CryptoJS from 'crypto-js';
|
||||||
|
import { PostLogin } from "@/api/Login";
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -22,28 +24,47 @@ const App: React.FC = () => {
|
||||||
});
|
});
|
||||||
const [spinning, setSpinning] = useState(false);
|
const [spinning, setSpinning] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (storage.getItem('user')) {
|
function toLogin() {
|
||||||
try {
|
|
||||||
window.electron.setMainWindowSize({
|
|
||||||
width: 1200,
|
|
||||||
height: 800,
|
|
||||||
})
|
|
||||||
} catch {
|
|
||||||
|
|
||||||
}
|
|
||||||
navigate('/home')
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
window.electron.setMainWindowSize({
|
window.electron.setMainWindowSize({
|
||||||
width: 752,
|
width: 752,
|
||||||
height: 520,
|
height: 520,
|
||||||
key: 'login'
|
key: 'login'
|
||||||
})
|
})
|
||||||
} catch {
|
} catch { }
|
||||||
|
storage.removeItem('user')
|
||||||
}
|
|
||||||
navigate('/login')
|
navigate('/login')
|
||||||
}
|
}
|
||||||
|
function toHome() {
|
||||||
|
try {
|
||||||
|
window.electron.setMainWindowSize({
|
||||||
|
width: 1200,
|
||||||
|
height: 800,
|
||||||
|
})
|
||||||
|
} catch { }
|
||||||
|
navigate('/home')
|
||||||
|
}
|
||||||
|
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
|
let loginInfo = JSON.parse(storage.getItem('login') as string)
|
||||||
|
if (userInfo) {
|
||||||
|
if (loginInfo && loginInfo.isAutoLogin) {
|
||||||
|
PostLogin({
|
||||||
|
account: loginInfo.account,
|
||||||
|
pwd: CryptoJS.MD5(loginInfo.password).toString(CryptoJS.enc.Hex)
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
storage.setItem('user', JSON.stringify(res.data))
|
||||||
|
toHome()
|
||||||
|
} else {
|
||||||
|
toLogin()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
toLogin()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toLogin()
|
||||||
|
}
|
||||||
if (import.meta.env.VITE_ENV !== 'development') {
|
if (import.meta.env.VITE_ENV !== 'development') {
|
||||||
document.addEventListener('keydown', (event) => {
|
document.addEventListener('keydown', (event) => {
|
||||||
if ((event.ctrlKey || event.metaKey) && event.key === 'r') {
|
if ((event.ctrlKey || event.metaKey) && event.key === 'r') {
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 414 B After Width: | Height: | Size: 301 B |
Binary file not shown.
|
Before Width: | Height: | Size: 312 B After Width: | Height: | Size: 245 B |
|
|
@ -0,0 +1,11 @@
|
||||||
|
.avatar {
|
||||||
|
background-color: #3F51B5;
|
||||||
|
height: 36px;
|
||||||
|
width: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
color: white;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import styles from '@/components/Avatar/index.module.scss'
|
||||||
|
import { useState, useImperativeHandle, forwardRef } from "react";
|
||||||
|
const Avatar = forwardRef((props: any, ref: any) => {
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
getData: () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={styles.avatar}>
|
||||||
|
{props.name ? props.name.slice(-2) : '访客'}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default Avatar
|
||||||
|
|
@ -29,17 +29,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
>div:nth-child(2) {
|
>div:nth-child(2) {
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
|
|
||||||
>img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
>span {
|
>span {
|
||||||
|
|
@ -86,17 +76,7 @@
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
>div {
|
>div {
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
|
|
||||||
>img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
>span {
|
>span {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
import styles from '@/components/InvitingPersonnelModal/index.module.scss'
|
import styles from '@/components/InvitingPersonnelModal/index.module.scss'
|
||||||
import { Button, Checkbox, Input, Modal, Pagination, message } from 'antd';
|
import { Button, Checkbox, Input, Modal, Pagination, message } from 'antd';
|
||||||
import { useState, useImperativeHandle, forwardRef, useEffect } from "react";
|
import { useState, useImperativeHandle, forwardRef, useEffect } from "react";
|
||||||
import ImageUrl from '@/utils/package/imageUrl';
|
|
||||||
import { SearchOutlined } from '@ant-design/icons';
|
import { SearchOutlined } from '@ant-design/icons';
|
||||||
import { GetUserList } from '@/api/Home/User';
|
import { GetUserList } from '@/api/Home/User';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { PostRoomInvite } from '@/api/Meeting';
|
import { PostRoomInvite } from '@/api/Meeting';
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
|
import Avatar from '@/components/Avatar';
|
||||||
const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
|
const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
changeInvitingPersonnelModal: () => {
|
changeInvitingPersonnelModal: () => {
|
||||||
|
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
|
setUser(userInfo)
|
||||||
getUserList()
|
getUserList()
|
||||||
setIsInvitingPersonnelModal(true)
|
setIsInvitingPersonnelModal(true)
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +19,7 @@ const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
const [isInvitingPersonnelModal, setIsInvitingPersonnelModal] = useState(false);
|
const [isInvitingPersonnelModal, setIsInvitingPersonnelModal] = useState(false);
|
||||||
const [isFirstRender, setIsFirstRender] = useState(true);
|
const [isFirstRender, setIsFirstRender] = useState(true);
|
||||||
|
const [user, setUser] = useState<any>({});
|
||||||
const [operation, setOperation] = useState<{
|
const [operation, setOperation] = useState<{
|
||||||
options: { label: string; value: number }[];
|
options: { label: string; value: number }[];
|
||||||
optionsValue: number[];
|
optionsValue: number[];
|
||||||
|
|
@ -96,7 +99,7 @@ const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
|
||||||
footer={null}
|
footer={null}
|
||||||
onCancel={() => setIsInvitingPersonnelModal(false)}
|
onCancel={() => setIsInvitingPersonnelModal(false)}
|
||||||
centered
|
centered
|
||||||
width={'560px'}
|
width={'700px'}
|
||||||
>
|
>
|
||||||
<div className={styles.invitingPersonnelModal}>
|
<div className={styles.invitingPersonnelModal}>
|
||||||
<div className={styles.invitingPersonnelModalContent}>
|
<div className={styles.invitingPersonnelModalContent}>
|
||||||
|
|
@ -147,8 +150,8 @@ const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
|
||||||
return checkedList
|
return checkedList
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}} defaultChecked={item.checked}></Checkbox>
|
}} defaultChecked={item.checked} disabled={!item.isOnline || item.account === user.account}></Checkbox>
|
||||||
<div><img src={ImageUrl.avatar} alt="" /></div>
|
<div><Avatar name={item.userName} /></div>
|
||||||
<span>{item.userName}</span>
|
<span>{item.userName}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color: item.isOnline ? '#02B188' : 'rgb(221 11 11)' }}>{item.isOnline ? '在线' : '离线'}</div>
|
<div style={{ color: item.isOnline ? '#02B188' : 'rgb(221 11 11)' }}>{item.isOnline ? '在线' : '离线'}</div>
|
||||||
|
|
@ -159,13 +162,13 @@ const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
|
||||||
...list,
|
...list,
|
||||||
pageIndex: e
|
pageIndex: e
|
||||||
})
|
})
|
||||||
}} pageSize={list.pageSize} current={list.pageIndex} hideOnSinglePage={true} />
|
}} pageSize={list.pageSize} current={list.pageIndex} hideOnSinglePage={true} showLessItems={true}/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.invitingPersonnelModalContentRight}>
|
<div className={styles.invitingPersonnelModalContentRight}>
|
||||||
<span>已选成员</span>
|
<span>已选成员</span>
|
||||||
<div>
|
<div>
|
||||||
{checkedList.map((item: any, index: number) => <div key={item.id + index}>
|
{checkedList.map((item: any, index: number) => <div key={item.id + index}>
|
||||||
<div><img src={ImageUrl.avatar} alt="" /></div>
|
<div><Avatar name={item.userName} /></div>
|
||||||
<span>{item.userName}</span>
|
<span>{item.userName}</span>
|
||||||
</div>)}
|
</div>)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -175,8 +178,7 @@ const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
|
||||||
<Button type="primary" onClick={() => { setIsInvitingPersonnelModal(false) }} style={{ backgroundColor: '#31353A', marginRight: '14px' }}>取消</Button>
|
<Button type="primary" onClick={() => { setIsInvitingPersonnelModal(false) }} style={{ backgroundColor: '#31353A', marginRight: '14px' }}>取消</Button>
|
||||||
<Button type="primary" className='m-ant-btn' onClick={() => {
|
<Button type="primary" className='m-ant-btn' onClick={() => {
|
||||||
if (checkedList.length) {
|
if (checkedList.length) {
|
||||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
let me = checkedList.find((item: any) => item.id === user.uid)
|
||||||
let me = checkedList.find((item: any) => item.id === userInfo.uid)
|
|
||||||
if (me) {
|
if (me) {
|
||||||
message.error('您不能邀请自己')
|
message.error('您不能邀请自己')
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
>div:nth-child(1) {
|
>div:nth-child(1) {}
|
||||||
width: 44px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
>img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
>div:nth-child(2) {
|
>div:nth-child(2) {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import ImageUrl from '@/utils/package/imageUrl';
|
||||||
import { Modal, message } from 'antd';
|
import { Modal, message } from 'antd';
|
||||||
import { useState, useImperativeHandle, forwardRef } from "react";
|
import { useState, useImperativeHandle, forwardRef } from "react";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import Avatar from '@/components/Avatar';
|
||||||
const JoinMeetingModal = forwardRef((props: any, ref: any) => {
|
const JoinMeetingModal = forwardRef((props: any, ref: any) => {
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
changeModal: (item: any) => {
|
changeModal: (item: any) => {
|
||||||
|
|
@ -40,7 +41,7 @@ const JoinMeetingModal = forwardRef((props: any, ref: any) => {
|
||||||
>
|
>
|
||||||
<div className={styles.joinMeetingModal}>
|
<div className={styles.joinMeetingModal}>
|
||||||
<div>
|
<div>
|
||||||
<div><img src={ImageUrl.avatar} alt="" /></div>
|
<div><Avatar name={info.InviterName} /></div>
|
||||||
<div>
|
<div>
|
||||||
<span>{info.InviterName} 邀请你加入</span>
|
<span>{info.InviterName} 邀请你加入</span>
|
||||||
<span>{info.roomName}</span>
|
<span>{info.roomName}</span>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
width: 144px;
|
width: 144px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
>span {
|
>span {
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
@ -26,6 +27,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
border: 2px #4096ff solid;
|
||||||
|
}
|
||||||
|
|
||||||
.freedomMode {
|
.freedomMode {
|
||||||
|
|
||||||
>div {
|
>div {
|
||||||
|
|
@ -104,6 +109,11 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-color: #101317;
|
background-color: #101317;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
border: 2px #4096ff solid;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dualScreenMode {
|
.dualScreenMode {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { useLocation } from 'react-router-dom';
|
||||||
import { GetSyncView } from '@/api/Meeting';
|
import { GetSyncView } from '@/api/Meeting';
|
||||||
interface Props {
|
interface Props {
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
|
meetingMode: string;
|
||||||
}
|
}
|
||||||
const SpeakerModeModal = forwardRef((props: any, ref: any) => {
|
const SpeakerModeModal = forwardRef((props: any, ref: any) => {
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
|
|
@ -13,6 +14,7 @@ const SpeakerModeModal = forwardRef((props: any, ref: any) => {
|
||||||
setIsSpeakerModeModal(true)
|
setIsSpeakerModeModal(true)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
const [meetingMode, setMeetingMode] = useState('StandardMode')
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
const [isSpeakerModeModal, setIsSpeakerModeModal] = useState(false);
|
const [isSpeakerModeModal, setIsSpeakerModeModal] = useState(false);
|
||||||
const [isView, setIsView] = useState(false);
|
const [isView, setIsView] = useState(false);
|
||||||
|
|
@ -21,6 +23,7 @@ const SpeakerModeModal = forwardRef((props: any, ref: any) => {
|
||||||
await GetSyncView(state.channelId, mode)
|
await GetSyncView(state.channelId, mode)
|
||||||
}
|
}
|
||||||
storage.setItem('meetingMode', mode)
|
storage.setItem('meetingMode', mode)
|
||||||
|
setMeetingMode(mode);
|
||||||
setIsSpeakerModeModal(false)
|
setIsSpeakerModeModal(false)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
@ -34,27 +37,27 @@ const SpeakerModeModal = forwardRef((props: any, ref: any) => {
|
||||||
width={'560px'}
|
width={'560px'}
|
||||||
>
|
>
|
||||||
<div className={styles.speakerModeModal}>
|
<div className={styles.speakerModeModal}>
|
||||||
<FreedomMode onClick={() => setMode('FreedomMode')} />
|
<FreedomMode onClick={() => setMode('FreedomMode')} meetingMode={meetingMode} />
|
||||||
<StandardMode onClick={() => setMode('StandardMode')} />
|
<StandardMode onClick={() => setMode('StandardMode')} meetingMode={meetingMode} />
|
||||||
<SpeakerMode onClick={() => setMode('SpeakerMode')} />
|
<SpeakerMode onClick={() => setMode('SpeakerMode')} meetingMode={meetingMode} />
|
||||||
<SingleScreenMode onClick={() => setMode('SingleScreenMode')} />
|
<SingleScreenMode onClick={() => setMode('SingleScreenMode')} meetingMode={meetingMode} />
|
||||||
<DualScreenMode onClick={() => setMode('DualScreenMode')} />
|
<DualScreenMode onClick={() => setMode('DualScreenMode')} meetingMode={meetingMode} />
|
||||||
<FourScreenMode onClick={() => setMode('FourScreenMode')} />
|
<FourScreenMode onClick={() => setMode('FourScreenMode')} meetingMode={meetingMode} />
|
||||||
</div>
|
</div>
|
||||||
<Checkbox onChange={(e) => {
|
<Checkbox onChange={(e) => {
|
||||||
setIsView(e.target.checked)
|
setIsView(e.target.checked)
|
||||||
}} value={isView}>同步所有视图</Checkbox>
|
}} defaultChecked={isView}>同步所有视图</Checkbox>
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const FreedomMode: React.FC<Props> = ({ onClick }) => {
|
const FreedomMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||||
// 自由者模式
|
// 自由者模式
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.freedomMode} onClick={onClick}>
|
<div className={styles.freedomMode} onClick={onClick}>
|
||||||
<div>
|
<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>
|
||||||
|
|
@ -62,12 +65,12 @@ const FreedomMode: React.FC<Props> = ({ onClick }) => {
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const StandardMode: React.FC<Props> = ({ onClick }) => {
|
const StandardMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||||
// 标准模式
|
// 标准模式
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.standardMode} onClick={onClick}>
|
<div className={styles.standardMode} onClick={onClick}>
|
||||||
<div>
|
<div className={`${meetingMode === 'StandardMode' ? styles.active : ''}`}>
|
||||||
<div>
|
<div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
|
|
@ -81,12 +84,12 @@ const StandardMode: React.FC<Props> = ({ onClick }) => {
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const SpeakerMode: React.FC<Props> = ({ onClick }) => {
|
const SpeakerMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||||
// 演讲者模式
|
// 演讲者模式
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.speakerMode} onClick={onClick}>
|
<div className={styles.speakerMode} onClick={onClick}>
|
||||||
<div>
|
<div className={`${meetingMode === 'SpeakerMode' ? styles.active : ''}`}>
|
||||||
<div>
|
<div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
|
|
@ -100,12 +103,12 @@ const SpeakerMode: React.FC<Props> = ({ onClick }) => {
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const SingleScreenMode: React.FC<Props> = ({ onClick }) => {
|
const SingleScreenMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||||
// 单画面模式
|
// 单画面模式
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.singleScreenMode} onClick={onClick}>
|
<div className={styles.singleScreenMode} onClick={onClick}>
|
||||||
<div>
|
<div className={`${meetingMode === 'SingleScreenMode' ? styles.active : ''}`}>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
<span>单画面模式</span>
|
<span>单画面模式</span>
|
||||||
|
|
@ -113,12 +116,12 @@ const SingleScreenMode: React.FC<Props> = ({ onClick }) => {
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const DualScreenMode: React.FC<Props> = ({ onClick }) => {
|
const DualScreenMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||||
// 二分屏模式
|
// 二分屏模式
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.dualScreenMode} onClick={onClick}>
|
<div className={styles.dualScreenMode} onClick={onClick}>
|
||||||
<div>
|
<div className={`${meetingMode === 'DualScreenMode' ? styles.active : ''}`}>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -127,12 +130,12 @@ const DualScreenMode: React.FC<Props> = ({ onClick }) => {
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const FourScreenMode: React.FC<Props> = ({ onClick }) => {
|
const FourScreenMode: React.FC<Props> = ({ onClick, meetingMode }) => {
|
||||||
// 四分屏模式
|
// 四分屏模式
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.fourScreenMode} onClick={onClick}>
|
<div className={styles.fourScreenMode} onClick={onClick}>
|
||||||
<div>
|
<div className={`${meetingMode === 'FourScreenMode' ? styles.active : ''}`}>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import '@/utils/styles/main.css'
|
||||||
import { HashRouter } from 'react-router-dom';
|
import { HashRouter } from 'react-router-dom';
|
||||||
import { ConfigProvider } from 'antd';
|
import { ConfigProvider } from 'antd';
|
||||||
import zhCN from 'antd/locale/zh_CN';
|
import zhCN from 'antd/locale/zh_CN';
|
||||||
|
import 'animate.css';
|
||||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
<ConfigProvider locale={zhCN}>
|
<ConfigProvider locale={zhCN}>
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,19 @@
|
||||||
border-bottom: 1px solid #2C2C2C;
|
border-bottom: 1px solid #2C2C2C;
|
||||||
|
|
||||||
.indexBtnsJoin {
|
.indexBtnsJoin {
|
||||||
background-color: #FFCFEB;
|
background-color: #3A1457;
|
||||||
color: red;
|
box-shadow: none;
|
||||||
|
color: white;
|
||||||
margin-left: 22px;
|
margin-left: 22px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: lighten(#FFCFEB, 5%) !important;
|
background-color: lighten(#3A1457, 5%) !important;
|
||||||
color: red;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
background-color: darken(#FFCFEB, 5%) !important;
|
background-color: darken(#3A1457, 5%) !important;
|
||||||
color: red;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ const Index: React.FC = () => {
|
||||||
setJoinRoomFrom('')
|
setJoinRoomFrom('')
|
||||||
setJoinRoomModal(true)
|
setJoinRoomModal(true)
|
||||||
}}
|
}}
|
||||||
icon={<img src={ImageUrl.icon7} alt="" />}
|
icon={<img src={ImageUrl.icon8} alt="" />}
|
||||||
className={`${styles.indexBtnsJoin} drag`}>
|
className={`${styles.indexBtnsJoin} drag`}>
|
||||||
加入会议
|
加入会议
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -157,17 +157,6 @@ const Index: React.FC = () => {
|
||||||
<Modal title="新建会议室" open={createRoomModal} footer={null} closable={false} centered width={'400px'}>
|
<Modal title="新建会议室" open={createRoomModal} footer={null} closable={false} centered width={'400px'}>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<Input
|
|
||||||
placeholder="请输入房间名字"
|
|
||||||
style={{ marginBottom: '14px' }}
|
|
||||||
value={createRoomFrom.roomName}
|
|
||||||
onChange={(e) => {
|
|
||||||
setCreateRoomFrom({
|
|
||||||
...createRoomFrom,
|
|
||||||
roomName: e.target.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Input
|
<Input
|
||||||
placeholder="请输入房间号"
|
placeholder="请输入房间号"
|
||||||
style={{ marginBottom: '14px' }}
|
style={{ marginBottom: '14px' }}
|
||||||
|
|
@ -187,15 +176,34 @@ const Index: React.FC = () => {
|
||||||
<span
|
<span
|
||||||
style={{ color: '#47D3D0', cursor: 'pointer' }}
|
style={{ color: '#47D3D0', cursor: 'pointer' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
function generateTimestampWithRandom(): string {
|
||||||
|
const timestamp = new Date().getTime();
|
||||||
|
const lastSixDigits = timestamp.toString().slice(-6);
|
||||||
|
const randomTwoDigits = ('0' + Math.floor(Math.random() * 100)).slice(-2);
|
||||||
|
return lastSixDigits + randomTwoDigits;
|
||||||
|
}
|
||||||
setCreateRoomFrom({
|
setCreateRoomFrom({
|
||||||
...createRoomFrom,
|
...createRoomFrom,
|
||||||
roomNum: Math.floor(+new Date() / 1000).toString().slice(-8),
|
roomNum: generateTimestampWithRandom(),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>获取随机房间号
|
>获取随机房间号
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<Input.TextArea
|
||||||
|
placeholder="请输入房间名字"
|
||||||
|
style={{ marginBottom: '14px' }}
|
||||||
|
showCount
|
||||||
|
maxLength={30}
|
||||||
|
value={createRoomFrom.roomName}
|
||||||
|
onChange={(e) => {
|
||||||
|
setCreateRoomFrom({
|
||||||
|
...createRoomFrom,
|
||||||
|
roomName: e.target.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
autoSize />
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex', justifyContent: 'center'
|
display: 'flex', justifyContent: 'center'
|
||||||
|
|
|
||||||
|
|
@ -22,18 +22,19 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.userBtnsDel {
|
.userBtnsDel {
|
||||||
background-color: #FFCFEB;
|
background-color: #3A1457;
|
||||||
color: red;
|
box-shadow: none;
|
||||||
|
color: white;
|
||||||
margin-left: 22px;
|
margin-left: 22px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: lighten(#FFCFEB, 5%) !important;
|
background-color: lighten(#3A1457, 5%) !important;
|
||||||
color: red;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
background-color: darken(#FFCFEB, 5%) !important;
|
background-color: darken(#3A1457, 5%) !important;
|
||||||
color: red;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ const User: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className={`${styles.userBtnsRight} drag`}>
|
<div className={`${styles.userBtnsRight} drag`}>
|
||||||
<Input
|
<Input
|
||||||
placeholder="请输入用户名"
|
placeholder="请输入用户名或账号"
|
||||||
prefix={<SearchOutlined style={{ color: 'white' }} />}
|
prefix={<SearchOutlined style={{ color: 'white' }} />}
|
||||||
value={list.searchKeywod}
|
value={list.searchKeywod}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,8 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
>div {
|
>div {
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-right: 14px;
|
margin-right: 14px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
>img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
>span {
|
>span {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import 'dayjs/locale/zh-cn'
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
import ImageUrl from '@/utils/package/imageUrl'
|
import ImageUrl from '@/utils/package/imageUrl'
|
||||||
import { startSignalr } from '@/utils/package/signalr';
|
import { startSignalr } from '@/utils/package/signalr';
|
||||||
|
import Avatar from '@/components/Avatar';
|
||||||
dayjs.locale('zh-cn');
|
dayjs.locale('zh-cn');
|
||||||
type navListType = {
|
type navListType = {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
@ -84,9 +85,9 @@ const Home: React.FC = () => {
|
||||||
<div className={styles.homeLeft}>
|
<div className={styles.homeLeft}>
|
||||||
<div className='drag'>
|
<div className='drag'>
|
||||||
<div>
|
<div>
|
||||||
<img src={ImageUrl.avatar} alt="" />
|
<Avatar name={userInfo.userName} />
|
||||||
</div>
|
</div>
|
||||||
<span>欢迎您,{userInfo?.userName}</span>
|
<span>欢迎您,{userInfo.userName}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<img src={ImageUrl.icon14} alt="" />
|
<img src={ImageUrl.icon14} alt="" />
|
||||||
|
|
|
||||||
|
|
@ -106,18 +106,19 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #FFCFEB;
|
background-color: #3A1457;
|
||||||
|
box-shadow: none;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
width: 56px;
|
width: 56px;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: lighten(#FFCFEB, 5%) !important;
|
background-color: lighten(#3A1457, 5%) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
background-color: darken(#FFCFEB, 5%) !important;
|
background-color: darken(#3A1457, 5%) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -139,6 +140,7 @@
|
||||||
.ant-input {
|
.ant-input {
|
||||||
height: 34px;
|
height: 34px;
|
||||||
line-height: 34px;
|
line-height: 34px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,10 @@ const Login: React.FC = () => {
|
||||||
setAccountPasswordStatus(false)
|
setAccountPasswordStatus(false)
|
||||||
}
|
}
|
||||||
// 继续
|
// 继续
|
||||||
const continueClick = (): void => {
|
const continueClick = (): any => {
|
||||||
|
if (!operation.account) {
|
||||||
|
return message.error('请输入账号!')
|
||||||
|
}
|
||||||
GetCheckUser(operation.account).then(res => {
|
GetCheckUser(operation.account).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
res.data ? setAccountPasswordStatus(true) : message.error('账号不存在!')
|
res.data ? setAccountPasswordStatus(true) : message.error('账号不存在!')
|
||||||
|
|
@ -87,6 +90,9 @@ const Login: React.FC = () => {
|
||||||
|
|
||||||
// 设置勾选
|
// 设置勾选
|
||||||
const changeOptionsValue = (checkedValues: string[]): void => {
|
const changeOptionsValue = (checkedValues: string[]): void => {
|
||||||
|
if (checkedValues.indexOf('isAutoLogin') >= 0 && checkedValues.indexOf('isRememberPassword') === -1) {
|
||||||
|
checkedValues.push('isRememberPassword')
|
||||||
|
}
|
||||||
setOperation({
|
setOperation({
|
||||||
...operation,
|
...operation,
|
||||||
optionsValue: checkedValues,
|
optionsValue: checkedValues,
|
||||||
|
|
@ -159,22 +165,22 @@ const Login: React.FC = () => {
|
||||||
placeholder="请输入账号"
|
placeholder="请输入账号"
|
||||||
prefix={<img src={ImageUrl.icon5} alt="" />}
|
prefix={<img src={ImageUrl.icon5} alt="" />}
|
||||||
suffix={
|
suffix={
|
||||||
<span
|
(accountPasswordStatus && operation.account ? <span
|
||||||
style={{ color: '#47D3D0', cursor: 'pointer' }}
|
style={{ color: '#47D3D0', cursor: 'pointer' }}
|
||||||
onClick={resetClick}
|
onClick={resetClick}
|
||||||
>重置
|
>重置
|
||||||
</span>
|
</span> : null)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!accountPasswordStatus ? <div style={{ marginTop: '36px' }} className='drag'>
|
{!accountPasswordStatus ? <div style={{ marginTop: '36px' }} className={`drag`}>
|
||||||
<Button type="primary"
|
<Button type="primary"
|
||||||
onClick={continueClick}
|
onClick={continueClick}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
className={`${styles.loginButton} m-ant-btn`}
|
className={`${styles.loginButton} m-ant-btn`}
|
||||||
>继续</Button>
|
>继续</Button>
|
||||||
</div> : null}
|
</div> : null}
|
||||||
{accountPasswordStatus ? <div>
|
{accountPasswordStatus ? <div className={`animate__animated animate__fadeIn`}>
|
||||||
<Input.Password
|
<Input.Password
|
||||||
value={operation.password}
|
value={operation.password}
|
||||||
onChange={e => {
|
onChange={e => {
|
||||||
|
|
@ -200,11 +206,11 @@ const Login: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.footer}>
|
{/* <div className={styles.footer}>
|
||||||
<div></div>
|
<div></div>
|
||||||
<span>or</span>
|
<span>or</span>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div> */}
|
||||||
{/* <div className={`${styles.code} drag`}>
|
{/* <div className={`${styles.code} drag`}>
|
||||||
<div>
|
<div>
|
||||||
<Input placeholder="输入会议号" className={`${styles.loginInput}`} />
|
<Input placeholder="输入会议号" className={`${styles.loginInput}`} />
|
||||||
|
|
|
||||||
|
|
@ -340,16 +340,6 @@
|
||||||
|
|
||||||
>div {
|
>div {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 50%;
|
|
||||||
|
|
||||||
>img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,18 +472,7 @@
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
>div {
|
>div {}
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 50%;
|
|
||||||
|
|
||||||
>img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
>div:nth-child(2) {
|
>div:nth-child(2) {
|
||||||
|
|
@ -597,6 +576,19 @@
|
||||||
color: #EEEEEE;
|
color: #EEEEEE;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
>span {
|
||||||
|
color: #4096ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
>span {
|
||||||
|
color: darken(#4096ff, 10%) !important;
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import dayjs from 'dayjs';
|
||||||
import durationPlugin from 'dayjs/plugin/duration';
|
import durationPlugin from 'dayjs/plugin/duration';
|
||||||
import { VideoSourceType } from 'agora-electron-sdk';
|
import { VideoSourceType } from 'agora-electron-sdk';
|
||||||
import { GetUserList } from '@/api/Home/User';
|
import { GetUserList } from '@/api/Home/User';
|
||||||
|
import Avatar from '@/components/Avatar';
|
||||||
dayjs.extend(durationPlugin);
|
dayjs.extend(durationPlugin);
|
||||||
const { Column } = Table
|
const { Column } = Table
|
||||||
const Meeting: React.FC = () => {
|
const Meeting: React.FC = () => {
|
||||||
|
|
@ -122,7 +123,7 @@ const Meeting: React.FC = () => {
|
||||||
let time = null as any;
|
let time = null as any;
|
||||||
if (isInit) {
|
if (isInit) {
|
||||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
setMeetingMode(storage.getItem('meetingMode') as string || 'FreedomMode');
|
setMeetingMode('StandardMode');
|
||||||
agora.init()
|
agora.init()
|
||||||
agora.registerEventHandler({
|
agora.registerEventHandler({
|
||||||
onJoinChannelSuccess: async (info: any, _elapsed: any) => {
|
onJoinChannelSuccess: async (info: any, _elapsed: any) => {
|
||||||
|
|
@ -258,14 +259,14 @@ const Meeting: React.FC = () => {
|
||||||
switch (row.title) {
|
switch (row.title) {
|
||||||
case '成员列表':
|
case '成员列表':
|
||||||
setStatusList({
|
setStatusList({
|
||||||
userList: true,
|
userList: statusList.userList ? false : true,
|
||||||
userChatList: false,
|
userChatList: false,
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case '聊天':
|
case '聊天':
|
||||||
setStatusList({
|
setStatusList({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: true,
|
userChatList: statusList.userChatList ? false : true,
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case '共享屏幕':
|
case '共享屏幕':
|
||||||
|
|
@ -606,10 +607,9 @@ const Meeting: React.FC = () => {
|
||||||
<div className={styles.meetingUserListContent}>
|
<div className={styles.meetingUserListContent}>
|
||||||
{roomUserList.map((item: any, index: number) => {
|
{roomUserList.map((item: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
<>
|
item.isShow ? <div key={index + item.id} className='drag'>
|
||||||
{item.isShow ? <div key={index + item.id} className='drag'>
|
|
||||||
<div>
|
<div>
|
||||||
<div><img src={ImageUrl.avatar} alt="" /></div>
|
<div><Avatar name={item.userName} /></div>
|
||||||
<span>
|
<span>
|
||||||
{item.userName}
|
{item.userName}
|
||||||
{item.roleId === '1' || item.isManager ?
|
{item.roleId === '1' || item.isManager ?
|
||||||
|
|
@ -673,8 +673,7 @@ const Meeting: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
>踢出房间</Button>
|
>踢出房间</Button>
|
||||||
</div> : null}
|
</div> : null}
|
||||||
</div> : null}
|
</div> : null
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
|
|
@ -701,7 +700,7 @@ const Meeting: React.FC = () => {
|
||||||
key={index}
|
key={index}
|
||||||
className={`${item.uid !== state.uid ? styles.meetingUserChatContentLeft : styles.meetingUserChatContentRight} drag`}>
|
className={`${item.uid !== state.uid ? styles.meetingUserChatContentLeft : styles.meetingUserChatContentRight} drag`}>
|
||||||
<div>
|
<div>
|
||||||
<div><img src={ImageUrl.avatar} alt="" /></div>
|
<div><Avatar name={item.userName} /></div>
|
||||||
<span>{item.userName}</span>
|
<span>{item.userName}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>{item.message}</div>
|
<div>{item.message}</div>
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,11 @@ class Request {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
storage.setItem('user', JSON.stringify(res.data))
|
storage.setItem('user', JSON.stringify(res.data))
|
||||||
location.reload()
|
location.reload()
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
storage.removeItem('user')
|
||||||
|
location.href = location.origin + '/#/login'
|
||||||
|
}, 3000)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@ $pagination-hover-background-color: #5575F2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-input-data-count {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
.ant-input-affix-wrapper {
|
.ant-input-affix-wrapper {
|
||||||
background-color: $input-background-color !important;
|
background-color: $input-background-color !important;
|
||||||
border: 1px solid $input-border-color;
|
border: 1px solid $input-border-color;
|
||||||
|
|
@ -208,6 +212,9 @@ $pagination-hover-background-color: #5575F2;
|
||||||
color: black !important;
|
color: black !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.ant-pagination-item-ellipsis{
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// popover
|
// popover
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue