agora-appbuilder-core 4.1.8-beta.1 → 4.1.8-beta.11
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/package.json +2 -2
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +1 -1
- package/template/agora-rn-uikit/src/Rtc/Join.tsx +18 -9
- package/template/bridge/rtc/webNg/RtcEngine.ts +2 -2
- package/template/defaultConfig.js +4 -3
- package/template/global.d.ts +1 -0
- package/template/package.json +1 -1
- package/template/src/atoms/TextInput.tsx +3 -0
- package/template/src/components/Controls.tsx +17 -15
- package/template/src/components/common/GenericPopup.tsx +0 -1
- package/template/src/components/common/data-table.tsx +42 -15
- package/template/src/components/controls/useControlPermissionMatrix.tsx +7 -4
- package/template/src/components/recordings/RecordingItemRow.tsx +289 -0
- package/template/src/components/recordings/RecordingsDateTable.tsx +99 -25
- package/template/src/components/recordings/TextTrackItemRow.tsx +120 -0
- package/template/src/components/room-info/useRoomInfo.tsx +1 -0
- package/template/src/components/{stt-transcript/STTTranscriptTable.tsx → text-tracks/TextTracksTable.tsx} +61 -50
- package/template/src/components/{stt-transcript/ViewSTTTranscriptModal.tsx → text-tracks/ViewTextTracksModal.tsx} +7 -7
- package/template/src/components/text-tracks/useFetchSTTTranscript.tsx +262 -0
- package/template/src/language/default-labels/videoCallScreenLabels.ts +7 -7
- package/template/src/pages/VideoCall.tsx +1 -1
- package/template/src/subComponents/ChatInput.tsx +72 -1
- package/template/src/subComponents/recording/useRecording.tsx +19 -4
- package/template/src/utils/useCreateRoom.ts +1 -1
- package/template/src/utils/useJoinRoom.ts +5 -1
- package/template/src/components/stt-transcript/useFetchSTTTranscript.tsx +0 -193
|
@@ -1,30 +1,67 @@
|
|
|
1
1
|
import React, {useState, useEffect} from 'react';
|
|
2
2
|
import {View, Text} from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import {
|
|
4
|
+
APIStatus,
|
|
5
|
+
FetchRecordingData,
|
|
6
|
+
useRecording,
|
|
7
|
+
} from '../../subComponents/recording/useRecording';
|
|
6
8
|
import events from '../../rtm-events-api';
|
|
7
9
|
import {EventNames} from '../../rtm-events';
|
|
10
|
+
import {style, TableBody, TableHeader} from '../common/data-table';
|
|
11
|
+
import Loading from '../../subComponents/Loading';
|
|
12
|
+
import ImageIcon from '../../atoms/ImageIcon';
|
|
13
|
+
import RecordingItemRow from './RecordingItemRow';
|
|
14
|
+
import GenericPopup from '../common/GenericPopup';
|
|
15
|
+
import {downloadS3Link} from '../../utils/common';
|
|
16
|
+
import {useControlPermissionMatrix} from '../controls/useControlPermissionMatrix';
|
|
17
|
+
|
|
18
|
+
function EmptyRecordingState() {
|
|
19
|
+
return (
|
|
20
|
+
<View style={style.infotextContainer}>
|
|
21
|
+
<View>
|
|
22
|
+
<ImageIcon
|
|
23
|
+
iconType="plain"
|
|
24
|
+
name="info"
|
|
25
|
+
tintColor={'#777777'}
|
|
26
|
+
iconSize={32}
|
|
27
|
+
/>
|
|
28
|
+
</View>
|
|
29
|
+
<View>
|
|
30
|
+
<Text style={[style.infoText, style.pt10, style.pl10]}>
|
|
31
|
+
No recording found for this meeting
|
|
32
|
+
</Text>
|
|
33
|
+
</View>
|
|
34
|
+
</View>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const defaultPageNumber = 1;
|
|
8
39
|
|
|
9
40
|
function RecordingsDateTable(props) {
|
|
10
|
-
const [state, setState] = React.useState
|
|
41
|
+
const [state, setState] = React.useState<{
|
|
42
|
+
status: APIStatus;
|
|
43
|
+
data: {
|
|
44
|
+
recordings: FetchRecordingData['recordings'];
|
|
45
|
+
pagination: FetchRecordingData['pagination'];
|
|
46
|
+
};
|
|
47
|
+
error: Error;
|
|
48
|
+
}>({
|
|
11
49
|
status: 'idle',
|
|
12
50
|
data: {
|
|
13
|
-
pagination: {},
|
|
14
51
|
recordings: [],
|
|
52
|
+
pagination: {total: 0, limit: 10, page: defaultPageNumber},
|
|
15
53
|
},
|
|
16
54
|
error: null,
|
|
17
55
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
data: {pagination, recordings},
|
|
21
|
-
error,
|
|
22
|
-
} = state;
|
|
56
|
+
|
|
57
|
+
const [currentPage, setCurrentPage] = useState(defaultPageNumber);
|
|
23
58
|
|
|
24
59
|
const {fetchRecordings} = useRecording();
|
|
60
|
+
const canAccessAllTextTracks =
|
|
61
|
+
useControlPermissionMatrix('viewAllTextTracks');
|
|
25
62
|
|
|
26
|
-
|
|
27
|
-
const [
|
|
63
|
+
// message for any download‐error popup
|
|
64
|
+
const [errorSnack, setErrorSnack] = React.useState<string | undefined>();
|
|
28
65
|
|
|
29
66
|
const onRecordingDeleteCallback = () => {
|
|
30
67
|
setCurrentPage(defaultPageNumber);
|
|
@@ -38,7 +75,7 @@ function RecordingsDateTable(props) {
|
|
|
38
75
|
};
|
|
39
76
|
}, []);
|
|
40
77
|
|
|
41
|
-
const getRecordings = pageNumber => {
|
|
78
|
+
const getRecordings = (pageNumber: number) => {
|
|
42
79
|
setState(prev => ({...prev, status: 'pending'}));
|
|
43
80
|
fetchRecordings(pageNumber).then(
|
|
44
81
|
response =>
|
|
@@ -47,8 +84,13 @@ function RecordingsDateTable(props) {
|
|
|
47
84
|
status: 'resolved',
|
|
48
85
|
data: {
|
|
49
86
|
recordings: response?.recordings || [],
|
|
50
|
-
pagination: response?.pagination || {
|
|
87
|
+
pagination: response?.pagination || {
|
|
88
|
+
total: 0,
|
|
89
|
+
limit: 10,
|
|
90
|
+
page: defaultPageNumber,
|
|
91
|
+
},
|
|
51
92
|
},
|
|
93
|
+
error: null,
|
|
52
94
|
})),
|
|
53
95
|
error => setState(prev => ({...prev, status: 'rejected', error})),
|
|
54
96
|
);
|
|
@@ -58,26 +100,58 @@ function RecordingsDateTable(props) {
|
|
|
58
100
|
getRecordings(currentPage);
|
|
59
101
|
}, [currentPage]);
|
|
60
102
|
|
|
61
|
-
if (status === 'rejected') {
|
|
103
|
+
if (state.status === 'rejected') {
|
|
62
104
|
return (
|
|
63
105
|
<Text style={[style.ttime, style.pv10, style.ph20]}>
|
|
64
|
-
{error?.message}
|
|
106
|
+
{state.error?.message}
|
|
65
107
|
</Text>
|
|
66
108
|
);
|
|
67
109
|
}
|
|
110
|
+
const onTextTrackDownload = (textTrackLink: string) => {
|
|
111
|
+
downloadS3Link(textTrackLink).catch((err: Error) => {
|
|
112
|
+
setErrorSnack(err.message || 'Download failed');
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const headers = canAccessAllTextTracks
|
|
117
|
+
? ['', 'Date/Time', 'Duration', 'Actions']
|
|
118
|
+
: ['Date/Time', 'Duration', 'Actions'];
|
|
119
|
+
|
|
68
120
|
return (
|
|
69
121
|
<View style={style.ttable}>
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
onDeleteAction={props?.onDeleteAction}
|
|
122
|
+
<TableHeader
|
|
123
|
+
columns={headers}
|
|
124
|
+
firstCellStyle={canAccessAllTextTracks ? style.thIconCell : {}}
|
|
125
|
+
lastCellStyle={style.alignCellToRight}
|
|
75
126
|
/>
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
127
|
+
<TableBody
|
|
128
|
+
status={state.status}
|
|
129
|
+
items={state.data.recordings}
|
|
130
|
+
loadingComponent={
|
|
131
|
+
<Loading background="transparent" text="Fetching recordingss.." />
|
|
132
|
+
}
|
|
133
|
+
renderRow={item => (
|
|
134
|
+
<RecordingItemRow
|
|
135
|
+
key={item.id}
|
|
136
|
+
item={item}
|
|
137
|
+
onDeleteAction={props?.onDeleteAction}
|
|
138
|
+
onTextTrackDownload={onTextTrackDownload}
|
|
139
|
+
showTextTracks={canAccessAllTextTracks}
|
|
140
|
+
/>
|
|
141
|
+
)}
|
|
142
|
+
emptyComponent={<EmptyRecordingState />}
|
|
80
143
|
/>
|
|
144
|
+
{/** ERROR POPUP **/}
|
|
145
|
+
{errorSnack && (
|
|
146
|
+
<GenericPopup
|
|
147
|
+
title="Error"
|
|
148
|
+
variant="error"
|
|
149
|
+
message={errorSnack}
|
|
150
|
+
visible={true}
|
|
151
|
+
setVisible={() => setErrorSnack(undefined)}
|
|
152
|
+
onConfirm={() => setErrorSnack(undefined)}
|
|
153
|
+
/>
|
|
154
|
+
)}
|
|
81
155
|
</View>
|
|
82
156
|
);
|
|
83
157
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {View, Text, TouchableOpacity} from 'react-native';
|
|
3
|
+
import IconButtonWithToolTip from '../../atoms/IconButton';
|
|
4
|
+
import Tooltip from '../../atoms/Tooltip';
|
|
5
|
+
import Clipboard from '../../subComponents/Clipboard';
|
|
6
|
+
import Spacer from '../../atoms/Spacer';
|
|
7
|
+
import PlatformWrapper from '../../utils/PlatformWrapper';
|
|
8
|
+
import {FetchSTTTranscriptResponse} from '../text-tracks/useFetchSTTTranscript';
|
|
9
|
+
import {style} from '../common/data-table';
|
|
10
|
+
import ImageIcon from '../../atoms/ImageIcon';
|
|
11
|
+
|
|
12
|
+
interface TextTrackItemRowProps {
|
|
13
|
+
item: FetchSTTTranscriptResponse['stts'][0];
|
|
14
|
+
onTextTrackDownload: (link: string) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function TextTrackItemRow({
|
|
18
|
+
item,
|
|
19
|
+
onTextTrackDownload,
|
|
20
|
+
}: TextTrackItemRowProps) {
|
|
21
|
+
const textTrackStatus = item.status;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<View style={style.td} key={item.id}>
|
|
25
|
+
{!item.download_url ? (
|
|
26
|
+
<View style={[style.tactions, {marginTop: 0}]}>
|
|
27
|
+
{textTrackStatus === 'STOPPING' ||
|
|
28
|
+
textTrackStatus === 'STARTED' ||
|
|
29
|
+
(textTrackStatus === 'INPROGRESS' && !item?.download_url) ? (
|
|
30
|
+
<Text style={style.placeHolder}>
|
|
31
|
+
{'The link will be generated once the meeting ends'}
|
|
32
|
+
</Text>
|
|
33
|
+
) : (
|
|
34
|
+
<Text style={style.placeHolder}>{'No text-tracks found'}</Text>
|
|
35
|
+
)}
|
|
36
|
+
</View>
|
|
37
|
+
) : item?.download_url?.length > 0 ? (
|
|
38
|
+
<View style={style.tactions}>
|
|
39
|
+
<View>
|
|
40
|
+
{item?.download_url?.map((link: string, i: number) => (
|
|
41
|
+
<View
|
|
42
|
+
key={i}
|
|
43
|
+
style={[
|
|
44
|
+
style.tactions,
|
|
45
|
+
//if stts contains multiple parts then we need to add some space each row
|
|
46
|
+
i >= 1 ? {marginTop: 8} : {},
|
|
47
|
+
]}>
|
|
48
|
+
<View>
|
|
49
|
+
<IconButtonWithToolTip
|
|
50
|
+
hoverEffect={true}
|
|
51
|
+
hoverEffectStyle={style.iconButtonHoverEffect}
|
|
52
|
+
containerStyle={style.iconButton}
|
|
53
|
+
iconProps={{
|
|
54
|
+
name: 'download',
|
|
55
|
+
iconType: 'plain',
|
|
56
|
+
iconSize: 20,
|
|
57
|
+
tintColor: `${$config.SECONDARY_ACTION_COLOR}`,
|
|
58
|
+
}}
|
|
59
|
+
onPress={() => {
|
|
60
|
+
onTextTrackDownload && onTextTrackDownload(link);
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
</View>
|
|
64
|
+
<View style={[style.pl10]}>
|
|
65
|
+
<Tooltip
|
|
66
|
+
isClickable
|
|
67
|
+
placement="left"
|
|
68
|
+
toolTipMessage="Link Copied"
|
|
69
|
+
onPress={() => {
|
|
70
|
+
Clipboard.setString(link);
|
|
71
|
+
}}
|
|
72
|
+
toolTipIcon={
|
|
73
|
+
<>
|
|
74
|
+
<ImageIcon
|
|
75
|
+
iconType="plain"
|
|
76
|
+
name="tick-fill"
|
|
77
|
+
tintColor={$config.SEMANTIC_SUCCESS}
|
|
78
|
+
iconSize={20}
|
|
79
|
+
/>
|
|
80
|
+
<Spacer size={8} horizontal={true} />
|
|
81
|
+
</>
|
|
82
|
+
}
|
|
83
|
+
fontSize={12}
|
|
84
|
+
renderContent={() => {
|
|
85
|
+
return (
|
|
86
|
+
<PlatformWrapper>
|
|
87
|
+
{(isHovered: boolean) => (
|
|
88
|
+
<TouchableOpacity
|
|
89
|
+
style={[
|
|
90
|
+
isHovered ? style.iconButtonHoverEffect : {},
|
|
91
|
+
style.iconShareLink,
|
|
92
|
+
]}
|
|
93
|
+
onPress={() => {
|
|
94
|
+
Clipboard.setString(link);
|
|
95
|
+
}}>
|
|
96
|
+
<ImageIcon
|
|
97
|
+
iconType="plain"
|
|
98
|
+
name="copy-link"
|
|
99
|
+
iconSize={20}
|
|
100
|
+
tintColor={$config.SECONDARY_ACTION_COLOR}
|
|
101
|
+
/>
|
|
102
|
+
</TouchableOpacity>
|
|
103
|
+
)}
|
|
104
|
+
</PlatformWrapper>
|
|
105
|
+
);
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
</View>
|
|
109
|
+
</View>
|
|
110
|
+
))}
|
|
111
|
+
</View>
|
|
112
|
+
</View>
|
|
113
|
+
) : (
|
|
114
|
+
<View style={(style.tactions, {marginTop: 0})}>
|
|
115
|
+
<Text style={style.placeHolder}>No text-tracks found</Text>
|
|
116
|
+
</View>
|
|
117
|
+
)}
|
|
118
|
+
</View>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, {useEffect} from 'react';
|
|
2
2
|
import {View, Text, TouchableOpacity} from 'react-native';
|
|
3
3
|
import Tooltip from '../../atoms/Tooltip';
|
|
4
4
|
import Clipboard from '../../subComponents/Clipboard';
|
|
@@ -22,20 +22,24 @@ import PlatformWrapper from '../../utils/PlatformWrapper';
|
|
|
22
22
|
|
|
23
23
|
const headers = ['Date', 'Time', 'Status', 'Actions'];
|
|
24
24
|
|
|
25
|
-
interface
|
|
25
|
+
interface TextTrackItemRowProps {
|
|
26
26
|
item: FetchSTTTranscriptResponse['stts'][0];
|
|
27
27
|
onDeleteAction: (id: string) => void;
|
|
28
28
|
onDownloadAction: (link: string) => void;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function
|
|
31
|
+
function TextTrackItemRow({
|
|
32
|
+
item,
|
|
33
|
+
onDeleteAction,
|
|
34
|
+
onDownloadAction,
|
|
35
|
+
}: TextTrackItemRowProps) {
|
|
32
36
|
const [date, time] = getFormattedDateTime(item.created_at);
|
|
33
|
-
const
|
|
37
|
+
const textTrackStatus = item.status;
|
|
34
38
|
|
|
35
39
|
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
(
|
|
40
|
+
textTrackStatus === 'STOPPING' ||
|
|
41
|
+
textTrackStatus === 'STARTED' ||
|
|
42
|
+
(textTrackStatus === 'INPROGRESS' && !item?.download_url)
|
|
39
43
|
) {
|
|
40
44
|
return (
|
|
41
45
|
<View key={item.id} style={style.pt12}>
|
|
@@ -63,12 +67,14 @@ function STTItemRow({item, onDeleteAction, onDownloadAction}: STTItemRowProps) {
|
|
|
63
67
|
<Text style={style.ttime}>{time}</Text>
|
|
64
68
|
</View>
|
|
65
69
|
<View style={[style.td]}>
|
|
66
|
-
<Text style={style.ttime}>
|
|
70
|
+
<Text style={style.ttime}>
|
|
71
|
+
{capitalizeFirstLetter(textTrackStatus)}
|
|
72
|
+
</Text>
|
|
67
73
|
</View>
|
|
68
74
|
<View style={style.td}>
|
|
69
75
|
{!item.download_url ? (
|
|
70
76
|
<View style={[style.tactions, {marginTop: 0}]}>
|
|
71
|
-
<Text style={style.placeHolder}>{'No
|
|
77
|
+
<Text style={style.placeHolder}>{'No text-tracks found'}</Text>
|
|
72
78
|
</View>
|
|
73
79
|
) : item?.download_url?.length > 0 ? (
|
|
74
80
|
<View style={style.tactions}>
|
|
@@ -165,7 +171,7 @@ function STTItemRow({item, onDeleteAction, onDownloadAction}: STTItemRowProps) {
|
|
|
165
171
|
</View>
|
|
166
172
|
) : (
|
|
167
173
|
<View style={(style.tactions, {marginTop: 0})}>
|
|
168
|
-
<Text style={style.placeHolder}>No
|
|
174
|
+
<Text style={style.placeHolder}>No text-tracks found</Text>
|
|
169
175
|
</View>
|
|
170
176
|
)}
|
|
171
177
|
</View>
|
|
@@ -173,7 +179,7 @@ function STTItemRow({item, onDeleteAction, onDownloadAction}: STTItemRowProps) {
|
|
|
173
179
|
);
|
|
174
180
|
}
|
|
175
181
|
|
|
176
|
-
function
|
|
182
|
+
function EmptyTextTrackState() {
|
|
177
183
|
return (
|
|
178
184
|
<View style={style.infotextContainer}>
|
|
179
185
|
<View>
|
|
@@ -186,49 +192,50 @@ function EmptyTranscriptState() {
|
|
|
186
192
|
</View>
|
|
187
193
|
<View>
|
|
188
194
|
<Text style={[style.infoText, style.pt10, style.pl10]}>
|
|
189
|
-
No
|
|
195
|
+
No text-tracks found for this meeting
|
|
190
196
|
</Text>
|
|
191
197
|
</View>
|
|
192
198
|
</View>
|
|
193
199
|
);
|
|
194
200
|
}
|
|
195
201
|
|
|
196
|
-
function
|
|
202
|
+
function ErrorTextTrackState({message}: {message: string}) {
|
|
197
203
|
return <Text style={[style.ttime, style.pv10, style.ph20]}>{message}</Text>;
|
|
198
204
|
}
|
|
199
205
|
|
|
200
|
-
function
|
|
206
|
+
function TextTracksTable() {
|
|
207
|
+
const {getSTTs, sttState, currentPage, setCurrentPage, deleteTranscript} =
|
|
208
|
+
useFetchSTTTranscript();
|
|
209
|
+
|
|
201
210
|
const {
|
|
202
211
|
status,
|
|
203
|
-
stts,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
currentPage,
|
|
207
|
-
setCurrentPage,
|
|
208
|
-
deleteTranscript,
|
|
209
|
-
} = useFetchSTTTranscript();
|
|
212
|
+
data: {stts, pagination},
|
|
213
|
+
error: fetchTranscriptError,
|
|
214
|
+
} = sttState;
|
|
210
215
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
);
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
getSTTs(currentPage);
|
|
218
|
+
}, [currentPage, getSTTs]);
|
|
215
219
|
|
|
216
|
-
//
|
|
217
|
-
const [
|
|
220
|
+
// id of text-tracj to delete
|
|
221
|
+
const [textTrackIdToDelete, setTextTrackIdToDelete] = React.useState<
|
|
218
222
|
string | undefined
|
|
219
|
-
>();
|
|
223
|
+
>(undefined);
|
|
224
|
+
|
|
225
|
+
// message for any download‐error popup
|
|
226
|
+
const [errorSnack, setErrorSnack] = React.useState<string | undefined>();
|
|
220
227
|
|
|
221
228
|
if (status === 'rejected') {
|
|
222
|
-
return <
|
|
229
|
+
return <ErrorTextTrackState message={fetchTranscriptError?.message} />;
|
|
223
230
|
}
|
|
224
231
|
|
|
225
|
-
const
|
|
232
|
+
const onDeleteTextTrackRecord = async (trackId: string) => {
|
|
226
233
|
try {
|
|
227
|
-
await deleteTranscript(
|
|
234
|
+
await deleteTranscript(trackId!);
|
|
228
235
|
} catch (err: any) {
|
|
229
|
-
|
|
236
|
+
setErrorSnack(err.message);
|
|
230
237
|
} finally {
|
|
231
|
-
|
|
238
|
+
setTextTrackIdToDelete(undefined);
|
|
232
239
|
}
|
|
233
240
|
};
|
|
234
241
|
|
|
@@ -240,23 +247,23 @@ function STTTranscriptTable() {
|
|
|
240
247
|
status={status}
|
|
241
248
|
items={stts}
|
|
242
249
|
loadingComponent={
|
|
243
|
-
<Loading background="transparent" text="Fetching
|
|
250
|
+
<Loading background="transparent" text="Fetching text-tracks.." />
|
|
244
251
|
}
|
|
245
252
|
renderRow={item => (
|
|
246
|
-
<
|
|
253
|
+
<TextTrackItemRow
|
|
247
254
|
key={item.id}
|
|
248
255
|
item={item}
|
|
249
256
|
onDeleteAction={id => {
|
|
250
|
-
|
|
257
|
+
setTextTrackIdToDelete(id);
|
|
251
258
|
}}
|
|
252
259
|
onDownloadAction={link => {
|
|
253
260
|
downloadS3Link(link).catch((err: Error) => {
|
|
254
|
-
|
|
261
|
+
setErrorSnack(err.message || 'Download failed');
|
|
255
262
|
});
|
|
256
263
|
}}
|
|
257
264
|
/>
|
|
258
265
|
)}
|
|
259
|
-
emptyComponent={<
|
|
266
|
+
emptyComponent={<EmptyTextTrackState />}
|
|
260
267
|
/>
|
|
261
268
|
<TableFooter
|
|
262
269
|
currentPage={currentPage}
|
|
@@ -264,32 +271,36 @@ function STTTranscriptTable() {
|
|
|
264
271
|
pagination={pagination}
|
|
265
272
|
/>
|
|
266
273
|
</View>
|
|
267
|
-
{
|
|
274
|
+
{textTrackIdToDelete && (
|
|
268
275
|
<GenericPopup
|
|
269
276
|
title="Delete ? "
|
|
270
277
|
variant="error"
|
|
271
|
-
message="Are you sure want to delete the
|
|
272
|
-
visible={!!
|
|
273
|
-
setVisible={() =>
|
|
274
|
-
onConfirm={
|
|
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
|
+
}}
|
|
275
286
|
onCancel={() => {
|
|
276
|
-
|
|
287
|
+
setTextTrackIdToDelete(undefined);
|
|
277
288
|
}}
|
|
278
289
|
/>
|
|
279
290
|
)}
|
|
280
291
|
{/** DOWNLOAD ERROR POPUP **/}
|
|
281
|
-
{
|
|
292
|
+
{errorSnack && (
|
|
282
293
|
<GenericPopup
|
|
283
|
-
title="
|
|
294
|
+
title="Error"
|
|
284
295
|
variant="error"
|
|
285
|
-
message={
|
|
296
|
+
message={errorSnack}
|
|
286
297
|
visible={true}
|
|
287
|
-
setVisible={() =>
|
|
288
|
-
onConfirm={() =>
|
|
298
|
+
setVisible={() => setErrorSnack(undefined)}
|
|
299
|
+
onConfirm={() => setErrorSnack(undefined)}
|
|
289
300
|
/>
|
|
290
301
|
)}
|
|
291
302
|
</>
|
|
292
303
|
);
|
|
293
304
|
}
|
|
294
305
|
|
|
295
|
-
export default
|
|
306
|
+
export default TextTracksTable;
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import React, {SetStateAction, Dispatch} from 'react';
|
|
2
2
|
import {View, StyleSheet} from 'react-native';
|
|
3
3
|
import {useString} from '../../utils/useString';
|
|
4
|
-
import {
|
|
4
|
+
import {textTrackModalTitleIntn} from '../../language/default-labels/videoCallScreenLabels';
|
|
5
5
|
import GenericModal from '../common/GenericModal';
|
|
6
|
-
import
|
|
6
|
+
import TextTracksTable from './TextTracksTable';
|
|
7
7
|
|
|
8
|
-
interface
|
|
8
|
+
interface ViewTextTracksModalProps {
|
|
9
9
|
setModalOpen: Dispatch<SetStateAction<boolean>>;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export default function
|
|
12
|
+
export default function ViewTextTracksModal(props: ViewTextTracksModalProps) {
|
|
13
13
|
const {setModalOpen} = props;
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const textTrackModalTitle = useString(textTrackModalTitleIntn)();
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
18
|
<GenericModal
|
|
19
19
|
visible={true}
|
|
20
20
|
onRequestClose={() => setModalOpen(false)}
|
|
21
21
|
showCloseIcon={true}
|
|
22
|
-
title={
|
|
22
|
+
title={textTrackModalTitle}
|
|
23
23
|
cancelable={false}
|
|
24
24
|
contentContainerStyle={style.contentContainer}>
|
|
25
25
|
<View style={style.fullBody}>
|
|
26
|
-
<
|
|
26
|
+
<TextTracksTable />
|
|
27
27
|
</View>
|
|
28
28
|
</GenericModal>
|
|
29
29
|
);
|