Commit 3a2d2dba authored by liujiaxin's avatar liujiaxin

添加iframe和白板切换

parent 4e8f74c3
......@@ -25,7 +25,7 @@ const useStyles = makeStyles({
flex: 1
},
style4: {
height: 30,
height: 36,
width: 100,
flex: 0
},
......@@ -39,7 +39,6 @@ const CourseWareFrame: React.FC = () => {
const ref = useRef<any>('');
const [src, setSrc] = useState('')
const changSrc = (evt: any) => {
debugger
setSrc(ref.current.value);
}
......
......@@ -23,6 +23,7 @@ import AgoraWebClient, { SHARE_ID } from '../utils/agora-rtc-client';
import "white-web-sdk/style/index.css";
import { ViewMode } from 'white-web-sdk';
const pathName = (path: string): string => {
const reg = /\/([^/]*)\//g;
reg.exec(path);
......@@ -560,7 +561,7 @@ const items = [
<UploadPanel />
{children ? children : null}
</div>
{me.role === 'teacher' && room ?
{/*me.role === 'teacher' && room ?
<ScaleController
zoomScale={scale}
onClick={() => {
......@@ -577,8 +578,7 @@ const items = [
}}
/>
:
null
}
null*/}
{ showControl ?
<Control
notice={globalState.notice}
......
......@@ -234,7 +234,7 @@ const MemberHolder: React.FC<MemberHolderProps> = ({
{me.uid === id || me.role === 'teacher' ?
<span className="media-btn">
<Link component="button" onClick={onAudioClick}>{audio ? "静音" : "开麦"}</Link>
<Link component="button" onClick={onStageUp}>上台</Link>
{me.role === 'teacher' ? <Link component="button" onClick={onStageUp}>上台</Link> : null}
{/*<Icon onClick={onAudioClick} className={audio ? "icon-speaker-on" : "icon-speaker-off"} data={"audio"} />*/}
{/*<Icon onClick={onVideoClick} className={video ? "icons-camera-unmute-s" : "icons-camera-mute-s"} data={"video"} />*/}
</span> : null}
......
......@@ -9,7 +9,7 @@ export default function Roomboard (props: any) {
messages, sendMessage, handleChange
} = useChatText();
const [active, setActive] = useState('chatroom');
const [active, setActive] = useState('studentList');
const [visible, setVisible] = useState(true);
const toggleCollapse = (evt: any) => {
......@@ -22,7 +22,7 @@ export default function Roomboard (props: any) {
{visible ?
<div className={`small-class chat-board`}>
<div className="menu">
<div onClick={() => { setActive('chatroom') }} className={`item ${active === 'chatroom' ? 'active' : ''}`}>Chatroom</div>
{/*<div onClick={() => { setActive('chatroom') }} className={`item ${active === 'chatroom' ? 'active' : ''}`}>Chatroom</div>*/}
<div onClick={() => { setActive('studentList') }} className={`item ${active === 'studentList' ? 'active' : ''}`}>Student List</div>
</div>
{
......
......@@ -22,13 +22,14 @@
font-weight:400;
color:rgba(3,3,3,1);
line-height:17px;
max-width: 113px;
min-width: 113px;
//max-width: 113px;
//min-width: 113px;
flex: 1;
}
.attrs-group {
display: flex;
min-width: 148px;
max-width: 148px;
//min-width: 148px;
//max-width: 148px;
justify-content: space-evenly;
.items {
margin: 4px;
......
......@@ -89,8 +89,8 @@ export default function StudentList ({
<div key={key} className="item">
<div className="nickname">{item.account}</div>
<div className="attrs-group">
<CustomIcon type="grantBoard" id={item.uid} value={Boolean(item.grantBoard)} icon="connect" onClick={handleClick} />
<CustomIcon type="chat" id={item.uid} value={Boolean(item.chat)} icon="chat" onClick={handleClick} />
{/*<CustomIcon type="grantBoard" id={item.uid} value={Boolean(item.grantBoard)} icon="connect" onClick={handleClick} />*/}
{/*<CustomIcon type="chat" id={item.uid} value={Boolean(item.chat)} icon="chat" onClick={handleClick} />*/}
<CustomIcon type="audio" id={item.uid} value={Boolean(item.audio)} icon="audio" onClick={handleClick} />
<CustomIcon type="video" id={item.uid} value={Boolean(item.video)} icon="video" onClick={handleClick} />
</div>
......
import React from 'react';
import BuildIcon from '@material-ui/icons/Build';
import {makeStyles} from "@material-ui/core/styles";
import {Link} from "react-router-dom";
export type ToolsSwitcherControllerProps = {
// zoomScale: number
// zoomChange: (scale: number) => void
onClick: () => void
// onClickBoardLock: () => void
};
const toolsStyle = makeStyles({
button: {
width: '42px!important',
lineHeight: 42,
cursor: 'pointer',
userSelect: 'none',
display: 'flex',
alignItems: 'center',
boxSizing: 'border-box',
position: 'absolute',
left: 10,
bottom: 10,
height: 42,
background: '#fff',
boxShadow: '0 2px 4px 0 rgba(0,0,0,.1)',
borderRadius: 6,
border: '1px solid #dbe2e5',
zIndex:9,
},
icon: {
margin: '0 auto'
}
});
export const ToolsSwitcherController: React.FC<ToolsSwitcherControllerProps> = ({onClick}) => {
const classes = toolsStyle();
return (
<div className={`tool-switcher-controls ${classes.button}`} onClick={() => onClick()}>
<BuildIcon className={classes.icon}></BuildIcon>
{/*<div className="zoom-icon" onClick={() => this.props.onClick()}>*/}
{/*</div>*/}
{/*<div className="zoom-hold"></div>*/}
{/*<div className="zoom-size">{Math.ceil(this.props.zoomScale * 100)} %</div>*/}
{/*<div className="zoom-items">*/}
{/* <div className="item zoom-in" onClick={() => this.moveRuleIndex(-1)}>-</div>*/}
{/* <div className="item zoom-out" onClick={() => this.moveRuleIndex(+1)}>+</div>*/}
{/*</div>*/}
{/*<div className="lock-board" onClick={() => this.props.onClickBoardLock() }></div>*/}
</div>
);
}
......@@ -11,8 +11,8 @@ import MemberHolder from "./member-holder";
function VideoShowList() {
const {teacher, stageStudents, onPlayerClick} = useStream();
const {teacher, students, onPlayerClick} = useStream();
......@@ -65,7 +65,7 @@ function VideoShowList() {
// return <div className="camera">
// <div key={`stage${i}`} className="agora-video-view camera-holder">{i}</div>
// </div> ;
const student = stageStudents.stage && stageStudents.stage[i];
const student = students && students.slice(0,STAGE_NUM)[i];
return <div className="camera" key={`stage_video${i}`}>
{student ? <VideoPlayer
......@@ -122,7 +122,7 @@ function VideoShowList() {
)*/}
{ stageStudents.wait ? stageStudents.wait.map((student: AgoraMediaStream, key: number) => (
{ students ? students.slice(STAGE_NUM).map((student: AgoraMediaStream, key: number) => (
// <VideoPlayer
// role="student"
// domId={`dom-${student.streamID}`}
......
......@@ -135,7 +135,7 @@ export default function Control({
: null}
</div>
<div className="controls">
{!sharing && role === 'teacher' ?
{/*!sharing && role === 'teacher' ?
<>
<ControlItem name={`first_page`}
active={'first_page' === current}
......@@ -154,14 +154,14 @@ export default function Control({
onClick={onClick} />
<div className="menu-split" style={{ marginLeft: '7px', marginRight: '7px' }}></div>
</> : null
}
*/}
{role === 'teacher' ?
<>
<ControlItem
name={whiteboard.state.recording ? 'stop_recording' : 'recording'}
onClick={onRecordButtonClick}
active={false}
/>
{/*<ControlItem*/}
{/*name={whiteboard.state.recording ? 'stop_recording' : 'recording'}*/}
{/*onClick={onRecordButtonClick}*/}
{/*active={false}*/}
{/*/>*/}
<ControlItem
name={sharing ? 'quit_screen_sharing' : 'screen_sharing'}
onClick={onClick}
......
......@@ -7,8 +7,7 @@ import {STAGE_NUM} from "../utils/consts";
type StreamValue ={
teacher: any
students?: any[]
stageStudents: {stage:any[], wait:any[]}
students: any[]
sharedStream: any
currentHost: any
onPlayerClick: (type: string, streamID: number, uid: string) => Promise<any>
......@@ -61,7 +60,7 @@ export default function useStream () {
roomState.rtc.remoteStreams,
roomState.rtc.localStream
]);
/*
const students__ = useMemo(() => {
const userAttrs = roomStore.state.users;
if (!me.uid || userAttrs.count() === 0) return [];
......@@ -125,19 +124,32 @@ export default function useStream () {
roomState.rtc.remoteStreams,
roomState.rtc.localStream
]);
const students_old = useMemo(() => {
*/
const students = useMemo(() => {
const userAttrs = roomStore.state.users;
if (!me.uid || userAttrs.count() === 0) return [];
const teacherUid = course.teacherId;
const peerUsers = roomState.rtc.users;
// exclude teacher and me
let studentIds = peerUsers.filter((it: number) => it !== +teacherUid && it !== +me.uid && it !== SHARE_ID);
studentIds = studentIds.add(+me.uid);
const studentStreams: any[] = [];
const myAttr = userAttrs.get(me.uid);
const studentsOrder = roomStore.state.studentsOrder || [];
console.log(100000, studentsOrder);
console.log(11111111, studentIds.toArray());
studentIds = studentIds.sort(function(a, b){
return studentsOrder.indexOf(+a) - studentsOrder.indexOf(+b);
});
console.log(222222, studentIds.toArray());
// when i m student
if (me.role === 'student') {
// capture all remote streams
for (let studentId of studentIds) {
if (me.role === 'student' && +me.uid == studentId) {
if (myAttr && roomState.rtc.localStream) {
const _tmpStream = {
...roomState.rtc.localStream,
......@@ -147,11 +159,9 @@ export default function useStream () {
local: true,
}
studentStreams.push(_tmpStream);
continue
}
}
// capture all remote streams
for (let studentId of studentIds) {
const studentAttr = userAttrs.get(''+studentId);
const stream = roomState.rtc.remoteStreams.get(+studentId);
if (studentAttr) {
......@@ -173,6 +183,7 @@ export default function useStream () {
studentStreams.push(_tmpStream);
}
}
console.log('studentStreams', studentStreams);
return studentStreams;
}, [
course,
......@@ -182,6 +193,7 @@ export default function useStream () {
roomState.rtc.localStream
]);
/*
const stageStudents: { wait: any[]; stage: any[] } = useMemo(() => {
const userAttrs = roomStore.state.users;
if (!me.uid || userAttrs.count() === 0) return { wait: [], stage:[] };
......@@ -191,7 +203,8 @@ export default function useStream () {
let studentIds = peerUsers.filter((it: number) => it !== +teacherUid && it !== +me.uid && it !== SHARE_ID);
const studentStreams: any[] = [];
userAttrs.forEach(u => {
if (me.role === 'student' && `${u.uid}` === `${me.uid}`) {
const uid = u.uid;
if (me.role === 'student' && `${uid}` === `${me.uid}`) {
if (roomState.rtc.localStream) {
const _tmpStream = {
...roomState.rtc.localStream,
......@@ -203,11 +216,11 @@ export default function useStream () {
studentStreams.push(_tmpStream);
}
} else {
const studentAttr = userAttrs.get(`${u.uid}`);
const stream = roomState.rtc.remoteStreams.get(+u.uid);
const studentAttr = userAttrs.get(`${uid}`);
const stream = roomState.rtc.remoteStreams.get(+uid);
if (studentAttr) {
let _tmpStream = {
streamID: u.uid,
streamID: uid,
account: studentAttr.account,
video: studentAttr.video,
audio: studentAttr.audio,
......@@ -215,7 +228,7 @@ export default function useStream () {
if (stream) {
_tmpStream = {
...stream,
streamID: u.uid,
streamID: uid,
account: studentAttr.account,
video: studentAttr.video,
audio: studentAttr.audio,
......@@ -225,55 +238,6 @@ export default function useStream () {
}
}
})
/*
const myAttr = userAttrs.get(me.uid);
const ss = [];
// when i m student
if (me.role === 'student') {
if (myAttr && roomState.rtc.localStream) {
const _tmpStream = {
...roomState.rtc.localStream,
account: myAttr.account,
video: myAttr.video,
audio: myAttr.audio,
local: true,
}
studentStreams.push(_tmpStream);
ss.push(me.uid)
}
}
for (let studentId of studentIds) {
ss.push(studentId)
}
console.log('studentIds', ss.join(', '))
// capture all remote streams
for (let studentId of studentIds) {
const studentAttr = userAttrs.get(''+studentId);
const stream = roomState.rtc.remoteStreams.get(+studentId);
if (studentAttr) {
let _tmpStream = {
streamID: studentId,
account: studentAttr.account,
video: studentAttr.video,
audio: studentAttr.audio,
}
if (stream) {
_tmpStream = {
...stream,
streamID: studentId,
account: studentAttr.account,
video: studentAttr.video,
audio: studentAttr.audio,
}
}
studentStreams.push(_tmpStream);
}
}*/
console.log('studentStreams', studentStreams)
return {
stage: [...studentStreams.slice(0,STAGE_NUM)],
......@@ -286,6 +250,8 @@ export default function useStream () {
roomState.rtc.remoteStreams,
roomState.rtc.localStream
]);
*/
const sharedStream = useMemo(() => {
const sharedUid = SHARE_ID;
......@@ -358,8 +324,8 @@ export default function useStream () {
const value: StreamValue = {
teacher: teacher,
// students: students,
stageStudents,
students: students,
// stageStudents,
sharedStream: sharedStream,
currentHost: currentHost,
onPlayerClick: async (type: string, streamID: number, uid: string) => {
......
......@@ -141,6 +141,7 @@ export function RoomPage({ children }: any) {
if (platform === 'web') {
const webClient = rtcClient as AgoraWebClient;
if (!webClient.published) return;
console.log('unpublish' ,2);
webClient
.unpublishLocalStream()
.then(() => {
......@@ -181,7 +182,7 @@ export function RoomPage({ children }: any) {
webClient
.publishLocalStream(streamSpec)
.then(() => {
console.log("[agora-web] publish local stream");
console.log("[agora-web] publish local stream", roomStore.state.me.uid);
}).catch(console.warn)
.finally(() => {
publishLock.current = false;
......@@ -234,6 +235,7 @@ export function RoomPage({ children }: any) {
roomStore.addLocalStream(_stream);
});
webClient.rtc.on('stream-subscribed', ({ stream }: any) => {
console.log('stream', 2, 'stream-subscribed')
const streamID = stream.getId();
// when streamID is not share_id use switch high or low stream in dual stream mode
if (location.pathname.match(/small-class/) && streamID !== SHARE_ID) {
......@@ -247,11 +249,13 @@ export function RoomPage({ children }: any) {
console.log("[agora-web] dual stream set low for student");
}
}
console.log('stream', 3, 'addRemoteStream to play')
const _stream = new AgoraStream(stream, stream.getId(), false);
console.log("[agora-web] subscribe remote stream, id: ", stream.getId());
roomStore.addRemoteStream(_stream);
});
webClient.rtc.on('stream-added', ({ stream }: any) => {
console.log('stream', 1, 'stream-added')
console.log("[agora-web] added remote stream, id: ", stream.getId());
webClient.subscribe(stream);
});
......@@ -316,6 +320,8 @@ export function RoomPage({ children }: any) {
for (let eventName of events) {
webClient.rtc.off(eventName, () => {});
}
console.log("[agora-web] rtmClient logout");
roomStore.rtmClient.logout();
console.log("[agora-web] remove event listener");
!rtc.current && webClient.exit().then(() => {
console.log("[agora-web] do remove event listener");
......
import React, {useLayoutEffect, useRef} from 'react';
import React, {useLayoutEffect, useMemo, useRef, useState} from 'react';
// import VideoMarquee from '../../components/video-marquee';
// import MediaBoard from '../../components/mediaboard';
import MediaBoard from '../../components/mediaboard';
import Roomboard from '../../components/roomboard';
import './small-class.scss';
import CourseWareFrame from "../../components/courseware-frame";
import VideoShowList from "../../components/video-stage-list";
import {ToolsSwitcherController} from "../../components/tools-switcher-controller";
export default function SmallClass() {
// let search = window.location.search;
// let params = new URLSearchParams(search);
// let src = params.get('src');
// console.log(9999, src)
// useLayoutEffect(() => {
// }, [src]);
const [tool, setTool] = useState(true);
return (
<div className="room-container">
{/*<VideoMarquee />*/}
<VideoShowList/>
<div className="container">
{/*<MediaBoard />*/}
<CourseWareFrame></CourseWareFrame>
<ToolsSwitcherController onClick={() => {
setTool(!tool);
}}/>
{tool ? <MediaBoard /> : <CourseWareFrame></CourseWareFrame>}
<Roomboard currentActive={'media'} />
</div>
</div>
......
......@@ -2,7 +2,7 @@ import { platform } from './../utils/platform';
import { AgoraElectronClient } from './../utils/agora-electron-client';
import { ChatMessage, AgoraStream } from '../utils/types';
import {Subject} from 'rxjs';
import {OrderedMap, Set, List, OrderedSet} from 'immutable';
import {OrderedMap, List, OrderedSet} from 'immutable';
import AgoraRTMClient, { RoomMessage } from '../utils/agora-rtm-client';
import {globalStore} from './global';
import AgoraWebClient from '../utils/agora-rtc-client';
......@@ -13,7 +13,7 @@ import { whiteboard } from './whiteboard';
import {STAGE_NUM} from "../utils/consts";
import {jsonParse} from "../utils/helper";
function canJoin({onlineStatus, roomType, channelCount, role}: {onlineStatus: any, role: string, channelCount: number, roomType: number}) {
function canJoin({uid, onlineStatus, roomType, channelCount, role}: { uid: any, onlineStatus: any, role: string, channelCount: number, roomType: number}) {
const result = {
permitted: true,
reason: ''
......@@ -31,7 +31,7 @@ function canJoin({onlineStatus, roomType, channelCount, role}: {onlineStatus: an
const totalCount: number = get(onlineStatus, 'totalCount', 0);
if (role === 'teacher') {
const isOnline = teacher;
const isOnline = teacher && `${uid}` !== `${onlineStatus.teacherId}`;
if (isOnline) {
result.permitted = false;
result.reason = 'Teacher already existed';
......@@ -192,6 +192,7 @@ export class RoomStore {
microphone: 0
},
messages: List<ChatMessage>(),
studentsOrder: [],
...GlobalStorage.read('agora_room')
});
......@@ -209,7 +210,6 @@ export class RoomStore {
}
async stageUpRtc(uid: string) {
debugger
let store = this._state.rtc.users;
let itemsList = store.toList();
const idx = itemsList.indexOf(+uid);
......@@ -234,7 +234,6 @@ export class RoomStore {
this.commit(this.state);
}
async stageDownRtc(uid: string) {
debugger
let store = this._state.rtc.users;
console.log(store);
// let uid = 2;
......@@ -261,8 +260,7 @@ export class RoomStore {
}
this.commit(this.state);
}
async stageUp(uid: string) {
debugger
async stageUp1(uid: string) {
const attrs = await this.rtmClient.getChannelAttrs();
let studentsOrder: any[] = [];
// if ((attrs as any).studentsOrder && (attrs as any).studentsOrder.value) {
......@@ -272,12 +270,11 @@ export class RoomStore {
const onlineStatus = JSON.parse(attrs)
const target = jsonParse(get(onlineStatus[uid], 'value'));
// 上台需要开启视频
if (!+target.video) {
target.video = 1
// if (!+target.video) {
target.video = 1;
data[uid] = JSON.stringify(target)
}
// }
debugger
const tmp: [string, AgoraUser][] =[];
this._state.users.forEach((v, k)=>{
if (/^[0-9]+$/.test(k)) {
......@@ -294,12 +291,12 @@ export class RoomStore {
tmp.unshift(uidObj);
tmp.push(stageEndObj)
// 下台关闭音视频
stageEndObj[1].audio = 0;
stageEndObj[1].video = 0;
// stageEndObj[1].audio = 0;
// stageEndObj[1].video = 0;
data[stageEndObj[1].uid] = JSON.stringify(stageEndObj[1])
tmp.forEach(o => {
studentsOrder.push(o[0]);
studentsOrder.push(+o[0]);
});
// const queue = {'studentsOrder': JSON.stringify(studentsOrder)};
data['studentsOrder'] = JSON.stringify(studentsOrder)
......@@ -308,16 +305,15 @@ export class RoomStore {
const users = OrderedMap(tmp);
this.state = {
...this.state,
users
}
// this.state = {
// ...this.state,
// users
// }
// this.commit(this.state);
}
async stageDown(uid: string) {
debugger
const tmp: [string, AgoraUser][] =[];
this._state.users.forEach((v, k)=>{
tmp.push([k, v])
......@@ -339,8 +335,61 @@ export class RoomStore {
}
this.commit(this.state);
}
async stageUp(uid: string) {
debugger
const attrs = await this.rtmClient.getChannelAttrs();
let studentsOrder: any[] = [];
// if ((attrs as any).studentsOrder && (attrs as any).studentsOrder.value) {
// studentsOrder = JSON.parse((attrs as any).studentsOrder.value) || [];
// }
const data: any = {};
const onlineStatus = JSON.parse(attrs)
const target = jsonParse(get(onlineStatus[uid], 'value'));
// 上台需要开启视频
// if (!+target.video) {
target.video = 1;
data[uid] = JSON.stringify(target)
// }
const tmp: [string, AgoraUser][] =[];
this._state.users.forEach((v, k)=>{
if (/^[0-9]+$/.test(k)) {
tmp.push([k, v])
}
})
const uidIdx = tmp.findIndex((o) => {
return `${o[0]}` == `${uid}`
})
const uidObj = tmp[uidIdx]
tmp.splice(uidIdx, 1)
const stageEndObj = tmp[STAGE_NUM - 1]
tmp.splice(STAGE_NUM - 1, 1)
tmp.unshift(uidObj);
tmp.push(stageEndObj)
// 下台关闭音视频
// stageEndObj[1].audio = 0;
// stageEndObj[1].video = 0;
data[stageEndObj[1].uid] = JSON.stringify(stageEndObj[1])
tmp.forEach(o => {
studentsOrder.push(+o[0]);
});
// const queue = {'studentsOrder': JSON.stringify(studentsOrder)};
data['studentsOrder'] = JSON.stringify(studentsOrder)
const aa = await this.rtmClient.addOrUpdateChannelAttributes(data);
console.log(aa)
const users = OrderedMap(tmp);
// this.state = {
// ...this.state,
// users
// }
// this.commit(this.state);
}
initialize() {
......@@ -712,23 +761,89 @@ export class RoomStore {
}
async loginAndJoin(payload: any, pass: boolean = false) {
debugger
const {roomType, role, uid, rid, token} = payload;
await this.rtmClient.login(uid, token);
const channelMemberCount = await this.rtmClient.getChannelMemberCount([rid]);
const channelCount = channelMemberCount[rid];
let accounts = await this.rtmClient.getChannelAttributeBy(rid);
const onlineStatus = await this.rtmClient.queryOnlineStatusBy(accounts);
// debugger
/*
const me = accounts.find((o)=>{return `${payload.uid}` === `${o.uid}`});
if (onlineStatus[payload.uid]) {
payload.audio = me.audio;
payload.video = me.video;
} else {
if (accounts.length >= STAGE_NUM) {
payload.audio = 0;
payload.video = 0;
// payload.stage = 0;
} else {
// payload.stage = 1;
payload.audio = 0;
payload.video = 1;
}
}*/
if (role === 'teacher') {
payload.audio = 1;
payload.video = 1;
}
// for test
payload.audio = 0;
payload.video = 0;
const argsJoin = {
uid,
channelCount,
onlineStatus,
role,
accounts,
roomType
};
const result = pass === false ? canJoin(argsJoin) : {permitted: true, reason: ''};
let result = pass === false ? canJoin(argsJoin) : {permitted: true, reason: ''};
// if (uid == this._state.course.teacherId) {
// result = {permitted: false, reason: 'same with teacher id'}
// }
let studentsOrder: number[] = [];
if (result.permitted) {
studentsOrder = this.state.studentsOrder;
if (!studentsOrder.length) {
accounts.forEach(a => {
if (!studentsOrder.includes(+a.uid)) {
studentsOrder.push(+a.uid);
}
})
} else {
debugger
const accIds = accounts.map(a=> +a.uid);
// if (accIds.length >= studentsOrder.length) {
let a = new Set(accIds);
let b = new Set(studentsOrder);
let diff = new Set([...a].filter(x => !b.has(x)));
diff.forEach(d => {
if (!studentsOrder.includes(+d)) {
studentsOrder.push(+d);
}
})
debugger
// }
}
if (!studentsOrder.includes(+uid)) {
studentsOrder.push(+uid);
} else {
if (!pass) {
const i = studentsOrder.indexOf(+uid)
studentsOrder.splice(i,1)
studentsOrder.push(+uid)
}
}
let res = await this.rtmClient.join(rid);
this.state = {
...this.state,
......@@ -739,7 +854,7 @@ export class RoomStore {
}
const grantBoard = role === 'teacher' ? 1 : 0;
console.log(">>>>>>>>>>#room: ", grantBoard);
await this.updateMe({...payload, grantBoard});
await this.updateMe({...payload, grantBoard}, studentsOrder);
this.commit(this.state);
return;
}
......@@ -828,7 +943,7 @@ export class RoomStore {
// return res;
}
async updateMe(user: any) {
async updateMe(user: any, studentsOrder: number[] = []) {
const {role, uid, account, rid, video, audio, chat, boardId, linkId, sharedId, muteChat, grantBoard} = user;
const key = role === 'teacher' ? 'teacher' : uid;
const me = this.state.me;
......@@ -876,14 +991,19 @@ export class RoomStore {
}
const data: any = {};
data[key] = attrs;
if (studentsOrder && studentsOrder.length) {
data['studentsOrder'] = studentsOrder;
}
await this.rtmClient.updateChannelAttrsByKey(data);
// let res = await this.rtmClient.updateChannelAttrsByKey(key, attrs);
// return res;
}
updateRoomAttrs ({teacher, accounts, room}: any) {
updateRoomAttrs ({teacher, accounts, room, studentsOrder}: any) {
console.log("[agora-board], room: ", room, " teacher: ", teacher, "accounts ", accounts);
const users = accounts.reduce((acc: Map<string, AgoraUser>, it: any) => {
const users = accounts.reduce((acc: OrderedMap<string, AgoraUser>, it: any) => {
return acc.set(it.uid, {
role: it.role,
account: it.account,
......@@ -899,6 +1019,25 @@ export class RoomStore {
});
}, OrderedMap<string, AgoraUser>());
/*
let users = OrderedMap<string, AgoraUser>();
for (const it of accounts) {
users = users.set(it.uid, {
role: it.role,
account: it.account,
uid: it.uid,
video: it.video,
audio: it.audio,
chat: it.chat,
boardId: it.whiteboard_uid,
sharedId: it.shared_uid,
linkId: it.link_uid,
lockBoard: it.lock_board,
grantBoard: it.grant_board,
})
}
*/
console.log('users 4', users.toArray());
const me = this.state.me;
if (users.get(me.uid)) {
......@@ -911,6 +1050,8 @@ export class RoomStore {
boardId: room.whiteboard_uid,
lockBoard: room.lock_board,
})
//教师维护学生顺序,并更新到频道属性
}
const newClassState: ClassState = {} as ClassState;
......@@ -936,7 +1077,8 @@ export class RoomStore {
course: {
...this.state.course,
...newClassState
}
},
studentsOrder
}
this.commit(this.state);
}
......
......@@ -155,7 +155,7 @@ class AgoraRTCClient {
this._bus.off(evtName, cb);
}
async publish() {
async publish() { console.log('rtc publish')
return new Promise((resolve, reject) => {
if (this._published) {
return resolve();
......@@ -170,7 +170,7 @@ class AgoraRTCClient {
})
}
async unpublish() {
async unpublish() {console.log('unpublish' , 1);
return new Promise((resolve, reject) => {
if (!this._published || !this._localStream) {
return resolve();
......@@ -234,7 +234,7 @@ class AgoraRTCClient {
})
}
async leave () {
async leave () { console.log(9999, 'rtc leave');
if (this._client) {
return new Promise((resolve, reject) => {
this._client.leave(resolve, reject);
......@@ -341,7 +341,7 @@ export default class AgoraWebClient {
roomStore.setRTCJoined(true);
}
async leaveChannel() {
async leaveChannel() { console.log('unpublish leaveChannel' , 3);
this.localUid = 0;
this.channel = '';
await this.unpublishLocalStream();
......@@ -357,17 +357,17 @@ export default class AgoraWebClient {
}
async publishLocalStream(data: AgoraStreamSpec) {
console.log(" publish local stream ", this.published);
console.log(" publish local stream ", roomStore.state.me.uid);
if (this.published) {
await this.unpublishLocalStream();
console.log("[agora-web] unpublished", this.published);
console.log("[agora-web] unpublished", roomStore.state.me.uid);
}
await this.rtc.createLocalStream(data);
await this.rtc.publish();
this.published = true;
}
async unpublishLocalStream() {
async unpublishLocalStream() { console.log('unpublish LocalStream' , 4);
console.log("[agora-web] invoke unpublishStream");
await this.rtc.unpublish();
this.published = false;
......
......@@ -54,8 +54,8 @@ export default class AgoraRTMClient {
this._channelAttrsKey = null;
this._client = AgoraRTM.createInstance(APP_ID, { enableLogUpload: false, logFilter });
}
async addOrUpdateChannelAttributes(data: any): Promise<string> {
return await this._client.addOrUpdateChannelAttributes(this._currentChannelName, data, {enableNotificationToChannelMembers: true});
async addOrUpdateChannelAttributes(data: any, enableNotificationToChannelMembers = true): Promise<string> {
return await this._client.addOrUpdateChannelAttributes(this._currentChannelName, data, {enableNotificationToChannelMembers});
}
public removeAllListeners(): any {
......@@ -83,6 +83,7 @@ export default class AgoraRTMClient {
}
async login (uid: string, token?: string) {
this._channelAttrsKey = uid;
await this._client.login({uid, token});
this._client.on("ConnectionStateChanged", (newState: string, reason: string) => {
this._bus.emit("ConnectionStateChanged", {newState, reason});
......@@ -96,6 +97,7 @@ export default class AgoraRTMClient {
async logout () {
if (!this._logged) return;
await this.leave(this._currentChannelName);
await this._client.logout();
this.destroy();
this._logged = false;
......@@ -155,6 +157,9 @@ export default class AgoraRTMClient {
async sendChannelMessage(msg: string) {
return this._currentChannel.sendMessage({ text: msg });
}
async setChannelAttrsKey(key: any) {
this._channelAttrsKey = `${key}`;
}
async updateChannelAttrsByKey (data: {[key: string]: string}/*key: string, attrs: any*/) {
// this._channelAttrsKey = key;
const channelAttributes: {[key: string]: string} = {};
......@@ -217,6 +222,7 @@ export default class AgoraRTMClient {
const teacher = accounts.find((it: any) => it.role === 'teacher');
if (teacher && results[teacher.uid]) {
results.teacher = results[teacher.uid];
results.teacherId = teacher.uid;
results.teacherCount = 1;
}
results.totalCount = accounts.filter((it: any) => results[it.uid]).length;
......@@ -240,6 +246,10 @@ export default class AgoraRTMClient {
}
continue;
}
// if (key === 'studentsOrder') {
// continue
// }
if (/^[0-9]+$/.test(key)) {
const student = jsonParse(_.get(json, `${key}.value`));
// when student is not empty object
if (student && Object.keys(student).length) {
......@@ -247,6 +257,7 @@ export default class AgoraRTMClient {
accounts.push(student);
}
}
}
return accounts;
}
......
......@@ -226,6 +226,7 @@ export function resolveChannelAttrs(json: object) {
let studentsOrder: number[] = [];
if ((json as any).studentsOrder && (json as any).studentsOrder.value) {
studentsOrder = JSON.parse((json as any).studentsOrder.value) || [];
studentsOrder = studentsOrder.map(id => +id)
}
delete (json as any).studentsOrder;
......@@ -249,52 +250,32 @@ export function resolveChannelAttrs(json: object) {
}
}
}
const students = [];
let students: any[] = [];
for (let key of Object.keys(json)) {
if (key === 'teacher') continue;
const student = jsonParse(_.get(json, `${key}.value`));
if (student && Object.keys(student).length) {
student.uid = key;
student.role = 'student';
students.push(student);
}
}
console.log('resolveChannelAttrs 1', students);
console.log('resolveChannelAttrs 2', studentsOrder);
/*
const studentsMeta = [];
for (let key of Object.keys(json)) {
if (key === 'teacher') continue;
// if (!/^[0-9]+$/.test(key)) continue;
// const student = jsonParse(_.get(json, `${key}.value`));
// @ts-ignore
const studentMeta = json[key];
studentMeta.key = key;
studentsMeta.push(studentMeta)
// if (student && Object.keys(student).length) {
// student.uid = key;
// students.push(student);
// }
}
studentsMeta.sort((a, b)=>{
return a.lastUpdateTs - b.lastUpdateTs
})
let i = 0;
for (const s of studentsMeta) {
// const studentMeta = jsonParse(s);
const student = jsonParse(_.get(json, `${s.key}.value`));
if (student && Object.keys(student).length) {
student.uid = s.key;
// student.posIdx = i;
students.push(student);
i++;
}
}*/
// console.log('resolveChannelAttrs', studentsMeta);
// const orderedStudents: any[] = [];
// students.sort(function(a, b){
// return studentsOrder.indexOf(+a.uid) - studentsOrder.indexOf(+b.uid);
// });
// console.log('resolveChannelAttrs 1', students);
// console.log('resolveChannelAttrs 2', studentsOrder);
const accounts = [];
const accounts:any[] = [];
if (teacherJson && Object.keys(teacherJson).length) {
accounts.push({
role: 'teacher',
......@@ -324,33 +305,15 @@ export function resolveChannelAttrs(json: object) {
grant_board: +student.grant_board,
});
}
// console.log('resolveChannelAttrs 3', accounts);
if (studentsOrder.length == 0) {
accounts.forEach(a => {
studentsOrder.push(+a.uid);
})
} else {
const notInOrder = [];
accounts.forEach(a => {
if (!studentsOrder.includes(+a.uid)) {
notInOrder.push(+a.uid)
}
})
const aUids = accounts.map(a => {
return +a.uid;
});
const a = new Set(studentsOrder);
const b = new Set(aUids);
}
return {
teacher: teacherJson,
students: students,
accounts,
room,
studentsOrder
};
}
......
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