@tellescope/video-chat 1.3.25 → 1.3.27

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.
Files changed (54) hide show
  1. package/lib/cjs/index.d.ts +1 -2
  2. package/lib/cjs/index.d.ts.map +1 -1
  3. package/lib/cjs/index.js +1 -5
  4. package/lib/cjs/index.js.map +1 -1
  5. package/lib/cjs/index.native.d.ts +1 -2
  6. package/lib/cjs/index.native.d.ts.map +1 -1
  7. package/lib/cjs/index.native.js +2 -5
  8. package/lib/cjs/index.native.js.map +1 -1
  9. package/lib/cjs/video.d.ts +17 -1
  10. package/lib/cjs/video.d.ts.map +1 -1
  11. package/lib/cjs/video.js +106 -1
  12. package/lib/cjs/video.js.map +1 -1
  13. package/lib/cjs/video.native.d.ts +6 -2
  14. package/lib/cjs/video.native.d.ts.map +1 -1
  15. package/lib/cjs/video.native.js +86 -9
  16. package/lib/cjs/video.native.js.map +1 -1
  17. package/lib/cjs/video_shared.d.ts +18 -2
  18. package/lib/cjs/video_shared.d.ts.map +1 -1
  19. package/lib/cjs/video_shared.js +114 -4
  20. package/lib/cjs/video_shared.js.map +1 -1
  21. package/lib/esm/controls.d.ts +0 -1
  22. package/lib/esm/controls.d.ts.map +1 -1
  23. package/lib/esm/hooks.d.ts +1 -13
  24. package/lib/esm/hooks.d.ts.map +1 -1
  25. package/lib/esm/hooks.js +1 -137
  26. package/lib/esm/hooks.js.map +1 -1
  27. package/lib/esm/index.d.ts +1 -2
  28. package/lib/esm/index.d.ts.map +1 -1
  29. package/lib/esm/index.js +1 -2
  30. package/lib/esm/index.js.map +1 -1
  31. package/lib/esm/index.native.d.ts +1 -2
  32. package/lib/esm/index.native.d.ts.map +1 -1
  33. package/lib/esm/index.native.js +1 -2
  34. package/lib/esm/index.native.js.map +1 -1
  35. package/lib/esm/video.d.ts +17 -1
  36. package/lib/esm/video.d.ts.map +1 -1
  37. package/lib/esm/video.js +102 -1
  38. package/lib/esm/video.js.map +1 -1
  39. package/lib/esm/video.native.d.ts +6 -2
  40. package/lib/esm/video.native.d.ts.map +1 -1
  41. package/lib/esm/video.native.js +85 -10
  42. package/lib/esm/video.native.js.map +1 -1
  43. package/lib/esm/video_shared.d.ts +18 -2
  44. package/lib/esm/video_shared.d.ts.map +1 -1
  45. package/lib/esm/video_shared.js +89 -1
  46. package/lib/esm/video_shared.js.map +1 -1
  47. package/lib/tsconfig.tsbuildinfo +1 -1
  48. package/package.json +3 -3
  49. package/src/index.native.ts +1 -5
  50. package/src/index.ts +1 -5
  51. package/src/video.native.tsx +103 -4
  52. package/src/video.tsx +108 -4
  53. package/src/video_shared.tsx +140 -2
  54. package/src/hooks.ts +0 -98
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/video-chat",
3
- "version": "1.3.25",
3
+ "version": "1.3.27",
4
4
  "description": "",
5
5
  "main": "./lib/cjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -35,7 +35,7 @@
35
35
  "@mui/icons-material": "^5.0.1",
36
36
  "@mui/material": "^5.0.2",
37
37
  "@tellescope/constants": "^1.3.24",
38
- "@tellescope/react-components": "^1.3.25",
38
+ "@tellescope/react-components": "^1.3.27",
39
39
  "@tellescope/sdk": "^1.3.25",
40
40
  "@tellescope/types-client": "^1.3.24",
41
41
  "@tellescope/types-models": "^1.3.24",
@@ -55,7 +55,7 @@
55
55
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
56
56
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
57
57
  },
58
- "gitHead": "b0763c5db209879f150d7289a2e031740b2fb371",
58
+ "gitHead": "84949695c66af0d03234a569d5cfc900515c7a7b",
59
59
  "publishConfig": {
60
60
  "access": "public"
61
61
  }
@@ -1,10 +1,6 @@
1
1
  export * from "./video"
2
- export * from "./hooks"
3
2
  export * from "./controls"
4
- export {
5
- CurrentCallContext,
6
- useCurrentCallContext,
7
- } from "./video_shared"
3
+ export * from "./video_shared"
8
4
  export {
9
5
  RNVideoRenderView,
10
6
  } from "./native/RNVideoRenderView"
package/src/index.ts CHANGED
@@ -1,7 +1,3 @@
1
1
  export * from "./video"
2
2
  export * from "./controls"
3
- export * from "./hooks"
4
- export {
5
- CurrentCallContext,
6
- useCurrentCallContext,
7
- } from "./video_shared"
3
+ export * from "./video_shared"
@@ -19,6 +19,7 @@ import {
19
19
  useResolvedSession,
20
20
  useSession,
21
21
  Flex,
22
+ useCalendarEvents,
22
23
  } from "@tellescope/react-components"
23
24
  import {
24
25
  Button,
@@ -32,6 +33,7 @@ import {
32
33
  VideoProps,
33
34
  AttendeeDisplayInfo,
34
35
  VideoViewProps,
36
+ VideoCallNativeProps,
35
37
  } from "./video_shared"
36
38
  import {
37
39
  CurrentCallContext,
@@ -39,7 +41,10 @@ import {
39
41
  getSDKEventEmitter,
40
42
  MobileSDKEvent,
41
43
  NativeFunction,
44
+ ControlBar,
42
45
  } from "./index.native"
46
+ import { borderColor, borderRadius } from "@mui/system"
47
+ // import RNSwitchAudioOutput from 'react-native-switch-audio-output';
43
48
 
44
49
  interface TileState {
45
50
  isLocal: boolean,
@@ -236,20 +241,52 @@ export const useStartVideoCall = (): StartVideoCallReturnType => {
236
241
  }
237
242
  }
238
243
 
244
+ export const useStartAndJoinMeetingForCalendarEvent = (calendarEventId: string) => {
245
+ const session = useSession()
246
+ const [, { updateLocalElement: updateLocalEvent }] = useCalendarEvents()
247
+
248
+ const { setMeeting, setIsHost } = useContext(CurrentCallContext)
249
+ if (!(!!setMeeting && setIsHost)) {
250
+ throw new Error("Missing CurrentCallContext")
251
+ }
252
+
253
+ const startAndJoinMeeting = useCallback(async () => {
254
+ const { meeting, host, id } = await session.api.meetings.start_meeting_for_event({ calendarEventId })
255
+
256
+ updateLocalEvent(calendarEventId, { meetingId: id } )
257
+
258
+ NativeFunction.startMeeting(meeting.Meeting, host.info)
259
+
260
+ setMeeting(meeting.Meeting)
261
+ setIsHost(true)
262
+ }, [session, setMeeting, setIsHost, updateLocalEvent])
263
+
264
+ return {
265
+ startAndJoinMeeting,
266
+ }
267
+ }
268
+
239
269
  export const useJoinVideoCall = (): JoinVideoCallReturnType => {
240
270
  const session = useResolvedSession()
241
- const { meeting, setMeeting, videoIsEnabled, toggleVideo } = React.useContext(CurrentCallContext)
271
+ const { meeting, setIsHost, setMeeting, videoIsEnabled, toggleVideo } = React.useContext(CurrentCallContext)
242
272
 
243
- const joinMeeting = async (meetingInfo: string | { Meeting: MeetingInfo }, attendeeInfo: { Attendee: AttendeeInfo }) => {
273
+ const joinMeeting = async (meetingInfo: string | { Meeting: MeetingInfo }, attendeeInfo?: { Attendee: AttendeeInfo }) => {
244
274
  if (typeof meetingInfo == 'string') {
245
275
  const meetings = await session.api.meetings.my_meetings()
246
276
  const meeting = meetings.find(m => m.id === meetingInfo)
247
277
  meetingInfo = meeting?.meetingInfo as { Meeting: MeetingInfo }
248
278
  attendeeInfo = { Attendee: meeting?.attendees.find?.(a => a.id === session.userInfo.id)?.info as AttendeeInfo}
279
+
280
+ if (attendeeInfo.Attendee.ExternalUserId === meeting?.creator) {
281
+ setIsHost(true)
282
+ }
249
283
  }
284
+
250
285
  if (!meetingInfo || typeof meetingInfo === 'string' || !attendeeInfo) return
251
286
 
252
- NativeFunction.startMeeting(meetingInfo.Meeting ?? meetingInfo, attendeeInfo)
287
+ NativeFunction.startMeeting(meetingInfo.Meeting ?? meetingInfo, attendeeInfo.Attendee ?? attendeeInfo)
288
+
289
+ setMeeting(meetingInfo.Meeting)
253
290
  }
254
291
 
255
292
  const leaveMeeting = () => setMeeting(undefined)
@@ -371,5 +408,67 @@ const styles = StyleSheet.create({
371
408
  });
372
409
 
373
410
  export const LocalPreview = () => {
374
- throw new Error("Unimplemented")
411
+ // console.error("LocalPreview unimplemented for Native")
412
+ return null
413
+ }
414
+
415
+ const get_video_styles = (count: number): React.CSSProperties => {
416
+ return ({
417
+ borderWidth: '1px',
418
+ borderColor: '#888888',
419
+ borderRadius: 5,
420
+ padding: 5,
421
+ width: count === 1 ? '100%' : '50%',
422
+ maxHeight: (
423
+ count <= 4
424
+ ? '50%'
425
+ : count <= 8
426
+ ? '25%'
427
+ : '20%'
428
+ ),
429
+ backgroundColor: '#bbbbbb'
430
+ })
431
+ }
432
+ export const VideoCallNative: React.JSXElementConstructor<VideoCallNativeProps> = ({
433
+ ...props
434
+ }) => {
435
+ const remoteViews = useRemoteViews()
436
+ // RNSwitchAudioOutput.selectAudioOutput(RNSwitchAudioOutput.AUDIO_SPEAKER)
437
+ const selfView = (
438
+ <SelfView
439
+ // style={{
440
+ // position: 'absolute',
441
+ // zIndex: '100',
442
+ // borderRadius: 100,
443
+ // width: 130,
444
+ // height: 130,
445
+ // bottom: 120,
446
+ // right: 25
447
+ // }}
448
+ />
449
+ )
450
+
451
+ const style = get_video_styles(remoteViews.length + 1)
452
+
453
+ return (
454
+ <Flex column flex={1} style={{ }}>
455
+ <Flex flex={1} style={{ marginBottom: 75 }}>
456
+
457
+ {remoteViews.map((view, i) => (
458
+ <Flex key={i} alignItems="center" justifyContent="center" style={style}>
459
+ {view}
460
+ </Flex>
461
+ ))}
462
+
463
+ <Flex alignItems="center" justifyContent="center" style={style}>
464
+ {selfView}
465
+ </Flex>
466
+
467
+ </Flex>
468
+
469
+ <ControlBar {...props}
470
+ style={{ position: 'absolute', bottom: 20, width: '100%' }}
471
+ />
472
+ </Flex>
473
+ )
375
474
  }
package/src/video.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useState, CSSProperties, Children, useEffect } from "react"
1
+ import React, { useCallback, useContext, useState, useEffect } from "react"
2
2
 
3
3
  import {
4
4
  useResolvedSession,
@@ -11,6 +11,7 @@ import {
11
11
  } from "@tellescope/types-utilities"
12
12
  import {
13
13
  AttendeeInfo,
14
+ Meeting,
14
15
  MeetingInfo,
15
16
  } from '@tellescope/types-models'
16
17
 
@@ -39,7 +40,8 @@ import {
39
40
  // useContentShareControls, // screen sharing
40
41
  } from 'amazon-chime-sdk-component-library-react';
41
42
  import {
42
- CurrentCallContext,
43
+ CurrentCallContext,
44
+ VideoCallNativeProps,
43
45
  } from "./index"
44
46
  import {
45
47
  AttendeeDisplayInfo,
@@ -51,6 +53,103 @@ import {
51
53
  } from "./video_shared"
52
54
  import { ConsoleLogger, DefaultDeviceController, Logger, LogLevel } from "amazon-chime-sdk-js";
53
55
 
56
+ import { useCalendarEvents } from "@tellescope/react-components"
57
+ import { useCurrentCallContext } from "./index"
58
+ import { CalendarEvent } from "@tellescope/types-client";
59
+
60
+ export const useMeetingForCalendarEvent = (event: CalendarEvent) => {
61
+ const { meeting } = useCurrentCallContext()
62
+ const { startAndJoinMeeting } = useStartAndJoinMeetingForCalendarEvent(event.id)
63
+ const { joinMeeting } = useJoinMeeting()
64
+
65
+ return {
66
+ startAndJoinMeeting,
67
+ joinMeeting,
68
+ meeting,
69
+ meetingStatus: (
70
+ !event.enableVideoCall
71
+ ? 'disabled'
72
+ : !(event.meetingId)
73
+ ? 'waiting-room'
74
+ : !!meeting
75
+ ? 'joined'
76
+ : 'loading'
77
+
78
+ )
79
+ }
80
+ }
81
+
82
+ export const useStartAndJoinMeetingForCalendarEvent = (calendarEventId: string) => {
83
+ const session = useSession()
84
+ const [, { updateLocalElement: updateLocalEvent }] = useCalendarEvents()
85
+
86
+ const meetingManager = useMeetingManager();
87
+
88
+ const { setMeeting, setIsHost } = useContext(CurrentCallContext)
89
+ if (!(!!setMeeting && setIsHost)) {
90
+ throw new Error("Missing CurrentCallContext")
91
+ }
92
+
93
+ const startAndJoinMeeting = useCallback(async () => {
94
+ const { meeting, host, id } = await session.api.meetings.start_meeting_for_event({ calendarEventId })
95
+
96
+ updateLocalEvent(calendarEventId, { meetingId: id } )
97
+
98
+ setMeeting(meeting as any)
99
+
100
+ await meetingManager.join({ meetingInfo: meeting, attendeeInfo: host.info }); // Use the join API to create a meeting session
101
+ await meetingManager.start(); // At this point you can let users setup their devices, or start the session immediately
102
+
103
+ setMeeting(meeting.Meeting)
104
+ setIsHost(true)
105
+ }, [session, calendarEventId, updateLocalEvent, meetingManager, setMeeting, setIsHost])
106
+
107
+ return {
108
+ startAndJoinMeeting,
109
+ }
110
+ }
111
+
112
+ export const useJoinMeeting = () => {
113
+ const session = useResolvedSession()
114
+ const meetingManager = useMeetingManager();
115
+
116
+ const { setMeeting, setIsHost } = useContext(CurrentCallContext)
117
+ if (!(!!setMeeting && setIsHost)) {
118
+ throw new Error("Missing CurrentCallContext")
119
+ }
120
+
121
+ const joinMeeting = useCallback(async (meeting: Meeting) => {
122
+ setMeeting(meeting.meetingInfo.Meeting)
123
+ setIsHost(meeting.creator === session.userInfo.id)
124
+
125
+ let attendeeInfo = meeting.attendees.find(a => a.id === session.userInfo.id)?.info
126
+ if (!attendeeInfo) {
127
+ const calendarEventId = meeting.calendarEventId
128
+ if (calendarEventId) {
129
+ const result = await session.api.meetings.join_meeting_for_event({ calendarEventId })
130
+
131
+ attendeeInfo = result.attendee.info
132
+ }
133
+
134
+ if (!attendeeInfo) {
135
+ console.error("Could not find attendee info for joining meeting and failed to join")
136
+ return
137
+ }
138
+ }
139
+
140
+ await meetingManager.join({
141
+ meetingInfo: meeting.meetingInfo,
142
+ attendeeInfo,
143
+ }); // Use the join API to create a meeting session
144
+ await meetingManager.start(); // At this point you can let users setup their devices, or start the session immediately
145
+
146
+ }, [setMeeting, meetingManager, setMeeting, setIsHost])
147
+
148
+ return {
149
+ joinMeeting,
150
+ }
151
+ }
152
+
54
153
  const WithContext = ({ children } : { children: React.ReactNode }) => {
55
154
  const [meeting, setMeeting] = useState(undefined as MeetingInfo | undefined)
56
155
  const [isHost, setIsHost] = useState(false)
@@ -150,7 +249,7 @@ export const useJoinVideoCall = (props?: JoinVideoCallProps): JoinVideoCallRetur
150
249
  const status = useMeetingStatus()
151
250
 
152
251
  // meetingInfo may be meetingId as string
153
- const joinMeeting = async (meetingInfo: string | { Meeting: MeetingInfo }, attendeeInfo: { Attendee: AttendeeInfo }) => {
252
+ const joinMeeting = async (meetingInfo: string | { Meeting: MeetingInfo }, attendeeInfo?: { Attendee: AttendeeInfo }) => {
154
253
  if (typeof meetingInfo == 'string') {
155
254
  const meetings = await session.api.meetings.my_meetings()
156
255
  const meeting = meetings.find(m => m.id === meetingInfo)
@@ -264,4 +363,9 @@ export const LocalPreview = ({ style=defaultPreviewStyle }: Styled) => {
264
363
 
265
364
  return <video id={PREVIEW_ELEMENT_ID} style={style}/>
266
365
  }
267
- export { VideoTileGrid }
366
+ export { VideoTileGrid }
367
+
368
+ // unimplemented for web
369
+ export const VideoCallNative: React.JSXElementConstructor<VideoCallNativeProps> = () => (
370
+ null
371
+ )
@@ -1,14 +1,34 @@
1
- import React, { CSSProperties } from "react"
1
+ import React, { CSSProperties, useCallback, useEffect, useState } from "react"
2
2
 
3
3
  import {
4
4
  AttendeeInfo,
5
5
  MeetingInfo,
6
6
  } from '@tellescope/types-models'
7
+ import {
8
+ CalendarEvent,
9
+ Enduser,
10
+ User,
11
+ } from '@tellescope/types-client'
7
12
 
8
13
  import {
14
+ APIError,
9
15
  UserIdentity,
10
16
  } from '@tellescope/types-utilities'
11
17
 
18
+ import {
19
+ UserAndEnduserSelectorProps,
20
+ useMeetings,
21
+ UserAndEnduserSelector,
22
+ useCalendarEvents,
23
+ Flex,
24
+ Typography,
25
+ LoadingButton,
26
+ useSession,
27
+ useResolvedSession,
28
+ Button,
29
+ } from "@tellescope/react-components"
30
+ import { LocalPreview, useJoinVideoCall, useStartAndJoinMeetingForCalendarEvent } from "./video"
31
+
12
32
  export type AttendeeDisplayInfo = { attendeeId: string, externalUserId: string }
13
33
  export interface CallContext {
14
34
  meeting: MeetingInfo | undefined, setMeeting: (m: MeetingInfo | undefined) => void,
@@ -43,7 +63,7 @@ export interface JoinVideoCallReturnType {
43
63
  videoIsEnabled: CallContext['videoIsEnabled'],
44
64
  toggleVideo: CallContext['toggleVideo'],
45
65
  leaveMeeting: () => void,
46
- joinMeeting: (meetingInfo: { Meeting: MeetingInfo } | string, attendeeInfo: { Attendee: AttendeeInfo }) => Promise<void>,
66
+ joinMeeting: (meetingInfo: { Meeting: MeetingInfo } | string, attendeeInfo?: { Attendee: AttendeeInfo }) => Promise<void>,
47
67
  }
48
68
 
49
69
  export interface StartVideoCallReturnType {
@@ -55,4 +75,122 @@ export interface StartVideoCallReturnType {
55
75
  createAndStartMeeting: (initialAttendees?: UserIdentity[]) => Promise<string>,
56
76
  addAttendees: (attendees: UserIdentity[]) => Promise<void>,
57
77
  endMeeting: () => Promise<void>,
78
+ }
79
+
80
+ export interface CreateCalendarEventForAttendeesProps extends Omit<UserAndEnduserSelectorProps, 'onSelect'> {
81
+ onSuccess?: (c: CalendarEvent) => void,
82
+ onError?: (e: APIError) => void,
83
+ eventProps?: Pick<CalendarEvent, 'startTimeInMS' | 'durationInMinutes' | 'title'>
84
+ }
85
+ export const CreateCalendarEventForAttendees = ({
86
+ onSuccess,
87
+ onError,
88
+ eventProps,
89
+ ...props
90
+ } : CreateCalendarEventForAttendeesProps) => {
91
+ const [, { createElement: createEvent }] = useCalendarEvents({ dontFetch: true })
92
+ const [eventTitle, /*setEventTitle*/] = useState(eventProps?.title ?? 'Video Call')
93
+ const session = useResolvedSession()
94
+
95
+ const handleCreateRoom = useCallback(({ users, endusers }: { users: User[], endusers: Enduser[] }) => {
96
+ const userIds = users.map(u => u.id)
97
+ const enduserIds = endusers.map(e => e.id)
98
+
99
+ createEvent({
100
+ title: eventTitle,
101
+ attendees: ([
102
+ ...userIds.map(id => ({ type: 'user', id } as UserIdentity)),
103
+ ...enduserIds.map(id => ({ type: 'enduser', id } as UserIdentity)),
104
+ ]),
105
+ startTimeInMS: eventProps?.startTimeInMS ?? Date.now(),
106
+ durationInMinutes: eventProps?.durationInMinutes || 30,
107
+ enableVideoCall: true,
108
+ })
109
+ .then(r => {
110
+ onSuccess?.(r)
111
+ })
112
+ .catch(onError)
113
+ }, [session, onSuccess, onError])
114
+
115
+ return (
116
+ <UserAndEnduserSelector {...props} onSelect={handleCreateRoom} />
117
+ )
118
+ }
119
+
120
+ export type WaitingRoomProps = {
121
+ calendarEvent: CalendarEvent,
122
+ onGoBack?: () => void,
123
+ }
124
+ export const WaitingRoom = ({ calendarEvent, onGoBack } : WaitingRoomProps) => {
125
+ const session = useSession()
126
+ const [, { findById: findEvent }] = useCalendarEvents()
127
+ const [, { findById: findMeeting }] = useMeetings()
128
+ const { startAndJoinMeeting } = useStartAndJoinMeetingForCalendarEvent(calendarEvent.id)
129
+ const { joinMeeting } = useJoinVideoCall()
130
+
131
+ const tsMeeting = findMeeting(calendarEvent?.meetingId ?? '')
132
+
133
+ // poll to check for started meeting
134
+ useEffect(() => {
135
+ const t = setInterval(() => {
136
+ const event = findEvent(calendarEvent.id, { reload: true })
137
+ findMeeting(event?.meetingId ?? '', { reload: true }) // reloads tsMeeting
138
+ }, 2500)
139
+
140
+ return () => { clearInterval(t) }
141
+ }, [calendarEvent, findMeeting, findEvent])
142
+
143
+ const meetingIsStarted = tsMeeting?.status === 'live'
144
+ const isHost = session.userInfo.id === calendarEvent?.creator
145
+
146
+ return (
147
+ <Flex flex={1} column alignItems="center" justifyContent="center">
148
+ <Typography style={{ fontSize: 20, fontWeight: 'bold' }}>
149
+ {calendarEvent.title}
150
+ </Typography>
151
+
152
+ <Typography style={{ marginBottom: 15 }}>
153
+ Waiting Room
154
+ </Typography>
155
+
156
+ <LocalPreview />
157
+
158
+ <LoadingButton variant="contained"
159
+ disabled={
160
+ (!meetingIsStarted && !isHost)
161
+ || (meetingIsStarted && !tsMeeting)
162
+ }
163
+ onClick={
164
+ meetingIsStarted
165
+ ? () => joinMeeting(tsMeeting.id)
166
+ : startAndJoinMeeting
167
+ }
168
+ submitText={
169
+ meetingIsStarted ? "Join Meeting" : "Start Meeting"
170
+ }
171
+ submittingText={
172
+ meetingIsStarted ? "Joining" : "Starting"
173
+ }
174
+ style={{
175
+ marginTop: 15,
176
+ }}
177
+ />
178
+
179
+ {onGoBack &&
180
+ <Button onClick={onGoBack} style={{ width: '100%' }}>
181
+ Back
182
+ </Button>
183
+ }
184
+
185
+ {!meetingIsStarted && !isHost &&
186
+ <Typography style={{ marginTop: 5 }}>
187
+ Waiting for the host to start the meeting
188
+ </Typography>
189
+ }
190
+ </Flex>
191
+ )
192
+ }
193
+
194
+ export interface VideoCallNativeProps {
195
+ onLeave?: () => void,
58
196
  }
package/src/hooks.ts DELETED
@@ -1,98 +0,0 @@
1
- import { useCallback, useContext } from "react"
2
- import { useCalendarEvents, useResolvedSession, useSession } from "@tellescope/react-components"
3
- import { useMeetingManager } from "amazon-chime-sdk-component-library-react"
4
- import { CurrentCallContext, useCurrentCallContext } from "./index"
5
- import { CalendarEvent, Meeting } from "@tellescope/types-client"
6
-
7
- export const useStartAndJoinMeetingForCalendarEvent = (calendarEventId: string) => {
8
- const session = useSession()
9
- const [, { updateLocalElement: updateLocalEvent }] = useCalendarEvents()
10
-
11
- const meetingManager = useMeetingManager();
12
-
13
- const { setMeeting, setIsHost } = useContext(CurrentCallContext)
14
- if (!(!!setMeeting && setIsHost)) {
15
- throw new Error("Missing CurrentCallContext")
16
- }
17
-
18
- const startAndJoinMeeting = useCallback(async () => {
19
- const { meeting, host, id } = await session.api.meetings.start_meeting_for_event({ calendarEventId })
20
-
21
- updateLocalEvent(calendarEventId, { meetingId: id } )
22
-
23
- setMeeting(meeting as any)
24
-
25
- await meetingManager.join({ meetingInfo: meeting, attendeeInfo: host.info }); // Use the join API to create a meeting session
26
- await meetingManager.start(); // At this point you can let users setup their devices, or start the session immediately
27
-
28
- setMeeting(meeting.Meeting)
29
- setIsHost(true)
30
- }, [session, calendarEventId, updateLocalEvent, meetingManager, setMeeting, setIsHost])
31
-
32
- return {
33
- startAndJoinMeeting,
34
- }
35
- }
36
-
37
- export const useJoinMeeting = () => {
38
- const session = useResolvedSession()
39
- const meetingManager = useMeetingManager();
40
-
41
- const { setMeeting, setIsHost } = useContext(CurrentCallContext)
42
- if (!(!!setMeeting && setIsHost)) {
43
- throw new Error("Missing CurrentCallContext")
44
- }
45
-
46
- const joinMeeting = useCallback(async (meeting: Meeting) => {
47
- setMeeting(meeting.meetingInfo.Meeting)
48
- setIsHost(meeting.creator === session.userInfo.id)
49
-
50
- let attendeeInfo = meeting.attendees.find(a => a.id === session.userInfo.id)?.info
51
- if (!attendeeInfo) {
52
- const calendarEventId = meeting.calendarEventId
53
- if (calendarEventId) {
54
- const result = await session.api.meetings.join_meeting_for_event({ calendarEventId })
55
-
56
- attendeeInfo = result.attendee.info
57
- }
58
-
59
- if (!attendeeInfo) {
60
- console.error("Could not find attendee info for joining meeting and failed to join")
61
- return
62
- }
63
- }
64
-
65
- await meetingManager.join({
66
- meetingInfo: meeting.meetingInfo,
67
- attendeeInfo,
68
- }); // Use the join API to create a meeting session
69
- await meetingManager.start(); // At this point you can let users setup their devices, or start the session immediately
70
-
71
- }, [setMeeting, meetingManager, setMeeting, setIsHost])
72
-
73
- return {
74
- joinMeeting,
75
- }
76
- }
77
-
78
- export const useMeetingForCalendarEvent = (event: CalendarEvent) => {
79
- const { meeting } = useCurrentCallContext()
80
- const { startAndJoinMeeting } = useStartAndJoinMeetingForCalendarEvent(event.id)
81
- const { joinMeeting } = useJoinMeeting()
82
-
83
- return {
84
- startAndJoinMeeting,
85
- joinMeeting,
86
- meeting,
87
- meetingStatus: (
88
- !event.enableVideoCall
89
- ? 'disabled'
90
- : !(event.meetingId)
91
- ? 'waiting-room'
92
- : !!meeting
93
- ? 'joined'
94
- : 'loading'
95
-
96
- )
97
- }
98
- }