Commit a4e226a0 authored by liujiaxin's avatar liujiaxin

feat:添加检测用户是否开启音视频权限功能

parent 788c9a76
...@@ -115,7 +115,13 @@ ...@@ -115,7 +115,13 @@
"pack:win": "npm run electron:build && electron-builder --win" "pack:win": "npm run electron:build && electron-builder --win"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "react-app" "extends": "react-app",
"rules": {
"jsx-a11y/href-no-hash": "off",
"no-throw-literal": "off",
"react-hooks/rules-of-hooks": "off",
"react-hooks/exhaustive-deps": "off"
}
}, },
"browserslist": { "browserslist": {
"production": [ "production": [
......
import React, { useEffect, useRef, useState } from 'react'; import React from 'react';
import './toast.scss'; import './toast.scss';
import {useGlobalState, useRoomState} from '../containers/root-container'; import { useRoomState} from '../containers/root-container';
import { isEmpty } from 'lodash'; // import { isEmpty } from 'lodash';
import {roomStore} from "../stores/room"; // import {roomStore} from "../stores/room";
import EmojiEventsIcon from "@material-ui/icons/EmojiEvents"; import EmojiEventsIcon from "@material-ui/icons/EmojiEvents";
import {eventBus} from "../stores/EventBus"; import {eventBus} from "../stores/EventBus";
import Link from "@material-ui/core/Link"; import Link from "@material-ui/core/Link";
...@@ -35,7 +35,7 @@ export default function AddStarsButton({type, uid}: AddStarsButtonProps) { ...@@ -35,7 +35,7 @@ export default function AddStarsButton({type, uid}: AddStarsButtonProps) {
const me = useRoomState().me; const me = useRoomState().me;
const style = useStyles(); const style = useStyles();
const addStar = async () => { const addStar = async () => {
if (me.role != 'teacher') { if (me.role !== 'teacher') {
return return
} }
eventBus.emit('showAddStartDialog', {uid}) eventBus.emit('showAddStartDialog', {uid})
......
import React, {useRef, useEffect, useMemo, useState} from 'react'; import React, {useEffect, useState} from 'react';
import Icon from './icon'; // import Icon from './icon';
import './video-player.scss'; import './video-player.scss';
import { AgoraElectronStream, StreamType, nativeRTCClient as nativeClient } from '../utils/agora-electron-client'; // import { AgoraElectronStream, StreamType, nativeRTCClient as nativeClient } from '../utils/agora-electron-client';
import { useRoomState } from '../containers/root-container'; // import { useRoomState } from '../containers/root-container';
import { platform } from '../utils/platform'; // import { platform } from '../utils/platform';
import {makeStyles} from "@material-ui/core/styles"; import {makeStyles} from "@material-ui/core/styles";
import { endPoint } from '../services/agora-end-points'; import { endPoint } from '../services/agora-end-points';
const contentMode = 0; // const contentMode = 0;
const useStyles = makeStyles({ const useStyles = makeStyles({
...@@ -45,7 +45,8 @@ const useStyles = makeStyles({ ...@@ -45,7 +45,8 @@ const useStyles = makeStyles({
const CourseWareFrame: React.FC = () => { const CourseWareFrame: React.FC = () => {
const classes = useStyles(); const classes = useStyles();
// `${ENDPOINT}/airclass_ol?token=${this.userToken}`; // `${ENDPOINT}/airclass_ol?token=${this.userToken}`;
let src = endPoint.getCourseUrl(); const cw_src = endPoint.getCourseUrl();
const [src, setSrc] = useState<string>(cw_src);
let refDom: any = null; let refDom: any = null;
const saveRef = (ref: any) => {refDom = ref}; const saveRef = (ref: any) => {refDom = ref};
useEffect(() => { useEffect(() => {
...@@ -60,15 +61,16 @@ const CourseWareFrame: React.FC = () => { ...@@ -60,15 +61,16 @@ const CourseWareFrame: React.FC = () => {
} }
return () => { return () => {
src = 'about:blank' setSrc('about:blank');
console.log('iframe to blank'); console.log('iframe to blank');
} }
// eslint-disable-next-line
}, []); }, []);
return ( return (
<div ref={saveRef} className={classes.style1}> <div ref={saveRef} className={classes.style1}>
{/*<svg viewBox="0 0 0 0"></svg>*/} {/*<svg viewBox="0 0 0 0"></svg>*/}
<iframe id="cwFrame" src={src} className={classes.frm}></iframe> <iframe title="courseware-player " id="cwFrame" src={src} className={classes.frm}></iframe>
</div> </div>
) )
} }
......
...@@ -8,7 +8,7 @@ import {roomStore, windowMonitor} from '../../stores/room'; ...@@ -8,7 +8,7 @@ import {roomStore, windowMonitor} from '../../stores/room';
import {globalStore} from '../../stores/global'; import {globalStore} from '../../stores/global';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { RoomMessage } from '../../utils/agora-rtm-client'; import { RoomMessage } from '../../utils/agora-rtm-client';
import {getApiServerHost, goHome} from "../../services/agora-end-points"; import { goHome} from "../../services/agora-end-points";
interface RoomProps { interface RoomProps {
onConfirm: (type: string) => void onConfirm: (type: string) => void
......
import React, {useEffect, useMemo, useRef, useState} from 'react'; import React, {useMemo} from 'react';
import { useRoomState} from '../containers/root-container'; import { useRoomState} from '../containers/root-container';
import { isEmpty } from 'lodash'; // import { isEmpty } from 'lodash';
import {roomStore} from "../stores/room"; // import {roomStore} from "../stores/room";
import PanToolIcon from "@material-ui/icons/PanTool"; import PanToolIcon from "@material-ui/icons/PanTool";
import './hands-up-icon.scss'; import './hands-up-icon.scss';
...@@ -22,11 +22,11 @@ export default function HandsUpIcon({id, streamID}: UserStarsProps) { ...@@ -22,11 +22,11 @@ export default function HandsUpIcon({id, streamID}: UserStarsProps) {
// }, [state.handsUpStudents]); // }, [state.handsUpStudents]);
const isHandUp = useMemo(() => { const isHandUp = useMemo(() => {
const hu = roomStore.state.handsUpStudents[streamID]; const hu = state.handsUpStudents[streamID];
console.log(streamID, hu) console.log(streamID, hu)
return hu return hu
}, [roomStore.state.handsUpStudents]); // eslint-disable-next-line
}, [state]);
return ( return (
......
...@@ -19,11 +19,10 @@ import { roomStore } from '../stores/room'; ...@@ -19,11 +19,10 @@ import { roomStore } from '../stores/room';
import { whiteboard } from '../stores/whiteboard'; import { whiteboard } from '../stores/whiteboard';
import { globalStore } from '../stores/global'; import { globalStore } from '../stores/global';
import { platform } from '../utils/platform'; import { platform } from '../utils/platform';
import AgoraWebClient, { SHARE_ID } from '../utils/agora-rtc-client'; import AgoraWebClient from '../utils/agora-rtc-client';
import "white-web-sdk/style/index.css"; import "white-web-sdk/style/index.css";
import { ViewMode } from 'white-web-sdk'; import { ViewMode } from 'white-web-sdk';
const pathName = (path: string): string => { const pathName = (path: string): string => {
const reg = /\/([^/]*)\//g; const reg = /\/([^/]*)\//g;
reg.exec(path); reg.exec(path);
...@@ -183,6 +182,7 @@ const MediaBoard: React.FC<MediaBoardProps> = ({ ...@@ -183,6 +182,7 @@ const MediaBoard: React.FC<MediaBoardProps> = ({
const isHost = useMemo(() => { const isHost = useMemo(() => {
return +roomStore.state.me.uid === +roomStore.state.course.linkId; return +roomStore.state.me.uid === +roomStore.state.course.linkId;
// eslint-disable-next-line
}, [roomStore.state.me.uid, }, [roomStore.state.me.uid,
roomStore.state.course.linkId]); roomStore.state.course.linkId]);
...@@ -247,7 +247,7 @@ const MediaBoard: React.FC<MediaBoardProps> = ({ ...@@ -247,7 +247,7 @@ const MediaBoard: React.FC<MediaBoardProps> = ({
const showControl: boolean = useMemo(() => { const showControl: boolean = useMemo(() => {
if (me.role === 'teacher') return true; if (me.role === 'teacher') return true;
return false; return false;
}, []); }, [me.role]);
const items = [ const items = [
{ {
...@@ -294,8 +294,10 @@ const items = [ ...@@ -294,8 +294,10 @@ const items = [
if (['add', 'folder', 'upload'].indexOf(item.name) === -1) { if (['add', 'folder', 'upload'].indexOf(item.name) === -1) {
return item; return item;
} }
return null;
}) })
}, []); // eslint-disable-next-line
}, [items]);
const drawable: string = useMemo(() => { const drawable: string = useMemo(() => {
if (location.pathname.match('small-class')) { if (location.pathname.match('small-class')) {
...@@ -312,6 +314,7 @@ const items = [ ...@@ -312,6 +314,7 @@ const items = [
} }
} }
return 'drawable'; return 'drawable';
// eslint-disable-next-line
}, [me.role, me.grantBoard, location]); }, [me.role, me.grantBoard, location]);
const [tool, setTool] = useState<string | any>(drawable === 'drawable' ? 'pencil' : ''); const [tool, setTool] = useState<string | any>(drawable === 'drawable' ? 'pencil' : '');
...@@ -372,6 +375,7 @@ const items = [ ...@@ -372,6 +375,7 @@ const items = [
}).catch(console.warn); }).catch(console.warn);
} }
// eslint-disable-next-line
}, []); }, []);
useEffect(() => { useEffect(() => {
...@@ -436,6 +440,7 @@ const items = [ ...@@ -436,6 +440,7 @@ const items = [
}) })
} }
*/ */
// eslint-disable-next-line
}, [rtmState.joined, me.boardId, course.boardId]); }, [rtmState.joined, me.boardId, course.boardId]);
const [uploadPhase, updateUploadPhase] = useState<string>(''); const [uploadPhase, updateUploadPhase] = useState<string>('');
...@@ -443,6 +448,7 @@ const items = [ ...@@ -443,6 +448,7 @@ const items = [
useEffect(() => { useEffect(() => {
console.log("[mediaboard] uploadPhase: ", uploadPhase, " convertPhase: ", convertPhase); console.log("[mediaboard] uploadPhase: ", uploadPhase, " convertPhase: ", convertPhase);
// eslint-disable-next-line
}, [uploadPhase, convertPhase]); }, [uploadPhase, convertPhase]);
const UploadPanel = useCallback(() => { const UploadPanel = useCallback(() => {
...@@ -483,6 +489,7 @@ const items = [ ...@@ -483,6 +489,7 @@ const items = [
} }
}} }}
/>) />)
// eslint-disable-next-line
}, [tool, room]); }, [tool, room]);
useEffect(() => { useEffect(() => {
...@@ -524,11 +531,12 @@ const items = [ ...@@ -524,11 +531,12 @@ const items = [
room.setViewMode(ViewMode.Freedom); room.setViewMode(ViewMode.Freedom);
} }
} }
// eslint-disable-next-line
}, [room, roomStore.state.course.lockBoard, roomStore.state.me.role]); }, [room, roomStore.state.course.lockBoard, roomStore.state.me.role]);
const globalState = useGlobalState(); const globalState = useGlobalState();
const scale = whiteboardState.scale ? whiteboardState.scale : 1; // const scale = whiteboardState.scale ? whiteboardState.scale : 1;
const UploadProgressView = useCallback(() => { const UploadProgressView = useCallback(() => {
if (uploadPhase === 'uploading') { if (uploadPhase === 'uploading') {
...@@ -583,7 +591,7 @@ const items = [ ...@@ -583,7 +591,7 @@ const items = [
items={toolItems} items={toolItems}
currentTool={tool} currentTool={tool}
handleToolClick={handleToolClick} /> handleToolClick={handleToolClick} />
{tool === 'color_picker' && strokeColor && roomStore.state.me.role == 'teacher'? {tool === 'color_picker' && strokeColor && roomStore.state.me.role === 'teacher'?
<SketchPicker <SketchPicker
color={strokeColor} color={strokeColor}
onChangeComplete={onColorChanged} /> onChangeComplete={onColorChanged} />
......
import React, { useRef, useEffect, useMemo } from 'react'; import React, { useRef, useEffect, useMemo } from 'react';
import Icon from './icon'; // import Icon from './icon';
import './member-holder.scss'; import './member-holder.scss';
import { AgoraElectronStream, StreamType, nativeRTCClient as nativeClient } from '../utils/agora-electron-client'; import { nativeRTCClient as nativeClient } from '../utils/agora-electron-client';
import { useRoomState } from '../containers/root-container'; import { useRoomState } from '../containers/root-container';
import { platform } from '../utils/platform'; import { platform } from '../utils/platform';
import AccountCircle from '@material-ui/icons/AccountCircle'; import AccountCircle from '@material-ui/icons/AccountCircle';
import Link from '@material-ui/core/Link'; import Link from '@material-ui/core/Link';
import PanToolIcon from '@material-ui/icons/PanTool'; // import PanToolIcon from '@material-ui/icons/PanTool';
import {roomStore} from "../stores/room"; // import {roomStore} from "../stores/room";
import UserStars from "./user-stars"; import UserStars from "./user-stars";
import {eventBus} from "../stores/EventBus"; // import {eventBus} from "../stores/EventBus";
import AddStarsButton, { StarsButtonType } from './add-stars-btn'; import AddStarsButton, { StarsButtonType } from './add-stars-btn';
import HandsUpIcon from "./hands-up-icon"; import HandsUpIcon from "./hands-up-icon";
const contentMode = 0; // const contentMode = 0;
interface MemberHolderProps { interface MemberHolderProps {
id?: string id?: string
...@@ -45,10 +45,11 @@ const MemberHolder: React.FC<MemberHolderProps> = ({ ...@@ -45,10 +45,11 @@ const MemberHolder: React.FC<MemberHolderProps> = ({
const loadVideo = useRef<boolean>(false); const loadVideo = useRef<boolean>(false);
const loadAudio = useRef<boolean>(false); const loadAudio = useRef<boolean>(false);
const lockPlay = useRef<boolean>(false); // const lockPlay = useRef<boolean>(false);
const AgoraRtcEngine = useMemo(() => { const AgoraRtcEngine = useMemo(() => {
return nativeClient.rtcEngine; return nativeClient.rtcEngine;
// eslint-disable-next-line
}, [nativeClient.rtcEngine]); }, [nativeClient.rtcEngine]);
/* /*
useEffect(() => { useEffect(() => {
...@@ -206,12 +207,13 @@ const MemberHolder: React.FC<MemberHolderProps> = ({ ...@@ -206,12 +207,13 @@ const MemberHolder: React.FC<MemberHolderProps> = ({
} }
} }
}, [stream, video, AgoraRtcEngine]); }, [stream, video, AgoraRtcEngine]);
/*
const onAudioClick = (evt: any) => { const onAudioClick = (evt: any) => {
if (handleClick && id) { if (handleClick && id) {
handleClick('audio', streamID, id); handleClick('audio', streamID, id);
} }
} }
*/
const onStageUp = (evt: any) => { const onStageUp = (evt: any) => {
if (handleClick && id) { if (handleClick && id) {
...@@ -219,6 +221,7 @@ const MemberHolder: React.FC<MemberHolderProps> = ({ ...@@ -219,6 +221,7 @@ const MemberHolder: React.FC<MemberHolderProps> = ({
} }
} }
/*
const onVideoClick = (evt: any) => { const onVideoClick = (evt: any) => {
if (handleClick && id) { if (handleClick && id) {
handleClick('video', streamID, id); handleClick('video', streamID, id);
...@@ -230,12 +233,14 @@ const MemberHolder: React.FC<MemberHolderProps> = ({ ...@@ -230,12 +233,14 @@ const MemberHolder: React.FC<MemberHolderProps> = ({
handleClose('close', streamID); handleClose('close', streamID);
} }
} }
const addStar = (evt: any) => { const addStar = (evt: any) => {
if (me.role != 'teacher') { if (me.role != 'teacher') {
return return
} }
eventBus.emit('showAddStartDialog', {uid: id}); eventBus.emit('showAddStartDialog', {uid: id});
} }
*/
const me = useRoomState().me; const me = useRoomState().me;
return ( return (
......
...@@ -13,8 +13,8 @@ import { isElectron, platform } from '../utils/platform'; ...@@ -13,8 +13,8 @@ import { isElectron, platform } from '../utils/platform';
import { useRoomState } from '../containers/root-container'; import { useRoomState } from '../containers/root-container';
import { roomStore } from '../stores/room'; import { roomStore } from '../stores/room';
import { globalStore } from '../stores/global'; import { globalStore } from '../stores/global';
import VoiceOverOffIcon from '@material-ui/icons/VoiceOverOff'; // import VoiceOverOffIcon from '@material-ui/icons/VoiceOverOff';
import RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver'; // import RecordVoiceOverIcon from '@material-ui/icons/RecordVoiceOver';
import RoomToolsBar from "./room-tools-bar"; import RoomToolsBar from "./room-tools-bar";
interface NavProps { interface NavProps {
delay: string delay: string
...@@ -123,6 +123,7 @@ export default function NavContainer() { ...@@ -123,6 +123,7 @@ export default function NavContainer() {
setTimer(null); setTimer(null);
} }
} }
// eslint-disable-next-line
}, []); }, []);
const roomState = useRoomState(); const roomState = useRoomState();
...@@ -169,6 +170,7 @@ export default function NavContainer() { ...@@ -169,6 +170,7 @@ export default function NavContainer() {
nativeClient.off('audioquality', () => {}); nativeClient.off('audioquality', () => {});
} }
} }
// eslint-disable-next-line
}, []); }, []);
const courseState = roomState.course.courseState; const courseState = roomState.course.courseState;
...@@ -184,6 +186,7 @@ export default function NavContainer() { ...@@ -184,6 +186,7 @@ export default function NavContainer() {
clearInterval(timer); clearInterval(timer);
setTimer(null); setTimer(null);
} }
// eslint-disable-next-line
}, [courseState]); }, [courseState]);
const lock = useRef<boolean>(false); const lock = useRef<boolean>(false);
......
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { useGlobalState } from '../containers/root-container';
const useStyles = makeStyles(theme => ({
progress: {
margin: theme.spacing(2),
color: '#44A2FC'
},
container: {
position: 'absolute',
top: '0px',
left: '0px',
height: '100%',
width: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor:'rgba(0, 0, 0, 0.5)',
// opacity: 0.8,
zIndex: 10
},
textWrap:{
padding: 32,
}
}));
export const Permission: React.FC<{}> = () => {
const classes = useStyles();
return (
<div className={classes.container}>
<div>
<div className="custom-card">
<div className="flex-item cover">
<div className="preview-video">
<div className="permission-placeholder"></div>
</div>
</div>
<div className="flex-item card">
<div className={classes.textWrap}>
<h3>提示</h3>
<p>请先开启摄像头、麦克风权限,<b>否则将无法正常上课!!!</b></p>
<p><b>第一步</b>:按照如下方法,设置摄像头/麦克风权限为<b>“允许”</b>
点击浏览器地址旁边的小锁头,在弹出的窗口中,设置摄像头/麦克风权限为<b>“允许”</b></p>
<p><b>第二步</b>:设置完成后,根据提示,点击<b>“重新加载”</b></p>
</div>
</div>
</div>
</div>
</div>
);
}
export default function PermissionContainer () {
const state = useGlobalState();
const permission = state.permission;
return (
permission ? <Permission /> : null
)
}
import React, {useMemo, useState} from 'react'; import React, {useMemo} from 'react';
import ChatPanel from './chat/panel'; // import ChatPanel from './chat/panel';
import StudentList from './student-list'; // import StudentList from './student-list';
import useChatText from '../hooks/use-chat-text'; // import useChatText from '../hooks/use-chat-text';
import { VolumeOff, VolumeUp, ImportExport } from '@material-ui/icons'; // import { VolumeOff, VolumeUp, ImportExport } from '@material-ui/icons';
import {roomStore} from "../stores/room"; import {roomStore} from "../stores/room";
import {useRoomState} from "../containers/root-container"; import {useRoomState} from "../containers/root-container";
import './room-tools-bar.scss'; import './room-tools-bar.scss';
...@@ -13,8 +13,8 @@ import ImportContacts from "@material-ui/icons/ImportContacts"; ...@@ -13,8 +13,8 @@ import ImportContacts from "@material-ui/icons/ImportContacts";
import SettingsApplicationsIcon from '@material-ui/icons/SettingsApplications'; import SettingsApplicationsIcon from '@material-ui/icons/SettingsApplications';
import SettingsPowerIcon from '@material-ui/icons/SettingsPower'; import SettingsPowerIcon from '@material-ui/icons/SettingsPower';
import {TOOL_TYPE} from "../utils/types"; import {TOOL_TYPE} from "../utils/types";
import EmojiEventsIcon from '@material-ui/icons/EmojiEvents'; // import EmojiEventsIcon from '@material-ui/icons/EmojiEvents';
import {eventBus} from "../stores/EventBus"; // import {eventBus} from "../stores/EventBus";
import AddStarsButton, {StarsButtonType} from './add-stars-btn'; import AddStarsButton, {StarsButtonType} from './add-stars-btn';
type Props = { type Props = {
...@@ -28,7 +28,7 @@ export default function RoomToolsBar (props: any) { ...@@ -28,7 +28,7 @@ export default function RoomToolsBar (props: any) {
const roomState = useRoomState(); const roomState = useRoomState();
const changeTool = async () => { const changeTool = async () => {
console.log(roomStore.state.course.currentTool); console.log(roomStore.state.course.currentTool);
if (roomStore.state.course.currentTool == TOOL_TYPE.WHITEBOARD) { if (roomStore.state.course.currentTool === TOOL_TYPE.WHITEBOARD) {
await roomStore.setCurrentTool(TOOL_TYPE.COURSE_WARE) await roomStore.setCurrentTool(TOOL_TYPE.COURSE_WARE)
} else { } else {
await roomStore.setCurrentTool(TOOL_TYPE.WHITEBOARD) await roomStore.setCurrentTool(TOOL_TYPE.WHITEBOARD)
...@@ -38,6 +38,7 @@ export default function RoomToolsBar (props: any) { ...@@ -38,6 +38,7 @@ export default function RoomToolsBar (props: any) {
return { return {
currentTool: roomStore.state.course.currentTool currentTool: roomStore.state.course.currentTool
} }
// eslint-disable-next-line
}, [roomState]); }, [roomState]);
const {muteAudio} = useMemo(() => { const {muteAudio} = useMemo(() => {
...@@ -56,15 +57,15 @@ export default function RoomToolsBar (props: any) { ...@@ -56,15 +57,15 @@ export default function RoomToolsBar (props: any) {
// const allAddStar = async () => { // const allAddStar = async () => {
// eventBus.emit('showAddStartDialog', {uid: 0}) // eventBus.emit('showAddStartDialog', {uid: 0})
// } // }
const randomStageUp = async () => { // const randomStageUp = async () => {
await roomStore.randomStageUp() // await roomStore.randomStageUp()
} // }
return ( return (
<> <>
<div className={'room-tool-box'}> <div className={'room-tool-box'}>
{roomStore.state.me.role == 'teacher' ? {roomStore.state.me.role === 'teacher' ?
<> <>
<AddStarsButton type={StarsButtonType.BIG} uid={0}></AddStarsButton> <AddStarsButton type={StarsButtonType.BIG} uid={0}></AddStarsButton>
{/*<div className="tool-btn" onClick={allAddStar}><EmojiEventsIcon/></div>*/} {/*<div className="tool-btn" onClick={allAddStar}><EmojiEventsIcon/></div>*/}
...@@ -72,7 +73,7 @@ export default function RoomToolsBar (props: any) { ...@@ -72,7 +73,7 @@ export default function RoomToolsBar (props: any) {
? <div className="tool-btn" onClick={allMuteOff}><RecordVoiceOverIcon/></div> ? <div className="tool-btn" onClick={allMuteOff}><RecordVoiceOverIcon/></div>
: <div onClick={allMuteOn} className="tool-btn"><VoiceOverOffIcon/></div> : <div onClick={allMuteOn} className="tool-btn"><VoiceOverOffIcon/></div>
} }
{currentTool == TOOL_TYPE.WHITEBOARD {currentTool === TOOL_TYPE.WHITEBOARD
? <div className="tool-btn" onClick={changeTool}><ImportContacts/></div> ? <div className="tool-btn" onClick={changeTool}><ImportContacts/></div>
: <div onClick={changeTool} className="tool-btn"><Category/></div> : <div onClick={changeTool} className="tool-btn"><Category/></div>
} }
......
...@@ -5,7 +5,6 @@ import Button from './custom-button'; ...@@ -5,7 +5,6 @@ import Button from './custom-button';
import FormSelect from './form-select'; import FormSelect from './form-select';
import SpeakerVolume from './volume/speaker'; import SpeakerVolume from './volume/speaker';
import useSettingControl from '../hooks/use-setting-control'; import useSettingControl from '../hooks/use-setting-control';
import { usePlatform } from '../containers/platform-container'; import { usePlatform } from '../containers/platform-container';
const useStyles = makeStyles ({ const useStyles = makeStyles ({
...@@ -34,7 +33,7 @@ export default function (props: SettingProps) { ...@@ -34,7 +33,7 @@ export default function (props: SettingProps) {
setCamera, setCamera,
setMicrophone, setMicrophone,
setSpeaker, setSpeaker,
volume, /*volume,*/
speakerVolume, speakerVolume,
setSpeakerVolume, setSpeakerVolume,
save, save,
......
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import './toast.scss'; import './toast.scss';
import {useGlobalState} from '../containers/root-container'; import {useGlobalState} from '../containers/root-container';
import { isEmpty } from 'lodash'; // import { isEmpty } from 'lodash';
export interface SnackbarMessage { export interface SnackbarMessage {
message: string; message: string;
...@@ -30,6 +30,7 @@ export default function ConsecutiveSnackbars({ ...@@ -30,6 +30,7 @@ export default function ConsecutiveSnackbars({
timerRef.current = null; timerRef.current = null;
}, duration); }, duration);
} }
// eslint-disable-next-line
}, [messages]); }, [messages]);
useEffect(() => { useEffect(() => {
...@@ -40,6 +41,7 @@ export default function ConsecutiveSnackbars({ ...@@ -40,6 +41,7 @@ export default function ConsecutiveSnackbars({
}) })
setMessages([...queueRef.current]); setMessages([...queueRef.current]);
} }
// eslint-disable-next-line
}, [globalState.toast]); }, [globalState.toast]);
return ( return (
......
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useState } from 'react';
import './toast.scss'; import './toast.scss';
import {useGlobalState} from '../containers/root-container'; // import {useGlobalState} from '../containers/root-container';
import { isEmpty } from 'lodash'; // import { isEmpty } from 'lodash';
import {roomStore} from "../stores/room"; import {roomStore} from "../stores/room";
...@@ -25,7 +25,8 @@ export default function UserStars({id, streamID}: UserStarsProps) { ...@@ -25,7 +25,8 @@ export default function UserStars({id, streamID}: UserStarsProps) {
} }
} }
// setStar() // setStar()
}, [roomStore.state.userStars]); // eslint-disable-next-line
}, [roomStore.state.userStars, streamID]);
......
import React, {useRef, useEffect, useMemo, useState} from 'react'; import React, {useRef, useEffect, useMemo} from 'react';
import Icon from './icon'; import Icon from './icon';
import './video-player.scss'; import './video-player.scss';
import { AgoraElectronStream, StreamType, nativeRTCClient as nativeClient } from '../utils/agora-electron-client'; import { AgoraElectronStream, StreamType, nativeRTCClient as nativeClient } from '../utils/agora-electron-client';
...@@ -8,7 +8,7 @@ import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward'; ...@@ -8,7 +8,7 @@ import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward';
import {makeStyles} from '@material-ui/core/styles'; import {makeStyles} from '@material-ui/core/styles';
import {roomStore} from "../stores/room"; import {roomStore} from "../stores/room";
import BuildIcon from '@material-ui/icons/Build'; import BuildIcon from '@material-ui/icons/Build';
import {eventBus} from "../stores/EventBus"; // import {eventBus} from "../stores/EventBus";
// import StarIcon from '@material-ui/icons/Star'; // import StarIcon from '@material-ui/icons/Star';
// import EmojiEventsOutlinedIcon from '@material-ui/icons/EmojiEventsOutlined'; // import EmojiEventsOutlinedIcon from '@material-ui/icons/EmojiEventsOutlined';
import UserStars from './user-stars'; import UserStars from './user-stars';
...@@ -108,6 +108,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ ...@@ -108,6 +108,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
const AgoraRtcEngine = useMemo(() => { const AgoraRtcEngine = useMemo(() => {
return nativeClient.rtcEngine; return nativeClient.rtcEngine;
// eslint-disable-next-line
}, [nativeClient.rtcEngine]); }, [nativeClient.rtcEngine]);
useEffect(() => { useEffect(() => {
...@@ -168,11 +169,13 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ ...@@ -168,11 +169,13 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
} }
} }
} }
// eslint-disable-next-line
}, [domId, stream, AgoraRtcEngine]); }, [domId, stream, AgoraRtcEngine]);
useEffect(() => { useEffect(() => {
if (platform === 'web') { if (platform === 'web') {
if (!stream || !domId || lockPlay.current && stream.isPlaying()) return; if (!stream || !domId || (lockPlay.current && stream.isPlaying())) return;
lockPlay.current = true; lockPlay.current = true;
/*const playFn = () => { /*const playFn = () => {
if (reloadStreamTimer) { if (reloadStreamTimer) {
...@@ -221,6 +224,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ ...@@ -221,6 +224,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
local && stream && stream.close(); local && stream && stream.close();
} }
} }
// eslint-disable-next-line
}, [domId, stream]); }, [domId, stream]);
/* /*
...@@ -277,6 +281,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ ...@@ -277,6 +281,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
console.log("[agora-electron] muteLocalAudioStream(true); ", res); console.log("[agora-electron] muteLocalAudioStream(true); ", res);
} }
} }
// eslint-disable-next-line
}, [stream, audio, AgoraRtcEngine]); }, [stream, audio, AgoraRtcEngine]);
useEffect(() => { useEffect(() => {
...@@ -319,6 +324,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ ...@@ -319,6 +324,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
console.log("[agora-electron] muteLocalVideoStream(true); ", res); console.log("[agora-electron] muteLocalVideoStream(true); ", res);
} }
} }
// eslint-disable-next-line
}, [stream, video, AgoraRtcEngine]); }, [stream, video, AgoraRtcEngine]);
const onAudioClick = (evt: any) => { const onAudioClick = (evt: any) => {
...@@ -350,16 +356,16 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ ...@@ -350,16 +356,16 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
handleClose('close', streamID); handleClose('close', streamID);
} }
} }
const addStar = (evt: any) => { // const addStar = (evt: any) => {
if (me.role != 'teacher') { // if (me.role != 'teacher') {
return // return
} // }
eventBus.emit('showAddStartDialog', {uid: id}); // eventBus.emit('showAddStartDialog', {uid: id});
} // }
const resumeStream = (evt: any) => { // const resumeStream = (evt: any) => {
stateError.current = false; // stateError.current = false;
stream.resume() // stream.resume()
} // }
const me = useRoomState().me; const me = useRoomState().me;
const teacherId = useRoomState().course.teacherId; const teacherId = useRoomState().course.teacherId;
...@@ -372,7 +378,7 @@ return ( ...@@ -372,7 +378,7 @@ return (
{preview ? null : {preview ? null :
account ? account ?
<> <>
{ streamID > 0 && id != teacherId? { streamID > 0 && id !== teacherId?
<> <>
<UserStars id={id} streamID={streamID}></UserStars> <UserStars id={id} streamID={streamID}></UserStars>
<div className="hands-wrapper"> <div className="hands-wrapper">
...@@ -399,7 +405,7 @@ return ( ...@@ -399,7 +405,7 @@ return (
<> <>
{id != roomStore.state.course.teacherId {id !== roomStore.state.course.teacherId
? ?
<> <>
{/*<EmojiEventsOutlinedIcon onClick={addStar} className={style.emojiEvent}></EmojiEventsOutlinedIcon>*/} {/*<EmojiEventsOutlinedIcon onClick={addStar} className={style.emojiEvent}></EmojiEventsOutlinedIcon>*/}
......
import React, { useRef, useEffect, useState, useLayoutEffect } from 'react'; import React, { useRef, useEffect, useState } from 'react';
import VideoPlayer from './video-player'; import VideoPlayer from './video-player';
// import Icon from './icon'; // import Icon from './icon';
import {ExpandMore, ExpandLess} from '@material-ui/icons'; import {ExpandMore, ExpandLess} from '@material-ui/icons';
...@@ -7,8 +7,8 @@ import useStream from '../hooks/use-streams'; ...@@ -7,8 +7,8 @@ import useStream from '../hooks/use-streams';
import { AgoraMediaStream } from '../utils/types'; import { AgoraMediaStream } from '../utils/types';
import {STAGE_NUM} from "../utils/consts"; import {STAGE_NUM} from "../utils/consts";
import MemberHolder from "./member-holder"; import MemberHolder from "./member-holder";
import { Dialog, Button, DialogContent, DialogActions, TextField, DialogContentText, DialogTitle } from '@material-ui/core'; // import { Dialog, Button, DialogContent, DialogActions, TextField, DialogContentText, DialogTitle } from '@material-ui/core';
import { roomStore } from '../stores/room'; // import { roomStore } from '../stores/room';
function VideoShowList() { function VideoShowList() {
......
...@@ -32,6 +32,7 @@ export default function ContinuousSlider(props: SliderProps) { ...@@ -32,6 +32,7 @@ export default function ContinuousSlider(props: SliderProps) {
useEffect(() => { useEffect(() => {
props.onChange(value); props.onChange(value);
// eslint-disable-next-line
}, [value]); }, [value]);
return ( return (
......
import React, { useRef } from 'react'; import React from 'react';
import Icon from '../icon'; import Icon from '../icon';
import { roomStore } from '../../stores/room'; // import { roomStore } from '../../stores/room';
import { whiteboard } from '../../stores/whiteboard'; // import { whiteboard } from '../../stores/whiteboard';
import moment from 'moment'; // import moment from 'moment';
import { globalStore } from '../../stores/global'; // import { globalStore } from '../../stores/global';
import { getOSSUrl } from '../../utils/helper'; // import { getOSSUrl } from '../../utils/helper';
interface ControlItemProps { interface ControlItemProps {
name: string name: string
onClick: (evt: any, name: string) => void onClick: (evt: any, name: string) => void
...@@ -58,8 +58,8 @@ export default function Control({ ...@@ -58,8 +58,8 @@ export default function Control({
role, role,
notice, notice,
}: ControlProps) { }: ControlProps) {
const lock = useRef<boolean>(false); // const lock = useRef<boolean>(false);
/*
const canStop = () => { const canStop = () => {
const timeMoment = moment(whiteboard.state.startTime).add(15, 'seconds'); const timeMoment = moment(whiteboard.state.startTime).add(15, 'seconds');
if (+timeMoment >= +Date.now()) { if (+timeMoment >= +Date.now()) {
...@@ -70,8 +70,9 @@ export default function Control({ ...@@ -70,8 +70,9 @@ export default function Control({
return false; return false;
} }
return true; return true;
} }*/
/*
const onRecordButtonClick = (evt: any, type: string) => { const onRecordButtonClick = (evt: any, type: string) => {
handleRecording(evt, type) handleRecording(evt, type)
.then(() => {}).catch(console.warn); .then(() => {}).catch(console.warn);
...@@ -124,7 +125,7 @@ export default function Control({ ...@@ -124,7 +125,7 @@ export default function Control({
} }
} }
} }
*/
return ( return (
<div className="controls-container"> <div className="controls-container">
<div className="interactive"> <div className="interactive">
......
import React from 'react'; import React from 'react';
import OSS from "ali-oss"; // import OSS from "ali-oss";
import uuidv4 from 'uuid/v4'; import uuidv4 from 'uuid/v4';
import { PPTProgressListener, UploadManager } from "../../../utils/upload-manager"; import { PPTProgressListener, UploadManager } from "../../../utils/upload-manager";
import { PptKind, Room } from "white-web-sdk"; import { Room } from "white-web-sdk";
import {ossConfig, ossClient, resolveFileInfo, getOssClient} from '../../../utils/helper'; import {ossConfig, resolveFileInfo, getOssClient} from '../../../utils/helper';
import { whiteboard } from '../../../stores/whiteboard'; import { whiteboard } from '../../../stores/whiteboard';
export type UploadBtnProps = { export type UploadBtnProps = {
...@@ -18,6 +18,7 @@ export const UploadBtn: React.FC<UploadBtnProps> = ({ ...@@ -18,6 +18,7 @@ export const UploadBtn: React.FC<UploadBtnProps> = ({
room, uuid, roomToken, room, uuid, roomToken,
onProgress, onFailure onProgress, onFailure
}) => { }) => {
/*
const uploadDynamic = async (event: any) => { const uploadDynamic = async (event: any) => {
try { try {
const file = event.currentTarget.files[0]; const file = event.currentTarget.files[0];
...@@ -60,7 +61,7 @@ export const UploadBtn: React.FC<UploadBtnProps> = ({ ...@@ -60,7 +61,7 @@ export const UploadBtn: React.FC<UploadBtnProps> = ({
console.warn(err) console.warn(err)
} }
} }
*/
const uploadImage = async (event: any) => { const uploadImage = async (event: any) => {
try { try {
const file = event.currentTarget.files[0]; const file = event.currentTarget.files[0];
......
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import Icon from '../components/icon'; import Icon from '../components/icon';
import _, {isFunction} from 'lodash'; import _ from 'lodash';
import { useLocation } from 'react-router'; import { useLocation } from 'react-router';
export interface IPlatformContext { export interface IPlatformContext {
......
...@@ -6,7 +6,7 @@ import { useHistory, useLocation } from 'react-router-dom'; ...@@ -6,7 +6,7 @@ import { useHistory, useLocation } from 'react-router-dom';
import { resolveMessage, resolvePeerMessage, resolveChannelAttrs, jsonParse } from '../utils/helper'; import { resolveMessage, resolvePeerMessage, resolveChannelAttrs, jsonParse } from '../utils/helper';
import GlobalStorage from '../utils/custom-storage'; import GlobalStorage from '../utils/custom-storage';
import {endPoint, goHome} from "../services/agora-end-points"; import {endPoint, goHome} from "../services/agora-end-points";
import {Map as immuMap} from "immutable"; // import {Map as immuMap} from "immutable";
export type IRootProvider = { export type IRootProvider = {
globalState: GlobalState globalState: GlobalState
...@@ -29,7 +29,7 @@ function useObserver<T>(store: IObserver<T>) { ...@@ -29,7 +29,7 @@ function useObserver<T>(store: IObserver<T>) {
return () => { return () => {
store.unsubscribe(); store.unsubscribe();
} }
}, []); }, [store]);
return state; return state;
} }
...@@ -114,7 +114,7 @@ export const RootProvider: React.FC<any> = ({children}) => { ...@@ -114,7 +114,7 @@ export const RootProvider: React.FC<any> = ({children}) => {
}).catch(console.warn); }).catch(console.warn);
}); });
rtmClient.on("AttributesUpdated", (attributes: object) => { rtmClient.on("AttributesUpdated", (attributes: object) => {
if (Object.keys(attributes).length == 0) { if (Object.keys(attributes).length === 0) {
globalStore.showToast({ globalStore.showToast({
type: 'rtmClient', type: 'rtmClient',
message: 'teacher close classroom' message: 'teacher close classroom'
...@@ -165,6 +165,7 @@ export const RootProvider: React.FC<any> = ({children}) => { ...@@ -165,6 +165,7 @@ export const RootProvider: React.FC<any> = ({children}) => {
return () => { return () => {
rtmClient.removeAllListeners(); rtmClient.removeAllListeners();
} }
// eslint-disable-next-line
}, [roomStore.state.rtm.joined]); }, [roomStore.state.rtm.joined]);
const location = useLocation(); const location = useLocation();
...@@ -199,7 +200,7 @@ export const RootProvider: React.FC<any> = ({children}) => { ...@@ -199,7 +200,7 @@ export const RootProvider: React.FC<any> = ({children}) => {
window.whiteboard = whiteboardState; window.whiteboard = whiteboardState;
//@ts-ignore //@ts-ignore
window.store = globalStore; window.store = globalStore;
// eslint-disable-next-line
}, [value, location]); }, [value, location]);
return ( return (
......
...@@ -42,7 +42,7 @@ export default function useChatText () { ...@@ -42,7 +42,7 @@ export default function useChatText () {
setValue(evt.target.value.slice(0, 100)); setValue(evt.target.value.slice(0, 100));
} }
const list = useMemo(() => { const list = useMemo(() => {
if (!roomState.me.uid || !roomState.rtc.users.count() && !roomState.rtc.localStream) return []; if (!roomState.me.uid || !roomState.rtc.users.count() /*&& !roomState.rtc.localStream*/) return [];
const my = roomState.users.get(roomState.me.uid); const my = roomState.users.get(roomState.me.uid);
const users = []; const users = [];
if (my) { if (my) {
...@@ -55,7 +55,7 @@ export default function useChatText () { ...@@ -55,7 +55,7 @@ export default function useChatText () {
} }
} }
return users.filter((user: AgoraUser) => user.role === 'student'); return users.filter((user: AgoraUser) => user.role === 'student');
}, [roomState.me.uid, roomState.rtc.users, roomState.users, roomState.rtc.localStream]); }, [roomState.me.uid, roomState.rtc.users, roomState.users/*, roomState.rtc.localStream*/]);
return { return {
list, list,
......
...@@ -43,13 +43,13 @@ export default function useSettingControl () { ...@@ -43,13 +43,13 @@ export default function useSettingControl () {
const [speakerVolume, setSpeakerVolume] = useState<number>(mediaDevice.speakerVolume); const [speakerVolume, setSpeakerVolume] = useState<number>(mediaDevice.speakerVolume);
const [volume, setVolume] = useState<number>(0); const [volume, setVolume] = useState<number>(0);
let mounted = false; const mounted = useRef<boolean>(false);
useEffect(() => { useEffect(() => {
const rtcClient: AgoraWebClient | AgoraElectronClient = roomStore.rtcClient; const rtcClient: AgoraWebClient | AgoraElectronClient = roomStore.rtcClient;
if (!platform || !rtcClient) return; if (!platform || !rtcClient) return;
if (platform === 'web' && !mounted) { if (platform === 'web' && !mounted.current) {
const webClient = rtcClient as AgoraWebClient; const webClient = rtcClient as AgoraWebClient;
const onChange = async () => { const onChange = async () => {
const devices: Device[] = await webClient.getDevices(); const devices: Device[] = await webClient.getDevices();
...@@ -62,13 +62,13 @@ export default function useSettingControl () { ...@@ -62,13 +62,13 @@ export default function useSettingControl () {
window.addEventListener('devicechange', onChange); window.addEventListener('devicechange', onChange);
onChange().then(() => { onChange().then(() => {
}).catch(console.warn); }).catch(console.warn);
mounted = true; mounted.current = true;
return () => { return () => {
window.removeEventListener('devicechange', onChange); window.removeEventListener('devicechange', onChange);
} }
} }
if (platform === 'electron' && !mounted) { if (platform === 'electron' && !mounted.current) {
const nativeClient = rtcClient as AgoraElectronClient; const nativeClient = rtcClient as AgoraElectronClient;
const onChange = async () => { const onChange = async () => {
...@@ -100,7 +100,7 @@ export default function useSettingControl () { ...@@ -100,7 +100,7 @@ export default function useSettingControl () {
nativeClient.on('videodevicestatechanged', onChange); nativeClient.on('videodevicestatechanged', onChange);
nativeClient.on('audiodevicestatechanged', onChange); nativeClient.on('audiodevicestatechanged', onChange);
mounted = true; mounted.current = true;
return () => { return () => {
nativeClient.off('videodevicestatechanged', onChange); nativeClient.off('videodevicestatechanged', onChange);
nativeClient.off('audiodevicestatechanged', onChange); nativeClient.off('audiodevicestatechanged', onChange);
...@@ -199,7 +199,7 @@ export default function useSettingControl () { ...@@ -199,7 +199,7 @@ export default function useSettingControl () {
console.log('startplayback off result', nativeClient.rtcEngine.stopAudioPlaybackDeviceTest()); console.log('startplayback off result', nativeClient.rtcEngine.stopAudioPlaybackDeviceTest());
} }
} }
}, [stream]); }, [stream, platform]);
const PreviewPlayer = useCallback(() => { const PreviewPlayer = useCallback(() => {
if (!stream) return null; if (!stream) return null;
......
import { useMemo } from 'react'; import { useMemo } from 'react';
import { SHARE_ID } from '../utils/agora-rtc-client'; import { SHARE_ID } from '../utils/agora-rtc-client';
import _ from 'lodash'; // import _ from 'lodash';
import { roomStore } from '../stores/room'; import { roomStore } from '../stores/room';
import { useRoomState } from '../containers/root-container'; import { useRoomState } from '../containers/root-container';
import {STAGE_NUM} from "../utils/consts"; // import {STAGE_NUM} from "../utils/consts";
type StreamValue ={ type StreamValue ={
teacher: any teacher: any
...@@ -132,7 +132,7 @@ export default function useStream () { ...@@ -132,7 +132,7 @@ export default function useStream () {
const studentsOrder = [...roomStore.state.studentsOrder] || []; const studentsOrder = [...roomStore.state.studentsOrder] || [];
// exclude teacher and me // exclude teacher and me
let studentIds = peerUsers.filter((it: number) => studentsOrder.includes(it) && `${it}` !== `${teacherUid}` && `${it}` !== `${me.uid}` && `${it}` !== `${SHARE_ID}`); let studentIds = peerUsers.filter((it: number) => studentsOrder.includes(it) && `${it}` !== `${teacherUid}` && `${it}` !== `${me.uid}` && `${it}` !== `${SHARE_ID}`);
if (me.role != 'teacher') { if (me.role !== 'teacher') {
studentIds = studentIds.add(+me.uid); studentIds = studentIds.add(+me.uid);
} }
...@@ -150,11 +150,11 @@ export default function useStream () { ...@@ -150,11 +150,11 @@ export default function useStream () {
const sids: any = []; const sids: any = [];
let orderIdx = 0; let orderIdx = 0;
for (const ouid of studentsOrder) { for (const ouid of studentsOrder) {
if (ouid == 0) { if (ouid === 0) {
sids.push(0) sids.push(0)
} else { } else {
// find in peer // find in peer
const uid = studentIds.find((it: number) => `${ouid}` == `${it}`); const uid = studentIds.find((it: number) => `${ouid}` === `${it}`);
if (uid) { if (uid) {
sids.push(uid); sids.push(uid);
roomStore.releaseWaitStreamHandle(+uid); roomStore.releaseWaitStreamHandle(+uid);
...@@ -193,11 +193,11 @@ export default function useStream () { ...@@ -193,11 +193,11 @@ export default function useStream () {
// capture all remote streams // capture all remote streams
for (let studentId of /*studentIds*/sids) { for (let studentId of /*studentIds*/sids) {
// console.log('*****************', studentId) // console.log('*****************', studentId)
if (studentId == undefined) { if (studentId === undefined) {
continue continue
} }
if (studentId == 0) { if (studentId === 0) {
const _tmpStream = { const _tmpStream = {
account: '空闲', account: '空闲',
streamID: studentId, streamID: studentId,
...@@ -220,7 +220,7 @@ export default function useStream () { ...@@ -220,7 +220,7 @@ export default function useStream () {
continue continue
} }
if (me.role === 'student' && +me.uid == studentId) { if (me.role === 'student' && +me.uid === studentId) {
if (myAttr && roomState.rtc.localStream) { if (myAttr && roomState.rtc.localStream) {
// console.log('use local stream') // console.log('use local stream')
const _tmpStream = { const _tmpStream = {
...@@ -267,14 +267,14 @@ export default function useStream () { ...@@ -267,14 +267,14 @@ export default function useStream () {
} }
userAttrs.forEach((v, k) => { userAttrs.forEach((v, k) => {
if (!sids.includes(+v.uid)) { if (!sids.includes(+v.uid)) {
if (`${v.uid}` != `${teacherUid}`) { if (`${v.uid}` !== `${teacherUid}`) {
const s: any = { const s: any = {
streamID: +v.uid, streamID: +v.uid,
account: v.account, account: v.account,
video: v.video, video: v.video,
audio: v.audio, // roomState.course.muteAudio ? 0 : v.audio, audio: v.audio, // roomState.course.muteAudio ? 0 : v.audio,
} }
if (`${me.uid}` == `${v.uid}`) { if (`${me.uid}` === `${v.uid}`) {
s.local = true; s.local = true;
} }
studentStreams.push(s) studentStreams.push(s)
...@@ -283,6 +283,7 @@ export default function useStream () { ...@@ -283,6 +283,7 @@ export default function useStream () {
}) })
// console.log('studentStreams', studentStreams); // console.log('studentStreams', studentStreams);
return studentStreams; return studentStreams;
// eslint-disable-next-line
}, [ }, [
// course, // course,
me.uid, me.uid,
...@@ -415,6 +416,7 @@ export default function useStream () { ...@@ -415,6 +416,7 @@ export default function useStream () {
} }
} }
return null; return null;
// eslint-disable-next-line
}, [ }, [
course, course,
me.uid, me.uid,
...@@ -458,7 +460,7 @@ export default function useStream () { ...@@ -458,7 +460,7 @@ export default function useStream () {
if (audio) { if (audio) {
await roomStore.mute(targetUid, 'audio'); await roomStore.mute(targetUid, 'audio');
} else { } else {
if (me.role == 'student' && roomStore.state.course.muteAudio) { if (me.role === 'student' && roomStore.state.course.muteAudio) {
return return
} }
await roomStore.unmute(targetUid, 'audio'); await roomStore.unmute(targetUid, 'audio');
......
...@@ -299,6 +299,27 @@ ...@@ -299,6 +299,27 @@
background-repeat: no-repeat; background-repeat: no-repeat;
opacity: 0.9; opacity: 0.9;
} }
.permission-placeholder{
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
display: flex;
flex: 1 1;
position: absolute;
height: 100%;
width: 100%;
}
.permission-placeholder::before {
content: ' ';
background-image: url(./assets/WechatIMG77.png);
background-position: center;
background-repeat: no-repeat;
//opacity: 0.9;
flex: 1 1;
background-color: #DBE2E5;
justify-content: center;
box-sizing: border-box;
background-size: contain;
}
.media-board.panel { .media-board.panel {
pointer-events: none; pointer-events: none;
......
...@@ -5,7 +5,7 @@ import RoomDialog from '../../components/dialog/room'; ...@@ -5,7 +5,7 @@ import RoomDialog from '../../components/dialog/room';
import { AgoraStream } from '../../utils/types'; import { AgoraStream } from '../../utils/types';
import './room.scss'; import './room.scss';
import NativeSharedWindow from '../../components/native-shared-window'; import NativeSharedWindow from '../../components/native-shared-window';
import { roomStore } from '../../stores/room'; import {roomStore, RTC_STATUS} from '../../stores/room';
import { useRoomState } from '../../containers/root-container'; import { useRoomState } from '../../containers/root-container';
import { globalStore } from '../../stores/global'; import { globalStore } from '../../stores/global';
import { platform } from '../../utils/platform'; import { platform } from '../../utils/platform';
...@@ -17,7 +17,6 @@ import { ...@@ -17,7 +17,6 @@ import {
Dialog, Dialog,
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogContentText,
DialogTitle, DialogTitle,
TextField TextField
} from "@material-ui/core"; } from "@material-ui/core";
...@@ -47,19 +46,25 @@ function StarDialog(props: StarDialogProps) { ...@@ -47,19 +46,25 @@ function StarDialog(props: StarDialogProps) {
setTitle(valueProp); setTitle(valueProp);
} }
}, [valueProp, open]); }, [valueProp, open]);
const handleChange = (evt: any) => { const handleChange = (evt: any) => {
console.log('dialog handleChange ');
const val = evt.target.value.match(NUMBER)[0]; let val = evt.target.value.match(NUMBER)[0];
if (val) { val = +val
setValue(+val); console.log('dialog handleChange ', val);
if (!val || isNaN(val)) {
setValue(0);
} else {
val = Math.abs(val)
setValue(val);
} }
}; };
const handleEntering = () => { // const handleEntering = () => {
// console.log('dialog handleEntering '); // // console.log('dialog handleEntering ');
onClose(uid, value); // onClose(uid, value);
setValue(0) // setValue(0)
}; // };
const handleCancel = () => { const handleCancel = () => {
console.log('dialog handleCancel '); console.log('dialog handleCancel ');
...@@ -91,7 +96,7 @@ function StarDialog(props: StarDialogProps) { ...@@ -91,7 +96,7 @@ function StarDialog(props: StarDialogProps) {
margin="dense" margin="dense"
id="starNumber" id="starNumber"
label="奖励值" label="奖励值"
type="number" type="text"
value={value || ''} value={value || ''}
onChange={handleChange} onChange={handleChange}
fullWidth fullWidth
...@@ -221,7 +226,7 @@ export function RoomPage({ children }: any) { ...@@ -221,7 +226,7 @@ export function RoomPage({ children }: any) {
.finally(() => { .finally(() => {
lock.current = false; lock.current = false;
}); });
}, []); }, [history]);
/* /*
...@@ -294,7 +299,7 @@ export function RoomPage({ children }: any) { ...@@ -294,7 +299,7 @@ export function RoomPage({ children }: any) {
const course = roomStore.state.course; const course = roomStore.state.course;
const classroom = Boolean(location.pathname.match(/classroom/)); const classroom = Boolean(location.pathname.match(/classroom/));
const isBigClass = Boolean(location.pathname.match(/big-class/)); const isBigClass = Boolean(location.pathname.match(/big-class/));
const isSmallClass = Boolean(location.pathname.match(/small-class/)); // const isSmallClass = Boolean(location.pathname.match(/small-class/));
const prevRoute = useRef<string>(location.pathname); const prevRoute = useRef<string>(location.pathname);
useEffect(() => { useEffect(() => {
...@@ -442,6 +447,7 @@ export function RoomPage({ children }: any) { ...@@ -442,6 +447,7 @@ export function RoomPage({ children }: any) {
publishLock.current = false; publishLock.current = false;
} }
} }
// eslint-disable-next-line
}, [ }, [
rtcJoined, rtcJoined,
uid, uid,
...@@ -449,19 +455,46 @@ export function RoomPage({ children }: any) { ...@@ -449,19 +455,46 @@ export function RoomPage({ children }: any) {
mediaDevice, mediaDevice,
canPublish canPublish
]); ]);
const checkPerMission = (status: string) => {
// granted, denied, prompt
if(status === 'granted'){
globalStore.stopPermission();
} else {
globalStore.showPermission();
}
}
useEffect(() => {
console.log('~~~~~~~~~~~~~~~~')
navigator.permissions.query(
// { name: 'camera' }
{ name: 'microphone' }
// { name: 'geolocation' }
// { name: 'notifications' }
// { name: 'midi', sysex: false }
// { name: 'midi', sysex: true }
// { name: 'push', userVisibleOnly: true }
// { name: 'push' } // without userVisibleOnly isn't supported in chrome M45, yet
).then(function(permissionStatus){
checkPerMission(permissionStatus.state);
permissionStatus.onchange = function(){
checkPerMission(this.state);
}
})
navigator.permissions.query(
{ name: 'camera' }
).then(function(permissionStatus){
checkPerMission(permissionStatus.state);
permissionStatus.onchange = function(){
checkPerMission(this.state);
}
})
}, []);
useEffect(() => { useEffect(() => {
if (!roomState.me.uid || !roomState.course.rid) return;
if (classroom) {
if (platform === 'web') {
const webClient = roomStore.rtcClient as AgoraWebClient; const webClient = roomStore.rtcClient as AgoraWebClient;
if (webClient.joined) { if (webClient.joined) {
return; return;
} }
console.log("[agora-rtc] add event listener");
webClient.rtc.on('stream-reconnect-start', (evt: any) => { webClient.rtc.on('stream-reconnect-start', (evt: any) => {
console.log('[agora-web] stream-reconnect-start', evt); console.log('[agora-web] stream-reconnect-start', evt);
}); });
...@@ -527,6 +560,9 @@ export function RoomPage({ children }: any) { ...@@ -527,6 +560,9 @@ export function RoomPage({ children }: any) {
console.log('stream', 1, 'stream-added') console.log('stream', 1, 'stream-added')
console.log("[agora-web] added remote stream, id: ", stream.getId()); console.log("[agora-web] added remote stream, id: ", stream.getId());
webClient.subscribe(stream); webClient.subscribe(stream);
const uid = stream.getId();
roomStore.setUserStreamStatus(+uid, RTC_STATUS.STREAM_ADDED)
}); });
webClient.rtc.on('stream-removed', ({ stream }: any) => { webClient.rtc.on('stream-removed', ({ stream }: any) => {
console.log("[agora-web] removed remote stream, id: ", stream.getId(), roomStore.applyUid); console.log("[agora-web] removed remote stream, id: ", stream.getId(), roomStore.applyUid);
...@@ -560,6 +596,22 @@ export function RoomPage({ children }: any) { ...@@ -560,6 +596,22 @@ export function RoomPage({ children }: any) {
const msg = attr === 0 ? 'resume to a&v mode' : 'fallback to audio mode'; const msg = attr === 0 ? 'resume to a&v mode' : 'fallback to audio mode';
console.info(`[agora-web] stream: ${uid} fallback: ${msg}`); console.info(`[agora-web] stream: ${uid} fallback: ${msg}`);
}) })
// eslint-disable-next-line
}, []);
useEffect(() => {
if (!roomState.me.uid || !roomState.course.rid) return;
if (classroom) {
if (platform === 'web') {
const webClient = roomStore.rtcClient as AgoraWebClient;
if (webClient.joined) {
return;
}
console.log("[agora-rtc] add event listener");
/* origin webClient.rtc.on in here */
rtc.current = true; rtc.current = true;
...@@ -576,7 +628,7 @@ export function RoomPage({ children }: any) { ...@@ -576,7 +628,7 @@ export function RoomPage({ children }: any) {
}).then(() => { }).then(() => {
console.info(2, 'rtc join ok', roomState.me.uid, [...studentsOrder], [...roomStore.state.studentsOrder], [...roomState.studentsOrder]) console.info(2, 'rtc join ok', roomState.me.uid, [...studentsOrder], [...roomStore.state.studentsOrder], [...roomState.studentsOrder])
if (roomState.me.role == 'teacher' || roomStore.state.studentsOrder.includes(+roomState.me.uid)) { if (roomState.me.role === 'teacher' || roomStore.state.studentsOrder.includes(+roomState.me.uid)) {
roomStore.publishMeStream(); roomStore.publishMeStream();
} }
...@@ -677,6 +729,7 @@ export function RoomPage({ children }: any) { ...@@ -677,6 +729,7 @@ export function RoomPage({ children }: any) {
*/ */
} }
// eslint-disable-next-line
}, [roomState.me.uid, roomState.course.rid]); }, [roomState.me.uid, roomState.course.rid]);
useEffect(() => { useEffect(() => {
...@@ -685,7 +738,7 @@ export function RoomPage({ children }: any) { ...@@ -685,7 +738,7 @@ export function RoomPage({ children }: any) {
if (!webClient.joined) { if (!webClient.joined) {
return; return;
} }
if (me.role == 'student') { if (me.role === 'student') {
if (studentsOrder.includes(+me.uid)) { if (studentsOrder.includes(+me.uid)) {
console.log(1.15,'stageup?', me.uid, 1111111 ); console.log(1.15,'stageup?', me.uid, 1111111 );
roomStore.publishMeStream(); roomStore.publishMeStream();
...@@ -695,6 +748,7 @@ export function RoomPage({ children }: any) { ...@@ -695,6 +748,7 @@ export function RoomPage({ children }: any) {
} }
console.log(1.2 ,studentsOrder, 'studentsOrder changed publish stream'); console.log(1.2 ,studentsOrder, 'studentsOrder changed publish stream');
} }
// eslint-disable-next-line
}, [studentsOrder]); }, [studentsOrder]);
return ( return (
......
import React, {useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import React, {useMemo, useRef} from 'react';
// import VideoMarquee from '../../components/video-marquee'; // import VideoMarquee from '../../components/video-marquee';
import MediaBoard from '../../components/mediaboard'; import MediaBoard from '../../components/mediaboard';
// import Roomboard from '../../components/roomboard'; // import Roomboard from '../../components/roomboard';
import './small-class.scss'; import './small-class.scss';
import CourseWareFrame from "../../components/courseware-frame"; import CourseWareFrame from "../../components/courseware-frame";
import VideoShowList from "../../components/video-stage-list"; import VideoShowList from "../../components/video-stage-list";
import {ToolsSwitcherController} from "../../components/tools-switcher-controller"; // import {ToolsSwitcherController} from "../../components/tools-switcher-controller";
import {roomStore} from "../../stores/room"; import {roomStore} from "../../stores/room";
import {TOOL_TYPE} from "../../utils/types"; import {TOOL_TYPE} from "../../utils/types";
// import {platform} from "../../utils/platform"; // import {platform} from "../../utils/platform";
...@@ -18,19 +18,19 @@ import Icon from "../../components/icon"; ...@@ -18,19 +18,19 @@ import Icon from "../../components/icon";
export default function SmallClass() { export default function SmallClass() {
const [tool, setTool] = useState(true); // const [tool, setTool] = useState(true);
const roomState = useRoomState(); const roomState = useRoomState();
const changeTool = async () => { /*const changeTool = async () => {
console.log(roomStore.state.course.currentTool); console.log(roomStore.state.course.currentTool);
if (roomStore.state.course.currentTool == TOOL_TYPE.WHITEBOARD) { if (roomStore.state.course.currentTool == TOOL_TYPE.WHITEBOARD) {
await roomStore.setCurrentTool(TOOL_TYPE.COURSE_WARE) await roomStore.setCurrentTool(TOOL_TYPE.COURSE_WARE)
} else { } else {
await roomStore.setCurrentTool(TOOL_TYPE.WHITEBOARD) await roomStore.setCurrentTool(TOOL_TYPE.WHITEBOARD)
} }
} }*/
const {currentTool} = useMemo(() => { const {currentTool} = useMemo(() => {
return { return {
currentTool: roomStore.state.course.currentTool currentTool: roomState.course.currentTool
} }
}, [roomState]); }, [roomState]);
...@@ -84,9 +84,7 @@ export default function SmallClass() { ...@@ -84,9 +84,7 @@ export default function SmallClass() {
*/ */
} }
useEffect(() => {
}, [roomStore.state.course.currentTool]);
return ( return (
<div className="room-container"> <div className="room-container">
{/*<VideoMarquee />*/} {/*<VideoMarquee />*/}
...@@ -96,16 +94,21 @@ export default function SmallClass() { ...@@ -96,16 +94,21 @@ export default function SmallClass() {
{/* changeTool();*/} {/* changeTool();*/}
{/*}}/> : null}*/} {/*}}/> : null}*/}
{currentTool == TOOL_TYPE.WHITEBOARD {currentTool === TOOL_TYPE.WHITEBOARD
? <MediaBoard /> ? <MediaBoard />
: <CourseWareFrame></CourseWareFrame>} : <CourseWareFrame></CourseWareFrame>}
<Icon
{
roomStore.state.me.role !== 'teacher'
? <Icon
data='hands_up' data='hands_up'
onClick={handleClick} onClick={handleClick}
className={`items hands_up ${false ? 'active' : ''}`} className={`items hands_up ${false ? 'active' : ''}`}
/> />
: null
}
{/*{ roomStore.state.me.role == 'teacher' ? <Roomboard currentActive={'media'} /> : null}*/} {/*{ roomStore.state.me.role == 'teacher' ? <Roomboard currentActive={'media'} /> : null}*/}
</div> </div>
......
...@@ -98,11 +98,11 @@ function HomePage() { ...@@ -98,11 +98,11 @@ function HomePage() {
setClasses([]) setClasses([])
return return
} }
// setLoading(true); setLoading(true);
globalStore.showLoading(); globalStore.showLoading();
const data = await endPoint.fetchClasses(session.yourName); const data = await endPoint.fetchClasses(session.yourName);
console.log(data); console.log(data);
// setLoading(false); setLoading(false);
globalStore.stopLoading(); globalStore.stopLoading();
setSessionInfo({ setSessionInfo({
...session, ...session,
...@@ -185,9 +185,9 @@ function HomePage() { ...@@ -185,9 +185,9 @@ function HomePage() {
// console.log(1111111111111, location ); // console.log(1111111111111, location );
const params = new URLSearchParams(location.search); const params = new URLSearchParams(location.search);
let token:any = params.get('token'); let token:any = params.get('token');
let isDebug = params.get('debug') && params.get('debug') == '1' ? true : false; let isDebug = params.get('debug') && params.get('debug') === '1' ? true : false;
let hasLogin = params.get('login') && params.get('login') == '1' ? true : false; let hasLogin = params.get('login') && params.get('login') === '1' ? true : false;
let isLocal = params.get('isLocal') && params.get('isLocal') == '1' ? true : false; let isLocal = params.get('isLocal') && params.get('isLocal') === '1' ? true : false;
console.log('token', token) console.log('token', token)
console.log('isDebug', isDebug) console.log('isDebug', isDebug)
console.log('hasLogin', hasLogin) console.log('hasLogin', hasLogin)
...@@ -196,11 +196,11 @@ function HomePage() { ...@@ -196,11 +196,11 @@ function HomePage() {
endPoint.setUserToken(token); endPoint.setUserToken(token);
const tokenParts = token.split('.') const tokenParts = token.split('.')
token = tokenParts[1]; token = tokenParts[1];
token = token.replace(/[\+]/g, '-'); token = token.replace(/[+]/g, '-');
token = token.replace(/[/]/g, '_'); token = token.replace(/[/]/g, '_');
const eqc = token.length % 4; const eqc = token.length % 4;
const ea: any = []; const ea: any = [];
if ( eqc != 0 ) { if ( eqc !== 0 ) {
ea.length = 4 - eqc; ea.length = 4 - eqc;
token = `${token}${Array.from(ea).fill('=').join('')}` token = `${token}${Array.from(ea).fill('=').join('')}`
} }
......
...@@ -6,6 +6,8 @@ import Home from './home'; ...@@ -6,6 +6,8 @@ import Home from './home';
import DeviceTest from './device-test'; import DeviceTest from './device-test';
import { RoomPage } from './classroom'; import { RoomPage } from './classroom';
import Loading from '../components/loading'; import Loading from '../components/loading';
import Permission from '../components/permission';
import Toast from '../components/toast'; import Toast from '../components/toast';
import '../icons.scss'; import '../icons.scss';
import { PlatformContainer } from '../containers/platform-container'; import { PlatformContainer } from '../containers/platform-container';
...@@ -23,6 +25,7 @@ export default function () { ...@@ -23,6 +25,7 @@ export default function () {
<PlatformContainer> <PlatformContainer>
<RootProvider> <RootProvider>
<Loading /> <Loading />
<Permission />
<Toast /> <Toast />
<Route exact path="/"> <Route exact path="/">
<Home /> <Home />
......
...@@ -201,9 +201,9 @@ export const Replay: React.FC<{}> = () => { ...@@ -201,9 +201,9 @@ export const Replay: React.FC<{}> = () => {
const player = useMemo(() => { const player = useMemo(() => {
if (!store.state || !store.state.player) return null; if (!store.state || !store.state.player) return null;
return store.state.player as Player; return store.state.player as Player;
// eslint-disable-next-line
}, [store.state]); }, [store.state]);
const handlePlayerClick = () => { const handlePlayerClick = () => {
if (!store.state || !player) return; if (!store.state || !player) return;
...@@ -267,6 +267,7 @@ export const Replay: React.FC<{}> = () => { ...@@ -267,6 +267,7 @@ export const Replay: React.FC<{}> = () => {
if (!startTime || !endTime) return 0; if (!startTime || !endTime) return 0;
const _duration = Math.abs(+startTime - +endTime); const _duration = Math.abs(+startTime - +endTime);
return _duration; return _duration;
// eslint-disable-next-line
}, [startTime, endTime]); }, [startTime, endTime]);
const lock = useRef<boolean>(false); const lock = useRef<boolean>(false);
...@@ -275,6 +276,7 @@ export const Replay: React.FC<{}> = () => { ...@@ -275,6 +276,7 @@ export const Replay: React.FC<{}> = () => {
return () => { return () => {
lock.current = true; lock.current = true;
} }
// eslint-disable-next-line
}, []); }, []);
useEffect(() => { useEffect(() => {
...@@ -338,6 +340,7 @@ export const Replay: React.FC<{}> = () => { ...@@ -338,6 +340,7 @@ export const Replay: React.FC<{}> = () => {
window.removeEventListener('resize', onWindowResize); window.removeEventListener('resize', onWindowResize);
window.removeEventListener('keydown', onWindowResize); window.removeEventListener('keydown', onWindowResize);
} }
// eslint-disable-next-line
}, []); }, []);
const totalTime = useMemo(() => { const totalTime = useMemo(() => {
...@@ -362,8 +365,10 @@ export const Replay: React.FC<{}> = () => { ...@@ -362,8 +365,10 @@ export const Replay: React.FC<{}> = () => {
<div className="play-btn" onClick={handlePlayerClick}></div> : null} <div className="play-btn" onClick={handlePlayerClick}></div> : null}
</div> </div>
) )
// eslint-disable-next-line
}, [player]); }, [player]);
return ( return (
<div className="replay"> <div className="replay">
<div className={`player-container`} > <div className={`player-container`} >
......
...@@ -46,6 +46,7 @@ export interface RoomParams { ...@@ -46,6 +46,7 @@ export interface RoomParams {
export function goHome(history: any){ export function goHome(history: any){
GlobalStorage.clear('agora_room'); GlobalStorage.clear('agora_room');
window.onbeforeunload = null;
window.location.href = 'http://iteachabc.com' window.location.href = 'http://iteachabc.com'
} }
export function goLogin(){ export function goLogin(){
......
...@@ -2,6 +2,7 @@ import {Subject} from 'rxjs'; ...@@ -2,6 +2,7 @@ import {Subject} from 'rxjs';
export type GlobalState = { export type GlobalState = {
loading: boolean loading: boolean
permission: boolean
toast: { toast: {
type: string type: string
message: string message: string
...@@ -31,6 +32,7 @@ export class Root { ...@@ -31,6 +32,7 @@ export class Root {
public state: GlobalState; public state: GlobalState;
public readonly defaultState: GlobalState = { public readonly defaultState: GlobalState = {
loading: false, loading: false,
permission: false,
toast: { toast: {
type: '', type: '',
message: '', message: '',
...@@ -198,6 +200,22 @@ export class Root { ...@@ -198,6 +200,22 @@ export class Root {
} }
this.commit(this.state); this.commit(this.state);
} }
showPermission () {
this.state = {
...this.state,
permission: true
}
this.commit(this.state);
}
stopPermission () {
this.state = {
...this.state,
permission: false
}
this.commit(this.state);
}
} }
export const globalStore = new Root(); export const globalStore = new Root();
......
...@@ -2,11 +2,11 @@ import {platform} from './../utils/platform'; ...@@ -2,11 +2,11 @@ import {platform} from './../utils/platform';
import {AgoraElectronClient} from './../utils/agora-electron-client'; import {AgoraElectronClient} from './../utils/agora-electron-client';
import {AgoraStream, ChatMessage, TOOL_TYPE} from '../utils/types'; import {AgoraStream, ChatMessage, TOOL_TYPE} from '../utils/types';
import {Subject} from 'rxjs'; import {Subject} from 'rxjs';
import {List, OrderedMap, OrderedSet, Map as immuMap} from 'immutable'; import {List, OrderedMap, OrderedSet} from 'immutable';
import AgoraRTMClient, {RoomMessage} from '../utils/agora-rtm-client'; import AgoraRTMClient, {RoomMessage} from '../utils/agora-rtm-client';
import {globalStore} from './global'; import {globalStore} from './global';
import AgoraWebClient from '../utils/agora-rtc-client'; import AgoraWebClient from '../utils/agora-rtc-client';
import {get, isEqual} from 'lodash'; import {get} from 'lodash';
import {isElectron} from '../utils/platform'; import {isElectron} from '../utils/platform';
import GlobalStorage from '../utils/custom-storage'; import GlobalStorage from '../utils/custom-storage';
import {STAGE_NUM} from "../utils/consts"; import {STAGE_NUM} from "../utils/consts";
...@@ -28,7 +28,7 @@ function canJoin({uid, onlineStatus, roomType, channelCount, role}: { uid: any, ...@@ -28,7 +28,7 @@ function canJoin({uid, onlineStatus, roomType, channelCount, role}: { uid: any,
// } // }
const teacher = get(onlineStatus, 'teacher', false); const teacher = get(onlineStatus, 'teacher', false);
const totalCount: number = get(onlineStatus, 'totalCount', 0); // const totalCount: number = get(onlineStatus, 'totalCount', 0);
if (role === 'teacher') { if (role === 'teacher') {
const isOnline = teacher && `${uid}` !== `${onlineStatus.teacherId}`; const isOnline = teacher && `${uid}` !== `${onlineStatus.teacherId}`;
...@@ -53,6 +53,10 @@ const WaitStreamPool = new Map(); ...@@ -53,6 +53,10 @@ const WaitStreamPool = new Map();
// const stageUpStudentTsMap: Map<number, number> = new Map(); // const stageUpStudentTsMap: Map<number, number> = new Map();
const studentsOrderTs: number[] = Array(STAGE_NUM).fill(0); const studentsOrderTs: number[] = Array(STAGE_NUM).fill(0);
export enum RTC_STATUS{
PEER_ONLINE, STREAM_PUBLISHED, STREAM_ADDED, STREAM_SUBSCRIBED, STREAM_REMOVED, PEER_LEAVE
}
const userStreamStatus: any = {};
export interface AgoraUser { export interface AgoraUser {
uid: string uid: string
account: string account: string
...@@ -430,7 +434,7 @@ export class RoomStore { ...@@ -430,7 +434,7 @@ export class RoomStore {
} }
async studentHandsUp(uid: number) { async studentHandsUp(uid: number) {
const hu = this.state.handsUpStudents[uid]; // const hu = this.state.handsUpStudents[uid];
// !hu && !this.state.studentsOrder.includes(uid) // !hu && !this.state.studentsOrder.includes(uid)
const handleId = setTimeout(() => { const handleId = setTimeout(() => {
this.cancelHandsUp(uid); this.cancelHandsUp(uid);
...@@ -463,7 +467,7 @@ export class RoomStore { ...@@ -463,7 +467,7 @@ export class RoomStore {
const oldestTs = Math.min(...studentsOrderTs); const oldestTs = Math.min(...studentsOrderTs);
orderIndex = studentsOrderTs.indexOf(oldestTs); orderIndex = studentsOrderTs.indexOf(oldestTs);
} }
if (studentsOrder[orderIndex] == +uid) { if (studentsOrder[orderIndex] === +uid) {
return ; return ;
} }
...@@ -526,7 +530,7 @@ export class RoomStore { ...@@ -526,7 +530,7 @@ export class RoomStore {
const downUser: any = []; const downUser: any = [];
users.forEach((u, uid) => { users.forEach((u, uid) => {
if (`${u.uid}` != `${this.state.course.teacherId}` && !studentsOrder.includes(+u.uid)) { if (`${u.uid}` !== `${this.state.course.teacherId}` && !studentsOrder.includes(+u.uid)) {
downUser.push(u); downUser.push(u);
} }
}) })
...@@ -686,7 +690,7 @@ export class RoomStore { ...@@ -686,7 +690,7 @@ export class RoomStore {
} }
_userIn(uid: number, role = 'student') { _userIn(uid: number, role = 'student') {
if (role !== 'teacher' && this.state.me.role != 'teacher') { if (role !== 'teacher' && this.state.me.role !== 'teacher') {
return; return;
} }
const currUser: AgoraUser | undefined = this.state.users.get(`${uid}`); const currUser: AgoraUser | undefined = this.state.users.get(`${uid}`);
...@@ -713,7 +717,7 @@ export class RoomStore { ...@@ -713,7 +717,7 @@ export class RoomStore {
} }
} }
_userOut(uid: number) { _userOut(uid: number) {
if (this.state.me.role != 'teacher') { if (this.state.me.role !== 'teacher') {
return; return;
} }
console.log('userusage _userOut', uid); console.log('userusage _userOut', uid);
...@@ -723,7 +727,7 @@ export class RoomStore { ...@@ -723,7 +727,7 @@ export class RoomStore {
uc.out = now; uc.out = now;
if (uc.in < uc.out) { if (uc.in < uc.out) {
let ts = 0; let ts = 0;
if (uc.in != 0) { if (uc.in !== 0) {
ts = uc.out - uc.in;; ts = uc.out - uc.in;;
} }
if (!uc.all) { if (!uc.all) {
...@@ -743,6 +747,7 @@ export class RoomStore { ...@@ -743,6 +747,7 @@ export class RoomStore {
// if (!userStars[uid]) { // if (!userStars[uid]) {
// userStars[uid] = 0; // userStars[uid] = 0;
// } // }
this.setUserStreamStatus(uid, RTC_STATUS.PEER_ONLINE);
this.state = { this.state = {
...this.state, ...this.state,
...@@ -761,6 +766,7 @@ export class RoomStore { ...@@ -761,6 +766,7 @@ export class RoomStore {
if (!uid) { if (!uid) {
return; return;
} }
this.deleteUserStreamStatus(uid)
// 如果一个流退了,检测是否是台上人员,移除掉,其实就是下台 // 如果一个流退了,检测是否是台上人员,移除掉,其实就是下台
// await this.stageDown(`${uid}`) // await this.stageDown(`${uid}`)
this.releaseWaitStreamHandle(uid); this.releaseWaitStreamHandle(uid);
...@@ -799,6 +805,19 @@ export class RoomStore { ...@@ -799,6 +805,19 @@ export class RoomStore {
await this.commit(this.state); await this.commit(this.state);
} }
setUserStreamStatus(uid: number, status: RTC_STATUS){
userStreamStatus[uid] = status;
}
getUserStreamStatus(uid: number | undefined) {
if (uid) {
return userStreamStatus[uid];
}
return userStreamStatus;
}
deleteUserStreamStatus(uid: number) {
return delete userStreamStatus[uid];
}
async addRemoteStream(stream: AgoraStream) { async addRemoteStream(stream: AgoraStream) {
// const sod = this.state.studentsOrder; // const sod = this.state.studentsOrder;
// const hasMe = sod.indexOf(stream.streamID); // const hasMe = sod.indexOf(stream.streamID);
...@@ -806,6 +825,7 @@ export class RoomStore { ...@@ -806,6 +825,7 @@ export class RoomStore {
// const emptyIndex = sod.indexOf(0); // const emptyIndex = sod.indexOf(0);
// sod.splice(emptyIndex, 1, stream.streamID) // sod.splice(emptyIndex, 1, stream.streamID)
// } // }
roomStore.setUserStreamStatus(stream.streamID, RTC_STATUS.STREAM_SUBSCRIBED)
console.log('remoteStreams added',5 , stream.streamID, this.state.users) console.log('remoteStreams added',5 , stream.streamID, this.state.users)
this.state = { this.state = {
...@@ -817,13 +837,13 @@ export class RoomStore { ...@@ -817,13 +837,13 @@ export class RoomStore {
// studentsOrder: sod // studentsOrder: sod
} }
await this.commit(this.state); await this.commit(this.state);
if (stream.streamID > 0 && +stream.streamID != +this.state.course.teacherId) { if (stream.streamID > 0 && +stream.streamID !== +this.state.course.teacherId) {
this.stageUp(''+stream.streamID) this.stageUp(''+stream.streamID)
} }
} }
async removeRemoteStream(uid: number) { async removeRemoteStream(uid: number) {
this.setUserStreamStatus(uid, RTC_STATUS.STREAM_REMOVED)
this.state = { this.state = {
...this.state, ...this.state,
rtc: { rtc: {
...@@ -1033,7 +1053,7 @@ export class RoomStore { ...@@ -1033,7 +1053,7 @@ export class RoomStore {
async unmute(uid: string, type: string) { async unmute(uid: string, type: string) {
// 有一个unmute的时候,就把course里的muteAudio 变成0 // 有一个unmute的时候,就把course里的muteAudio 变成0
if (this.state.me.role == 'teacher') { if (this.state.me.role === 'teacher') {
this.state = { this.state = {
...this.state, ...this.state,
course: { course: {
...@@ -1095,12 +1115,12 @@ export class RoomStore { ...@@ -1095,12 +1115,12 @@ export class RoomStore {
const channelCount = channelMemberCount[rid]; const channelCount = channelMemberCount[rid];
const channelMeta = await this.rtmClient.getChannelAttributeBy(rid); const channelMeta = await this.rtmClient.getChannelAttributeBy(rid);
console.log('channelMeta', channelMeta) console.log('channelMeta', channelMeta)
if (payload.role == 'student' && !channelMeta.teacher) { if (payload.role === 'student' && !channelMeta.teacher) {
// eslint-disable-next-line
throw { throw {
type: 'not_permitted', type: 'not_permitted',
reason: 'classroom not start yet' reason: 'classroom not start yet'
} }
return
} }
let accounts = channelMeta.accounts; let accounts = channelMeta.accounts;
const onlineStatus = await this.rtmClient.queryOnlineStatusBy(accounts); const onlineStatus = await this.rtmClient.queryOnlineStatusBy(accounts);
...@@ -1142,7 +1162,7 @@ export class RoomStore { ...@@ -1142,7 +1162,7 @@ export class RoomStore {
let studentsOrder: number[] = channelMeta.studentsOrder || []; let studentsOrder: number[] = channelMeta.studentsOrder || [];
if (result.permitted) { if (result.permitted) {
if (payload.role == 'teacher') { if (payload.role === 'teacher') {
// const t = this.state.userUsage[payload.uid]; // const t = this.state.userUsage[payload.uid];
this._userIn(payload.uid, 'teacher') this._userIn(payload.uid, 'teacher')
...@@ -1167,7 +1187,7 @@ export class RoomStore { ...@@ -1167,7 +1187,7 @@ export class RoomStore {
*/ */
} }
console.log('login accounts', accounts) console.log('login accounts', accounts)
let onlineMe = accounts.find((it: any) => `${it.uid}` == `${payload.uid}`); let onlineMe = accounts.find((it: any) => `${it.uid}` === `${payload.uid}`);
if (onlineMe) { if (onlineMe) {
payload.video = onlineMe.video; payload.video = onlineMe.video;
payload.audio = onlineMe.audio; payload.audio = onlineMe.audio;
...@@ -1182,7 +1202,7 @@ export class RoomStore { ...@@ -1182,7 +1202,7 @@ export class RoomStore {
console.log('login payload', payload) console.log('login payload', payload)
console.log('login studentsOrder', studentsOrder) console.log('login studentsOrder', studentsOrder)
let res = await this.rtmClient.join(rid).then(async r => { await this.rtmClient.join(rid).then(async r => {
this.state = { this.state = {
...this.state, ...this.state,
rtm: { rtm: {
...@@ -1207,14 +1227,17 @@ export class RoomStore { ...@@ -1207,14 +1227,17 @@ export class RoomStore {
// await this.updateMe({...payload, grantBoard}); // await this.updateMe({...payload, grantBoard});
// this.commit(this.state); // this.commit(this.state);
return; return;
} } else {
await this.rtmClient.logout(); await this.rtmClient.logout();
// eslint-disable-next-line
throw { throw {
type: 'not_permitted', type: 'not_permitted',
reason: result.reason reason: result.reason
} }
} }
}
publishMeStream() { publishMeStream() {
console.log(3, 'set rtc join flag, should auto publish', this.state.rtc.joined) console.log(3, 'set rtc join flag, should auto publish', this.state.rtc.joined)
// return await (this.rtcClient as AgoraWebClient).publishStream() // return await (this.rtcClient as AgoraWebClient).publishStream()
...@@ -1307,7 +1330,7 @@ export class RoomStore { ...@@ -1307,7 +1330,7 @@ export class RoomStore {
chat: user.chat, chat: user.chat,
grant_board: user.grantBoard, grant_board: user.grantBoard,
last_stage_ts: user.lastStageTs, last_stage_ts: user.lastStageTs,
stars: user.stars stars: user.stars || 0
} }
if (user.role === 'teacher') { if (user.role === 'teacher') {
Object.assign(attrs, { Object.assign(attrs, {
...@@ -1326,7 +1349,7 @@ export class RoomStore { ...@@ -1326,7 +1349,7 @@ export class RoomStore {
const data: any = {}; const data: any = {};
data[key] = attrs; data[key] = attrs;
// await this.rtmClient.addOrUpdateChannelAttributes(data); // await this.rtmClient.addOrUpdateChannelAttributes(data);
let res = await this.rtmClient.updateChannelAttrsByKey(key, attrs); await this.rtmClient.updateChannelAttrsByKey(key, attrs);
// return res; // return res;
} }
async allStudentMuteOn(){ async allStudentMuteOn(){
...@@ -1423,7 +1446,7 @@ export class RoomStore { ...@@ -1423,7 +1446,7 @@ export class RoomStore {
} }
} }
async lockWaitStreamHandle(streamId: number) { async lockWaitStreamHandle(streamId: number) {
if (this.state.me.role != 'teacher') { if (this.state.me.role !== 'teacher') {
return return
} }
// console.log('waitStreamHandle', streamId); // console.log('waitStreamHandle', streamId);
...@@ -1444,7 +1467,7 @@ export class RoomStore { ...@@ -1444,7 +1467,7 @@ export class RoomStore {
} }
async updateMe(user: any, studentsOrder: number[] = []) { async updateMe(user: any, studentsOrder: number[] = []) {
const {role, uid, account, rid, video, audio, chat, boardId, linkId, sharedId, muteChat, muteAudio, grantBoard, stars} = user; let {role, uid, account, /*rid,*/ video, audio, chat, boardId, linkId, sharedId, /*muteChat, muteAudio,*/ grantBoard, stars} = user;
const key = role === 'teacher' ? 'teacher' : uid; const key = role === 'teacher' ? 'teacher' : uid;
const me = this.state.me; const me = this.state.me;
const attrs = { const attrs = {
...@@ -1454,6 +1477,7 @@ export class RoomStore { ...@@ -1454,6 +1477,7 @@ export class RoomStore {
video: me.video, video: me.video,
audio: me.audio, audio: me.audio,
} }
stars = stars || 0;
Object.assign(attrs, { Object.assign(attrs, {
uid, uid,
account, account,
...@@ -1511,9 +1535,9 @@ export class RoomStore { ...@@ -1511,9 +1535,9 @@ export class RoomStore {
this._userOut(+memberId); this._userOut(+memberId);
const studentsOrder = [...this.state.studentsOrder]; const studentsOrder = [...this.state.studentsOrder];
const userIndex = studentsOrder.indexOf(+memberId); const userIndex = studentsOrder.indexOf(+memberId);
let rtc = { // let rtc = {
...this.state.rtc, // ...this.state.rtc,
}; // };
if (userIndex > -1) { if (userIndex > -1) {
studentsOrder.splice(userIndex, 1, 0); studentsOrder.splice(userIndex, 1, 0);
studentsOrder[userIndex] = 0; studentsOrder[userIndex] = 0;
...@@ -1558,11 +1582,11 @@ export class RoomStore { ...@@ -1558,11 +1582,11 @@ export class RoomStore {
async rtmJoinUser(memberId: string) { async rtmJoinUser(memberId: string) {
console.log('新学生登录', memberId, this.state.studentsOrder); console.log('新学生登录', memberId, this.state.studentsOrder);
const data: any = {}; // const data: any = {};
let needUpdate = false; let needUpdate = false;
const newUid = +memberId; const newUid = +memberId;
const studentsOrder = [...this.state.studentsOrder]; const studentsOrder = [...this.state.studentsOrder];
if (studentsOrder.length != STAGE_NUM) { if (studentsOrder.length !== STAGE_NUM) {
const len = STAGE_NUM - studentsOrder.length ? STAGE_NUM - studentsOrder.length : 0; const len = STAGE_NUM - studentsOrder.length ? STAGE_NUM - studentsOrder.length : 0;
if (len > 0) { if (len > 0) {
Array(len).forEach(_ =>{ Array(len).forEach(_ =>{
...@@ -1603,7 +1627,7 @@ export class RoomStore { ...@@ -1603,7 +1627,7 @@ export class RoomStore {
const newAccData: any = {}; const newAccData: any = {};
const newUids: number[] = [] const newUids: number[] = []
newUsers.forEach(([uid, userInfo]) =>{ newUsers.forEach(([uid, userInfo]) =>{
if (userInfo.role != 'teacher') { if (userInfo.role !== 'teacher') {
newAccData[uid] = userInfo; newAccData[uid] = userInfo;
newUids.push(+uid); newUids.push(+uid);
} }
...@@ -1611,7 +1635,7 @@ export class RoomStore { ...@@ -1611,7 +1635,7 @@ export class RoomStore {
const oldUids: number[] = [] const oldUids: number[] = []
oldUsers.forEach( ([uid, userInfo]) => { oldUsers.forEach( ([uid, userInfo]) => {
if (userInfo.role != 'teacher') { if (userInfo.role !== 'teacher') {
oldUids.push(+uid) oldUids.push(+uid)
} }
}); });
...@@ -1652,7 +1676,7 @@ export class RoomStore { ...@@ -1652,7 +1676,7 @@ export class RoomStore {
_to2.sort((a, b) => a - b) _to2.sort((a, b) => a - b)
const tSOrderStr2 = JSON.stringify(_to2) const tSOrderStr2 = JSON.stringify(_to2)
console.log(tSOrderStr1, tSOrderStr2); console.log(tSOrderStr1, tSOrderStr2);
if (tSOrderStr1 != tSOrderStr2) { if (tSOrderStr1 !== tSOrderStr2) {
data['studentsOrder'] = [...tSOrder]; data['studentsOrder'] = [...tSOrder];
console.log('new channel attr to every one'); console.log('new channel attr to every one');
return data return data
...@@ -1667,7 +1691,7 @@ export class RoomStore { ...@@ -1667,7 +1691,7 @@ export class RoomStore {
async updateRoomAttrs ({teacher, accounts, room, studentsOrder, userStars}: {teacher: any, accounts: any, room: any, studentsOrder: number[], userStars: any}) { async updateRoomAttrs ({teacher, accounts, room, studentsOrder, userStars}: {teacher: any, accounts: any, room: any, studentsOrder: number[], userStars: any}) {
console.log("[agora-board], room: ",teacher, accounts, room, studentsOrder); console.log("[agora-board], room: ",teacher, accounts, room, studentsOrder);
const currentRoomUsers = this.state.users.toArray(); const currentRoomUsers = this.state.users.toArray();
const exitUserIds = []; // const exitUserIds = [];
const users: OrderedMap<string, AgoraUser> = accounts.reduce((acc: OrderedMap<string, AgoraUser>, it: any) => { const users: OrderedMap<string, AgoraUser> = accounts.reduce((acc: OrderedMap<string, AgoraUser>, it: any) => {
roomStore.releaseWaitStreamHandle(it.uid); roomStore.releaseWaitStreamHandle(it.uid);
return acc.set(it.uid, { return acc.set(it.uid, {
...@@ -1683,10 +1707,10 @@ export class RoomStore { ...@@ -1683,10 +1707,10 @@ export class RoomStore {
lockBoard: it.lock_board, lockBoard: it.lock_board,
grantBoard: it.grant_board, grantBoard: it.grant_board,
lastStageTs: it.last_stage_ts, lastStageTs: it.last_stage_ts,
stars: it.stars stars: it.stars || 0
}); });
}, OrderedMap<string, AgoraUser>()); }, OrderedMap<string, AgoraUser>());
if (this.state.studentsOrder.length == 0) { if (this.state.studentsOrder.length === 0) {
this.state.studentsOrder = Array(STAGE_NUM).fill(0) this.state.studentsOrder = Array(STAGE_NUM).fill(0)
} }
/* /*
...@@ -1730,7 +1754,7 @@ export class RoomStore { ...@@ -1730,7 +1754,7 @@ export class RoomStore {
let cos = JSON.stringify(studentsOrder); let cos = JSON.stringify(studentsOrder);
console.log('频道StudentsOrder', newStudentsOrder); console.log('频道StudentsOrder', newStudentsOrder);
console.log('用户保存StudentsOrder', this.state.studentsOrder); console.log('用户保存StudentsOrder', this.state.studentsOrder);
let updateOrders = false; // let updateOrders = false;
if (me.role === 'teacher') { if (me.role === 'teacher') {
/* /*
// remove exist user from studentsOrder // remove exist user from studentsOrder
...@@ -1765,7 +1789,7 @@ export class RoomStore { ...@@ -1765,7 +1789,7 @@ export class RoomStore {
console.log('newInfo', newInfo) console.log('newInfo', newInfo)
if (newInfo) { if (newInfo) {
updateOrders = true; // updateOrders = true;
newStudentsOrder = newInfo['studentsOrder']; newStudentsOrder = newInfo['studentsOrder'];
cos = JSON.stringify(newInfo['studentsOrder']); cos = JSON.stringify(newInfo['studentsOrder']);
await this.rtmClient.addOrUpdateChannelAttributes(newInfo); await this.rtmClient.addOrUpdateChannelAttributes(newInfo);
...@@ -1808,7 +1832,7 @@ export class RoomStore { ...@@ -1808,7 +1832,7 @@ export class RoomStore {
userStars userStars
} }
console.log('update orders?', cos, uos) console.log('update orders?', cos, uos)
if (cos != uos) { if (cos !== uos) {
this.state = { this.state = {
...this.state, ...this.state,
studentsOrder: newStudentsOrder studentsOrder: newStudentsOrder
...@@ -1858,6 +1882,7 @@ export class RoomStore { ...@@ -1858,6 +1882,7 @@ export class RoomStore {
ifm.remove() ifm.remove()
}) })
} }
/*
const events = [ const events = [
'onTokenPrivilegeWillExpire', 'onTokenPrivilegeWillExpire',
'onTokenPrivilegeDidExpire', 'onTokenPrivilegeDidExpire',
...@@ -1870,6 +1895,7 @@ export class RoomStore { ...@@ -1870,6 +1895,7 @@ export class RoomStore {
'peer-leave', 'peer-leave',
'stream-fallback' 'stream-fallback'
] ]
*/
const webClient = roomStore.rtcClient as AgoraWebClient; const webClient = roomStore.rtcClient as AgoraWebClient;
// for (let eventName of events) { // for (let eventName of events) {
// webClient.rtc.off(eventName, () => {}); // webClient.rtc.off(eventName, () => {});
...@@ -1900,7 +1926,7 @@ export class RoomStore { ...@@ -1900,7 +1926,7 @@ export class RoomStore {
console.log('exitAll'); console.log('exitAll');
try { try {
if (this.state.me.role == 'teacher') { if (this.state.me.role === 'teacher') {
await this.rtmClient.clearChannelAttributes() await this.rtmClient.clearChannelAttributes()
} else { } else {
await this.rtmClient.clearChannelAttributesByKeys([`${this.state.me.uid}`]); await this.rtmClient.clearChannelAttributesByKeys([`${this.state.me.uid}`]);
...@@ -1909,7 +1935,7 @@ export class RoomStore { ...@@ -1909,7 +1935,7 @@ export class RoomStore {
await this.rtmClient.logout(); await this.rtmClient.logout();
} catch(e) {} } catch(e) {}
const webClient = roomStore.rtcClient as AgoraWebClient; // const webClient = roomStore.rtcClient as AgoraWebClient;
// setTimeout(()=>{ // setTimeout(()=>{
// alert('clear2') // alert('clear2')
GlobalStorage.clear('agora_room'); GlobalStorage.clear('agora_room');
...@@ -1953,7 +1979,7 @@ class WindowMonitor { ...@@ -1953,7 +1979,7 @@ class WindowMonitor {
this.roomStore = roomStore this.roomStore = roomStore
} }
b4Leave(e: any){ b4Leave(e: any){
if (this.roomStore.state.me.role != 'teacher') { if (this.roomStore.state.me.role !== 'teacher') {
return return
} }
return "确定退出吗?"; return "确定退出吗?";
...@@ -1968,7 +1994,7 @@ class WindowMonitor { ...@@ -1968,7 +1994,7 @@ class WindowMonitor {
// } // }
} }
leave(){ leave(){
if (this.roomStore.state.me.role != 'teacher') { if (this.roomStore.state.me.role !== 'teacher') {
return return
} }
const userUsage = this.roomStore.getUserUsage(); const userUsage = this.roomStore.getUserUsage();
...@@ -1984,16 +2010,16 @@ class WindowMonitor { ...@@ -1984,16 +2010,16 @@ class WindowMonitor {
const students: any = []; const students: any = [];
Object.values(userUsage).forEach( u => { Object.values(userUsage).forEach( u => {
let _e = now; let _e = now;
if (u.out != 0 ) { if (u.out !== 0 ) {
_e = u.out; _e = u.out;
} }
const time = u.all + (u.in > 0 ? (_e - u.in) : 0); const time = u.all + (u.in > 0 ? (_e - u.in) : 0);
if (u.role == "student") { if (u.role === "student") {
students.push({ students.push({
uid: u.uid, uid: u.uid,
time time
}) })
} else if (u.role == 'teacher') { } else if (u.role === 'teacher') {
data.time = time; data.time = time;
data.uid = +this.roomStore.state.course.teacherId; data.uid = +this.roomStore.state.course.teacherId;
} }
...@@ -2019,7 +2045,7 @@ class WindowMonitor { ...@@ -2019,7 +2045,7 @@ class WindowMonitor {
return !!window.onbeforeunload; return !!window.onbeforeunload;
} }
addUnloadEvent(){ addUnloadEvent(){
if (this.roomStore.state.me.role != 'teacher') { if (this.roomStore.state.me.role !== 'teacher') {
return return
} }
if (this.hasUnloadEvent()) { if (this.hasUnloadEvent()) {
...@@ -2029,7 +2055,7 @@ class WindowMonitor { ...@@ -2029,7 +2055,7 @@ class WindowMonitor {
window.onunload = this.leave window.onunload = this.leave
} }
removeUnloadEvent() { removeUnloadEvent() {
if (this.roomStore.state.me.role != 'teacher') { if (this.roomStore.state.me.role !== 'teacher') {
return return
} }
window.onbeforeunload = null window.onbeforeunload = null
......
...@@ -37,7 +37,7 @@ export interface SceneResource { ...@@ -37,7 +37,7 @@ export interface SceneResource {
} }
const pathName = (path: string): string => { const pathName = (path: string): string => {
const reg = /\/([^\/]*)\//g; const reg = /\/([^/]*)\//g;
reg.exec(path); reg.exec(path);
if (RegExp.$1 === "aria") { if (RegExp.$1 === "aria") {
return ""; return "";
......
...@@ -14,7 +14,7 @@ if (AgoraRtcEngine) { ...@@ -14,7 +14,7 @@ if (AgoraRtcEngine) {
AgoraRtcEngine.setVideoProfile(43, false); AgoraRtcEngine.setVideoProfile(43, false);
} }
const SHARE_ID = 7; const SHARE_ID = 0;
export interface Stream { export interface Stream {
uid: number uid: number
...@@ -31,10 +31,12 @@ export class AgoraElectronStream { ...@@ -31,10 +31,12 @@ export class AgoraElectronStream {
public stream: Stream; public stream: Stream;
public playing: boolean = false; public playing: boolean = false;
private domID: string; private domID: string;
public uid: number;
constructor( constructor(
public uid: number = uid, uid: number,
public readonly type: StreamType = StreamType.remote, public readonly type: StreamType = StreamType.remote,
) { ) {
this.uid = uid;
this.domID = ''; this.domID = '';
this.stream = { this.stream = {
uid: this.uid, uid: this.uid,
......
...@@ -46,7 +46,7 @@ const clientEvents: string[] = [ ...@@ -46,7 +46,7 @@ const clientEvents: string[] = [
export const APP_ID = process.env.REACT_APP_AGORA_APP_ID as string; export const APP_ID = process.env.REACT_APP_AGORA_APP_ID as string;
export const APP_TOKEN = process.env.REACT_APP_AGORA_APP_TOKEN as string; export const APP_TOKEN = process.env.REACT_APP_AGORA_APP_TOKEN as string;
export const ENABLE_LOG = process.env.REACT_APP_AGORA_LOG as string === "true"; export const ENABLE_LOG = process.env.REACT_APP_AGORA_LOG as string === "true";
export const SHARE_ID = 65535; export const SHARE_ID = 0;
const BindEventMap: any = {}; const BindEventMap: any = {};
class AgoraRTCClient { class AgoraRTCClient {
......
...@@ -121,7 +121,11 @@ export default class AgoraRTMClient { ...@@ -121,7 +121,11 @@ export default class AgoraRTMClient {
async login (uid: string, token?: string) { async login (uid: string, token?: string) {
this._channelAttrsKey = uid; this._channelAttrsKey = uid;
try{
await this._client.login({uid, token}); await this._client.login({uid, token});
} catch (e) {
}
this._client.on("ConnectionStateChanged", (newState: string, reason: string) => { this._client.on("ConnectionStateChanged", (newState: string, reason: string) => {
this._bus.emit("ConnectionStateChanged", {newState, reason}); this._bus.emit("ConnectionStateChanged", {newState, reason});
}); });
......
...@@ -120,6 +120,7 @@ export class RecordOperator { ...@@ -120,6 +120,7 @@ export class RecordOperator {
if (typeof res.resourceId === "string") { if (typeof res.resourceId === "string") {
this.resourceId = res.resourceId; this.resourceId = res.resourceId;
} else { } else {
// eslint-disable-next-line
throw { throw {
recordingErr: { recordingErr: {
message: 'acquire recording failed', message: 'acquire recording failed',
...@@ -129,6 +130,7 @@ export class RecordOperator { ...@@ -129,6 +130,7 @@ export class RecordOperator {
} }
} }
public async release(): Promise<void> { public async release(): Promise<void> {
this.resourceId = undefined; this.resourceId = undefined;
this.recordId = undefined; this.recordId = undefined;
...@@ -137,6 +139,7 @@ export class RecordOperator { ...@@ -137,6 +139,7 @@ export class RecordOperator {
public async start(): Promise<any> { public async start(): Promise<any> {
if (this.resourceId === undefined) { if (this.resourceId === undefined) {
// eslint-disable-next-line
throw { throw {
recordingErr: { recordingErr: {
message: 'start recording failed', message: 'start recording failed',
...@@ -164,6 +167,7 @@ export class RecordOperator { ...@@ -164,6 +167,7 @@ export class RecordOperator {
if (typeof res.sid === "string") { if (typeof res.sid === "string") {
this.recordId = res.sid; this.recordId = res.sid;
} else { } else {
// eslint-disable-next-line
throw { throw {
recordingErr: { recordingErr: {
message: 'start recording failed', message: 'start recording failed',
...@@ -176,6 +180,7 @@ export class RecordOperator { ...@@ -176,6 +180,7 @@ export class RecordOperator {
public async stop(): Promise<any> { public async stop(): Promise<any> {
if (this.resourceId === undefined) { if (this.resourceId === undefined) {
// eslint-disable-next-line
throw { throw {
recordingErr: { recordingErr: {
message: 'stop recording failed', message: 'stop recording failed',
...@@ -184,6 +189,7 @@ export class RecordOperator { ...@@ -184,6 +189,7 @@ export class RecordOperator {
} }
} }
if (this.recordId === undefined) { if (this.recordId === undefined) {
// eslint-disable-next-line
throw { throw {
recordingErr: { recordingErr: {
message: 'stop recording failed', message: 'stop recording failed',
...@@ -216,6 +222,7 @@ export class RecordOperator { ...@@ -216,6 +222,7 @@ export class RecordOperator {
public async query(): Promise<any> { public async query(): Promise<any> {
if (this.resourceId === undefined) { if (this.resourceId === undefined) {
// eslint-disable-next-line
throw { throw {
recordingErr: { recordingErr: {
message: 'query recording failed', message: 'query recording failed',
...@@ -224,6 +231,7 @@ export class RecordOperator { ...@@ -224,6 +231,7 @@ export class RecordOperator {
} }
} }
if (this.recordId === undefined) { if (this.recordId === undefined) {
// eslint-disable-next-line
throw { throw {
recordingErr: { recordingErr: {
message: 'query recording failed', message: 'query recording failed',
......
...@@ -341,6 +341,10 @@ export function resolveChannelAttrs(json: object) { ...@@ -341,6 +341,10 @@ export function resolveChannelAttrs(json: object) {
}); });
} }
for (let student of students) { for (let student of students) {
student.stars = +student.stars;
if (!student.stars || isNaN(student.stars)) {
student.stars = 0;
}
accounts.push({ accounts.push({
role: 'student', role: 'student',
account: student.account, account: student.account,
......
...@@ -27,8 +27,11 @@ export interface AgoraMediaStream { ...@@ -27,8 +27,11 @@ export interface AgoraMediaStream {
export class AgoraStream { export class AgoraStream {
constructor( constructor(
// eslint-disable-next-line
public readonly stream: any = stream, public readonly stream: any = stream,
// eslint-disable-next-line
public readonly streamID: number = streamID, public readonly streamID: number = streamID,
// eslint-disable-next-line
public readonly local: boolean = local, public readonly local: boolean = local,
) { ) {
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment