Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
live
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liujiaxin
live
Commits
3a2d2dba
Commit
3a2d2dba
authored
Feb 11, 2020
by
liujiaxin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加iframe和白板切换
parent
4e8f74c3
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
376 additions
and
235 deletions
+376
-235
courseware-frame.tsx
src/components/courseware-frame.tsx
+1
-2
mediaboard.tsx
src/components/mediaboard.tsx
+15
-15
member-holder.tsx
src/components/member-holder.tsx
+1
-1
roomboard.tsx
src/components/roomboard.tsx
+4
-4
student-list.scss
src/components/student-list.scss
+6
-5
student-list.tsx
src/components/student-list.tsx
+3
-3
tools-switcher-controller.tsx
src/components/tools-switcher-controller.tsx
+54
-0
video-stage-list.tsx
src/components/video-stage-list.tsx
+3
-3
control.tsx
src/components/whiteboard/control.tsx
+12
-12
use-streams.ts
src/hooks/use-streams.ts
+39
-73
index.tsx
src/pages/classroom/index.tsx
+15
-9
small-class.tsx
src/pages/classroom/small-class.tsx
+9
-10
room.ts
src/stores/room.ts
+169
-27
agora-rtc-client.ts
src/utils/agora-rtc-client.ts
+10
-10
agora-rtm-client.ts
src/utils/agora-rtm-client.ts
+18
-7
helper.ts
src/utils/helper.ts
+17
-54
No files found.
src/components/courseware-frame.tsx
View file @
3a2d2dba
...
@@ -25,7 +25,7 @@ const useStyles = makeStyles({
...
@@ -25,7 +25,7 @@ const useStyles = makeStyles({
flex
:
1
flex
:
1
},
},
style4
:
{
style4
:
{
height
:
3
0
,
height
:
3
6
,
width
:
100
,
width
:
100
,
flex
:
0
flex
:
0
},
},
...
@@ -39,7 +39,6 @@ const CourseWareFrame: React.FC = () => {
...
@@ -39,7 +39,6 @@ const CourseWareFrame: React.FC = () => {
const
ref
=
useRef
<
any
>
(
''
);
const
ref
=
useRef
<
any
>
(
''
);
const
[
src
,
setSrc
]
=
useState
(
''
)
const
[
src
,
setSrc
]
=
useState
(
''
)
const
changSrc
=
(
evt
:
any
)
=>
{
const
changSrc
=
(
evt
:
any
)
=>
{
debugger
setSrc
(
ref
.
current
.
value
);
setSrc
(
ref
.
current
.
value
);
}
}
...
...
src/components/mediaboard.tsx
View file @
3a2d2dba
...
@@ -23,6 +23,7 @@ import AgoraWebClient, { SHARE_ID } from '../utils/agora-rtc-client';
...
@@ -23,6 +23,7 @@ import AgoraWebClient, { SHARE_ID } 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
);
...
@@ -46,13 +47,13 @@ const MediaBoard: React.FC<MediaBoardProps> = ({
...
@@ -46,13 +47,13 @@ const MediaBoard: React.FC<MediaBoardProps> = ({
const
roomState
=
useRoomState
();
const
roomState
=
useRoomState
();
const
whiteboardState
=
useWhiteboardState
();
const
whiteboardState
=
useWhiteboardState
();
const
role
=
roomState
.
me
.
role
;
const
role
=
roomState
.
me
.
role
;
const
room
=
whiteboardState
.
room
;
const
room
=
whiteboardState
.
room
;
const
me
=
roomState
.
me
;
const
me
=
roomState
.
me
;
const
course
=
roomState
.
course
;
const
course
=
roomState
.
course
;
const
rtmState
=
roomState
.
rtm
;
const
rtmState
=
roomState
.
rtm
;
const
ref
=
useRef
<
any
>
(
false
);
const
ref
=
useRef
<
any
>
(
false
);
const
[
pageTool
,
setPageTool
]
=
useState
<
string
>
(
''
);
const
[
pageTool
,
setPageTool
]
=
useState
<
string
>
(
''
);
...
@@ -184,7 +185,7 @@ const MediaBoard: React.FC<MediaBoardProps> = ({
...
@@ -184,7 +185,7 @@ const MediaBoard: React.FC<MediaBoardProps> = ({
return
+
roomStore
.
state
.
me
.
uid
===
+
roomStore
.
state
.
course
.
linkId
;
return
+
roomStore
.
state
.
me
.
uid
===
+
roomStore
.
state
.
course
.
linkId
;
},
[
roomStore
.
state
.
me
.
uid
,
},
[
roomStore
.
state
.
me
.
uid
,
roomStore
.
state
.
course
.
linkId
]);
roomStore
.
state
.
course
.
linkId
]);
const
location
=
useLocation
();
const
location
=
useLocation
();
const
current
=
useMemo
(()
=>
{
const
current
=
useMemo
(()
=>
{
...
@@ -309,7 +310,7 @@ const items = [
...
@@ -309,7 +310,7 @@ const items = [
},
[
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
'
:
''
);
const
[
selector
,
updateSelector
]
=
useState
<
string
>
(
''
);
const
[
selector
,
updateSelector
]
=
useState
<
string
>
(
''
);
const
handleToolClick
=
(
evt
:
any
,
name
:
string
)
=>
{
const
handleToolClick
=
(
evt
:
any
,
name
:
string
)
=>
{
...
@@ -417,7 +418,7 @@ const items = [
...
@@ -417,7 +418,7 @@ const items = [
const
UploadPanel
=
useCallback
(()
=>
{
const
UploadPanel
=
useCallback
(()
=>
{
if
(
tool
!==
'
upload
'
||
!
room
)
return
null
;
if
(
tool
!==
'
upload
'
||
!
room
)
return
null
;
return
(<
UploadBtn
return
(<
UploadBtn
room=
{
room
}
room=
{
room
}
uuid=
{
room
.
uuid
}
uuid=
{
room
.
uuid
}
roomToken=
{
room
.
roomToken
}
roomToken=
{
room
.
roomToken
}
...
@@ -505,7 +506,7 @@ const items = [
...
@@ -505,7 +506,7 @@ const items = [
return
(
return
(
<
Progress
title=
{
"
uploading...
"
}
/>
<
Progress
title=
{
"
uploading...
"
}
/>
)
)
}
else
}
else
if
(
convertPhase
===
'
converting
'
)
{
if
(
convertPhase
===
'
converting
'
)
{
return
(
return
(
<
Progress
title=
{
"
converting...
"
}
/>
<
Progress
title=
{
"
converting...
"
}
/>
...
@@ -524,10 +525,10 @@ const items = [
...
@@ -524,10 +525,10 @@ const items = [
b
:
color
[
2
],
b
:
color
[
2
],
}
}
}
}
return
(
return
(
<
div
className=
{
`media-board ${drawable}`
}
>
<
div
className=
{
`media-board ${drawable}`
}
>
{
sharedStream
?
{
sharedStream
?
<
VideoPlayer
<
VideoPlayer
id=
{
`${sharedStream.streamID}`
}
id=
{
`${sharedStream.streamID}`
}
domId=
{
`shared-${sharedStream.streamID}`
}
domId=
{
`shared-${sharedStream.streamID}`
}
...
@@ -545,7 +546,7 @@ const items = [
...
@@ -545,7 +546,7 @@ const items = [
/>
/>
}
}
<
div
className=
"layer"
>
<
div
className=
"layer"
>
{
!
sharedStream
?
{
!
sharedStream
?
<>
<>
<
Tools
<
Tools
items=
{
toolItems
}
items=
{
toolItems
}
...
@@ -560,7 +561,7 @@ const items = [
...
@@ -560,7 +561,7 @@ const items = [
<
UploadPanel
/>
<
UploadPanel
/>
{
children
?
children
:
null
}
{
children
?
children
:
null
}
</
div
>
</
div
>
{
me
.
role
===
'
teacher
'
&&
room
?
{
/*
me.role === 'teacher' && room ?
<ScaleController
<ScaleController
zoomScale={scale}
zoomScale={scale}
onClick={() => {
onClick={() => {
...
@@ -577,8 +578,7 @@ const items = [
...
@@ -577,8 +578,7 @@ const items = [
}}
}}
/>
/>
:
:
null
null*/
}
}
{
showControl
?
{
showControl
?
<
Control
<
Control
notice=
{
globalState
.
notice
}
notice=
{
globalState
.
notice
}
...
@@ -589,7 +589,7 @@ const items = [
...
@@ -589,7 +589,7 @@ const items = [
totalPage=
{
totalPage
}
totalPage=
{
totalPage
}
isHost=
{
isHost
}
isHost=
{
isHost
}
onClick=
{
handlePageTool
}
/>
:
null
}
onClick=
{
handlePageTool
}
/>
:
null
}
{
tool
===
'
folder
'
&&
whiteboardState
.
room
?
{
tool
===
'
folder
'
&&
whiteboardState
.
room
?
<
ResourcesMenu
<
ResourcesMenu
active=
{
whiteboardState
.
activeDir
}
active=
{
whiteboardState
.
activeDir
}
items=
{
whiteboardState
.
dirs
}
items=
{
whiteboardState
.
dirs
}
...
@@ -609,6 +609,6 @@ const items = [
...
@@ -609,6 +609,6 @@ const items = [
<
UploadProgressView
/>
<
UploadProgressView
/>
</
div
>
</
div
>
)
)
}
}
export
default
React
.
memo
(
MediaBoard
);
export
default
React
.
memo
(
MediaBoard
);
\ No newline at end of file
src/components/member-holder.tsx
View file @
3a2d2dba
...
@@ -234,7 +234,7 @@ const MemberHolder: React.FC<MemberHolderProps> = ({
...
@@ -234,7 +234,7 @@ const MemberHolder: React.FC<MemberHolderProps> = ({
{
me
.
uid
===
id
||
me
.
role
===
'
teacher
'
?
{
me
.
uid
===
id
||
me
.
role
===
'
teacher
'
?
<
span
className=
"media-btn"
>
<
span
className=
"media-btn"
>
<
Link
component=
"button"
onClick=
{
onAudioClick
}
>
{
audio
?
"
静音
"
:
"
开麦
"
}
</
Link
>
<
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={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"} />*/
}
{
/*<Icon onClick={onVideoClick} className={video ? "icons-camera-unmute-s" : "icons-camera-mute-s"} data={"video"} />*/
}
</
span
>
:
null
}
</
span
>
:
null
}
...
...
src/components/roomboard.tsx
View file @
3a2d2dba
...
@@ -9,7 +9,7 @@ export default function Roomboard (props: any) {
...
@@ -9,7 +9,7 @@ export default function Roomboard (props: any) {
messages
,
sendMessage
,
handleChange
messages
,
sendMessage
,
handleChange
}
=
useChatText
();
}
=
useChatText
();
const
[
active
,
setActive
]
=
useState
(
'
chatroom
'
);
const
[
active
,
setActive
]
=
useState
(
'
studentList
'
);
const
[
visible
,
setVisible
]
=
useState
(
true
);
const
[
visible
,
setVisible
]
=
useState
(
true
);
const
toggleCollapse
=
(
evt
:
any
)
=>
{
const
toggleCollapse
=
(
evt
:
any
)
=>
{
...
@@ -19,10 +19,10 @@ export default function Roomboard (props: any) {
...
@@ -19,10 +19,10 @@ export default function Roomboard (props: any) {
return
(
return
(
<>
<>
<
div
className=
{
`${visible ? "icon-collapse-off" : "icon-collapse-on" } fixed`
}
onClick=
{
toggleCollapse
}
></
div
>
<
div
className=
{
`${visible ? "icon-collapse-off" : "icon-collapse-on" } fixed`
}
onClick=
{
toggleCollapse
}
></
div
>
{
visible
?
{
visible
?
<
div
className=
{
`small-class chat-board`
}
>
<
div
className=
{
`small-class chat-board`
}
>
<
div
className=
"menu"
>
<
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
onClick=
{
()
=>
{
setActive
(
'
studentList
'
)
}
}
className=
{
`item ${active === 'studentList' ? 'active' : ''}`
}
>
Student List
</
div
>
</
div
>
</
div
>
{
{
...
@@ -42,4 +42,4 @@ export default function Roomboard (props: any) {
...
@@ -42,4 +42,4 @@ export default function Roomboard (props: any) {
:
null
}
:
null
}
</>
</>
)
)
}
}
\ No newline at end of file
src/components/student-list.scss
View file @
3a2d2dba
...
@@ -22,13 +22,14 @@
...
@@ -22,13 +22,14 @@
font-weight
:
400
;
font-weight
:
400
;
color
:rgba
(
3
,
3
,
3
,
1
)
;
color
:rgba
(
3
,
3
,
3
,
1
)
;
line-height
:
17px
;
line-height
:
17px
;
max-width
:
113px
;
//max-width: 113px;
min-width
:
113px
;
//min-width: 113px;
flex
:
1
;
}
}
.attrs-group
{
.attrs-group
{
display
:
flex
;
display
:
flex
;
min-width
:
148px
;
//
min-width: 148px;
max-width
:
148px
;
//
max-width: 148px;
justify-content
:
space-evenly
;
justify-content
:
space-evenly
;
.items
{
.items
{
margin
:
4px
;
margin
:
4px
;
...
@@ -43,4 +44,4 @@
...
@@ -43,4 +44,4 @@
}
}
}
}
}
}
}
}
\ No newline at end of file
src/components/student-list.tsx
View file @
3a2d2dba
...
@@ -89,8 +89,8 @@ export default function StudentList ({
...
@@ -89,8 +89,8 @@ export default function StudentList ({
<
div
key=
{
key
}
className=
"item"
>
<
div
key=
{
key
}
className=
"item"
>
<
div
className=
"nickname"
>
{
item
.
account
}
</
div
>
<
div
className=
"nickname"
>
{
item
.
account
}
</
div
>
<
div
className=
"attrs-group"
>
<
div
className=
"attrs-group"
>
<
CustomIcon
type=
"grantBoard"
id=
{
item
.
uid
}
value=
{
Boolean
(
item
.
grantBoard
)
}
icon=
"connect"
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="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=
"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
}
/>
<
CustomIcon
type=
"video"
id=
{
item
.
uid
}
value=
{
Boolean
(
item
.
video
)
}
icon=
"video"
onClick=
{
handleClick
}
/>
</
div
>
</
div
>
...
@@ -98,4 +98,4 @@ export default function StudentList ({
...
@@ -98,4 +98,4 @@ export default function StudentList ({
))
}
))
}
</
div
>
</
div
>
)
)
}
}
\ No newline at end of file
src/components/tools-switcher-controller.tsx
0 → 100644
View file @
3a2d2dba
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
>
);
}
src/components/video-stage-list.tsx
View file @
3a2d2dba
...
@@ -11,8 +11,8 @@ import MemberHolder from "./member-holder";
...
@@ -11,8 +11,8 @@ import MemberHolder from "./member-holder";
function
VideoShowList
()
{
function
VideoShowList
()
{
const
{
teacher
,
stageStudents
,
onPlayerClick
}
=
useStream
();
const
{
teacher
,
students
,
onPlayerClick
}
=
useStream
();
...
@@ -65,7 +65,7 @@ function VideoShowList() {
...
@@ -65,7 +65,7 @@ function VideoShowList() {
// return <div className="camera">
// return <div className="camera">
// <div key=
{
`stage${i}`
}
className
=
"
agora-video-view camera-holder
"
>
{
i
}<
/
div
>
// <div key=
{
`stage${i}`
}
className
=
"
agora-video-view camera-holder
"
>
{
i
}<
/
div
>
//
</
div
>
;
//
</
div
>
;
const
student
=
st
ageStudents
.
stage
&&
stageStudents
.
stage
[
i
];
const
student
=
st
udents
&&
students
.
slice
(
0
,
STAGE_NUM
)
[
i
];
return
<
div
className=
"camera"
key=
{
`stage_video${i}`
}
>
return
<
div
className=
"camera"
key=
{
`stage_video${i}`
}
>
{
student
?
<
VideoPlayer
{
student
?
<
VideoPlayer
...
@@ -122,7 +122,7 @@ function VideoShowList() {
...
@@ -122,7 +122,7 @@ function VideoShowList() {
)*/
}
)*/
}
{
st
ageStudents
.
wait
?
stageStudents
.
wait
.
map
((
student
:
AgoraMediaStream
,
key
:
number
)
=>
(
{
st
udents
?
students
.
slice
(
STAGE_NUM
)
.
map
((
student
:
AgoraMediaStream
,
key
:
number
)
=>
(
// <VideoPlayer
// <VideoPlayer
// role="student"
// role="student"
// domId=
{
`dom-${student.streamID}`
}
// domId=
{
`dom-${student.streamID}`
}
...
...
src/components/whiteboard/control.tsx
View file @
3a2d2dba
...
@@ -76,13 +76,13 @@ export default function Control({
...
@@ -76,13 +76,13 @@ export default function Control({
handleRecording
(
evt
,
type
)
handleRecording
(
evt
,
type
)
.
then
(()
=>
{}).
catch
(
console
.
warn
);
.
then
(()
=>
{}).
catch
(
console
.
warn
);
}
}
const
handleRecording
=
async
(
evt
:
any
,
type
:
string
)
=>
{
const
handleRecording
=
async
(
evt
:
any
,
type
:
string
)
=>
{
try
{
try
{
const
roomState
=
roomStore
.
state
;
const
roomState
=
roomStore
.
state
;
const
me
=
roomState
.
me
;
const
me
=
roomState
.
me
;
if
(
lock
.
current
||
!
me
.
uid
)
return
;
if
(
lock
.
current
||
!
me
.
uid
)
return
;
if
(
whiteboard
.
state
.
recording
)
{
if
(
whiteboard
.
state
.
recording
)
{
if
(
!
canStop
())
return
;
if
(
!
canStop
())
return
;
let
mediaUrl
=
await
whiteboard
.
stopRecording
();
let
mediaUrl
=
await
whiteboard
.
stopRecording
();
...
@@ -90,7 +90,7 @@ export default function Control({
...
@@ -90,7 +90,7 @@ export default function Control({
type
:
'
recording
'
,
type
:
'
recording
'
,
message
:
'
stop recording success
'
,
message
:
'
stop recording success
'
,
});
});
if
(
whiteboard
.
state
.
endTime
if
(
whiteboard
.
state
.
endTime
&&
whiteboard
.
state
.
startTime
)
{
&&
whiteboard
.
state
.
startTime
)
{
const
{
endTime
,
startTime
,
roomUUID
}
=
whiteboard
.
clearRecording
();
const
{
endTime
,
startTime
,
roomUUID
}
=
whiteboard
.
clearRecording
();
await
roomStore
.
rtmClient
.
sendChannelMessage
(
JSON
.
stringify
({
await
roomStore
.
rtmClient
.
sendChannelMessage
(
JSON
.
stringify
({
...
@@ -128,14 +128,14 @@ export default function Control({
...
@@ -128,14 +128,14 @@ export default function Control({
return
(
return
(
<
div
className=
"controls-container"
>
<
div
className=
"controls-container"
>
<
div
className=
"interactive"
>
<
div
className=
"interactive"
>
{
notice
?
{
notice
?
<
ControlItem
name=
{
notice
.
reason
}
<
ControlItem
name=
{
notice
.
reason
}
onClick=
{
onClick
}
onClick=
{
onClick
}
active=
{
notice
.
reason
===
current
}
/>
active=
{
notice
.
reason
===
current
}
/>
:
null
}
:
null
}
</
div
>
</
div
>
<
div
className=
"controls"
>
<
div
className=
"controls"
>
{
!
sharing
&&
role
===
'
teacher
'
?
{
/*
!sharing && role === 'teacher' ?
<>
<>
<ControlItem name={`first_page`}
<ControlItem name={`first_page`}
active={'first_page' === current}
active={'first_page' === current}
...
@@ -154,14 +154,14 @@ export default function Control({
...
@@ -154,14 +154,14 @@ export default function Control({
onClick={onClick} />
onClick={onClick} />
<div className="menu-split" style={{ marginLeft: '7px', marginRight: '7px' }}></div>
<div className="menu-split" style={{ marginLeft: '7px', marginRight: '7px' }}></div>
</> : null
</> : null
}
*/
}
{
role
===
'
teacher
'
?
{
role
===
'
teacher
'
?
<>
<>
<
ControlItem
{
/*<ControlItem*/
}
name=
{
whiteboard
.
state
.
recording
?
'
stop_recording
'
:
'
recording
'
}
{
/*name={whiteboard.state.recording ? 'stop_recording' : 'recording'}*/
}
onClick=
{
onRecordButtonClick
}
{
/*onClick={onRecordButtonClick}*/
}
active=
{
false
}
{
/*active={false}*/
}
/>
{
/*/>*/
}
<
ControlItem
<
ControlItem
name=
{
sharing
?
'
quit_screen_sharing
'
:
'
screen_sharing
'
}
name=
{
sharing
?
'
quit_screen_sharing
'
:
'
screen_sharing
'
}
onClick=
{
onClick
}
onClick=
{
onClick
}
...
@@ -183,4 +183,4 @@ export default function Control({
...
@@ -183,4 +183,4 @@ export default function Control({
</
div
>
</
div
>
)
)
}
}
\ No newline at end of file
src/hooks/use-streams.ts
View file @
3a2d2dba
...
@@ -7,8 +7,7 @@ import {STAGE_NUM} from "../utils/consts";
...
@@ -7,8 +7,7 @@ import {STAGE_NUM} from "../utils/consts";
type
StreamValue
=
{
type
StreamValue
=
{
teacher
:
any
teacher
:
any
students
?:
any
[]
students
:
any
[]
stageStudents
:
{
stage
:
any
[],
wait
:
any
[]}
sharedStream
:
any
sharedStream
:
any
currentHost
:
any
currentHost
:
any
onPlayerClick
:
(
type
:
string
,
streamID
:
number
,
uid
:
string
)
=>
Promise
<
any
>
onPlayerClick
:
(
type
:
string
,
streamID
:
number
,
uid
:
string
)
=>
Promise
<
any
>
...
@@ -61,7 +60,7 @@ export default function useStream () {
...
@@ -61,7 +60,7 @@ export default function useStream () {
roomState
.
rtc
.
remoteStreams
,
roomState
.
rtc
.
remoteStreams
,
roomState
.
rtc
.
localStream
roomState
.
rtc
.
localStream
]);
]);
/*
const students__ = useMemo(() => {
const students__ = useMemo(() => {
const userAttrs = roomStore.state.users;
const userAttrs = roomStore.state.users;
if (!me.uid || userAttrs.count() === 0) return [];
if (!me.uid || userAttrs.count() === 0) return [];
...
@@ -125,33 +124,44 @@ export default function useStream () {
...
@@ -125,33 +124,44 @@ export default function useStream () {
roomState.rtc.remoteStreams,
roomState.rtc.remoteStreams,
roomState.rtc.localStream
roomState.rtc.localStream
]);
]);
const
students_old
=
useMemo
(()
=>
{
*/
const
students
=
useMemo
(()
=>
{
const
userAttrs
=
roomStore
.
state
.
users
;
const
userAttrs
=
roomStore
.
state
.
users
;
if
(
!
me
.
uid
||
userAttrs
.
count
()
===
0
)
return
[];
if
(
!
me
.
uid
||
userAttrs
.
count
()
===
0
)
return
[];
const
teacherUid
=
course
.
teacherId
;
const
teacherUid
=
course
.
teacherId
;
const
peerUsers
=
roomState
.
rtc
.
users
;
const
peerUsers
=
roomState
.
rtc
.
users
;
// exclude teacher and me
// exclude teacher and me
let
studentIds
=
peerUsers
.
filter
((
it
:
number
)
=>
it
!==
+
teacherUid
&&
it
!==
+
me
.
uid
&&
it
!==
SHARE_ID
);
let
studentIds
=
peerUsers
.
filter
((
it
:
number
)
=>
it
!==
+
teacherUid
&&
it
!==
+
me
.
uid
&&
it
!==
SHARE_ID
);
studentIds
=
studentIds
.
add
(
+
me
.
uid
);
const
studentStreams
:
any
[]
=
[];
const
studentStreams
:
any
[]
=
[];
const
myAttr
=
userAttrs
.
get
(
me
.
uid
);
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
// 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
);
}
}
// capture all remote streams
// capture all remote streams
for
(
let
studentId
of
studentIds
)
{
for
(
let
studentId
of
studentIds
)
{
if
(
me
.
role
===
'
student
'
&&
+
me
.
uid
==
studentId
)
{
if
(
myAttr
&&
roomState
.
rtc
.
localStream
)
{
const
_tmpStream
=
{
...
roomState
.
rtc
.
localStream
,
account
:
myAttr
.
account
,
video
:
myAttr
.
video
,
audio
:
myAttr
.
audio
,
local
:
true
,
}
studentStreams
.
push
(
_tmpStream
);
continue
}
}
const
studentAttr
=
userAttrs
.
get
(
''
+
studentId
);
const
studentAttr
=
userAttrs
.
get
(
''
+
studentId
);
const
stream
=
roomState
.
rtc
.
remoteStreams
.
get
(
+
studentId
);
const
stream
=
roomState
.
rtc
.
remoteStreams
.
get
(
+
studentId
);
if
(
studentAttr
)
{
if
(
studentAttr
)
{
...
@@ -173,6 +183,7 @@ export default function useStream () {
...
@@ -173,6 +183,7 @@ export default function useStream () {
studentStreams
.
push
(
_tmpStream
);
studentStreams
.
push
(
_tmpStream
);
}
}
}
}
console
.
log
(
'
studentStreams
'
,
studentStreams
);
return
studentStreams
;
return
studentStreams
;
},
[
},
[
course
,
course
,
...
@@ -182,6 +193,7 @@ export default function useStream () {
...
@@ -182,6 +193,7 @@ export default function useStream () {
roomState
.
rtc
.
localStream
roomState
.
rtc
.
localStream
]);
]);
/*
const stageStudents: { wait: any[]; stage: any[] } = useMemo(() => {
const stageStudents: { wait: any[]; stage: any[] } = useMemo(() => {
const userAttrs = roomStore.state.users;
const userAttrs = roomStore.state.users;
if (!me.uid || userAttrs.count() === 0) return { wait: [], stage:[] };
if (!me.uid || userAttrs.count() === 0) return { wait: [], stage:[] };
...
@@ -191,7 +203,8 @@ export default function useStream () {
...
@@ -191,7 +203,8 @@ export default function useStream () {
let studentIds = peerUsers.filter((it: number) => it !== +teacherUid && it !== +me.uid && it !== SHARE_ID);
let studentIds = peerUsers.filter((it: number) => it !== +teacherUid && it !== +me.uid && it !== SHARE_ID);
const studentStreams: any[] = [];
const studentStreams: any[] = [];
userAttrs.forEach(u => {
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) {
if (roomState.rtc.localStream) {
const _tmpStream = {
const _tmpStream = {
...roomState.rtc.localStream,
...roomState.rtc.localStream,
...
@@ -203,11 +216,11 @@ export default function useStream () {
...
@@ -203,11 +216,11 @@ export default function useStream () {
studentStreams.push(_tmpStream);
studentStreams.push(_tmpStream);
}
}
} else {
} else {
const
studentAttr
=
userAttrs
.
get
(
`
${
u
.
u
id
}
`
);
const studentAttr = userAttrs.get(`${uid}`);
const
stream
=
roomState
.
rtc
.
remoteStreams
.
get
(
+
u
.
u
id
);
const stream = roomState.rtc.remoteStreams.get(+uid);
if (studentAttr) {
if (studentAttr) {
let _tmpStream = {
let _tmpStream = {
streamID
:
u
.
u
id
,
streamID: uid,
account: studentAttr.account,
account: studentAttr.account,
video: studentAttr.video,
video: studentAttr.video,
audio: studentAttr.audio,
audio: studentAttr.audio,
...
@@ -215,7 +228,7 @@ export default function useStream () {
...
@@ -215,7 +228,7 @@ export default function useStream () {
if (stream) {
if (stream) {
_tmpStream = {
_tmpStream = {
...stream,
...stream,
streamID
:
u
.
u
id
,
streamID: uid,
account: studentAttr.account,
account: studentAttr.account,
video: studentAttr.video,
video: studentAttr.video,
audio: studentAttr.audio,
audio: studentAttr.audio,
...
@@ -225,55 +238,6 @@ export default function useStream () {
...
@@ -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)
console.log('studentStreams', studentStreams)
return {
return {
stage: [...studentStreams.slice(0,STAGE_NUM)],
stage: [...studentStreams.slice(0,STAGE_NUM)],
...
@@ -286,6 +250,8 @@ export default function useStream () {
...
@@ -286,6 +250,8 @@ export default function useStream () {
roomState.rtc.remoteStreams,
roomState.rtc.remoteStreams,
roomState.rtc.localStream
roomState.rtc.localStream
]);
]);
*/
const
sharedStream
=
useMemo
(()
=>
{
const
sharedStream
=
useMemo
(()
=>
{
const
sharedUid
=
SHARE_ID
;
const
sharedUid
=
SHARE_ID
;
...
@@ -358,8 +324,8 @@ export default function useStream () {
...
@@ -358,8 +324,8 @@ export default function useStream () {
const
value
:
StreamValue
=
{
const
value
:
StreamValue
=
{
teacher
:
teacher
,
teacher
:
teacher
,
//
students: students,
students
:
students
,
stageStudents
,
//
stageStudents,
sharedStream
:
sharedStream
,
sharedStream
:
sharedStream
,
currentHost
:
currentHost
,
currentHost
:
currentHost
,
onPlayerClick
:
async
(
type
:
string
,
streamID
:
number
,
uid
:
string
)
=>
{
onPlayerClick
:
async
(
type
:
string
,
streamID
:
number
,
uid
:
string
)
=>
{
...
...
src/pages/classroom/index.tsx
View file @
3a2d2dba
...
@@ -93,7 +93,7 @@ export function RoomPage({ children }: any) {
...
@@ -93,7 +93,7 @@ export function RoomPage({ children }: any) {
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
(()
=>
{
console
.
log
(
"
[route] prevRoute:
"
,
prevRoute
.
current
);
console
.
log
(
"
[route] prevRoute:
"
,
prevRoute
.
current
);
...
@@ -107,12 +107,12 @@ export function RoomPage({ children }: any) {
...
@@ -107,12 +107,12 @@ export function RoomPage({ children }: any) {
});
});
}
}
},
[
location
]);
},
[
location
]);
const
rtc
=
useRef
<
boolean
>
(
false
);
const
rtc
=
useRef
<
boolean
>
(
false
);
const
canPublish
=
useMemo
(()
=>
{
const
canPublish
=
useMemo
(()
=>
{
return
!
isBigClass
||
return
!
isBigClass
||
(
isBigClass
&&
(
isBigClass
&&
(
me
.
role
===
'
teacher
'
||
(
me
.
role
===
'
teacher
'
||
+
me
.
uid
===
+
course
.
linkId
));
+
me
.
uid
===
+
course
.
linkId
));
},
[
me
.
uid
,
course
.
linkId
,
me
.
role
,
isBigClass
]);
},
[
me
.
uid
,
course
.
linkId
,
me
.
role
,
isBigClass
]);
...
@@ -141,6 +141,7 @@ export function RoomPage({ children }: any) {
...
@@ -141,6 +141,7 @@ export function RoomPage({ children }: any) {
if
(
platform
===
'
web
'
)
{
if
(
platform
===
'
web
'
)
{
const
webClient
=
rtcClient
as
AgoraWebClient
;
const
webClient
=
rtcClient
as
AgoraWebClient
;
if
(
!
webClient
.
published
)
return
;
if
(
!
webClient
.
published
)
return
;
console
.
log
(
'
unpublish
'
,
2
);
webClient
webClient
.
unpublishLocalStream
()
.
unpublishLocalStream
()
.
then
(()
=>
{
.
then
(()
=>
{
...
@@ -181,7 +182,7 @@ export function RoomPage({ children }: any) {
...
@@ -181,7 +182,7 @@ export function RoomPage({ children }: any) {
webClient
webClient
.
publishLocalStream
(
streamSpec
)
.
publishLocalStream
(
streamSpec
)
.
then
(()
=>
{
.
then
(()
=>
{
console
.
log
(
"
[agora-web] publish local stream
"
);
console
.
log
(
"
[agora-web] publish local stream
"
,
roomStore
.
state
.
me
.
uid
);
}).
catch
(
console
.
warn
)
}).
catch
(
console
.
warn
)
.
finally
(()
=>
{
.
finally
(()
=>
{
publishLock
.
current
=
false
;
publishLock
.
current
=
false
;
...
@@ -215,13 +216,13 @@ export function RoomPage({ children }: any) {
...
@@ -215,13 +216,13 @@ export function RoomPage({ children }: any) {
}
}
console
.
log
(
"
[agora-rtc] add event listener
"
);
console
.
log
(
"
[agora-rtc] add event listener
"
);
webClient
.
rtc
.
on
(
'
onTokenPrivilegeWillExpire
'
,
(
evt
:
any
)
=>
{
webClient
.
rtc
.
on
(
'
onTokenPrivilegeWillExpire
'
,
(
evt
:
any
)
=>
{
// you need obtain the `newToken` token from server side
// you need obtain the `newToken` token from server side
const
newToken
=
''
;
const
newToken
=
''
;
webClient
.
rtc
.
renewToken
(
newToken
);
webClient
.
rtc
.
renewToken
(
newToken
);
console
.
log
(
'
[agora-web] onTokenPrivilegeWillExpire
'
,
evt
);
console
.
log
(
'
[agora-web] onTokenPrivilegeWillExpire
'
,
evt
);
});
});
webClient
.
rtc
.
on
(
'
onTokenPrivilegeDidExpire
'
,
(
evt
:
any
)
=>
{
webClient
.
rtc
.
on
(
'
onTokenPrivilegeDidExpire
'
,
(
evt
:
any
)
=>
{
// you need obtain the `newToken` token from server side
// you need obtain the `newToken` token from server side
const
newToken
=
''
;
const
newToken
=
''
;
webClient
.
rtc
.
renewToken
(
newToken
);
webClient
.
rtc
.
renewToken
(
newToken
);
console
.
log
(
'
[agora-web] onTokenPrivilegeDidExpire
'
,
evt
);
console
.
log
(
'
[agora-web] onTokenPrivilegeDidExpire
'
,
evt
);
...
@@ -234,6 +235,7 @@ export function RoomPage({ children }: any) {
...
@@ -234,6 +235,7 @@ export function RoomPage({ children }: any) {
roomStore
.
addLocalStream
(
_stream
);
roomStore
.
addLocalStream
(
_stream
);
});
});
webClient
.
rtc
.
on
(
'
stream-subscribed
'
,
({
stream
}:
any
)
=>
{
webClient
.
rtc
.
on
(
'
stream-subscribed
'
,
({
stream
}:
any
)
=>
{
console
.
log
(
'
stream
'
,
2
,
'
stream-subscribed
'
)
const
streamID
=
stream
.
getId
();
const
streamID
=
stream
.
getId
();
// when streamID is not share_id use switch high or low stream in dual stream mode
// 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
)
{
if
(
location
.
pathname
.
match
(
/small-class/
)
&&
streamID
!==
SHARE_ID
)
{
...
@@ -247,11 +249,13 @@ export function RoomPage({ children }: any) {
...
@@ -247,11 +249,13 @@ export function RoomPage({ children }: any) {
console
.
log
(
"
[agora-web] dual stream set low for student
"
);
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
);
const
_stream
=
new
AgoraStream
(
stream
,
stream
.
getId
(),
false
);
console
.
log
(
"
[agora-web] subscribe remote stream, id:
"
,
stream
.
getId
());
console
.
log
(
"
[agora-web] subscribe remote stream, id:
"
,
stream
.
getId
());
roomStore
.
addRemoteStream
(
_stream
);
roomStore
.
addRemoteStream
(
_stream
);
});
});
webClient
.
rtc
.
on
(
'
stream-added
'
,
({
stream
}:
any
)
=>
{
webClient
.
rtc
.
on
(
'
stream-added
'
,
({
stream
}:
any
)
=>
{
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
);
});
});
...
@@ -291,12 +295,12 @@ export function RoomPage({ children }: any) {
...
@@ -291,12 +295,12 @@ export function RoomPage({ children }: any) {
// WARN: IF YOU ENABLED APP CERTIFICATE, PLEASE SIGN YOUR TOKEN IN YOUR SERVER SIDE AND OBTAIN IT FROM YOUR OWN TRUSTED SERVER API
// WARN: IF YOU ENABLED APP CERTIFICATE, PLEASE SIGN YOUR TOKEN IN YOUR SERVER SIDE AND OBTAIN IT FROM YOUR OWN TRUSTED SERVER API
webClient
webClient
.
joinChannel
({
.
joinChannel
({
uid
:
+
roomState
.
me
.
uid
,
uid
:
+
roomState
.
me
.
uid
,
channel
:
roomState
.
course
.
rid
,
channel
:
roomState
.
course
.
rid
,
token
:
''
,
token
:
''
,
dual
:
isSmallClass
dual
:
isSmallClass
}).
then
(()
=>
{
}).
then
(()
=>
{
}).
catch
(
console
.
warn
).
finally
(()
=>
{
}).
catch
(
console
.
warn
).
finally
(()
=>
{
rtc
.
current
=
false
;
rtc
.
current
=
false
;
});
});
...
@@ -316,6 +320,8 @@ export function RoomPage({ children }: any) {
...
@@ -316,6 +320,8 @@ export function RoomPage({ children }: any) {
for
(
let
eventName
of
events
)
{
for
(
let
eventName
of
events
)
{
webClient
.
rtc
.
off
(
eventName
,
()
=>
{});
webClient
.
rtc
.
off
(
eventName
,
()
=>
{});
}
}
console
.
log
(
"
[agora-web] rtmClient logout
"
);
roomStore
.
rtmClient
.
logout
();
console
.
log
(
"
[agora-web] remove event listener
"
);
console
.
log
(
"
[agora-web] remove event listener
"
);
!
rtc
.
current
&&
webClient
.
exit
().
then
(()
=>
{
!
rtc
.
current
&&
webClient
.
exit
().
then
(()
=>
{
console
.
log
(
"
[agora-web] do remove event listener
"
);
console
.
log
(
"
[agora-web] do remove event listener
"
);
...
@@ -379,7 +385,7 @@ export function RoomPage({ children }: any) {
...
@@ -379,7 +385,7 @@ export function RoomPage({ children }: any) {
});
});
// WARN: IF YOU ENABLED APP CERTIFICATE, PLEASE SIGN YOUR TOKEN IN YOUR SERVER SIDE AND OBTAIN IT FROM YOUR OWN TRUSTED SERVER API
// WARN: IF YOU ENABLED APP CERTIFICATE, PLEASE SIGN YOUR TOKEN IN YOUR SERVER SIDE AND OBTAIN IT FROM YOUR OWN TRUSTED SERVER API
nativeClient
.
joinChannel
({
nativeClient
.
joinChannel
({
uid
:
+
roomState
.
me
.
uid
,
uid
:
+
roomState
.
me
.
uid
,
channel
:
roomState
.
course
.
rid
,
channel
:
roomState
.
course
.
rid
,
token
:
''
,
token
:
''
,
dual
:
isSmallClass
dual
:
isSmallClass
...
...
src/pages/classroom/small-class.tsx
View file @
3a2d2dba
import
React
,
{
useLayoutEffect
,
use
Ref
}
from
'
react
'
;
import
React
,
{
useLayoutEffect
,
use
Memo
,
useRef
,
useState
}
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
"
;
export
default
function
SmallClass
()
{
export
default
function
SmallClass
()
{
// let search = window.location.search;
const
[
tool
,
setTool
]
=
useState
(
true
);
// let params = new URLSearchParams(search);
// let src = params.get('src');
// console.log(9999, src)
// useLayoutEffect(() => {
// }, [src]);
return
(
return
(
<
div
className=
"room-container"
>
<
div
className=
"room-container"
>
{
/*<VideoMarquee />*/
}
{
/*<VideoMarquee />*/
}
<
VideoShowList
/>
<
VideoShowList
/>
<
div
className=
"container"
>
<
div
className=
"container"
>
{
/*<MediaBoard />*/
}
<
ToolsSwitcherController
onClick=
{
()
=>
{
<
CourseWareFrame
></
CourseWareFrame
>
setTool
(
!
tool
);
}
}
/>
{
tool
?
<
MediaBoard
/>
:
<
CourseWareFrame
></
CourseWareFrame
>
}
<
Roomboard
currentActive=
{
'
media
'
}
/>
<
Roomboard
currentActive=
{
'
media
'
}
/>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
src/stores/room.ts
View file @
3a2d2dba
This diff is collapsed.
Click to expand it.
src/utils/agora-rtc-client.ts
View file @
3a2d2dba
...
@@ -20,7 +20,7 @@ export interface AgoraStreamSpec {
...
@@ -20,7 +20,7 @@ export interface AgoraStreamSpec {
}
}
const
streamEvents
:
string
[]
=
[
const
streamEvents
:
string
[]
=
[
"
accessAllowed
"
,
"
accessAllowed
"
,
"
accessDenied
"
,
"
accessDenied
"
,
"
stopScreenSharing
"
,
"
stopScreenSharing
"
,
"
videoTrackEnded
"
,
"
videoTrackEnded
"
,
...
@@ -104,7 +104,7 @@ class AgoraRTCClient {
...
@@ -104,7 +104,7 @@ class AgoraRTCClient {
if
(
evtName
===
"
peer-leave
"
)
{
if
(
evtName
===
"
peer-leave
"
)
{
console
.
log
(
"
[agora-web] peer-leave:
"
,
args
);
console
.
log
(
"
[agora-web] peer-leave:
"
,
args
);
}
}
this
.
_bus
.
emit
(
evtName
,
args
);
this
.
_bus
.
emit
(
evtName
,
args
);
});
});
}
}
...
@@ -155,7 +155,7 @@ class AgoraRTCClient {
...
@@ -155,7 +155,7 @@ class AgoraRTCClient {
this
.
_bus
.
off
(
evtName
,
cb
);
this
.
_bus
.
off
(
evtName
,
cb
);
}
}
async
publish
()
{
async
publish
()
{
console
.
log
(
'
rtc publish
'
)
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
this
.
_published
)
{
if
(
this
.
_published
)
{
return
resolve
();
return
resolve
();
...
@@ -170,7 +170,7 @@ class AgoraRTCClient {
...
@@ -170,7 +170,7 @@ class AgoraRTCClient {
})
})
}
}
async
unpublish
()
{
async
unpublish
()
{
console
.
log
(
'
unpublish
'
,
1
);
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
!
this
.
_published
||
!
this
.
_localStream
)
{
if
(
!
this
.
_published
||
!
this
.
_localStream
)
{
return
resolve
();
return
resolve
();
...
@@ -234,7 +234,7 @@ class AgoraRTCClient {
...
@@ -234,7 +234,7 @@ class AgoraRTCClient {
})
})
}
}
async
leave
()
{
async
leave
()
{
console
.
log
(
9999
,
'
rtc leave
'
);
if
(
this
.
_client
)
{
if
(
this
.
_client
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
_client
.
leave
(
resolve
,
reject
);
this
.
_client
.
leave
(
resolve
,
reject
);
...
@@ -341,7 +341,7 @@ export default class AgoraWebClient {
...
@@ -341,7 +341,7 @@ export default class AgoraWebClient {
roomStore
.
setRTCJoined
(
true
);
roomStore
.
setRTCJoined
(
true
);
}
}
async
leaveChannel
()
{
async
leaveChannel
()
{
console
.
log
(
'
unpublish leaveChannel
'
,
3
);
this
.
localUid
=
0
;
this
.
localUid
=
0
;
this
.
channel
=
''
;
this
.
channel
=
''
;
await
this
.
unpublishLocalStream
();
await
this
.
unpublishLocalStream
();
...
@@ -357,17 +357,17 @@ export default class AgoraWebClient {
...
@@ -357,17 +357,17 @@ export default class AgoraWebClient {
}
}
async
publishLocalStream
(
data
:
AgoraStreamSpec
)
{
async
publishLocalStream
(
data
:
AgoraStreamSpec
)
{
console
.
log
(
"
publish local stream
"
,
this
.
publishe
d
);
console
.
log
(
"
publish local stream
"
,
roomStore
.
state
.
me
.
ui
d
);
if
(
this
.
published
)
{
if
(
this
.
published
)
{
await
this
.
unpublishLocalStream
();
await
this
.
unpublishLocalStream
();
console
.
log
(
"
[agora-web] unpublished
"
,
this
.
publishe
d
);
console
.
log
(
"
[agora-web] unpublished
"
,
roomStore
.
state
.
me
.
ui
d
);
}
}
await
this
.
rtc
.
createLocalStream
(
data
);
await
this
.
rtc
.
createLocalStream
(
data
);
await
this
.
rtc
.
publish
();
await
this
.
rtc
.
publish
();
this
.
published
=
true
;
this
.
published
=
true
;
}
}
async
unpublishLocalStream
()
{
async
unpublishLocalStream
()
{
console
.
log
(
'
unpublish LocalStream
'
,
4
);
console
.
log
(
"
[agora-web] invoke unpublishStream
"
);
console
.
log
(
"
[agora-web] invoke unpublishStream
"
);
await
this
.
rtc
.
unpublish
();
await
this
.
rtc
.
unpublish
();
this
.
published
=
false
;
this
.
published
=
false
;
...
@@ -443,4 +443,4 @@ export default class AgoraWebClient {
...
@@ -443,4 +443,4 @@ export default class AgoraWebClient {
setRemoteVideoStreamType
(
stream
:
any
,
type
:
number
)
{
setRemoteVideoStreamType
(
stream
:
any
,
type
:
number
)
{
this
.
rtc
.
setRemoteVideoStreamType
(
stream
,
type
);
this
.
rtc
.
setRemoteVideoStreamType
(
stream
,
type
);
}
}
}
}
\ No newline at end of file
src/utils/agora-rtm-client.ts
View file @
3a2d2dba
...
@@ -54,8 +54,8 @@ export default class AgoraRTMClient {
...
@@ -54,8 +54,8 @@ export default class AgoraRTMClient {
this
.
_channelAttrsKey
=
null
;
this
.
_channelAttrsKey
=
null
;
this
.
_client
=
AgoraRTM
.
createInstance
(
APP_ID
,
{
enableLogUpload
:
false
,
logFilter
});
this
.
_client
=
AgoraRTM
.
createInstance
(
APP_ID
,
{
enableLogUpload
:
false
,
logFilter
});
}
}
async
addOrUpdateChannelAttributes
(
data
:
any
):
Promise
<
string
>
{
async
addOrUpdateChannelAttributes
(
data
:
any
,
enableNotificationToChannelMembers
=
true
):
Promise
<
string
>
{
return
await
this
.
_client
.
addOrUpdateChannelAttributes
(
this
.
_currentChannelName
,
data
,
{
enableNotificationToChannelMembers
:
true
});
return
await
this
.
_client
.
addOrUpdateChannelAttributes
(
this
.
_currentChannelName
,
data
,
{
enableNotificationToChannelMembers
});
}
}
public
removeAllListeners
():
any
{
public
removeAllListeners
():
any
{
...
@@ -83,6 +83,7 @@ export default class AgoraRTMClient {
...
@@ -83,6 +83,7 @@ export default class AgoraRTMClient {
}
}
async
login
(
uid
:
string
,
token
?:
string
)
{
async
login
(
uid
:
string
,
token
?:
string
)
{
this
.
_channelAttrsKey
=
uid
;
await
this
.
_client
.
login
({
uid
,
token
});
await
this
.
_client
.
login
({
uid
,
token
});
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
});
...
@@ -96,6 +97,7 @@ export default class AgoraRTMClient {
...
@@ -96,6 +97,7 @@ export default class AgoraRTMClient {
async
logout
()
{
async
logout
()
{
if
(
!
this
.
_logged
)
return
;
if
(
!
this
.
_logged
)
return
;
await
this
.
leave
(
this
.
_currentChannelName
);
await
this
.
_client
.
logout
();
await
this
.
_client
.
logout
();
this
.
destroy
();
this
.
destroy
();
this
.
_logged
=
false
;
this
.
_logged
=
false
;
...
@@ -155,6 +157,9 @@ export default class AgoraRTMClient {
...
@@ -155,6 +157,9 @@ export default class AgoraRTMClient {
async
sendChannelMessage
(
msg
:
string
)
{
async
sendChannelMessage
(
msg
:
string
)
{
return
this
.
_currentChannel
.
sendMessage
({
text
:
msg
});
return
this
.
_currentChannel
.
sendMessage
({
text
:
msg
});
}
}
async
setChannelAttrsKey
(
key
:
any
)
{
this
.
_channelAttrsKey
=
`
${
key
}
`
;
}
async
updateChannelAttrsByKey
(
data
:
{[
key
:
string
]:
string
}
/*key: string, attrs: any*/
)
{
async
updateChannelAttrsByKey
(
data
:
{[
key
:
string
]:
string
}
/*key: string, attrs: any*/
)
{
// this._channelAttrsKey = key;
// this._channelAttrsKey = key;
const
channelAttributes
:
{[
key
:
string
]:
string
}
=
{};
const
channelAttributes
:
{[
key
:
string
]:
string
}
=
{};
...
@@ -217,6 +222,7 @@ export default class AgoraRTMClient {
...
@@ -217,6 +222,7 @@ export default class AgoraRTMClient {
const
teacher
=
accounts
.
find
((
it
:
any
)
=>
it
.
role
===
'
teacher
'
);
const
teacher
=
accounts
.
find
((
it
:
any
)
=>
it
.
role
===
'
teacher
'
);
if
(
teacher
&&
results
[
teacher
.
uid
])
{
if
(
teacher
&&
results
[
teacher
.
uid
])
{
results
.
teacher
=
results
[
teacher
.
uid
];
results
.
teacher
=
results
[
teacher
.
uid
];
results
.
teacherId
=
teacher
.
uid
;
results
.
teacherCount
=
1
;
results
.
teacherCount
=
1
;
}
}
results
.
totalCount
=
accounts
.
filter
((
it
:
any
)
=>
results
[
it
.
uid
]).
length
;
results
.
totalCount
=
accounts
.
filter
((
it
:
any
)
=>
results
[
it
.
uid
]).
length
;
...
@@ -240,11 +246,16 @@ export default class AgoraRTMClient {
...
@@ -240,11 +246,16 @@ export default class AgoraRTMClient {
}
}
continue
;
continue
;
}
}
const
student
=
jsonParse
(
_
.
get
(
json
,
`
${
key
}
.value`
));
// if (key === 'studentsOrder') {
// when student is not empty object
// continue
if
(
student
&&
Object
.
keys
(
student
).
length
)
{
// }
student
.
uid
=
key
;
if
(
/^
[
0-9
]
+$/
.
test
(
key
))
{
accounts
.
push
(
student
);
const
student
=
jsonParse
(
_
.
get
(
json
,
`
${
key
}
.value`
));
// when student is not empty object
if
(
student
&&
Object
.
keys
(
student
).
length
)
{
student
.
uid
=
key
;
accounts
.
push
(
student
);
}
}
}
}
}
return
accounts
;
return
accounts
;
...
...
src/utils/helper.ts
View file @
3a2d2dba
...
@@ -226,6 +226,7 @@ export function resolveChannelAttrs(json: object) {
...
@@ -226,6 +226,7 @@ export function resolveChannelAttrs(json: object) {
let
studentsOrder
:
number
[]
=
[];
let
studentsOrder
:
number
[]
=
[];
if
((
json
as
any
).
studentsOrder
&&
(
json
as
any
).
studentsOrder
.
value
)
{
if
((
json
as
any
).
studentsOrder
&&
(
json
as
any
).
studentsOrder
.
value
)
{
studentsOrder
=
JSON
.
parse
((
json
as
any
).
studentsOrder
.
value
)
||
[];
studentsOrder
=
JSON
.
parse
((
json
as
any
).
studentsOrder
.
value
)
||
[];
studentsOrder
=
studentsOrder
.
map
(
id
=>
+
id
)
}
}
delete
(
json
as
any
).
studentsOrder
;
delete
(
json
as
any
).
studentsOrder
;
...
@@ -249,52 +250,32 @@ export function resolveChannelAttrs(json: object) {
...
@@ -249,52 +250,32 @@ export function resolveChannelAttrs(json: object) {
}
}
}
}
}
}
const
students
=
[];
let
students
:
any
[]
=
[];
for
(
let
key
of
Object
.
keys
(
json
))
{
for
(
let
key
of
Object
.
keys
(
json
))
{
if
(
key
===
'
teacher
'
)
continue
;
if
(
key
===
'
teacher
'
)
continue
;
const
student
=
jsonParse
(
_
.
get
(
json
,
`
${
key
}
.value`
));
const
student
=
jsonParse
(
_
.
get
(
json
,
`
${
key
}
.value`
));
if
(
student
&&
Object
.
keys
(
student
).
length
)
{
if
(
student
&&
Object
.
keys
(
student
).
length
)
{
student
.
uid
=
key
;
student
.
uid
=
key
;
student
.
role
=
'
student
'
;
students
.
push
(
student
);
students
.
push
(
student
);
}
}
}
}
console
.
log
(
'
resolveChannelAttrs 1
'
,
students
);
console
.
log
(
'
resolveChannelAttrs 2
'
,
studentsOrder
);
// const orderedStudents: any[] = [];
/*
// students.sort(function(a, b){
const studentsMeta = [];
// return studentsOrder.indexOf(+a.uid) - studentsOrder.indexOf(+b.uid);
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);
// console.log('resolveChannelAttrs 1', students);
// console.log('resolveChannelAttrs 2', studentsOrder);
const
accounts
=
[];
const
accounts
:
any
[]
=
[];
if
(
teacherJson
&&
Object
.
keys
(
teacherJson
).
length
)
{
if
(
teacherJson
&&
Object
.
keys
(
teacherJson
).
length
)
{
accounts
.
push
({
accounts
.
push
({
role
:
'
teacher
'
,
role
:
'
teacher
'
,
...
@@ -324,33 +305,15 @@ export function resolveChannelAttrs(json: object) {
...
@@ -324,33 +305,15 @@ export function resolveChannelAttrs(json: object) {
grant_board
:
+
student
.
grant_board
,
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
{
return
{
teacher
:
teacherJson
,
teacher
:
teacherJson
,
students
:
students
,
students
:
students
,
accounts
,
accounts
,
room
,
room
,
studentsOrder
};
};
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment