agora-appbuilder-core 4.0.29-beta-24 → 4.0.29-beta-25
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 +1 -1
- package/template/customization-api/sub-components.ts +1 -0
- package/template/src/atoms/ActionMenu.tsx +9 -1
- package/template/src/atoms/Checkbox.tsx +17 -3
- package/template/src/atoms/TertiaryButton.tsx +20 -4
- package/template/src/atoms/Toggle.tsx +9 -3
- package/template/src/components/CustomSidePanel.tsx +1 -2
- package/template/src/components/EventsConfigure.tsx +9 -3
- package/template/src/pages/VideoCall.tsx +3 -0
- package/template/src/subComponents/recording/useRecording.tsx +54 -29
package/package.json
CHANGED
|
@@ -85,3 +85,4 @@ export {default as TranscriptPanel} from '../src/subComponents/caption/Transcrip
|
|
|
85
85
|
export type {TranscriptProps} from '../src/subComponents/caption/Transcript';
|
|
86
86
|
export {default as CaptionPanel} from '../src/subComponents/caption/CaptionContainer';
|
|
87
87
|
export {default as VBPreview} from '../src/components/virtual-background/VideoPreview';
|
|
88
|
+
export {default as Toast} from '../react-native-toast-message';
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
TouchableOpacity,
|
|
10
10
|
ViewStyle,
|
|
11
11
|
useWindowDimensions,
|
|
12
|
+
StyleProp,
|
|
13
|
+
TextStyle,
|
|
12
14
|
} from 'react-native';
|
|
13
15
|
import React, {SetStateAction, useState} from 'react';
|
|
14
16
|
|
|
@@ -32,6 +34,7 @@ export interface ActionMenuItem {
|
|
|
32
34
|
iconColor: string;
|
|
33
35
|
textColor: string;
|
|
34
36
|
title: string;
|
|
37
|
+
titleStyle?: StyleProp<TextStyle>;
|
|
35
38
|
label?: string;
|
|
36
39
|
toggleStatus?: boolean;
|
|
37
40
|
onPress: () => void;
|
|
@@ -97,6 +100,7 @@ const ActionMenu = (props: ActionMenuProps) => {
|
|
|
97
100
|
onHoverCallback = undefined,
|
|
98
101
|
onHoverContent = undefined,
|
|
99
102
|
iconSize = 20,
|
|
103
|
+
titleStyle = {},
|
|
100
104
|
} = item;
|
|
101
105
|
return (
|
|
102
106
|
<PlatformWrapper key={props.from + '_' + title + index}>
|
|
@@ -175,7 +179,11 @@ const ActionMenu = (props: ActionMenuProps) => {
|
|
|
175
179
|
)}
|
|
176
180
|
</View>
|
|
177
181
|
<Text
|
|
178
|
-
style={[
|
|
182
|
+
style={[
|
|
183
|
+
styles.text,
|
|
184
|
+
titleStyle,
|
|
185
|
+
textColor ? {color: textColor} : {},
|
|
186
|
+
]}>
|
|
179
187
|
{label || title}
|
|
180
188
|
</Text>
|
|
181
189
|
{toggleStatus !== undefined && toggleStatus !== null ? (
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
Platform,
|
|
7
7
|
StyleSheet,
|
|
8
8
|
TextStyle,
|
|
9
|
+
ViewStyle,
|
|
9
10
|
} from 'react-native';
|
|
10
11
|
|
|
11
12
|
import ThemeConfig from '../theme';
|
|
@@ -17,6 +18,9 @@ interface CheckboxProps {
|
|
|
17
18
|
onChange: (checked: boolean) => void;
|
|
18
19
|
labelStye?: TextStyle;
|
|
19
20
|
disabled?: boolean;
|
|
21
|
+
containerStyle?: ViewStyle;
|
|
22
|
+
checkBoxStyle?: ViewStyle;
|
|
23
|
+
tickColor?: string;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
const Checkbox: React.FC<CheckboxProps> = ({
|
|
@@ -25,6 +29,9 @@ const Checkbox: React.FC<CheckboxProps> = ({
|
|
|
25
29
|
onChange,
|
|
26
30
|
disabled = false,
|
|
27
31
|
labelStye = {},
|
|
32
|
+
containerStyle = {},
|
|
33
|
+
checkBoxStyle = {},
|
|
34
|
+
tickColor = $config.FONT_COLOR,
|
|
28
35
|
}) => {
|
|
29
36
|
const [isChecked, setIsChecked] = useState(checked);
|
|
30
37
|
|
|
@@ -40,15 +47,21 @@ const Checkbox: React.FC<CheckboxProps> = ({
|
|
|
40
47
|
};
|
|
41
48
|
|
|
42
49
|
return (
|
|
43
|
-
<TouchableOpacity
|
|
50
|
+
<TouchableOpacity
|
|
51
|
+
onPress={handleCheckboxToggle}
|
|
52
|
+
style={(styles.container, containerStyle)}>
|
|
44
53
|
<View
|
|
45
|
-
style={[
|
|
54
|
+
style={[
|
|
55
|
+
styles.checkboxContainer,
|
|
56
|
+
checkBoxStyle,
|
|
57
|
+
isChecked && styles.fillSelected,
|
|
58
|
+
]}>
|
|
46
59
|
{isChecked && (
|
|
47
60
|
<ImageIcon
|
|
48
61
|
iconType="plain"
|
|
49
62
|
name={'tick'}
|
|
50
63
|
iconSize={8}
|
|
51
|
-
tintColor={
|
|
64
|
+
tintColor={tickColor}
|
|
52
65
|
/>
|
|
53
66
|
)}
|
|
54
67
|
</View>
|
|
@@ -76,6 +89,7 @@ const styles = StyleSheet.create({
|
|
|
76
89
|
borderColor: $config.SEMANTIC_NEUTRAL,
|
|
77
90
|
justifyContent: 'center',
|
|
78
91
|
alignItems: 'center',
|
|
92
|
+
borderRadius: 1,
|
|
79
93
|
},
|
|
80
94
|
checkIcon: {
|
|
81
95
|
position: 'absolute',
|
|
@@ -31,6 +31,7 @@ const TertiaryButton = (props: ButtonProps) => {
|
|
|
31
31
|
iconName,
|
|
32
32
|
iconSize = 26,
|
|
33
33
|
iconColor = $config.PRIMARY_ACTION_TEXT_COLOR,
|
|
34
|
+
disabled = false,
|
|
34
35
|
...rest
|
|
35
36
|
} = props;
|
|
36
37
|
const [isHovered, setIsHovered] = useState(false);
|
|
@@ -38,16 +39,17 @@ const TertiaryButton = (props: ButtonProps) => {
|
|
|
38
39
|
return (
|
|
39
40
|
<PlatformWrapper setIsHovered={setIsHovered}>
|
|
40
41
|
<TouchableOpacity
|
|
41
|
-
ref={
|
|
42
|
+
ref={ref => props?.setRef && props.setRef(ref)}
|
|
42
43
|
style={[
|
|
43
44
|
styles.container,
|
|
44
|
-
isHovered
|
|
45
|
+
isHovered && !disabled
|
|
45
46
|
? {
|
|
46
47
|
backgroundColor:
|
|
47
48
|
$config.CARD_LAYER_5_COLOR + hexadecimalTransparency['15%'],
|
|
48
49
|
}
|
|
49
50
|
: {},
|
|
50
51
|
props?.containerStyle,
|
|
52
|
+
disabled ? styles.disabledContainer : {},
|
|
51
53
|
]}
|
|
52
54
|
{...rest}>
|
|
53
55
|
<View style={styles.flexRow}>
|
|
@@ -57,11 +59,18 @@ const TertiaryButton = (props: ButtonProps) => {
|
|
|
57
59
|
iconSize={iconSize}
|
|
58
60
|
iconType="plain"
|
|
59
61
|
name={iconName}
|
|
60
|
-
tintColor={iconColor}
|
|
62
|
+
tintColor={disabled ? $config.SEMANTIC_NEUTRAL : iconColor}
|
|
61
63
|
/>
|
|
62
64
|
</View>
|
|
63
65
|
)}
|
|
64
|
-
<Text
|
|
66
|
+
<Text
|
|
67
|
+
style={[
|
|
68
|
+
styles.text,
|
|
69
|
+
props?.textStyle,
|
|
70
|
+
disabled ? styles.disabledText : {},
|
|
71
|
+
]}>
|
|
72
|
+
{text}
|
|
73
|
+
</Text>
|
|
65
74
|
</View>
|
|
66
75
|
</TouchableOpacity>
|
|
67
76
|
</PlatformWrapper>
|
|
@@ -105,4 +114,11 @@ const styles = StyleSheet.create({
|
|
|
105
114
|
fontSize: ThemeConfig.FontSize.small,
|
|
106
115
|
fontWeight: '600',
|
|
107
116
|
},
|
|
117
|
+
disabledContainer: {
|
|
118
|
+
borderColor: $config.SEMANTIC_NEUTRAL,
|
|
119
|
+
cursor: 'default',
|
|
120
|
+
},
|
|
121
|
+
disabledText: {
|
|
122
|
+
color: $config.SEMANTIC_NEUTRAL,
|
|
123
|
+
},
|
|
108
124
|
});
|
|
@@ -6,10 +6,16 @@ interface SwitchProps {
|
|
|
6
6
|
isEnabled: boolean;
|
|
7
7
|
disabled?: boolean;
|
|
8
8
|
toggleSwitch: (isEnabled: boolean) => void;
|
|
9
|
+
circleColor?: string;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
const Toggle = (props: SwitchProps) => {
|
|
12
|
-
const {
|
|
13
|
+
const {
|
|
14
|
+
isEnabled,
|
|
15
|
+
toggleSwitch,
|
|
16
|
+
disabled = false,
|
|
17
|
+
circleColor = $config.CARD_LAYER_1_COLOR,
|
|
18
|
+
} = props;
|
|
13
19
|
return (
|
|
14
20
|
<View>
|
|
15
21
|
<CustomSwitch
|
|
@@ -21,8 +27,8 @@ const Toggle = (props: SwitchProps) => {
|
|
|
21
27
|
disabled={false}
|
|
22
28
|
backgroundActive={$config.PRIMARY_ACTION_BRAND_COLOR}
|
|
23
29
|
backgroundInactive={$config.SEMANTIC_NEUTRAL}
|
|
24
|
-
circleActiveColor={
|
|
25
|
-
circleInActiveColor={
|
|
30
|
+
circleActiveColor={circleColor}
|
|
31
|
+
circleInActiveColor={circleColor}
|
|
26
32
|
// renderInsideCircle={() => <CustomComponent />} // custom component to render inside the Switch circle (Text, Image, etc.)
|
|
27
33
|
changeValueImmediately={true} // if rendering inside circle, change state immediately or wait for animation to complete
|
|
28
34
|
innerCircleStyle={{
|
|
@@ -65,7 +65,7 @@ const CustomSidePanelView = (props: CustomSidePanelViewInterface) => {
|
|
|
65
65
|
{showHeader && (
|
|
66
66
|
<CustomSidePanelHeader name={name} title={title} onClose={onClose} />
|
|
67
67
|
)}
|
|
68
|
-
<ScrollView
|
|
68
|
+
<ScrollView contentContainerStyle={[style.bodyContainer]}>
|
|
69
69
|
{CustomSidePanelContent ? <CustomSidePanelContent /> : <></>}
|
|
70
70
|
</ScrollView>
|
|
71
71
|
</View>
|
|
@@ -75,7 +75,6 @@ const CustomSidePanelView = (props: CustomSidePanelViewInterface) => {
|
|
|
75
75
|
const style = StyleSheet.create({
|
|
76
76
|
bodyContainer: {
|
|
77
77
|
flex: 1,
|
|
78
|
-
padding: 20,
|
|
79
78
|
},
|
|
80
79
|
});
|
|
81
80
|
|
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
import {useString} from '../utils/useString';
|
|
55
55
|
import useEndCall from '../utils/useEndCall';
|
|
56
56
|
import {logger, LogSource} from '../logger/AppBuilderLogger';
|
|
57
|
+
import {useIsRecordingBot} from '../subComponents/recording/useIsRecordingBot';
|
|
57
58
|
|
|
58
59
|
interface Props {
|
|
59
60
|
children: React.ReactNode;
|
|
@@ -68,6 +69,7 @@ const EventsConfigure: React.FC<Props> = ({
|
|
|
68
69
|
setSttAutoStarted,
|
|
69
70
|
sttAutoStarted,
|
|
70
71
|
}) => {
|
|
72
|
+
const {isRecordingBot} = useIsRecordingBot();
|
|
71
73
|
const isSTTAlreadyActiveRef = useRef(undefined);
|
|
72
74
|
// mute user audio
|
|
73
75
|
const hostMutedUserAudioToastHeadingTT = useString<I18nMuteType>(
|
|
@@ -270,6 +272,7 @@ const EventsConfigure: React.FC<Props> = ({
|
|
|
270
272
|
//auto start stt
|
|
271
273
|
useEffect(() => {
|
|
272
274
|
if (
|
|
275
|
+
!isRecordingBot &&
|
|
273
276
|
$config.ENABLE_CAPTION &&
|
|
274
277
|
$config.STT_AUTO_START &&
|
|
275
278
|
callActive &&
|
|
@@ -279,7 +282,9 @@ const EventsConfigure: React.FC<Props> = ({
|
|
|
279
282
|
) {
|
|
280
283
|
//host will start the caption
|
|
281
284
|
if (isHost && roomId?.host && !isSTTAlreadyActiveRef.current) {
|
|
282
|
-
logger.log(LogSource.Internals, 'STT', 'STT_AUTO_START triggered'
|
|
285
|
+
logger.log(LogSource.Internals, 'STT', 'STT_AUTO_START triggered', {
|
|
286
|
+
uidWhoTriggered: localUid,
|
|
287
|
+
});
|
|
283
288
|
//start with default language
|
|
284
289
|
startSpeechToText(['en-US'])
|
|
285
290
|
.then(() => {
|
|
@@ -289,7 +294,7 @@ const EventsConfigure: React.FC<Props> = ({
|
|
|
289
294
|
.catch(err => {
|
|
290
295
|
logger.log(
|
|
291
296
|
LogSource.Internals,
|
|
292
|
-
'
|
|
297
|
+
'STT',
|
|
293
298
|
'STT_AUTO_START failed',
|
|
294
299
|
err,
|
|
295
300
|
);
|
|
@@ -301,12 +306,13 @@ const EventsConfigure: React.FC<Props> = ({
|
|
|
301
306
|
logger.log(
|
|
302
307
|
LogSource.Internals,
|
|
303
308
|
'STT',
|
|
304
|
-
'STT_AUTO_START triggered
|
|
309
|
+
'STT_AUTO_START already triggered by some other host',
|
|
305
310
|
);
|
|
306
311
|
setSttAutoStarted(true);
|
|
307
312
|
}
|
|
308
313
|
}
|
|
309
314
|
}, [
|
|
315
|
+
isRecordingBot,
|
|
310
316
|
callActive,
|
|
311
317
|
isHost,
|
|
312
318
|
hasUserJoinedRTM,
|
|
@@ -151,6 +151,7 @@ const VideoCall: React.FC = () => {
|
|
|
151
151
|
const [waitingRoomAttendeeJoined, setWaitingRoomAttendeeJoined] =
|
|
152
152
|
useState(false);
|
|
153
153
|
const [sttAutoStarted, setSttAutoStarted] = useState(false);
|
|
154
|
+
const [recordingAutoStarted, setRecordingAutoStarted] = useState(false);
|
|
154
155
|
|
|
155
156
|
const {phrase} = useParams<{phrase: string}>();
|
|
156
157
|
|
|
@@ -489,6 +490,8 @@ const VideoCall: React.FC = () => {
|
|
|
489
490
|
setRecordingActive,
|
|
490
491
|
isRecordingActive,
|
|
491
492
|
callActive,
|
|
493
|
+
recordingAutoStarted,
|
|
494
|
+
setRecordingAutoStarted,
|
|
492
495
|
}}>
|
|
493
496
|
<NetworkQualityProvider>
|
|
494
497
|
{!isMobileUA() && (
|
|
@@ -104,6 +104,8 @@ interface RecordingProviderProps {
|
|
|
104
104
|
setRecordingActive: React.Dispatch<SetStateAction<boolean>>;
|
|
105
105
|
isRecordingActive: boolean;
|
|
106
106
|
callActive: boolean;
|
|
107
|
+
recordingAutoStarted: boolean;
|
|
108
|
+
setRecordingAutoStarted: React.Dispatch<React.SetStateAction<boolean>>;
|
|
107
109
|
};
|
|
108
110
|
}
|
|
109
111
|
|
|
@@ -141,8 +143,13 @@ const showErrorToast = (text1: string, text2?: string) => {
|
|
|
141
143
|
};
|
|
142
144
|
|
|
143
145
|
const RecordingProvider = (props: RecordingProviderProps) => {
|
|
144
|
-
const {
|
|
145
|
-
|
|
146
|
+
const {
|
|
147
|
+
setRecordingActive,
|
|
148
|
+
isRecordingActive,
|
|
149
|
+
callActive,
|
|
150
|
+
recordingAutoStarted,
|
|
151
|
+
setRecordingAutoStarted,
|
|
152
|
+
} = props?.value;
|
|
146
153
|
const {
|
|
147
154
|
data: {isHost, roomId},
|
|
148
155
|
} = useRoomInfo();
|
|
@@ -167,7 +174,8 @@ const RecordingProvider = (props: RecordingProviderProps) => {
|
|
|
167
174
|
|
|
168
175
|
const userlabel = useString(videoRoomUserFallbackText)();
|
|
169
176
|
|
|
170
|
-
const {localUid, hasUserJoinedRTM} =
|
|
177
|
+
const {localUid, hasUserJoinedRTM, isInitialQueueCompleted} =
|
|
178
|
+
useContext(ChatContext);
|
|
171
179
|
const {store} = React.useContext(StorageContext);
|
|
172
180
|
|
|
173
181
|
const {setChatType} = useChatUIControls();
|
|
@@ -841,33 +849,50 @@ const RecordingProvider = (props: RecordingProviderProps) => {
|
|
|
841
849
|
_stopRecording,
|
|
842
850
|
]);
|
|
843
851
|
|
|
844
|
-
//commented auto start for cloud recording
|
|
845
852
|
// auto start recording
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
853
|
+
useEffect(() => {
|
|
854
|
+
if (
|
|
855
|
+
$config.CLOUD_RECORDING &&
|
|
856
|
+
$config.CLOUD_RECORDING_AUTO_START &&
|
|
857
|
+
callActive &&
|
|
858
|
+
hasUserJoinedRTM &&
|
|
859
|
+
isInitialQueueCompleted &&
|
|
860
|
+
isHost &&
|
|
861
|
+
roomId?.host &&
|
|
862
|
+
!isRecordingBot &&
|
|
863
|
+
!recordingAutoStarted
|
|
864
|
+
) {
|
|
865
|
+
if (!isRecordingActive) {
|
|
866
|
+
logger.log(
|
|
867
|
+
LogSource.Internals,
|
|
868
|
+
'RECORDING',
|
|
869
|
+
'CLOUD_RECORDING_AUTO_START triggered',
|
|
870
|
+
{
|
|
871
|
+
uidWhoTriggered: localUid,
|
|
872
|
+
},
|
|
873
|
+
);
|
|
874
|
+
startRecording();
|
|
875
|
+
setRecordingAutoStarted(true);
|
|
876
|
+
} else {
|
|
877
|
+
logger.log(
|
|
878
|
+
LogSource.Internals,
|
|
879
|
+
'RECORDING',
|
|
880
|
+
'CLOUD_RECORDING_AUTO_START already triggered by some other host',
|
|
881
|
+
);
|
|
882
|
+
setRecordingAutoStarted(true);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}, [
|
|
886
|
+
callActive,
|
|
887
|
+
hasUserJoinedRTM,
|
|
888
|
+
isInitialQueueCompleted,
|
|
889
|
+
isHost,
|
|
890
|
+
isRecordingBot,
|
|
891
|
+
isRecordingActive,
|
|
892
|
+
recordingAutoStarted,
|
|
893
|
+
localUid,
|
|
894
|
+
roomId,
|
|
895
|
+
]);
|
|
871
896
|
|
|
872
897
|
// useEffect(() => { //
|
|
873
898
|
// if (hasUserJoinedRTM && isRecordingBot) {
|