@tellescope/video-chat 0.0.12 → 0.0.16

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 (77) hide show
  1. package/lib/cjs/controls.d.ts +3 -0
  2. package/lib/cjs/controls.d.ts.map +1 -0
  3. package/lib/cjs/controls.js +23 -0
  4. package/lib/cjs/controls.js.map +1 -0
  5. package/lib/cjs/index.d.ts +1 -0
  6. package/lib/cjs/index.d.ts.map +1 -1
  7. package/lib/cjs/index.js +1 -0
  8. package/lib/cjs/index.js.map +1 -1
  9. package/lib/cjs/index.native.d.ts +1 -0
  10. package/lib/cjs/index.native.d.ts.map +1 -1
  11. package/lib/cjs/index.native.js +1 -0
  12. package/lib/cjs/index.native.js.map +1 -1
  13. package/lib/cjs/native/RNVideoRenderView.d.ts +11 -0
  14. package/lib/cjs/native/RNVideoRenderView.d.ts.map +1 -0
  15. package/lib/cjs/native/RNVideoRenderView.js +62 -0
  16. package/lib/cjs/native/RNVideoRenderView.js.map +1 -0
  17. package/lib/cjs/native/bridge.d.ts +36 -0
  18. package/lib/cjs/native/bridge.d.ts.map +1 -0
  19. package/lib/cjs/native/bridge.js +59 -0
  20. package/lib/cjs/native/bridge.js.map +1 -0
  21. package/lib/cjs/video.d.ts +11 -3
  22. package/lib/cjs/video.d.ts.map +1 -1
  23. package/lib/cjs/video.js +32 -5
  24. package/lib/cjs/video.js.map +1 -1
  25. package/lib/cjs/video.native.d.ts +6 -1
  26. package/lib/cjs/video.native.d.ts.map +1 -1
  27. package/lib/cjs/video.native.js +78 -33
  28. package/lib/cjs/video.native.js.map +1 -1
  29. package/lib/esm/components.d.ts +1 -0
  30. package/lib/esm/components.d.ts.map +1 -0
  31. package/lib/esm/components.js +3 -0
  32. package/lib/esm/components.js.map +1 -0
  33. package/lib/esm/controls.d.ts +3 -0
  34. package/lib/esm/controls.d.ts.map +1 -0
  35. package/lib/esm/controls.js +15 -0
  36. package/lib/esm/controls.js.map +1 -0
  37. package/lib/esm/index.d.ts +1 -0
  38. package/lib/esm/index.d.ts.map +1 -1
  39. package/lib/esm/index.js +1 -0
  40. package/lib/esm/index.js.map +1 -1
  41. package/lib/esm/index.native.d.ts +1 -0
  42. package/lib/esm/index.native.d.ts.map +1 -1
  43. package/lib/esm/index.native.js +1 -0
  44. package/lib/esm/index.native.js.map +1 -1
  45. package/lib/esm/native/RNVideoRenderView.d.ts +11 -0
  46. package/lib/esm/native/RNVideoRenderView.d.ts.map +1 -0
  47. package/lib/esm/native/RNVideoRenderView.js +56 -0
  48. package/lib/esm/native/RNVideoRenderView.js.map +1 -0
  49. package/lib/esm/native/bridge.d.ts +36 -0
  50. package/lib/esm/native/bridge.d.ts.map +1 -0
  51. package/lib/esm/native/bridge.js +55 -0
  52. package/lib/esm/native/bridge.js.map +1 -0
  53. package/lib/esm/video.d.ts +11 -3
  54. package/lib/esm/video.d.ts.map +1 -1
  55. package/lib/esm/video.js +30 -6
  56. package/lib/esm/video.js.map +1 -1
  57. package/lib/esm/video.native.d.ts +6 -1
  58. package/lib/esm/video.native.d.ts.map +1 -1
  59. package/lib/esm/video.native.js +77 -34
  60. package/lib/esm/video.native.js.map +1 -1
  61. package/lib/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +10 -10
  63. package/src/controls.tsx +33 -0
  64. package/src/index.native.ts +2 -1
  65. package/src/index.ts +2 -1
  66. package/src/native/RNVideoRenderView.tsx +31 -0
  67. package/src/native/bridge.ts +60 -0
  68. package/src/video.native.tsx +113 -52
  69. package/src/video.tsx +39 -14
  70. package/lib/cjs/chat.d.ts +0 -69
  71. package/lib/cjs/chat.d.ts.map +0 -1
  72. package/lib/cjs/chat.js +0 -171
  73. package/lib/cjs/chat.js.map +0 -1
  74. package/lib/esm/chat.d.ts +0 -69
  75. package/lib/esm/chat.d.ts.map +0 -1
  76. package/lib/esm/chat.js +0 -160
  77. package/lib/esm/chat.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/video-chat",
3
- "version": "0.0.12",
3
+ "version": "0.0.16",
4
4
  "description": "",
5
5
  "main": "./lib/cjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -33,17 +33,17 @@
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.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",
36
+ "@tellescope/constants": "^0.0.16",
37
+ "@tellescope/react-components": "^0.0.16",
38
+ "@tellescope/sdk": "^0.0.16",
39
+ "@tellescope/types-client": "^0.0.16",
40
+ "@tellescope/types-models": "^0.0.16",
41
+ "@tellescope/types-utilities": "^0.0.16",
42
+ "@tellescope/utilities": "^0.0.16",
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",
46
- "amazon-chime-sdk-js": "^2.23.0",
46
+ "amazon-chime-sdk-js": "^2.24.0",
47
47
  "eslint": "^7.32.0",
48
48
  "eslint-plugin-react": "^7.26.1",
49
49
  "nodemon": "^2.0.13",
@@ -54,7 +54,7 @@
54
54
  "react": "^17.0.2",
55
55
  "react-dom": "^17.0.2"
56
56
  },
57
- "gitHead": "5d67de4721a3cbc3537a870281f2c657099e07b4",
57
+ "gitHead": "06e581f4d3a6c5b57fd0cfcc22103b94125f9da4",
58
58
  "publishConfig": {
59
59
  "access": "public"
60
60
  }
@@ -0,0 +1,33 @@
1
+ // components that work with web or native
2
+ import React from "react"
3
+
4
+ import {
5
+ VideoIcon,
6
+ VideoOffIcon,
7
+ MicrophoneIcon,
8
+ MicrophoneOffIcon,
9
+ } from "@tellescope/react-components/lib/esm/mui"
10
+ import { LabeledIconButton } from "@tellescope/react-components/lib/esm/controls"
11
+ import {
12
+ CurrentCallContext,
13
+ } from "./video"
14
+
15
+ export const VideoToggle = () => {
16
+ const { toggleVideo, videoIsEnabled } = React.useContext(CurrentCallContext)
17
+
18
+ return (
19
+ <LabeledIconButton Icon={videoIsEnabled ? VideoIcon : VideoOffIcon} onClick={toggleVideo}
20
+ label={videoIsEnabled ? "Turn Camera Off" : "Turn Camera On"}
21
+ />
22
+ )
23
+ }
24
+
25
+ export const MicrophoneToggle = () => {
26
+ const { microphoneIsEnabled, toggleMicrophone } = React.useContext(CurrentCallContext)
27
+
28
+ return (
29
+ <LabeledIconButton Icon={microphoneIsEnabled ? MicrophoneIcon : MicrophoneOffIcon} onClick={toggleMicrophone}
30
+ label={microphoneIsEnabled ? "Turn Microphone Off" : "Turn Microphone On"}
31
+ />
32
+ )
33
+ }
@@ -1 +1,2 @@
1
- export * from "./video"
1
+ export * from "./video"
2
+ export * from "./controls"
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
- export * from "./video";
1
+ export * from "./video";
2
+ export * from "./controls"
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: MIT-0
4
+ */
5
+
6
+ import PropTypes from 'prop-types';
7
+ import React from 'react';
8
+ import { requireNativeComponent, findNodeHandle, ViewStyle } from 'react-native';
9
+ import { NativeFunction } from './bridge';
10
+
11
+ export class RNVideoView extends React.Component<{ tileId: number, style?: ViewStyle }> {
12
+ componentDidMount() {
13
+ // we need to delay the bind video
14
+ // Because "componentDidMount" will be called "immediately after the initial rendering occurs"
15
+ // This is *before* RCTUIManager add this view to register (so that viewForReactTag() can return a view)
16
+ // So we need to dispatch bindVideoView after this function complete
17
+ setTimeout(() => {
18
+ NativeFunction.bindVideoView(findNodeHandle(this), this.props.tileId);
19
+ });
20
+ }
21
+
22
+ componentWillUnmount() {
23
+ NativeFunction.unbindVideoView(this.props.tileId);
24
+ }
25
+
26
+ render() {
27
+ return <RNVideoRenderViewNative {...this.props} />;
28
+ }
29
+ }
30
+
31
+ const RNVideoRenderViewNative = requireNativeComponent('RNVideoView');
@@ -0,0 +1,60 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: MIT-0
4
+ */
5
+
6
+ import { NativeModules, NativeEventEmitter } from 'react-native';
7
+
8
+ /**
9
+ * These are the function that will be called from native side
10
+ * i.e. Native -> React Native
11
+ *
12
+ * NativeEventEmitter.onMeetingStart(meetingName)
13
+ * NativeEventEmitter.onMeetingEnd()
14
+ * NativeEventEmitter.onAttendeesJoin(attendeeInfo)
15
+ * NativeEventEmitter.onAttendeesLeave(attendeeInfo)
16
+ * NativeEventEmitter.onAddVideoTile(tileState)
17
+ * NativeEventEmitter.onRemoveVideoTile(tileState)
18
+ * NativeEventEmitter.onError(errorMessage)
19
+ */
20
+ const _eventEmitter = new NativeEventEmitter(NativeModules.NativeMobileSDKBridge);
21
+
22
+ export const MobileSDKEvent = {
23
+ OnMeetingStart: 'OnMeetingStart',
24
+ OnMeetingEnd: 'OnMeetingEnd',
25
+ OnAttendeesJoin: 'OnAttendeesJoin',
26
+ OnAttendeesLeave: 'OnAttendeesLeave',
27
+ OnAttendeesMute: 'OnAttendeesMute',
28
+ OnAttendeesUnmute: 'OnAttendeesUnmute',
29
+ OnAddVideoTile: 'OnAddVideoTile',
30
+ OnRemoveVideoTile: 'OnRemoveVideoTile',
31
+ OnError: 'OnError',
32
+ }
33
+
34
+ export const MeetingError = {
35
+ OnMaximumConcurrentVideoReached: "OnMaximumConcurrentVideoReached"
36
+ }
37
+
38
+ export function getSDKEventEmitter() {
39
+ return _eventEmitter;
40
+ }
41
+
42
+ /**
43
+ * These are functions available for React native to call on native
44
+ * i.e. React Native -> Native
45
+ *
46
+ * NativeModules.NativeMobileSDKBridge.startMeeting(meetingId, userName)
47
+ * NativeModules.NativeMobileSDKBridge.stopMeeting()
48
+ * NativeModules.NativeMobileSDKBridge.setMute(isMute) -> boolean
49
+ * NativeModules.NativeMobileSDKBridge.setCameraOn(isOn) -> boolean
50
+ * NativeModules.NativeMobileSDKBridge.bindVideoView(reactTagId, tileId)
51
+ * NativeModules.NativeMobileSDKBridge.unbindVideoView(reactTagId, tileId)
52
+ */
53
+ export const NativeFunction = {
54
+ startMeeting: NativeModules.NativeMobileSDKBridge.startMeeting,
55
+ stopMeeting: NativeModules.NativeMobileSDKBridge.stopMeeting,
56
+ setMute: NativeModules.NativeMobileSDKBridge.setMute,
57
+ setCameraOn: NativeModules.NativeMobileSDKBridge.setCameraOn,
58
+ bindVideoView: NativeModules.NativeMobileSDKBridge.bindVideoView,
59
+ unbindVideoView: NativeModules.NativeMobileSDKBridge.unbindVideoView,
60
+ }
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import React, { useCallback, useContext, useEffect, useState } from "react"
10
- import { View, Text, StyleSheet } from "react-native"
10
+ import { View, StyleSheet } from "react-native"
11
11
  import {
12
12
  AttendeeInfo,
13
13
  MeetingInfo,
@@ -16,14 +16,25 @@ import {
16
16
  UserIdentity,
17
17
  } from '@tellescope/types-utilities'
18
18
  import { useSession } from "@tellescope/react-components/lib/esm/authentication"
19
- import { Button } from "@tellescope/react-components/lib/esm/mui"
19
+ import { Flex } from "@tellescope/react-components/lib/esm/layout"
20
+ import {
21
+ Button,
22
+ Typography,
23
+ convert_CSS_to_RNStyles,
24
+
25
+ VideoIcon,
26
+ VideoOffIcon,
27
+ MicrophoneIcon,
28
+ MicrophoneOffIcon,
29
+ } from "@tellescope/react-components/lib/esm/mui.native"
20
30
 
21
31
  import {
22
32
  CurrentCallContext,
23
33
  JoinVideoCallReturnType,
24
34
  StartVideoCallReturnType,
25
35
  VideoProps,
26
- AttendeeDisplayInfo
36
+ AttendeeDisplayInfo,
37
+ VideoViewProps,
27
38
  } from "./video.js"
28
39
 
29
40
  import {
@@ -33,17 +44,32 @@ import {
33
44
  } from "./native/bridge"
34
45
  import { RNVideoView } from "./native/RNVideoRenderView"
35
46
 
36
- export const WithVideo = ({ children } : VideoProps ) => {
47
+ interface TileState {
48
+ isLocal: boolean,
49
+ isScreenShare: boolean,
50
+ tileId: number,
51
+ }
52
+
53
+ export const WithVideo = ({ children } : VideoProps) => {
37
54
  const [meeting, setMeeting] = useState(undefined as MeetingInfo | undefined)
38
55
 
39
56
  const [inMeeting, setInMeeting] = useState(false)
40
57
  const [isLoading, setIsLoading] = useState(false)
58
+ const [muted, setMuted] = useState(false)
41
59
  const [videoIsEnabled, setVideoIsEnabled] = useState(false)
42
- const [videoTiles, setVideoTiles] = useState([] as string[])
43
- const [screenShareTile, setScreenShareTile] = useState('')
60
+ const [videoTiles, setVideoTiles] = useState([] as number[])
61
+ const [localTileId, setLocalTileId] = useState(null as number | null)
62
+ const [screenShareTile, setScreenShareTile] = useState(null as number | null)
44
63
  const [attendees, setAttendees] = useState ([] as AttendeeDisplayInfo[])
45
64
 
46
- const toggleVideo = () => NativeFunction.setCameraOn(!videoIsEnabled)
65
+ const toggleVideo = async () => {
66
+ NativeFunction.setCameraOn(!videoIsEnabled)
67
+ setVideoIsEnabled(v => !v)
68
+ }
69
+ const toggleMic = async () => {
70
+ NativeFunction.setMute(!muted)
71
+ setMuted(m => !m)
72
+ }
47
73
  const emitter = getSDKEventEmitter()
48
74
 
49
75
  useEffect(() => {
@@ -52,19 +78,22 @@ export const WithVideo = ({ children } : VideoProps ) => {
52
78
  setIsLoading(false)
53
79
  });
54
80
 
55
- const endSubscription = emitter.addListener(MobileSDKEvent.OnMeetingEnd, () => {
56
- setInMeeting(true)
81
+ // called when user clicks Leave Meeting or meeting is ended by host
82
+ const endSubscription = emitter.addListener(MobileSDKEvent.OnMeetingEnd, a => {
83
+ setInMeeting(false)
57
84
  setIsLoading(false)
58
85
  });
59
86
 
60
- const joinSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesJoin, ({ attendeeId, externalUserId }) => {
87
+ const joinSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesJoin, (added: { attendeeId: string, externalUserId: string }) => {
88
+ const { attendeeId, externalUserId } = added
61
89
  setAttendees(as => !as.find(a => a.attendeeId === attendeeId)
62
90
  ? [{ attendeeId, externalUserId, muted: false }, ...as]
63
91
  : as
64
92
  )
65
93
  });
66
94
 
67
- const leaveSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesLeave, ({ attendeeId }) => {
95
+ const leaveSubscription = emitter.addListener(MobileSDKEvent.OnAttendeesLeave, (leaving: { attendeeId: string }) => {
96
+ const { attendeeId } = leaving
68
97
  setAttendees(as => as.filter(a => a.attendeeId !== attendeeId))
69
98
  });
70
99
 
@@ -80,25 +109,27 @@ export const WithVideo = ({ children } : VideoProps ) => {
80
109
  setAttendees(as => as.map(a => a.attendeeId === attendeeId ? { ...a, muted: false } : a))
81
110
  });
82
111
 
83
- const addVideoSubscription = emitter.addListener(MobileSDKEvent.OnAddVideoTile, (tileState) => {
112
+ const addVideoSubscription = emitter.addListener(MobileSDKEvent.OnAddVideoTile, (tileState: TileState) => {
84
113
  if (tileState.isScreenShare) {
85
114
  setScreenShareTile(tileState.tileId)
86
115
  return
87
116
  }
88
- setVideoTiles(v => [...v, tileState.titleId])
117
+ if (tileState.isLocal) {
118
+ setLocalTileId(tileState.tileId)
119
+ }
120
+ setVideoTiles(v => [...v, tileState.tileId])
89
121
  setVideoIsEnabled(v => tileState.isLocal ? true : v)
90
122
  });
91
123
 
92
- const removeVideoSubscription = emitter.addListener(MobileSDKEvent.OnRemoveVideoTile, (tileState) => {
124
+ const removeVideoSubscription = emitter.addListener(MobileSDKEvent.OnRemoveVideoTile, (tileState: TileState) => {
93
125
  if (tileState.isScreenShare) {
94
- setScreenShareTile('')
126
+ setScreenShareTile(null)
95
127
  return
96
128
  }
97
129
  setVideoTiles(vs => vs.filter(v => v !== tileState.tileId))
98
130
  setVideoIsEnabled(v => tileState.isLocal ? false : v)
99
131
  });
100
132
 
101
-
102
133
  return () => {
103
134
  startSubscription.remove();
104
135
  endSubscription.remove();
@@ -113,12 +144,42 @@ export const WithVideo = ({ children } : VideoProps ) => {
113
144
  }, [emitter])
114
145
 
115
146
  return (
116
- <CurrentCallContext.Provider value={{ attendees, videoTiles, meeting, shareScreenId: screenShareTile, setMeeting, videoIsEnabled, toggleVideo }}>
147
+ <CurrentCallContext.Provider value={{
148
+ attendees,
149
+ localTileId,
150
+ videoTiles,
151
+ meeting,
152
+ shareScreenId: screenShareTile,
153
+ setMeeting,
154
+ videoIsEnabled,
155
+ toggleVideo,
156
+ microphoneIsEnabled: !muted,
157
+ toggleMicrophone: toggleMic,
158
+ }}>
117
159
  {children}
118
160
  </CurrentCallContext.Provider>
119
161
  )
120
162
  }
121
163
 
164
+
165
+ export const useRemoteViews = ({ style } : { style: React.CSSProperties }) => {
166
+ const { localTileId, videoTiles } = React.useContext(CurrentCallContext)
167
+ const nonLocal = videoTiles.filter(v => v !== localTileId)
168
+
169
+ return nonLocal.map(tileId =>
170
+ <RNVideoView style={convert_CSS_to_RNStyles(style) ?? styles.video} tileId={tileId} />
171
+ )
172
+ }
173
+
174
+ export const SelfView = ({ style } : VideoViewProps) => {
175
+ const { localTileId } = React.useContext(CurrentCallContext)
176
+ if (!localTileId) return null
177
+
178
+ return (
179
+ <RNVideoView style={convert_CSS_to_RNStyles(style) ?? styles.video} tileId={localTileId}/>
180
+ )
181
+ }
182
+
122
183
  export const useStartVideoCall = (): StartVideoCallReturnType => {
123
184
  const session = useSession()
124
185
  const { meeting, setMeeting, videoIsEnabled, toggleVideo } = React.useContext(CurrentCallContext)
@@ -162,7 +223,16 @@ export const useStartVideoCall = (): StartVideoCallReturnType => {
162
223
  setMeeting(undefined)
163
224
  }
164
225
 
165
- return { meeting, videoIsEnabled, starting, ending, toggleVideo, createAndStartMeeting, addAttendees, endMeeting }
226
+ return {
227
+ meeting,
228
+ videoIsEnabled,
229
+ starting,
230
+ ending,
231
+ toggleVideo,
232
+ createAndStartMeeting,
233
+ addAttendees,
234
+ endMeeting,
235
+ }
166
236
  }
167
237
 
168
238
  export const useJoinVideoCall = (): JoinVideoCallReturnType => {
@@ -174,66 +244,57 @@ export const useJoinVideoCall = (): JoinVideoCallReturnType => {
174
244
 
175
245
  return { meeting, videoIsEnabled, toggleVideo, joinMeeting }
176
246
  }
177
-
178
247
  export const VideoTileGrid = () => {
179
248
  const {
180
249
  // attendees,
181
- videoIsEnabled,
182
250
  videoTiles,
183
- shareScreenId
251
+ toggleVideo,
184
252
  } = useContext(CurrentCallContext)
185
253
 
186
254
  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}>
255
+ <Flex column justifyContent="space-between" alignItems="center">
256
+ <Flex style={styles.videoContainer}>
200
257
  {
201
258
  videoTiles.length > 0 ? videoTiles.map(tileId =>
202
259
  <RNVideoView style={styles.video} key={tileId} tileId={tileId} />
203
- ) : <Text style={styles.subtitle}>No one is sharing video at this moment</Text>
260
+ ) : <Typography style={styles.subtitle}>No one is sharing video at this moment</Typography>
204
261
  }
205
- </View>
262
+ </Flex>
263
+
264
+ {/*
206
265
  {
207
266
  !!shareScreenId &&
208
267
  <React.Fragment>
209
- <Text style={styles.title}>Screen Share</Text>
268
+ <Typography style={styles.title}>Screen Share</Typography>
210
269
  <View style={styles.videoContainer}>
211
270
  <RNVideoView style={styles.screenShare} key={shareScreenId} tileId={shareScreenId} />
212
271
  </View>
213
272
  </React.Fragment>
214
- }
215
- <Text style={styles.title}>Attendee</Text>
273
+ }
274
+ */}
275
+
276
+ <Flex justifyContent="space-between" style={{ height: '5%' }}>
277
+ {/* <MuteButton muted={currentMuted} onPress={() => NativeFunction.setMute(!currentMuted) }/> */}
278
+ {/* <CameraButton disabled={selfVideoEnabled} onPress={() => NativeFunction.setCameraOn(!videoIsEnabled)}/> */}
279
+ <Button onPress={toggleVideo}>
280
+ Toggle Video
281
+ </Button>
282
+ {/* <HangOffButton onPress={() => NativeFunction.stopMeeting()} /> */}
283
+ <Button onPress={() => NativeFunction.stopMeeting()}> Leave Meeting </Button>
284
+ </Flex>
285
+
216
286
  {/* <FlatList
217
287
  style={styles.attendeeList}
218
288
  data={attendees}
219
289
  renderItem={({ item }) => <AttendeeItem attendeeName={attendeeNameMap[item] ? attendeeNameMap[item] : item} muted={this.state.mutedAttendee.includes(item)}/>}
220
290
  keyExtractor={(item) => item}
221
291
  /> */}
222
- </View>
292
+
293
+ </Flex>
223
294
  );
224
295
  }
225
296
 
226
297
  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
298
  title: {
238
299
  fontSize: 30,
239
300
  fontWeight: '700'
@@ -247,6 +308,7 @@ const styles = StyleSheet.create({
247
308
  flexDirection: 'row',
248
309
  justifyContent: 'space-around',
249
310
  width: '100%',
311
+ height: '95%',
250
312
  // This is an existing React Native issue:
251
313
  // When you create a native android component
252
314
  // that use GLSurfaceView (We use this internally), the entire screen will
@@ -254,8 +316,7 @@ const styles = StyleSheet.create({
254
316
  overflow: 'hidden'
255
317
  },
256
318
  video: {
257
- width: '45%',
258
- margin: '1%',
319
+ width: '100%',
259
320
  aspectRatio: 16 / 9,
260
321
  },
261
322
  screenShare: {
package/src/video.tsx CHANGED
@@ -12,14 +12,6 @@ import {
12
12
  MeetingInfo,
13
13
  } from '@tellescope/types-models'
14
14
 
15
- import {
16
- user_display_name,
17
- } from "@tellescope/utilities"
18
-
19
- import {
20
- Session,
21
- EnduserSession,
22
- } from "@tellescope/sdk"
23
15
 
24
16
  import { ThemeProvider } from 'styled-components';
25
17
  import {
@@ -31,11 +23,15 @@ import {
31
23
  // VideoGrid,
32
24
  // VideoTile,
33
25
  // PreviewVideo,
34
- // RemoteVideo,
26
+ RemoteVideo,
27
+ useAttendeeAudioStatus,
28
+ LocalVideo,
35
29
  useLocalVideo,
36
30
  useMeetingManager,
37
31
  useRosterState,
38
- useRemoteVideoTileState
32
+ useRemoteVideoTileState,
33
+ VideoTile,
34
+ useToggleLocalMute,
39
35
  // useRemoteVideoTileState,
40
36
  // useContentShareControls, // screen sharing
41
37
  } from 'amazon-chime-sdk-component-library-react';
@@ -46,8 +42,10 @@ export type AttendeeDisplayInfo = { attendeeId: string, externalUserId: string
46
42
  export const CurrentCallContext = React.createContext({} as {
47
43
  meeting: MeetingInfo | undefined, setMeeting: (m: MeetingInfo | undefined) => void,
48
44
  videoIsEnabled: boolean, toggleVideo: () => Promise<void>,
49
- attendees: AttendeeDisplayInfo[], shareScreenId: string,
50
- videoTiles: (number | string)[],
45
+ microphoneIsEnabled: boolean, toggleMicrophone: () => Promise<void>,
46
+ attendees: AttendeeDisplayInfo[], shareScreenId: number | null,
47
+ localTileId: number | null,
48
+ videoTiles: (number)[],
51
49
  })
52
50
  export interface VideoProps {
53
51
  children?: React.ReactNode,
@@ -55,10 +53,11 @@ export interface VideoProps {
55
53
  }
56
54
  const WithContext = ({ children } : { children: React.ReactNode }) => {
57
55
  const [meeting, setMeeting] = useState(undefined as MeetingInfo | undefined)
58
- const { toggleVideo, isVideoEnabled: videoIsEnabled } = useLocalVideo();
56
+ const { toggleVideo, isVideoEnabled: videoIsEnabled, tileId: localTileId } = useLocalVideo();
59
57
  const { roster } = useRosterState()
60
58
  const { tileId } = useContentShareState()
61
59
  const { tiles } = useRemoteVideoTileState()
60
+ const { muted, toggleMute } = useToggleLocalMute()
62
61
 
63
62
  const attendees = [] as AttendeeDisplayInfo[]
64
63
  for (const attendeeId in roster) {
@@ -67,7 +66,18 @@ const WithContext = ({ children } : { children: React.ReactNode }) => {
67
66
  }
68
67
 
69
68
  return (
70
- <CurrentCallContext.Provider value={{ attendees, videoTiles: tiles, shareScreenId: tileId?.toString() ?? '', meeting, setMeeting, videoIsEnabled, toggleVideo }}>
69
+ <CurrentCallContext.Provider value={{
70
+ attendees,
71
+ localTileId,
72
+ videoTiles: tiles,
73
+ shareScreenId: tileId,
74
+ meeting,
75
+ setMeeting,
76
+ videoIsEnabled,
77
+ toggleVideo,
78
+ microphoneIsEnabled: !muted,
79
+ toggleMicrophone: async () => toggleMute(),
80
+ }}>
71
81
  {children}
72
82
  </CurrentCallContext.Provider>
73
83
  )
@@ -147,4 +157,19 @@ export const useJoinVideoCall = () => {
147
157
  }
148
158
  export type JoinVideoCallReturnType = ReturnType<typeof useJoinVideoCall>
149
159
 
160
+ export interface VideoViewProps {
161
+ style?: CSSProperties,
162
+ }
163
+ export const SelfView = ({ style }: VideoViewProps) => <div style={style}><LocalVideo/></div>
164
+
165
+ export const useRemoteViews = ({ style } : VideoViewProps) => {
166
+ const { localTileId, videoTiles } = React.useContext(CurrentCallContext)
167
+ const nonLocal = videoTiles.filter(v => v !== localTileId)
168
+
169
+ return nonLocal.map(tileId =>
170
+ <RemoteVideo style={style} tileId={tileId} />
171
+ )
172
+ }
173
+
174
+
150
175
  export { VideoTileGrid }
package/lib/cjs/chat.d.ts DELETED
@@ -1,69 +0,0 @@
1
- import React, { CSSProperties } from "react";
2
- import { Styled } from "@tellescope/react-components/lib/esm/mui";
3
- import { ChatRoom, ChatMessage } from "@tellescope/types-client";
4
- import { LoadedData, SessionType } from "@tellescope/types-utilities";
5
- import { Session, EnduserSession } from "@tellescope/sdk";
6
- export interface MessagesHeaderProps {
7
- room?: ChatRoom;
8
- resolveSenderName?: (room: ChatRoom) => React.ReactNode;
9
- style?: CSSProperties;
10
- }
11
- interface Messages_T {
12
- resolveSenderName?: (room: ChatRoom) => React.ReactNode;
13
- messages: LoadedData<ChatMessage[]>;
14
- chatUserId: string;
15
- Header?: React.JSXElementConstructor<MessagesHeaderProps>;
16
- headerProps?: MessagesHeaderProps;
17
- receivedMessageStyle?: CSSProperties;
18
- receivedMessageTextStyle?: CSSProperties;
19
- sentMessageStyle?: CSSProperties;
20
- sentMessageTextStyle?: CSSProperties;
21
- }
22
- export declare const Messages: ({ resolveSenderName, messages, chatUserId, Header, headerProps, style, receivedMessageStyle, receivedMessageTextStyle, sentMessageStyle, sentMessageTextStyle, }: Messages_T & Styled) => JSX.Element;
23
- export interface ConversationPreviewProps {
24
- onClick?: (roomId: string) => void;
25
- room: ChatRoom;
26
- selected?: boolean;
27
- resolveSenderName?: (room: ChatRoom) => React.ReactNode;
28
- style?: CSSProperties;
29
- selectedStyle?: CSSProperties;
30
- }
31
- interface SidebarInfo {
32
- selectedRoom?: string;
33
- onRoomSelect: (roomId: string) => void;
34
- style?: CSSProperties;
35
- selectedItemStyle?: CSSProperties;
36
- itemStyle?: CSSProperties;
37
- nameStyle?: CSSProperties;
38
- PreviewComponent?: React.JSXElementConstructor<ConversationPreviewProps>;
39
- previewStyle?: CSSProperties;
40
- }
41
- interface ConversationsProps extends SidebarInfo {
42
- resolveSenderName: (r: ChatRoom) => string;
43
- rooms: LoadedData<ChatRoom[]>;
44
- }
45
- export declare const Conversations: ({ rooms, selectedRoom, onRoomSelect, resolveSenderName, PreviewComponent, style, selectedItemStyle, itemStyle }: ConversationsProps) => JSX.Element;
46
- export declare const EndusersConversations: ({ enduserId, ...p }: SidebarInfo & {
47
- enduserId: string;
48
- }) => JSX.Element;
49
- export declare const UsersConversations: ({ userId, ...p }: SidebarInfo & {
50
- userId: string;
51
- }) => JSX.Element;
52
- interface SendMessage_T {
53
- session: Session | EnduserSession;
54
- roomId: string;
55
- onNewMessage: (m: ChatMessage) => void;
56
- placeholderText?: string;
57
- Icon?: React.ElementType<any>;
58
- style?: CSSProperties;
59
- }
60
- export declare const SendMessage: ({ session, roomId, Icon, onNewMessage, placeholderText, style, }: SendMessage_T) => JSX.Element;
61
- interface SplitChat_T {
62
- session: EnduserSession | Session;
63
- type: SessionType;
64
- }
65
- export declare const SplitChat: ({ session, type, style }: SplitChat_T & Styled) => JSX.Element;
66
- export declare const UserChatSplit: ({ style }: Styled) => JSX.Element;
67
- export declare const EnduserChatSplit: ({ style }: Styled) => JSX.Element;
68
- export {};
69
- //# sourceMappingURL=chat.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/chat.tsx"],"names":[],"mappings":"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"}