Commit 9e379994 authored by liujiaxin's avatar liujiaxin

modify 由独立的userStars 变量改成 stars保存到用户频道属性

parent c21f5e58
......@@ -39,5 +39,20 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script>
function getQueryString(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
const r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
var token = getQueryString('token');
if (token) {
window.location.href = `${window.location.origin}/#/?token=${token}`
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
跳转中。。。
<script>
function getQueryString(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
const r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
var token = getQueryString('token');
</script>
</body>
</html>
......@@ -32,24 +32,44 @@ const useStyles = makeStyles({
},
frm: {
flex: 1,
border: 0
border: 0,
},
fixParent :{
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0
}
});
const CourseWareFrame: React.FC = () => {
const classes = useStyles();
// `${ENDPOINT}/airclass_ol?token=${this.userToken}`;
let src = endPoint.getCourseUrl();
let refDom: any = null;
const saveRef = (ref: any) => {refDom = ref};
useEffect(() => {
const hel = document.querySelector('.on-show')
let helh = 0;
if (hel){
helh = hel.clientHeight;
}
if (helh && refDom) {
const hh = 48 + helh + 8;
refDom.style.height = `${document.body.clientHeight - hh}px`;
}
return () => {
src = 'about:blank'
console.log('iframe to blank');
}
}, []);
return (
<div className={classes.style1}>
<iframe id="cwFrame" src={src} className={classes.frm}></iframe>
</div>
<div ref={saveRef} className={classes.style1}>
{/*<svg viewBox="0 0 0 0"></svg>*/}
<iframe id="cwFrame" src={src} className={classes.frm}></iframe>
</div>
)
}
......
......@@ -8,7 +8,7 @@ import {roomStore, windowMonitor} from '../../stores/room';
import {globalStore} from '../../stores/global';
import { useHistory } from 'react-router-dom';
import { RoomMessage } from '../../utils/agora-rtm-client';
import {getApiServerHost} from "../../services/agora-end-points";
import {getApiServerHost, goHome} from "../../services/agora-end-points";
interface RoomProps {
onConfirm: (type: string) => void
......@@ -71,7 +71,7 @@ const DialogContainer = () => {
const onClose = (type: string) => {
if (type === 'exitRoom') {
globalStore.removeDialog();
// history.push('/');
;
}
else if (type === 'apply') {
roomStore.rtmClient.sendPeerMessage(
......@@ -84,7 +84,7 @@ const DialogContainer = () => {
const onConfirm = (type: string) => {
if (type === 'exitRoom') {
// debugger
// const data = roomStore.getUserUsage();
// const host = getApiServerHost();
// var blob = new Blob([JSON.stringify(data)], {
......@@ -96,7 +96,8 @@ const DialogContainer = () => {
roomStore.exitAll().then(() => {
globalStore.stopLoading();
globalStore.removeDialog();
history.push('/');
// history.push('/');
goHome(history)
})
}
......
......@@ -376,7 +376,7 @@ const items = [
useEffect(() => {
if (!rtmState.joined) return;
// debugger
if (!lock.current && !whiteboard.state.room) {
console.log('do join whiteboard room');
......
......@@ -13,7 +13,8 @@ import ImportContacts from "@material-ui/icons/ImportContacts";
import SettingsApplicationsIcon from '@material-ui/icons/SettingsApplications';
import SettingsPowerIcon from '@material-ui/icons/SettingsPower';
import {TOOL_TYPE} from "../utils/types";
import EmojiEventsIcon from '@material-ui/icons/EmojiEvents';
import {eventBus} from "../stores/EventBus";
type Props = {
// zoomScale: number
......@@ -51,6 +52,9 @@ export default function RoomToolsBar (props: any) {
console.log('allStudentMuteOff');
await roomStore.allStudentMuteOff()
}
const allAddStar = async () => {
eventBus.emit('showAddStartDialog', {uid: 0})
}
const randomStageUp = async () => {
await roomStore.randomStageUp()
}
......@@ -61,7 +65,7 @@ export default function RoomToolsBar (props: any) {
{roomStore.state.me.role == 'teacher' ?
<>
{/*<div className="tool-btn" onClick={audioOn}><VoiceOverOffIcon/></div>*/}
<div className="tool-btn" onClick={allAddStar}><EmojiEventsIcon/></div>
{muteAudio
? <div className="tool-btn" onClick={allMuteOff}><RecordVoiceOverIcon/></div>
: <div onClick={allMuteOn} className="tool-btn"><VoiceOverOffIcon/></div>
......
.media-btn {
display: flex;
justify-content: space-between;
width: 58px;
//width: 80px;
margin-right: 10px;
}
.media-btn>.icon.disabled{
......@@ -17,6 +17,13 @@
.student-placeholder {
z-index: 9;
}
}
.medal{
width: 16px;
z-index: 99;
background-size: contain;
background-image: url("data:image/png;base64,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");
}
.menu-close {
cursor: pointer;
......@@ -42,6 +49,36 @@
background-image: url('../assets/icon-resource-menu-close.png');
}
}
.star{
position: absolute;
z-index: 10;
left: 4px;
top: 4px;
color: #fff;
line-height: 20px;
height: 20px;
display: flex;
flex-direction: row;
//cursor: pointer;
}
.star .medal-bg{
position: absolute;
background: #000;
opacity: .6;
height: 16px;
top: 2px;
left: 6px;
border-radius: 0 4px 4px 0;
padding-left: 12px;
padding-right: 8px;
}
.star .points{
line-height: 16px;
height: 16px;
font-size: 14px;
display: block;
}
.video-profile {
z-index: 3;
width: 100%;
......
import React, { useRef, useEffect, useMemo } from 'react';
import React, {useRef, useEffect, useMemo, useState} from 'react';
import Icon from './icon';
import './video-player.scss';
import { AgoraElectronStream, StreamType, nativeRTCClient as nativeClient } from '../utils/agora-electron-client';
......@@ -8,11 +8,16 @@ import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward';
import {makeStyles} from '@material-ui/core/styles';
import {roomStore} from "../stores/room";
import BuildIcon from '@material-ui/icons/Build';
import {eventBus} from "../stores/EventBus";
// import StarIcon from '@material-ui/icons/Star';
import EmojiEventsOutlinedIcon from '@material-ui/icons/EmojiEventsOutlined';
const useStyles = makeStyles({
stageDown : {
display: 'flex',
width: 18,
marginLeft: 2,
marginRight: 2,
width: 20,
height: 24,
color: '#fff',
lineHeight: 24,
......@@ -20,7 +25,23 @@ const useStyles = makeStyles({
cursor:'pointer'
},
fixStream: {
width: 14,
marginLeft: 4,
marginRight: 4,
width: 16,
height: 24,
color: '#fff',
lineHeight: 24,
opacity: .8,
cursor:'pointer'
},
star: {
height: 20,
color: '#ebb445'
},
emojiEvent: {
width: 18,
marginLeft: 3,
marginRight: 3,
height: 24,
color: '#fff',
lineHeight: 24,
......@@ -73,6 +94,9 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
const loadAudio = useRef<boolean>(false);
const stateError = useRef<boolean>(false);
const [star, setStar] = useState<number>(0);
// const hasError = useMemo(() => {
// return stateError.current;
// }, [stateError]);
......@@ -181,13 +205,13 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
}
})
return () => {
console.log(2343454567,local, streamID, me)
// console.log(2343454567,local, streamID, me)
if (reloadStreamTimer) {
clearTimeout(reloadStreamTimer)
reloadStreamTimer = null;
}
if (stream.isPlaying()) {
// debugger
stream.stop();
// stream.stop();
}
......@@ -196,6 +220,16 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
}
}, [domId, stream]);
useEffect(() => {
console.log('roomStore.state.userStars change')
if (id) {
const u = roomStore.state.users.get(id)
if (u) {
setStar(u.stars);
}
}
// setStar()
}, [roomStore.state.users]);
useEffect(() => {
if (stream && platform === 'web') {
......@@ -310,13 +344,20 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
handleClose('close', streamID);
}
}
const addStar = (evt: any) => {
if (me.role != 'teacher') {
return
}
eventBus.emit('showAddStartDialog', {uid: id});
}
const resumeStream = (evt: any) => {
stateError.current = false;
stream.resume()
}
const me = useRoomState().me;
const teacherId = useRoomState().course.teacherId;
// let stu = useRoomState().users.get(`${id}`);
return (
<div className={`${className ? className : (preview ? 'preview-video' : `agora-video-view ${Boolean(video) === false && stream ? 'show-placeholder' : ''}`)}`}>
......@@ -324,20 +365,36 @@ return (
{className !== 'screen-sharing' ? <div className={role === 'teacher' ? 'teacher-placeholder' : 'student-placeholder'}></div> : null }
{preview ? null :
account ?
<>
{ streamID > 0 && id != teacherId?
<div className='star'>
<div className="medal"></div>
<div className="medal-bg">
<span className="points">
{star}
</span>
</div>
</div>: null }
<div className="video-profile">
<span className="account">{account}</span>
{/*{stateError.current?<span onClick={resumeStream}>恢复</span>: null}*/}
{streamID <= 0 ? null :
<div>
<>
{
/*me.uid === id ||*/ me.role === 'teacher'
? <span className="media-btn">
<>
{
id != roomStore.state.course.teacherId
?<ArrowDownwardIcon onClick={onStageDownClick} className={style.stageDown}></ArrowDownwardIcon>
:<BuildIcon onClick={fixUserStream} className={style.fixStream}></BuildIcon>}
{id != roomStore.state.course.teacherId
?
<>
<EmojiEventsOutlinedIcon onClick={addStar} className={style.emojiEvent}></EmojiEventsOutlinedIcon>
<ArrowDownwardIcon onClick={onStageDownClick} className={style.stageDown}></ArrowDownwardIcon>
</>
:<BuildIcon onClick={fixUserStream} className={style.fixStream}></BuildIcon>}
<Icon onClick={onAudioClick} className={audio ? "icon-speaker-on" : "icon-speaker-off"}
......@@ -351,15 +408,17 @@ return (
<Icon className={video ? "icons-camera-unmute-s disabled" : "icons-camera-mute-s disabled"}
data={"video"}/>
</span>
}</div>
}</>
}
</div>
</>
: null
}
<div id={`${domId}`} className={`agora-rtc-video ${local && platform === 'electron' ? 'rotateY180deg' : ''}`}></div>
</div>
)
......
......@@ -3,15 +3,15 @@
display: flex;
min-width: 990px;
background: #F5F7F8;
max-height: 122px;
min-height: 122px;
//max-height: 122px;
//min-height: 122px;
align-items: flex-start;
padding-top: 5px;
position: relative;
z-index: 1;
.show-platform{
width: 100%;
position: absolute;
//position: absolute;
//height: 100%;
//margin-left: 3.33px;
//margin-right: 3.33px;
......
import React, { useRef, useEffect, useState, useLayoutEffect } from 'react';
import VideoPlayer from './video-player';
import Icon from './icon';
// import Icon from './icon';
import {ExpandMore, ExpandLess} from '@material-ui/icons';
import './video-stage-list.scss';
import useStream from '../hooks/use-streams';
import { AgoraMediaStream } from '../utils/types';
import {STAGE_NUM} from "../utils/consts";
import MemberHolder from "./member-holder";
import { Dialog, Button, DialogContent, DialogActions, TextField, DialogContentText, DialogTitle } from '@material-ui/core';
import { roomStore } from '../stores/room';
function VideoShowList() {
......@@ -16,7 +17,6 @@ function VideoShowList() {
const ref = useRef<boolean>(false);
useEffect(() => {
......@@ -38,6 +38,7 @@ function VideoShowList() {
return (
<div className="video-show-list-container">
<div className="show-platform">
<div className="on-show">
{teacher ?
......
......@@ -19,8 +19,11 @@ export default function Whiteboard ({
whiteboard.updateRoomState();
if ($whiteboard) {
window.addEventListener("resize", (evt: any) => {
room.moveCamera({centerX: 0, centerY: 0});
room.refreshViewSize();
try{
room.moveCamera({centerX: 0, centerY: 0});
room.refreshViewSize();
}catch(e){}
});
return () => {
window.removeEventListener("resize", (evt: any) => {});
......@@ -34,4 +37,4 @@ export default function Whiteboard ({
<div id="whiteboard" className={`whiteboard-canvas ${className}`}></div>
</div>
)
}
\ No newline at end of file
}
......@@ -5,7 +5,7 @@ import { WhiteboardState, whiteboard } from '../stores/whiteboard';
import { useHistory, useLocation } from 'react-router-dom';
import { resolveMessage, resolvePeerMessage, resolveChannelAttrs, jsonParse } from '../utils/helper';
import GlobalStorage from '../utils/custom-storage';
import {endPoint} from "../services/agora-end-points";
import {endPoint, goHome} from "../services/agora-end-points";
import {Map as immuMap} from "immutable";
export type IRootProvider = {
......@@ -89,7 +89,8 @@ export const RootProvider: React.FC<any> = ({children}) => {
type: 'rtmClient',
message: 'login failure'
});
history.push('/');
// history.push('/');
goHome(history)
return;
}
if (reason === 'REMOTE_LOGIN' || newState === 'ABORTED') {
......@@ -97,15 +98,17 @@ export const RootProvider: React.FC<any> = ({children}) => {
type: 'rtmClient',
message: 'kick'
});
history.push('/');
// history.push('/');
goHome(history)
return;
}
});
rtmClient.on("MessageFromPeer", ({ message: { text }, peerId, props }: { message: { text: string }, peerId: string, props: any }) => {
console.log('MessageFromPeer', text);
const body = resolvePeerMessage(text);
resolveMessage(peerId, body);
body.cmd = +body.cmd
resolveMessage(peerId, body);
roomStore.handlePeerMessage(body.cmd, peerId)
.then(() => {
}).catch(console.warn);
......@@ -116,7 +119,8 @@ export const RootProvider: React.FC<any> = ({children}) => {
type: 'rtmClient',
message: 'teacher close classroom'
});
history.push('/');
// history.push('/');
goHome(history)
return;
}
console.log('[rtm-client] updated origin attributes', JSON.parse(JSON.stringify(attributes)));
......
......@@ -140,8 +140,8 @@ export default function useStream () {
const myAttr = userAttrs.get(me.uid);
console.log(100000, studentsOrder);
console.log(11111111, studentIds.toArray());
// console.log(100000, studentsOrder);
// console.log(11111111, studentIds.toArray());
// studentIds = studentIds.sort(function(a, b){
// if (studentsOrder.indexOf(+a) < 0) {return 0}
// if (studentsOrder.indexOf(+b) < 0) {return 0}
......@@ -222,7 +222,7 @@ export default function useStream () {
if (me.role === 'student' && +me.uid == studentId) {
if (myAttr && roomState.rtc.localStream) {
console.log('use local stream')
// console.log('use local stream')
const _tmpStream = {
...roomState.rtc.localStream,
account: myAttr.account,
......@@ -281,7 +281,7 @@ export default function useStream () {
}
}
})
console.log('studentStreams', studentStreams);
// console.log('studentStreams', studentStreams);
return studentStreams;
}, [
// course,
......@@ -496,6 +496,7 @@ export default function useStream () {
await roomStore.unPublishMeStream();
await roomStore.publishMeStream();
}
}
}
return value;
......
......@@ -101,11 +101,11 @@
background-image: url('./assets/icon-speaker@2x.png');
}
.icon-speaker-on,
.icon-speaker-off
{
width: 37px;
}
//.icon-speaker-on,
//.icon-speaker-off
//{
// width: 37px;
//}
.icon-speaker-on::after {
width: 100%;
......@@ -118,7 +118,7 @@
}
.icon-speaker-off::after {
width: 100%;
width: 24px;
height: 100%;
background-position: center;
background-repeat: no-repeat;
......@@ -916,4 +916,4 @@
height: 14px;
background-repeat: no-repeat;
background-size: cover;
}
\ No newline at end of file
}
......@@ -11,6 +11,17 @@ import { globalStore } from '../../stores/global';
import { platform } from '../../utils/platform';
import AgoraWebClient, { AgoraStreamSpec, SHARE_ID } from '../../utils/agora-rtc-client';
import { AgoraElectronClient } from '../../utils/agora-electron-client';
import {eventBus} from "../../stores/EventBus";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
TextField
} from "@material-ui/core";
import {goHome} from "../../services/agora-end-points";
export const roomTypes = [
{value: 0, text: 'One-on-One', path: 'one-to-one'},
......@@ -18,12 +29,131 @@ export const roomTypes = [
{value: 2, text: 'Large Class', path: 'big-class'},
];
export interface StarDialogProps {
uid: number;
keepMounted?: boolean;
title: string;
open: boolean;
onClose: (uid:number , value: number) => void;
}
const NUMBER = /^[0-9]*/
function StarDialog(props: StarDialogProps) {
let { onClose, title: valueProp, open, uid, ...other } = props;
const [title, setTitle] = React.useState(valueProp);
const [value, setValue] = React.useState<number>(0);
React.useEffect(() => {
if (!open) {
setTitle(valueProp);
}
}, [valueProp, open]);
const handleChange = (evt: any) => {
console.log('dialog handleChange ');
const val = evt.target.value.match(NUMBER)[0];
if (val) {
setValue(+val);
}
};
const handleEntering = () => {
// console.log('dialog handleEntering ');
onClose(uid, value);
};
const handleCancel = () => {
console.log('dialog handleCancel ');
onClose(-1, 0);
};
const handleOk = () => {
// console.log('dialog handleOk ');
onClose(uid, value);
};
return (
<Dialog
disableBackdropClick
disableEscapeKeyDown
maxWidth="xs"
aria-labelledby="confirmation-dialog-title"
open={open}
{...other}
>
<DialogTitle id="confirmation-dialog-title">{title}</DialogTitle>
<DialogContent >
<TextField
autoFocus
margin="dense"
id="starNumber"
label="奖励值"
type="number"
onChange={handleChange}
fullWidth
/>
</DialogContent>
<DialogActions>
<Button autoFocus onClick={handleCancel} color="primary">
取消
</Button>
<Button onClick={handleOk} color="primary">
确认
</Button>
</DialogActions>
</Dialog>
);
}
export function RoomPage({ children }: any) {
const history = useHistory();
const lock = useRef<boolean>(false);
/////////////////////////
const [open, setOpen] = React.useState(false);
const [tid, setTid] = React.useState(0);
const [title, setTitle] = React.useState('');
const dialogLock = useRef<boolean>(false);
const handleDialogClose = (uid:number, val:number) => {
setOpen(false);
dialogLock.current = false;
if (uid < 0 || val <= 0) {
return;
}
console.log('handleDialogClose', uid, val);
roomStore.addStarToUser(uid, val);
};
const eventNames = eventBus.eventNames();
if (!eventNames.includes('showAddStartDialog')) {
console.log(3333333);
eventBus.on('showAddStartDialog', (data) => {
if (dialogLock.current) {
return
}
dialogLock.current = true;
let titleTxt = '全部学生'
if (data.uid) {
const stu = roomStore.state.users.get(data.uid);
titleTxt = `学生:${stu?.account}`
}
setTid(+data.uid);
setTitle(titleTxt);
console.log('addStar', data);
setTimeout(()=>setOpen(true))
})
}
///////////////////////////////////
useEffect(() => {
......@@ -33,7 +163,8 @@ export function RoomPage({ children }: any) {
const roomName = roomStore.state.course.roomName;
if (!rid || !me.uid) {
history.push('/');
// history.push('/');
goHome(history)
}
const uid = me.uid;
......@@ -65,7 +196,8 @@ export function RoomPage({ children }: any) {
type: 'rtmClient',
message: 'login failure'
});
history.push('/');
// history.push('/');
goHome(history)
console.warn(err)
}).finally(() => {
globalStore.stopLoading();
......@@ -76,7 +208,8 @@ export function RoomPage({ children }: any) {
type: 'rtmClient',
message: 'login failure'
});
history.push('/');
// history.push('/');
goHome(history)
console.warn(err)
})
.finally(() => {
......@@ -288,7 +421,8 @@ export function RoomPage({ children }: any) {
type: 'rtmClient',
message: err.message
});
history.push('/');
// history.push('/');
goHome(history)
}
}
......@@ -310,7 +444,7 @@ export function RoomPage({ children }: any) {
]);
useEffect(() => {
// debugger
if (!roomState.me.uid || !roomState.course.rid) return;
if (classroom) {
if (platform === 'web') {
......@@ -421,7 +555,7 @@ export function RoomPage({ children }: any) {
})
rtc.current = true;
// debugger
// WARN: IF YOU ENABLED APP CERTIFICATE, PLEASE SIGN YOUR TOKEN IN YOUR SERVER SIDE AND OBTAIN IT FROM YOUR OWN TRUSTED SERVER API
console.info(1.1, 'rtc join')
// if (roomState.me.role == 'teacher' || roomState.studentsOrder.includes(+roomState.me.uid)) {
......@@ -558,6 +692,7 @@ export function RoomPage({ children }: any) {
return (
<div className={`classroom ${roomType.path}`}>
<StarDialog title={title} uid={tid} open={open} onClose={handleDialogClose}></StarDialog>
<NativeSharedWindow />
<Nav />
{children}
......
......@@ -13,7 +13,7 @@ import { roomStore } from '../stores/room';
// import { genUid } from '../utils/helper';
// import MD5 from 'js-md5';
import { globalStore } from '../stores/global';
import { endPoint } from '../services/agora-end-points';
import {endPoint, goLogin} from '../services/agora-end-points';
import Select from "@material-ui/core/Select";
import MenuItem from "@material-ui/core/MenuItem";
import InputLabel from "@material-ui/core/InputLabel";
......@@ -117,7 +117,7 @@ function HomePage() {
}
const doCheckWithUser = () => {
endPoint.login({username: session.yourName, password: session.yourPass, classid: session.classId}).then((userInfo: any) => {
endPoint.login({username: session.yourName, password: session.yourPass, classid: session.classId}, isDebug).then((userInfo: any) => {
loginLive(userInfo);
}).catch((err: any) => {
globalStore.showToast({
......@@ -177,11 +177,16 @@ function HomePage() {
const location = useLocation();
// console.log(1111111111111, location );
const params = new URLSearchParams(location.search);
let token = params.get('token');
let token:any = params.get('token');
let isDebug = params.get('debug') && params.get('debug') == '1' ? true : false;
let hasLogin = params.get('login') && params.get('login') == '1' ? true : false;
// console.log('params', token)
// debugger
let isLocal = params.get('isLocal') && params.get('isLocal') == '1' ? true : false;
console.log('token', token)
console.log('isDebug', isDebug)
console.log('hasLogin', hasLogin)
console.log('isLocal', isLocal)
if (token) {
endPoint.setUserToken(token);
const tokenParts = token.split('.')
token = tokenParts[1];
token = token.replace(/[\+]/g, '-');
......@@ -193,6 +198,7 @@ function HomePage() {
token = `${token}${Array.from(ea).fill('=').join('')}`
}
let userInfo = Base64.decode(token);
userInfo = JSON.parse(userInfo)
console.log(userInfo)
......@@ -206,6 +212,10 @@ function HomePage() {
// // data.password: session.yourPass
// };
doCheckWithToken(userInfo);
} else {
if (!hasLogin && !isDebug) {
goLogin()
}
}
const handleSubmit = () => {
if (!session.yourName) {
......@@ -373,7 +383,20 @@ function HomePage() {
requiredText={required.yourName}
/>
</FormControl>
<FormControl className={style.formControl}>
{isDebug
?<FormControl className={style.formControl}>
<FormInput Label={"频道"} value={session.classId} onChange={
(val: string) => {
setSessionInfo({
...session,
classId: val
});
}}
requiredText="请输入频道"
/>
</FormControl>
:<FormControl className={style.formControl}>
<InputLabel>请选择班级</InputLabel>
<Select
......@@ -385,8 +408,8 @@ function HomePage() {
<em>请正确输入账号</em>
</MenuItem>
:
classes.map((item: any, key: number) =>
<MenuItem key={key} value={item.id}>{item.name}</MenuItem>)
classes.map((item: any, key: number) =>
<MenuItem key={key} value={item.id}>{item.name}</MenuItem>)
}
{/*<MenuItem value={10}>Ten</MenuItem>
......@@ -394,7 +417,9 @@ function HomePage() {
<MenuItem value={30}>Thirty</MenuItem>*/}
</Select>
</FormControl>
</FormControl>}
<FormControl className={style.formControl}>
<FormInput Label={"密码"} type="password" value={session.yourPass} onChange={
(val: string) => {
......
......@@ -42,7 +42,15 @@ export interface RoomParams {
enableAudio: number
linkUsers: number[]
}
export function goHome(history: any){
window.location.href = 'http://iteachabc.com'
}
export function goLogin(){
window.location.href = 'http://iteachabc.com/manage/login'
}
export function getApiServerHost(online = false) {
// return 'http://127.0.0.1:1339'
let host = `https://ac.iplayabc.com`;
if (window.location.host.includes('s-live.')) {
host = 'https://staging-ac.ireadabc.com';
......@@ -73,7 +81,9 @@ export class EndPoint {
roomId: string = '';
userToken: string = '';
recordId: string = '';
setUserToken(token: string) {
this.userToken = token
}
async sts () {
let response = await AgoraFetch(`https://omt.iplayabc.com/api/oss/live/static`, {
method: 'GET',
......@@ -97,12 +107,12 @@ export class EndPoint {
}
return [];
}
async login(data: any) {
if (window.location.origin.includes('://127.0.0.1')
|| window.location.origin.includes('://localhost')) {
async login(data: any, local=false) {
if (local) {
return {
id: `${data.username}`,
class_id: "test_03__123",
class_id: `${data.classid}`,
classRole: (`${data.username}`==="1" || `${data.username}`==="11")?"tea":"",
roomType: 1,
nick_name: `${data.username}`,
......@@ -144,7 +154,7 @@ export class EndPoint {
this.userToken = roomStore.state.cwLink;
}
console.log('getCourseUrl', this.userToken)
const host = getApiServerHost();
const host = getApiServerHost(true);
return `${host}/airclass_ol?token=${this.userToken}`;
}
......
import EventEmitter from "events";
export const eventBus = new EventEmitter();
This diff is collapsed.
......@@ -46,7 +46,7 @@ const clientEvents: 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 ENABLE_LOG = process.env.REACT_APP_AGORA_LOG as string === "true";
export const SHARE_ID = 9999999999999;
export const SHARE_ID = 65535;
const BindEventMap: any = {};
class AgoraRTCClient {
......@@ -232,7 +232,7 @@ class AgoraRTCClient {
this._localStream.init(async () => {
this.streamID = data.streamID;
// debugger
/*
if (roomStore.state.me.role == 'teacher') {
const result = await this._localStream.setBeautyEffectOptions(true, {
......
......@@ -37,9 +37,10 @@ export type SessionProps = {
room: string,
token: string
}
let _channelAttrCallCounterTimer: any = null;
let _channelAttrCallCounter = 0;
export default class AgoraRTMClient {
private _bus: EventEmitter;
public _currentChannel: any;
public _currentChannelName: string | any;
......@@ -50,6 +51,7 @@ export default class AgoraRTMClient {
private _joined: boolean = false;
constructor () {
this._bus = new EventEmitter();
this._channels = {};
this._currentChannel = null;
......@@ -58,6 +60,17 @@ export default class AgoraRTMClient {
this._client = AgoraRTM.createInstance(APP_ID, { enableLogUpload: false, logFilter });
}
async addOrUpdateChannelAttributes(data: any, enableNotificationToChannelMembers = true): Promise<string> {
if (!_channelAttrCallCounterTimer) {
_channelAttrCallCounterTimer = setTimeout(()=>{
console.log('current 10s call', _channelAttrCallCounter);
_channelAttrCallCounter = 0;
clearTimeout(_channelAttrCallCounterTimer)
_channelAttrCallCounterTimer = null;
}, 10 * 1000 );
}
_channelAttrCallCounter++;
const channelAttributes: {[key: string]: string} = {};
for (const k of Object.keys(data)) {
channelAttributes[k] = typeof(data[k]) != 'string' ? JSON.stringify(data[k]) : data[k];
......
......@@ -266,6 +266,15 @@ export function resolveChannelAttrs(json: object) {
}
delete (json as any).studentsOrder;
// let userStars: any = {};
// if ((json as any).userStars && (json as any).userStars.value) {
// userStars = JSON.parse((json as any).userStars.value) || [];
// Object.keys(userStars).forEach(k => {
// userStars[k] = +userStars[k];
// })
// }
// delete (json as any).userStars;
const teacherJson = jsonParse(_.get(json, 'teacher.value'));
const room: any = {
......@@ -343,7 +352,8 @@ export function resolveChannelAttrs(json: object) {
shared_uid: student.shared_uid,
whiteboard_uid: student.whiteboard_uid,
grant_board: +student.grant_board,
last_stage_ts: +student.last_stage_ts
last_stage_ts: +student.last_stage_ts,
stars: +student.stars
});
}
// console.log('resolveChannelAttrs 3', accounts);
......@@ -354,7 +364,8 @@ export function resolveChannelAttrs(json: object) {
students: students,
accounts,
room,
studentsOrder
studentsOrder,
// userStars
};
}
......
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