@tellescope/video-chat 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/video.d.ts +14 -3
- package/lib/cjs/video.d.ts.map +1 -1
- package/lib/cjs/video.js +21 -9
- package/lib/cjs/video.js.map +1 -1
- package/lib/cjs/video.native.d.ts +6 -0
- package/lib/cjs/video.native.d.ts.map +1 -0
- package/lib/cjs/video.native.js +328 -0
- package/lib/cjs/video.native.js.map +1 -0
- package/lib/esm/video.d.ts +14 -3
- package/lib/esm/video.d.ts.map +1 -1
- package/lib/esm/video.js +23 -12
- package/lib/esm/video.js.map +1 -1
- package/lib/esm/video.native.d.ts +6 -0
- package/lib/esm/video.native.d.ts.map +1 -0
- package/lib/esm/video.native.js +302 -0
- package/lib/esm/video.native.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/video.native.tsx +298 -0
- package/src/video.tsx +40 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellescope/video-chat",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/cjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"@fontsource/roboto": "^4.5.1",
|
|
34
34
|
"@mui/icons-material": "^5.0.1",
|
|
35
35
|
"@mui/material": "^5.0.2",
|
|
36
|
-
"@tellescope/constants": "^0.0.
|
|
37
|
-
"@tellescope/react-components": "^0.0.
|
|
38
|
-
"@tellescope/sdk": "^0.0.
|
|
39
|
-
"@tellescope/types-client": "^0.0.
|
|
40
|
-
"@tellescope/types-models": "^0.0.
|
|
41
|
-
"@tellescope/types-utilities": "^0.0.
|
|
42
|
-
"@tellescope/utilities": "^0.0.
|
|
36
|
+
"@tellescope/constants": "^0.0.12",
|
|
37
|
+
"@tellescope/react-components": "^0.0.12",
|
|
38
|
+
"@tellescope/sdk": "^0.0.12",
|
|
39
|
+
"@tellescope/types-client": "^0.0.12",
|
|
40
|
+
"@tellescope/types-models": "^0.0.12",
|
|
41
|
+
"@tellescope/types-utilities": "^0.0.12",
|
|
42
|
+
"@tellescope/utilities": "^0.0.12",
|
|
43
43
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
|
44
44
|
"@typescript-eslint/parser": "^4.33.0",
|
|
45
45
|
"amazon-chime-sdk-component-library-react": "^2.12.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"react": "^17.0.2",
|
|
55
55
|
"react-dom": "^17.0.2"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "5d67de4721a3cbc3537a870281f2c657099e07b4",
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|
|
60
60
|
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
// logic pulled + refactored from
|
|
2
|
+
// https://github.com/aws-samples/amazon-chime-react-native-demo/blob/master/src/containers/Meeting.js
|
|
3
|
+
// which includes the following copyright disclaimer
|
|
4
|
+
/*
|
|
5
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
6
|
+
* SPDX-License-Identifier: MIT-0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React, { useCallback, useContext, useEffect, useState } from "react"
|
|
10
|
+
import { View, Text, StyleSheet } from "react-native"
|
|
11
|
+
import {
|
|
12
|
+
AttendeeInfo,
|
|
13
|
+
MeetingInfo,
|
|
14
|
+
} from '@tellescope/types-models'
|
|
15
|
+
import {
|
|
16
|
+
UserIdentity,
|
|
17
|
+
} from '@tellescope/types-utilities'
|
|
18
|
+
import { useSession } from "@tellescope/react-components/lib/esm/authentication"
|
|
19
|
+
import { Button } from "@tellescope/react-components/lib/esm/mui"
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
CurrentCallContext,
|
|
23
|
+
JoinVideoCallReturnType,
|
|
24
|
+
StartVideoCallReturnType,
|
|
25
|
+
VideoProps,
|
|
26
|
+
AttendeeDisplayInfo
|
|
27
|
+
} from "./video.js"
|
|
28
|
+
|
|
29
|
+
import {
|
|
30
|
+
getSDKEventEmitter,
|
|
31
|
+
MobileSDKEvent,
|
|
32
|
+
NativeFunction,
|
|
33
|
+
} from "./native/bridge"
|
|
34
|
+
import { RNVideoView } from "./native/RNVideoRenderView"
|
|
35
|
+
|
|
36
|
+
export const WithVideo = ({ children } : VideoProps ) => {
|
|
37
|
+
const [meeting, setMeeting] = useState(undefined as MeetingInfo | undefined)
|
|
38
|
+
|
|
39
|
+
const [inMeeting, setInMeeting] = useState(false)
|
|
40
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
41
|
+
const [videoIsEnabled, setVideoIsEnabled] = useState(false)
|
|
42
|
+
const [videoTiles, setVideoTiles] = useState([] as string[])
|
|
43
|
+
const [screenShareTile, setScreenShareTile] = useState('')
|
|
44
|
+
const [attendees, setAttendees] = useState ([] as AttendeeDisplayInfo[])
|
|
45
|
+
|
|
46
|
+
const toggleVideo = () => NativeFunction.setCameraOn(!videoIsEnabled)
|
|
47
|
+
const emitter = getSDKEventEmitter()
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const startSubscription = emitter.addListener(MobileSDKEvent.OnMeetingStart, () => {
|
|
51
|
+
setInMeeting(true)
|
|
52
|
+
setIsLoading(false)
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const endSubscription = emitter.addListener(MobileSDKEvent.OnMeetingEnd, () => {
|
|
56
|
+
setInMeeting(true)
|
|
57
|
+
setIsLoading(false)
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const joinSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesJoin, ({ attendeeId, externalUserId }) => {
|
|
61
|
+
setAttendees(as => !as.find(a => a.attendeeId === attendeeId)
|
|
62
|
+
? [{ attendeeId, externalUserId, muted: false }, ...as]
|
|
63
|
+
: as
|
|
64
|
+
)
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const leaveSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesLeave, ({ attendeeId }) => {
|
|
68
|
+
setAttendees(as => as.filter(a => a.attendeeId !== attendeeId))
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const errorSubscription = emitter.addListener(MobileSDKEvent.OnError, (message) => {
|
|
72
|
+
console.error("SDK Error", message);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const muteSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesMute, attendeeId => {
|
|
76
|
+
setAttendees(as => as.map(a => a.attendeeId === attendeeId ? { ...a, muted: true } : a))
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const unmuteSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesUnmute, attendeeId => {
|
|
80
|
+
setAttendees(as => as.map(a => a.attendeeId === attendeeId ? { ...a, muted: false } : a))
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const addVideoSubscription = emitter.addListener(MobileSDKEvent.OnAddVideoTile, (tileState) => {
|
|
84
|
+
if (tileState.isScreenShare) {
|
|
85
|
+
setScreenShareTile(tileState.tileId)
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
setVideoTiles(v => [...v, tileState.titleId])
|
|
89
|
+
setVideoIsEnabled(v => tileState.isLocal ? true : v)
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const removeVideoSubscription = emitter.addListener(MobileSDKEvent.OnRemoveVideoTile, (tileState) => {
|
|
93
|
+
if (tileState.isScreenShare) {
|
|
94
|
+
setScreenShareTile('')
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
setVideoTiles(vs => vs.filter(v => v !== tileState.tileId))
|
|
98
|
+
setVideoIsEnabled(v => tileState.isLocal ? false : v)
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
return () => {
|
|
103
|
+
startSubscription.remove();
|
|
104
|
+
endSubscription.remove();
|
|
105
|
+
errorSubscription.remove();
|
|
106
|
+
joinSubscription.remove();
|
|
107
|
+
leaveSubscription.remove();
|
|
108
|
+
muteSubscription.remove();
|
|
109
|
+
unmuteSubscription.remove();
|
|
110
|
+
addVideoSubscription.remove();
|
|
111
|
+
removeVideoSubscription.remove();
|
|
112
|
+
}
|
|
113
|
+
}, [emitter])
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<CurrentCallContext.Provider value={{ attendees, videoTiles, meeting, shareScreenId: screenShareTile, setMeeting, videoIsEnabled, toggleVideo }}>
|
|
117
|
+
{children}
|
|
118
|
+
</CurrentCallContext.Provider>
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const useStartVideoCall = (): StartVideoCallReturnType => {
|
|
123
|
+
const session = useSession()
|
|
124
|
+
const { meeting, setMeeting, videoIsEnabled, toggleVideo } = React.useContext(CurrentCallContext)
|
|
125
|
+
|
|
126
|
+
const [starting, setStarting] = useState(false)
|
|
127
|
+
const [ending, setEnding] = useState(false)
|
|
128
|
+
|
|
129
|
+
const createAndStartMeeting = async (initialAttendees?: UserIdentity[]) => {
|
|
130
|
+
try {
|
|
131
|
+
const { meeting, host } = await session.api.meetings.start_meeting()
|
|
132
|
+
|
|
133
|
+
if (initialAttendees) {
|
|
134
|
+
session.api.meetings.add_attendees_to_meeting({ id: meeting.Meeting.ExternalMeetingId, attendees: initialAttendees })
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
NativeFunction.startMeeting(meeting.Meeting, host.Attendee)
|
|
138
|
+
|
|
139
|
+
setMeeting(meeting.Meeting)
|
|
140
|
+
} catch(err) {
|
|
141
|
+
console.error(err)
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const addAttendees = useCallback(async (attendees: UserIdentity[]) => {
|
|
149
|
+
if (!meeting) return
|
|
150
|
+
await session.api.meetings.add_attendees_to_meeting({ id: meeting?.ExternalMeetingId, attendees })
|
|
151
|
+
}, [session, meeting])
|
|
152
|
+
|
|
153
|
+
const endMeeting = async () => {
|
|
154
|
+
if (!meeting) return
|
|
155
|
+
setEnding(true)
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
await session.api.meetings.end_meeting({ id: meeting.ExternalMeetingId })
|
|
159
|
+
} catch(err) { console.error(err) }
|
|
160
|
+
|
|
161
|
+
setEnding(false)
|
|
162
|
+
setMeeting(undefined)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return { meeting, videoIsEnabled, starting, ending, toggleVideo, createAndStartMeeting, addAttendees, endMeeting }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export const useJoinVideoCall = (): JoinVideoCallReturnType => {
|
|
169
|
+
const { meeting, setMeeting, videoIsEnabled, toggleVideo } = React.useContext(CurrentCallContext)
|
|
170
|
+
|
|
171
|
+
const joinMeeting = async (meetingInfo: { Meeting: MeetingInfo }, attendeeInfo: { Attendee: AttendeeInfo }) => {
|
|
172
|
+
NativeFunction.startMeeting(meetingInfo.Meeting, attendeeInfo.Attendee)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return { meeting, videoIsEnabled, toggleVideo, joinMeeting }
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export const VideoTileGrid = () => {
|
|
179
|
+
const {
|
|
180
|
+
// attendees,
|
|
181
|
+
videoIsEnabled,
|
|
182
|
+
videoTiles,
|
|
183
|
+
shareScreenId
|
|
184
|
+
} = useContext(CurrentCallContext)
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<View style={[styles.container, { justifyContent: 'flex-start' }]}>
|
|
188
|
+
<Text style={styles.title}>TITLE</Text>
|
|
189
|
+
<View style={styles.buttonContainer}>
|
|
190
|
+
{/* <MuteButton muted={currentMuted} onPress={() => NativeFunction.setMute(!currentMuted) }/> */}
|
|
191
|
+
{/* <CameraButton disabled={selfVideoEnabled} onPress={() => NativeFunction.setCameraOn(!videoIsEnabled)}/> */}
|
|
192
|
+
<Button disabled={videoIsEnabled} onPress={() => NativeFunction.setCameraOn(!videoIsEnabled)}>
|
|
193
|
+
Toggle Video
|
|
194
|
+
</Button>
|
|
195
|
+
{/* <HangOffButton onPress={() => NativeFunction.stopMeeting()} /> */}
|
|
196
|
+
<Button onPress={() => NativeFunction.stopMeeting()}> Leave Meeting </Button>
|
|
197
|
+
</View>
|
|
198
|
+
<Text style={styles.title}>Video</Text>
|
|
199
|
+
<View style={styles.videoContainer}>
|
|
200
|
+
{
|
|
201
|
+
videoTiles.length > 0 ? videoTiles.map(tileId =>
|
|
202
|
+
<RNVideoView style={styles.video} key={tileId} tileId={tileId} />
|
|
203
|
+
) : <Text style={styles.subtitle}>No one is sharing video at this moment</Text>
|
|
204
|
+
}
|
|
205
|
+
</View>
|
|
206
|
+
{
|
|
207
|
+
!!shareScreenId &&
|
|
208
|
+
<React.Fragment>
|
|
209
|
+
<Text style={styles.title}>Screen Share</Text>
|
|
210
|
+
<View style={styles.videoContainer}>
|
|
211
|
+
<RNVideoView style={styles.screenShare} key={shareScreenId} tileId={shareScreenId} />
|
|
212
|
+
</View>
|
|
213
|
+
</React.Fragment>
|
|
214
|
+
}
|
|
215
|
+
<Text style={styles.title}>Attendee</Text>
|
|
216
|
+
{/* <FlatList
|
|
217
|
+
style={styles.attendeeList}
|
|
218
|
+
data={attendees}
|
|
219
|
+
renderItem={({ item }) => <AttendeeItem attendeeName={attendeeNameMap[item] ? attendeeNameMap[item] : item} muted={this.state.mutedAttendee.includes(item)}/>}
|
|
220
|
+
keyExtractor={(item) => item}
|
|
221
|
+
/> */}
|
|
222
|
+
</View>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const styles = StyleSheet.create({
|
|
227
|
+
container: {
|
|
228
|
+
justifyContent: 'center',
|
|
229
|
+
alignItems: 'center',
|
|
230
|
+
height: '95%',
|
|
231
|
+
backgroundColor: 'white'
|
|
232
|
+
},
|
|
233
|
+
buttonContainer: {
|
|
234
|
+
flexDirection: 'row',
|
|
235
|
+
justifyContent: 'space-between',
|
|
236
|
+
},
|
|
237
|
+
title: {
|
|
238
|
+
fontSize: 30,
|
|
239
|
+
fontWeight: '700'
|
|
240
|
+
},
|
|
241
|
+
subtitle: {
|
|
242
|
+
marginBottom: 25,
|
|
243
|
+
marginTop: 10,
|
|
244
|
+
color: 'grey'
|
|
245
|
+
},
|
|
246
|
+
videoContainer: {
|
|
247
|
+
flexDirection: 'row',
|
|
248
|
+
justifyContent: 'space-around',
|
|
249
|
+
width: '100%',
|
|
250
|
+
// This is an existing React Native issue:
|
|
251
|
+
// When you create a native android component
|
|
252
|
+
// that use GLSurfaceView (We use this internally), the entire screen will
|
|
253
|
+
// black out
|
|
254
|
+
overflow: 'hidden'
|
|
255
|
+
},
|
|
256
|
+
video: {
|
|
257
|
+
width: '45%',
|
|
258
|
+
margin: '1%',
|
|
259
|
+
aspectRatio: 16 / 9,
|
|
260
|
+
},
|
|
261
|
+
screenShare: {
|
|
262
|
+
width: '90%',
|
|
263
|
+
margin: '1%',
|
|
264
|
+
aspectRatio: 16 / 9,
|
|
265
|
+
},
|
|
266
|
+
attendeeList: {
|
|
267
|
+
flex: 1,
|
|
268
|
+
width: '80%'
|
|
269
|
+
},
|
|
270
|
+
attendeeContainer: {
|
|
271
|
+
fontSize: 20,
|
|
272
|
+
margin: 5,
|
|
273
|
+
padding: 5,
|
|
274
|
+
height: 30,
|
|
275
|
+
backgroundColor: '#eee',
|
|
276
|
+
justifyContent: 'space-between',
|
|
277
|
+
flexDirection: 'row',
|
|
278
|
+
},
|
|
279
|
+
attendeeMuteImage: {
|
|
280
|
+
resizeMode: 'contain',
|
|
281
|
+
width: 20,
|
|
282
|
+
height: 20
|
|
283
|
+
},
|
|
284
|
+
inputBox: {
|
|
285
|
+
height: 40,
|
|
286
|
+
borderColor: 'black',
|
|
287
|
+
borderWidth: 1,
|
|
288
|
+
margin: 5,
|
|
289
|
+
width: '50%',
|
|
290
|
+
padding: 10,
|
|
291
|
+
color: 'black'
|
|
292
|
+
},
|
|
293
|
+
meetingButton: {
|
|
294
|
+
resizeMode: 'contain',
|
|
295
|
+
width: 50,
|
|
296
|
+
height: 50
|
|
297
|
+
}
|
|
298
|
+
});
|
package/src/video.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useState, CSSProperties } from "react"
|
|
1
|
+
import React, { useCallback, useState, CSSProperties, Children } from "react"
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
useSession,
|
|
@@ -24,8 +24,8 @@ import {
|
|
|
24
24
|
import { ThemeProvider } from 'styled-components';
|
|
25
25
|
import {
|
|
26
26
|
MeetingProvider,
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
darkTheme,
|
|
28
|
+
useContentShareState,
|
|
29
29
|
// LocalVideo,
|
|
30
30
|
VideoTileGrid,
|
|
31
31
|
// VideoGrid,
|
|
@@ -34,41 +34,61 @@ import {
|
|
|
34
34
|
// RemoteVideo,
|
|
35
35
|
useLocalVideo,
|
|
36
36
|
useMeetingManager,
|
|
37
|
-
|
|
37
|
+
useRosterState,
|
|
38
|
+
useRemoteVideoTileState
|
|
38
39
|
// useRemoteVideoTileState,
|
|
39
40
|
// useContentShareControls, // screen sharing
|
|
40
41
|
} from 'amazon-chime-sdk-component-library-react';
|
|
41
42
|
import { } from "../../../types-client/node_modules/@tellescope/types-models/src"
|
|
42
43
|
|
|
44
|
+
export type AttendeeDisplayInfo = { attendeeId: string, externalUserId: string }
|
|
45
|
+
|
|
43
46
|
export const CurrentCallContext = React.createContext({} as {
|
|
44
47
|
meeting: MeetingInfo | undefined, setMeeting: (m: MeetingInfo | undefined) => void,
|
|
48
|
+
videoIsEnabled: boolean, toggleVideo: () => Promise<void>,
|
|
49
|
+
attendees: AttendeeDisplayInfo[], shareScreenId: string,
|
|
50
|
+
videoTiles: (number | string)[],
|
|
45
51
|
})
|
|
46
|
-
interface VideoProps {
|
|
52
|
+
export interface VideoProps {
|
|
47
53
|
children?: React.ReactNode,
|
|
48
|
-
theme?: typeof
|
|
54
|
+
theme?: typeof darkTheme,
|
|
49
55
|
}
|
|
50
|
-
|
|
56
|
+
const WithContext = ({ children } : { children: React.ReactNode }) => {
|
|
51
57
|
const [meeting, setMeeting] = useState(undefined as MeetingInfo | undefined)
|
|
52
|
-
|
|
58
|
+
const { toggleVideo, isVideoEnabled: videoIsEnabled } = useLocalVideo();
|
|
59
|
+
const { roster } = useRosterState()
|
|
60
|
+
const { tileId } = useContentShareState()
|
|
61
|
+
const { tiles } = useRemoteVideoTileState()
|
|
62
|
+
|
|
63
|
+
const attendees = [] as AttendeeDisplayInfo[]
|
|
64
|
+
for (const attendeeId in roster) {
|
|
65
|
+
const { externalUserId } = roster[attendeeId]
|
|
66
|
+
attendees.push({ attendeeId, externalUserId: externalUserId as string })
|
|
67
|
+
}
|
|
68
|
+
|
|
53
69
|
return (
|
|
54
|
-
<CurrentCallContext.Provider value={{ meeting, setMeeting }}>
|
|
55
|
-
<ThemeProvider theme={theme}>
|
|
56
|
-
<MeetingProvider>
|
|
70
|
+
<CurrentCallContext.Provider value={{ attendees, videoTiles: tiles, shareScreenId: tileId?.toString() ?? '', meeting, setMeeting, videoIsEnabled, toggleVideo }}>
|
|
57
71
|
{children}
|
|
58
|
-
</MeetingProvider>
|
|
59
|
-
</ThemeProvider>
|
|
60
72
|
</CurrentCallContext.Provider>
|
|
61
73
|
)
|
|
62
74
|
}
|
|
75
|
+
export const WithVideo = ({ children, theme=darkTheme }: VideoProps) => (
|
|
76
|
+
<ThemeProvider theme={theme}>
|
|
77
|
+
<MeetingProvider>
|
|
78
|
+
<WithContext>
|
|
79
|
+
{children}
|
|
80
|
+
</WithContext>
|
|
81
|
+
</MeetingProvider>
|
|
82
|
+
</ThemeProvider>
|
|
83
|
+
)
|
|
63
84
|
|
|
64
85
|
export const useStartVideoCall = () => {
|
|
65
86
|
const [starting, setStarting] = useState(false)
|
|
66
87
|
const [ending, setEnding] = useState(false)
|
|
67
|
-
const { meeting, setMeeting } = React.useContext(CurrentCallContext)
|
|
88
|
+
const { meeting, setMeeting, toggleVideo, videoIsEnabled } = React.useContext(CurrentCallContext)
|
|
68
89
|
|
|
69
90
|
const session = useSession()
|
|
70
91
|
const meetingManager = useMeetingManager();
|
|
71
|
-
const { toggleVideo, isVideoEnabled } = useLocalVideo();
|
|
72
92
|
|
|
73
93
|
const createAndStartMeeting = async (initialAttendees?: UserIdentity[]) => {
|
|
74
94
|
setStarting(false)
|
|
@@ -109,13 +129,13 @@ export const useStartVideoCall = () => {
|
|
|
109
129
|
setMeeting(undefined)
|
|
110
130
|
}
|
|
111
131
|
|
|
112
|
-
return { starting, ending, meeting, videoIsEnabled
|
|
132
|
+
return { starting, ending, meeting, videoIsEnabled, toggleVideo, createAndStartMeeting, addAttendees, endMeeting }
|
|
113
133
|
}
|
|
134
|
+
export type StartVideoCallReturnType = ReturnType<typeof useStartVideoCall>
|
|
114
135
|
|
|
115
136
|
export const useJoinVideoCall = () => {
|
|
116
137
|
const meetingManager = useMeetingManager();
|
|
117
|
-
const { toggleVideo,
|
|
118
|
-
const { meeting, setMeeting } = React.useContext(CurrentCallContext)
|
|
138
|
+
const { meeting, setMeeting, toggleVideo, videoIsEnabled } = React.useContext(CurrentCallContext)
|
|
119
139
|
|
|
120
140
|
const joinMeeting = async (meetingInfo: { Meeting: MeetingInfo }, attendeeInfo: { Attendee: AttendeeInfo }) => {
|
|
121
141
|
await meetingManager.join({ meetingInfo, attendeeInfo }); // Use the join API to create a meeting session
|
|
@@ -123,7 +143,8 @@ export const useJoinVideoCall = () => {
|
|
|
123
143
|
setMeeting(meetingInfo.Meeting)
|
|
124
144
|
}
|
|
125
145
|
|
|
126
|
-
return { meeting, videoIsEnabled:
|
|
146
|
+
return { meeting, videoIsEnabled: videoIsEnabled, toggleVideo, joinMeeting }
|
|
127
147
|
}
|
|
148
|
+
export type JoinVideoCallReturnType = ReturnType<typeof useJoinVideoCall>
|
|
128
149
|
|
|
129
150
|
export { VideoTileGrid }
|