agora-appbuilder-core 4.1.7 → 4.1.8-2

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 (43) hide show
  1. package/package.json +2 -2
  2. package/template/_package-lock.json +30671 -5376
  3. package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +1 -1
  4. package/template/agora-rn-uikit/src/Rtc/Join.tsx +18 -9
  5. package/template/bridge/rtc/webNg/RtcEngine.ts +2 -2
  6. package/template/defaultConfig.js +4 -3
  7. package/template/esbuild.rsdk.go +1 -2
  8. package/template/global.d.ts +1 -0
  9. package/template/package.json +1 -2
  10. package/template/src/AppWrapper.tsx +30 -35
  11. package/template/src/atoms/TextInput.tsx +3 -0
  12. package/template/src/auth/AuthProvider.tsx +28 -35
  13. package/template/src/auth/IDPAuth.tsx +1 -14
  14. package/template/src/components/Controls.tsx +47 -15
  15. package/template/src/components/common/GenericModal.tsx +143 -0
  16. package/template/src/components/common/GenericPopup.tsx +151 -0
  17. package/template/src/components/common/data-table.tsx +412 -0
  18. package/template/src/components/controls/useControlPermissionMatrix.tsx +9 -7
  19. package/template/src/components/precall/usePreCall.tsx +1 -2
  20. package/template/src/components/recordings/RecordingItemRow.tsx +289 -0
  21. package/template/src/components/recordings/RecordingsDateTable.tsx +99 -25
  22. package/template/src/components/recordings/TextTrackItemRow.tsx +120 -0
  23. package/template/src/components/room-info/useRoomInfo.tsx +1 -0
  24. package/template/src/components/text-tracks/TextTracksTable.tsx +306 -0
  25. package/template/src/components/text-tracks/ViewTextTracksModal.tsx +44 -0
  26. package/template/src/components/text-tracks/useFetchSTTTranscript.tsx +262 -0
  27. package/template/src/components/useUserPreference.tsx +0 -11
  28. package/template/src/language/default-labels/videoCallScreenLabels.ts +7 -0
  29. package/template/src/logger/AppBuilderLogger.tsx +1 -0
  30. package/template/src/pages/Create.tsx +2 -2
  31. package/template/src/pages/VideoCall.tsx +1 -6
  32. package/template/src/subComponents/ChatInput.tsx +72 -1
  33. package/template/src/subComponents/LogoutButton.tsx +1 -11
  34. package/template/src/subComponents/recording/useRecording.tsx +19 -4
  35. package/template/src/subComponents/recording/useRecordingLayoutQuery.tsx +83 -78
  36. package/template/src/utils/common.tsx +79 -1
  37. package/template/src/utils/useCreateRoom.ts +94 -112
  38. package/template/src/utils/useEndCall.ts +16 -3
  39. package/template/src/utils/useGetMeetingPhrase.ts +67 -76
  40. package/template/src/utils/useJoinRoom.ts +5 -4
  41. package/template/src/utils/useMutePSTN.ts +47 -45
  42. package/template/webpack.rsdk.config.js +1 -2
  43. package/template/src/components/GraphQLProvider.tsx +0 -122
@@ -0,0 +1,306 @@
1
+ import React, {useEffect} from 'react';
2
+ import {View, Text, TouchableOpacity} from 'react-native';
3
+ import Tooltip from '../../atoms/Tooltip';
4
+ import Clipboard from '../../subComponents/Clipboard';
5
+ import Spacer from '../../atoms/Spacer';
6
+ import {style} from '../recordings/style';
7
+ import {TableBody, TableFooter, TableHeader} from '../common/data-table';
8
+ import {
9
+ FetchSTTTranscriptResponse,
10
+ useFetchSTTTranscript,
11
+ } from './useFetchSTTTranscript';
12
+ import {
13
+ capitalizeFirstLetter,
14
+ downloadS3Link,
15
+ getFormattedDateTime,
16
+ } from '../../utils/common';
17
+ import IconButtonWithToolTip from '../../atoms/IconButton';
18
+ import ImageIcon from '../../atoms/ImageIcon';
19
+ import Loading from '../../subComponents/Loading';
20
+ import GenericPopup from '../common/GenericPopup';
21
+ import PlatformWrapper from '../../utils/PlatformWrapper';
22
+
23
+ const headers = ['Date', 'Time', 'Status', 'Actions'];
24
+
25
+ interface TextTrackItemRowProps {
26
+ item: FetchSTTTranscriptResponse['stts'][0];
27
+ onDeleteAction: (id: string) => void;
28
+ onDownloadAction: (link: string) => void;
29
+ }
30
+
31
+ function TextTrackItemRow({
32
+ item,
33
+ onDeleteAction,
34
+ onDownloadAction,
35
+ }: TextTrackItemRowProps) {
36
+ const [date, time] = getFormattedDateTime(item.created_at);
37
+ const textTrackStatus = item.status;
38
+
39
+ if (
40
+ textTrackStatus === 'STOPPING' ||
41
+ textTrackStatus === 'STARTED' ||
42
+ (textTrackStatus === 'INPROGRESS' && !item?.download_url)
43
+ ) {
44
+ return (
45
+ <View key={item.id} style={style.pt12}>
46
+ <View style={[style.infotextContainer, style.captionContainer]}>
47
+ <ImageIcon
48
+ iconSize={20}
49
+ iconType="plain"
50
+ name="info"
51
+ tintColor={$config.SEMANTIC_NEUTRAL}
52
+ />
53
+ <Text style={[style.captionText]}>
54
+ Current STT is ongoing. Once the meeting concludes, we'll generate
55
+ the link
56
+ </Text>
57
+ </View>
58
+ </View>
59
+ );
60
+ }
61
+ return (
62
+ <View style={style.tbrow} key={item.id}>
63
+ <View style={[style.td, style.plzero]}>
64
+ <Text style={style.ttime}>{date}</Text>
65
+ </View>
66
+ <View style={[style.td]}>
67
+ <Text style={style.ttime}>{time}</Text>
68
+ </View>
69
+ <View style={[style.td]}>
70
+ <Text style={style.ttime}>
71
+ {capitalizeFirstLetter(textTrackStatus)}
72
+ </Text>
73
+ </View>
74
+ <View style={style.td}>
75
+ {!item.download_url ? (
76
+ <View style={[style.tactions, {marginTop: 0}]}>
77
+ <Text style={style.placeHolder}>{'No text-tracks found'}</Text>
78
+ </View>
79
+ ) : item?.download_url?.length > 0 ? (
80
+ <View style={style.tactions}>
81
+ <View>
82
+ {item?.download_url?.map((link: string, i: number) => (
83
+ <View
84
+ key={i}
85
+ style={[
86
+ style.tactions,
87
+ //if stts contains multiple parts then we need to add some space each row
88
+ i >= 1 ? {marginTop: 8} : {},
89
+ ]}>
90
+ <View>
91
+ <IconButtonWithToolTip
92
+ hoverEffect={true}
93
+ hoverEffectStyle={style.iconButtonHoverEffect}
94
+ containerStyle={style.iconButton}
95
+ iconProps={{
96
+ name: 'download',
97
+ iconType: 'plain',
98
+ iconSize: 20,
99
+ tintColor: `${$config.SECONDARY_ACTION_COLOR}`,
100
+ }}
101
+ onPress={() => {
102
+ onDownloadAction(link);
103
+ }}
104
+ />
105
+ </View>
106
+ <View style={[style.pl10]}>
107
+ <Tooltip
108
+ isClickable
109
+ placement="left"
110
+ toolTipMessage="Link Copied"
111
+ onPress={() => {
112
+ Clipboard.setString(link);
113
+ }}
114
+ toolTipIcon={
115
+ <>
116
+ <ImageIcon
117
+ iconType="plain"
118
+ name="tick-fill"
119
+ tintColor={$config.SEMANTIC_SUCCESS}
120
+ iconSize={20}
121
+ />
122
+ <Spacer size={8} horizontal={true} />
123
+ </>
124
+ }
125
+ fontSize={12}
126
+ renderContent={() => {
127
+ return (
128
+ <PlatformWrapper>
129
+ {(isHovered: boolean) => (
130
+ <TouchableOpacity
131
+ style={[
132
+ isHovered ? style.iconButtonHoverEffect : {},
133
+ style.iconShareLink,
134
+ ]}
135
+ onPress={() => {
136
+ Clipboard.setString(link);
137
+ }}>
138
+ <ImageIcon
139
+ iconType="plain"
140
+ name="copy-link"
141
+ iconSize={20}
142
+ tintColor={$config.SECONDARY_ACTION_COLOR}
143
+ />
144
+ </TouchableOpacity>
145
+ )}
146
+ </PlatformWrapper>
147
+ );
148
+ }}
149
+ />
150
+ </View>
151
+ <View style={[style.pl10]}>
152
+ <IconButtonWithToolTip
153
+ hoverEffect={true}
154
+ hoverEffectStyle={style.iconButtonHoverEffect}
155
+ containerStyle={style.iconButton}
156
+ iconProps={{
157
+ name: 'delete',
158
+ iconType: 'plain',
159
+ iconSize: 20,
160
+ tintColor: `${$config.SEMANTIC_ERROR}`,
161
+ }}
162
+ onPress={() => {
163
+ //show confirmation popup
164
+ onDeleteAction && onDeleteAction(item.id);
165
+ }}
166
+ />
167
+ </View>
168
+ </View>
169
+ ))}
170
+ </View>
171
+ </View>
172
+ ) : (
173
+ <View style={(style.tactions, {marginTop: 0})}>
174
+ <Text style={style.placeHolder}>No text-tracks found</Text>
175
+ </View>
176
+ )}
177
+ </View>
178
+ </View>
179
+ );
180
+ }
181
+
182
+ function EmptyTextTrackState() {
183
+ return (
184
+ <View style={style.infotextContainer}>
185
+ <View>
186
+ <ImageIcon
187
+ iconType="plain"
188
+ name="info"
189
+ tintColor={'#777777'}
190
+ iconSize={32}
191
+ />
192
+ </View>
193
+ <View>
194
+ <Text style={[style.infoText, style.pt10, style.pl10]}>
195
+ No text-tracks found for this meeting
196
+ </Text>
197
+ </View>
198
+ </View>
199
+ );
200
+ }
201
+
202
+ function ErrorTextTrackState({message}: {message: string}) {
203
+ return <Text style={[style.ttime, style.pv10, style.ph20]}>{message}</Text>;
204
+ }
205
+
206
+ function TextTracksTable() {
207
+ const {getSTTs, sttState, currentPage, setCurrentPage, deleteTranscript} =
208
+ useFetchSTTTranscript();
209
+
210
+ const {
211
+ status,
212
+ data: {stts, pagination},
213
+ error: fetchTranscriptError,
214
+ } = sttState;
215
+
216
+ useEffect(() => {
217
+ getSTTs(currentPage);
218
+ }, [currentPage, getSTTs]);
219
+
220
+ // id of text-tracj to delete
221
+ const [textTrackIdToDelete, setTextTrackIdToDelete] = React.useState<
222
+ string | undefined
223
+ >(undefined);
224
+
225
+ // message for any download‐error popup
226
+ const [errorSnack, setErrorSnack] = React.useState<string | undefined>();
227
+
228
+ if (status === 'rejected') {
229
+ return <ErrorTextTrackState message={fetchTranscriptError?.message} />;
230
+ }
231
+
232
+ const onDeleteTextTrackRecord = async (trackId: string) => {
233
+ try {
234
+ await deleteTranscript(trackId!);
235
+ } catch (err: any) {
236
+ setErrorSnack(err.message);
237
+ } finally {
238
+ setTextTrackIdToDelete(undefined);
239
+ }
240
+ };
241
+
242
+ return (
243
+ <>
244
+ <View style={style.ttable}>
245
+ <TableHeader columns={headers} />
246
+ <TableBody
247
+ status={status}
248
+ items={stts}
249
+ loadingComponent={
250
+ <Loading background="transparent" text="Fetching text-tracks.." />
251
+ }
252
+ renderRow={item => (
253
+ <TextTrackItemRow
254
+ key={item.id}
255
+ item={item}
256
+ onDeleteAction={id => {
257
+ setTextTrackIdToDelete(id);
258
+ }}
259
+ onDownloadAction={link => {
260
+ downloadS3Link(link).catch((err: Error) => {
261
+ setErrorSnack(err.message || 'Download failed');
262
+ });
263
+ }}
264
+ />
265
+ )}
266
+ emptyComponent={<EmptyTextTrackState />}
267
+ />
268
+ <TableFooter
269
+ currentPage={currentPage}
270
+ onPageChange={setCurrentPage}
271
+ pagination={pagination}
272
+ />
273
+ </View>
274
+ {textTrackIdToDelete && (
275
+ <GenericPopup
276
+ title="Delete ? "
277
+ variant="error"
278
+ message="Are you sure want to delete the text-track ? This action can't be undone."
279
+ visible={!!textTrackIdToDelete}
280
+ setVisible={() => setTextTrackIdToDelete(undefined)}
281
+ onConfirm={() => {
282
+ const idToDelete = textTrackIdToDelete;
283
+ setTextTrackIdToDelete(undefined);
284
+ onDeleteTextTrackRecord(idToDelete);
285
+ }}
286
+ onCancel={() => {
287
+ setTextTrackIdToDelete(undefined);
288
+ }}
289
+ />
290
+ )}
291
+ {/** DOWNLOAD ERROR POPUP **/}
292
+ {errorSnack && (
293
+ <GenericPopup
294
+ title="Error"
295
+ variant="error"
296
+ message={errorSnack}
297
+ visible={true}
298
+ setVisible={() => setErrorSnack(undefined)}
299
+ onConfirm={() => setErrorSnack(undefined)}
300
+ />
301
+ )}
302
+ </>
303
+ );
304
+ }
305
+
306
+ export default TextTracksTable;
@@ -0,0 +1,44 @@
1
+ import React, {SetStateAction, Dispatch} from 'react';
2
+ import {View, StyleSheet} from 'react-native';
3
+ import {useString} from '../../utils/useString';
4
+ import {textTrackModalTitleIntn} from '../../language/default-labels/videoCallScreenLabels';
5
+ import GenericModal from '../common/GenericModal';
6
+ import TextTracksTable from './TextTracksTable';
7
+
8
+ interface ViewTextTracksModalProps {
9
+ setModalOpen: Dispatch<SetStateAction<boolean>>;
10
+ }
11
+
12
+ export default function ViewTextTracksModal(props: ViewTextTracksModalProps) {
13
+ const {setModalOpen} = props;
14
+
15
+ const textTrackModalTitle = useString(textTrackModalTitleIntn)();
16
+
17
+ return (
18
+ <GenericModal
19
+ visible={true}
20
+ onRequestClose={() => setModalOpen(false)}
21
+ showCloseIcon={true}
22
+ title={textTrackModalTitle}
23
+ cancelable={false}
24
+ contentContainerStyle={style.contentContainer}>
25
+ <View style={style.fullBody}>
26
+ <TextTracksTable />
27
+ </View>
28
+ </GenericModal>
29
+ );
30
+ }
31
+
32
+ const style = StyleSheet.create({
33
+ contentContainer: {
34
+ display: 'flex',
35
+ flexDirection: 'column',
36
+ alignItems: 'flex-start',
37
+ flexShrink: 0,
38
+ width: '100%',
39
+ },
40
+ fullBody: {
41
+ width: '100%',
42
+ flex: 1,
43
+ },
44
+ });
@@ -0,0 +1,262 @@
1
+ import {useState, useCallback, useEffect, useContext} from 'react';
2
+ import StorageContext from '../StorageContext';
3
+ import {useRoomInfo} from 'customization-api';
4
+ import getUniqueID from '../../utils/getUniqueID';
5
+ import {logger, LogSource} from '../../logger/AppBuilderLogger';
6
+
7
+ export interface FetchSTTTranscriptResponse {
8
+ pagination: {limit: number; total: number; page: number};
9
+ stts: {
10
+ id: string;
11
+ download_url: string[];
12
+ title: string;
13
+ product_name: string;
14
+ status: 'COMPLETED' | 'STARTED' | 'INPROGRESS' | 'STOPPING';
15
+ created_at: string;
16
+ ended_at: string;
17
+ }[];
18
+ }
19
+
20
+ export type APIStatus = 'idle' | 'pending' | 'resolved' | 'rejected';
21
+
22
+ export function useFetchSTTTranscript() {
23
+ const {
24
+ data: {roomId},
25
+ } = useRoomInfo();
26
+ const {store} = useContext(StorageContext);
27
+
28
+ const [currentPage, setCurrentPage] = useState(1);
29
+
30
+ const [sttState, setSttState] = useState<{
31
+ status: APIStatus;
32
+ data: {
33
+ stts: FetchSTTTranscriptResponse['stts'];
34
+ pagination: FetchSTTTranscriptResponse['pagination'];
35
+ };
36
+ error: Error | null;
37
+ }>({
38
+ status: 'idle',
39
+ data: {stts: [], pagination: {total: 0, limit: 10, page: 1}},
40
+ error: null,
41
+ });
42
+
43
+ //–– by‐recording state ––
44
+ const [sttRecState, setSttRecState] = useState<{
45
+ status: APIStatus;
46
+ data: {stts: FetchSTTTranscriptResponse['stts']};
47
+ error: Error | null;
48
+ }>({
49
+ status: 'idle',
50
+ data: {
51
+ stts: [],
52
+ },
53
+ error: null,
54
+ });
55
+
56
+ const getSTTs = useCallback(
57
+ (page: number) => {
58
+ setSttState(s => ({...s, status: 'pending', error: null}));
59
+ const reqId = getUniqueID();
60
+ const start = Date.now();
61
+
62
+ fetch(`${$config.BACKEND_ENDPOINT}/v1/stt-transcript`, {
63
+ method: 'POST',
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ authorization: store.token ? `Bearer ${store.token}` : '',
67
+ 'X-Request-Id': reqId,
68
+ 'X-Session-Id': logger.getSessionId(),
69
+ },
70
+ body: JSON.stringify({
71
+ passphrase: roomId.host,
72
+ limit: 10,
73
+ page,
74
+ }),
75
+ })
76
+ .then(async res => {
77
+ const json = await res.json();
78
+ const end = Date.now();
79
+ if (!res.ok) {
80
+ logger.error(
81
+ LogSource.NetworkRest,
82
+ 'stt-transcript',
83
+ 'Fetch STT transcripts failed',
84
+ {
85
+ json,
86
+ start,
87
+ end,
88
+ latency: end - start,
89
+ requestId: reqId,
90
+ },
91
+ );
92
+ throw new Error(json?.error?.message || res.statusText);
93
+ }
94
+ logger.debug(
95
+ LogSource.NetworkRest,
96
+ 'stt-transcript',
97
+ 'Fetch STT transcripts succeeded',
98
+ {
99
+ json,
100
+ start,
101
+ end,
102
+ latency: end - start,
103
+ requestId: reqId,
104
+ },
105
+ );
106
+ return json as FetchSTTTranscriptResponse;
107
+ })
108
+ .then(({stts = [], pagination = {total: 0, limit: 10, page}}) => {
109
+ setSttState({
110
+ status: 'resolved',
111
+ data: {stts, pagination},
112
+ error: null,
113
+ });
114
+ })
115
+ .catch(err => {
116
+ setSttState(s => ({...s, status: 'rejected', error: err}));
117
+ });
118
+ },
119
+ [roomId.host, store.token],
120
+ );
121
+
122
+ // Delete stts
123
+ const deleteTranscript = useCallback(
124
+ async (id: string) => {
125
+ const reqId = getUniqueID();
126
+ const start = Date.now();
127
+
128
+ const res = await fetch(
129
+ `${
130
+ $config.BACKEND_ENDPOINT
131
+ }/v1/stt-transcript/${id}?passphrase=${encodeURIComponent(
132
+ roomId.host,
133
+ )}`,
134
+ {
135
+ method: 'DELETE',
136
+ headers: {
137
+ 'Content-Type': 'application/json',
138
+ authorization: store.token ? `Bearer ${store.token}` : '',
139
+ 'X-Request-Id': reqId,
140
+ 'X-Session-Id': logger.getSessionId(),
141
+ },
142
+ },
143
+ );
144
+ const end = Date.now();
145
+
146
+ if (!res.ok) {
147
+ logger.error(
148
+ LogSource.NetworkRest,
149
+ 'stt-transcript',
150
+ 'Delete transcript failed',
151
+ {start, end, latency: end - start, requestId: reqId},
152
+ );
153
+ throw new Error(`Delete failed (${res.status})`);
154
+ }
155
+ logger.debug(
156
+ LogSource.NetworkRest,
157
+ 'stt-transcript',
158
+ 'Delete transcript succeeded',
159
+ {start, end, latency: end - start, requestId: reqId},
160
+ );
161
+
162
+ // optimistic remove from paginated list
163
+ setSttState(prev => {
164
+ // remove the deleted item
165
+ const newStts = prev.data.stts.filter(item => item.id !== id);
166
+ // decrement total count
167
+ const newTotal = Math.max(prev.data.pagination.total - 1, 0);
168
+ let newPage = prev.data.pagination.page;
169
+ if (prev.data.stts.length === 1 && newPage > 1) {
170
+ newPage--;
171
+ }
172
+ return {
173
+ ...prev,
174
+ data: {
175
+ stts: newStts,
176
+
177
+ pagination: {
178
+ ...prev.data.pagination,
179
+ total: newTotal,
180
+ page: newPage,
181
+ },
182
+ },
183
+ };
184
+ });
185
+ },
186
+ [roomId.host, store.token],
187
+ );
188
+
189
+ //–– fetch for a given recording ––
190
+ const getSTTsForRecording = useCallback(
191
+ (recordingId: string) => {
192
+ setSttRecState(r => ({...r, status: 'pending', error: null}));
193
+ const reqId = getUniqueID();
194
+ const start = Date.now();
195
+
196
+ fetch(`${$config.BACKEND_ENDPOINT}/v1/recording/stt-transcript`, {
197
+ method: 'POST',
198
+ headers: {
199
+ 'Content-Type': 'application/json',
200
+ authorization: store.token ? `Bearer ${store.token}` : '',
201
+ 'X-Request-Id': reqId,
202
+ 'X-Session-Id': logger.getSessionId(),
203
+ },
204
+ body: JSON.stringify({
205
+ project_id: $config.PROJECT_ID,
206
+ recording_id: recordingId,
207
+ }),
208
+ })
209
+ .then(async res => {
210
+ const json = await res.json();
211
+ const end = Date.now();
212
+ console.log('supriua json', json);
213
+ if (!res.ok) {
214
+ logger.error(
215
+ LogSource.NetworkRest,
216
+ 'stt-transcript',
217
+ 'Fetch stt-by-recording failed',
218
+ {json, start, end, latency: end - start, requestId: reqId},
219
+ );
220
+ throw new Error(json?.error?.message || res.statusText);
221
+ }
222
+ logger.debug(
223
+ LogSource.NetworkRest,
224
+ 'stt-transcript',
225
+ 'Fetch stt-by-recording succeeded',
226
+ {json, start, end, latency: end - start, requestId: reqId},
227
+ );
228
+ if (json?.error) {
229
+ logger.debug(
230
+ LogSource.NetworkRest,
231
+ 'stt-transcript',
232
+ `No STT records found (code ${json.error.code}): ${json.error.message}`,
233
+ {start, end, latency: end - start, reqId},
234
+ );
235
+ return [];
236
+ } else {
237
+ return json as FetchSTTTranscriptResponse['stts'];
238
+ }
239
+ })
240
+ .then(stts =>
241
+ setSttRecState({status: 'resolved', data: {stts}, error: null}),
242
+ )
243
+ .catch(err =>
244
+ setSttRecState(r => ({...r, status: 'rejected', error: err})),
245
+ );
246
+ },
247
+ [store.token],
248
+ );
249
+
250
+ return {
251
+ // stt list
252
+ sttState,
253
+ getSTTs,
254
+ currentPage,
255
+ setCurrentPage,
256
+ // STT per recording
257
+ sttRecState,
258
+ getSTTsForRecording,
259
+ // delete
260
+ deleteTranscript,
261
+ };
262
+ }
@@ -24,7 +24,6 @@ import useLocalScreenShareUid from '../utils/useLocalShareScreenUid';
24
24
  import {createHook} from 'customization-implementation';
25
25
  import ChatContext from './ChatContext';
26
26
  import {filterObject, useContent, useRoomInfo, useRtc} from 'customization-api';
27
- import {gql, useMutation} from '@apollo/client';
28
27
  import {
29
28
  PSTNUserLabel,
30
29
  videoRoomScreenshareText,
@@ -55,15 +54,6 @@ const UserPreferenceContext =
55
54
  uids: {},
56
55
  });
57
56
 
58
- const UPDATE_USER_NAME_MUTATION = gql`
59
- mutation updateUserName($name: String!) {
60
- updateUserName(name: $name) {
61
- name
62
- email
63
- }
64
- }
65
- `;
66
-
67
57
  const UserPreferenceProvider = (props: {
68
58
  children: React.ReactNode;
69
59
  callActive: boolean;
@@ -81,7 +71,6 @@ const UserPreferenceProvider = (props: {
81
71
  const getInitialUsername = () =>
82
72
  store?.displayName ? store.displayName : '';
83
73
  const [displayName, setDisplayName] = useState(getInitialUsername());
84
- const [updateUserName] = useMutation(UPDATE_USER_NAME_MUTATION);
85
74
 
86
75
  const {languageCode} = useLanguage();
87
76
  const {screenShareData} = useScreenContext();
@@ -109,6 +109,8 @@ export const toolbarItemNoiseCancellationText =
109
109
  export const toolbarItemWhiteboardText = 'toolbarItemWhiteboardText';
110
110
  export const toolbarItemCaptionText = 'toolbarItemCaptionText';
111
111
  export const toolbarItemTranscriptText = 'toolbarItemTranscriptText';
112
+ export const toolbarItemManageTextTracksText =
113
+ 'toolbarItemManageTextTracksText';
112
114
  export const toolbarItemVirtualBackgroundText =
113
115
  'toolbarItemVirtualBackgroundText';
114
116
  export const toolbarItemViewRecordingText = 'toolbarItemViewRecordingText';
@@ -149,6 +151,7 @@ export const nativeStopScreensharePopupPrimaryBtnText =
149
151
  'nativeStopScreensharePopupPrimaryBtnText';
150
152
 
151
153
  export const recordingModalTitleIntn = 'recordingModalTitleIntn';
154
+ export const textTrackModalTitleIntn = 'textTrackModalTitleIntn';
152
155
  export const stopRecordingPopupHeading = 'stopRecordingPopupHeading';
153
156
  export const stopRecordingPopupSubHeading = 'stopRecordingPopupSubHeading';
154
157
  export const stopRecordingPopupPrimaryBtnText =
@@ -570,6 +573,7 @@ export interface I18nVideoCallScreenLabelsInterface {
570
573
  [toolbarItemWhiteboardText]?: I18nConditionalType;
571
574
  [toolbarItemCaptionText]?: I18nConditionalType;
572
575
  [toolbarItemTranscriptText]?: I18nConditionalType;
576
+ [toolbarItemManageTextTracksText]?: I18nConditionalType;
573
577
  [toolbarItemVirtualBackgroundText]?: I18nBaseType;
574
578
  [toolbarItemViewRecordingText]?: I18nConditionalType;
575
579
 
@@ -605,6 +609,7 @@ export interface I18nVideoCallScreenLabelsInterface {
605
609
  [nativeStopScreensharePopupPrimaryBtnText]?: I18nBaseType;
606
610
 
607
611
  [recordingModalTitleIntn]?: I18nBaseType;
612
+ [textTrackModalTitleIntn]?: I18nBaseType;
608
613
  [stopRecordingPopupHeading]?: I18nBaseType;
609
614
  [stopRecordingPopupSubHeading]?: I18nBaseType;
610
615
  [stopRecordingPopupPrimaryBtnText]?: I18nBaseType;
@@ -937,6 +942,7 @@ export const VideoCallScreenLabels: I18nVideoCallScreenLabelsInterface = {
937
942
  [toolbarItemTranscriptText]: active =>
938
943
  active ? 'Hide Transcript' : 'Show Transcript',
939
944
  [toolbarItemViewRecordingText]: 'View Recordings',
945
+ [toolbarItemManageTextTracksText]: 'View Text-tracks',
940
946
 
941
947
  [toolbarItemRaiseHandText]: active => (active ? 'Lower Hand' : 'Raise Hand'),
942
948
  [toolbarItemSwitchCameraText]: 'Switch Camera',
@@ -1019,6 +1025,7 @@ export const VideoCallScreenLabels: I18nVideoCallScreenLabelsInterface = {
1019
1025
  `Once removed, ${name} will still be able to screen share later.`,
1020
1026
  [removeScreenshareFromRoomPopupPrimaryBtnText]: 'REMOVE',
1021
1027
 
1028
+ [textTrackModalTitleIntn]: 'Text Tracks',
1022
1029
  [sttChangeLanguagePopupHeading]: isFirstTimeOpened =>
1023
1030
  isFirstTimeOpened ? 'Set Spoken Language' : 'Change Spoken Language',
1024
1031
  [sttChangeLanguagePopupSubHeading]:
@@ -95,6 +95,7 @@ type LogType = {
95
95
  | 'channel_join_request'
96
96
  | 'channel_join_approval'
97
97
  | 'stt'
98
+ | 'stt-transcript'
98
99
  | 'whiteboard_get_s3_signed_url'
99
100
  | 'whiteboard_get_s3_upload_url'
100
101
  | 'whiteboard_s3_upload'