agora-appbuilder-core 4.0.35 → 4.1.0-beta-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.
- package/package.json +2 -2
- package/template/agora-rn-uikit/README.md +1 -40
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +1 -0
- package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +1 -0
- package/template/agora-rn-uikit/src/Reducer/Spotlight.ts +11 -0
- package/template/agora-rn-uikit/src/Reducer/index.ts +1 -0
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +7 -0
- package/template/bridge/rtc/webNg/RtcEngine.ts +4 -1
- package/template/customization-api/app-state.ts +11 -7
- package/template/customization-api/{customize.ts → customize.tsx} +116 -11
- package/template/customization-api/sub-components.ts +4 -0
- package/template/customization-api/temp.ts +2 -0
- package/template/customization-api/typeDefinition.ts +2 -1
- package/template/customization-api/utils.ts +6 -1
- package/template/defaultConfig.js +4 -2
- package/template/global.d.ts +2 -0
- package/template/src/AppRoutes.tsx +15 -5
- package/template/src/ai-agent/components/AgentControls/AgentContext.tsx +163 -0
- package/template/src/ai-agent/components/AgentControls/LeaveCall.png +0 -0
- package/template/src/ai-agent/components/AgentControls/Vector.svg +3 -0
- package/template/src/ai-agent/components/AgentControls/const.ts +58 -0
- package/template/src/ai-agent/components/AgentControls/index.tsx +293 -0
- package/template/src/ai-agent/components/AudioVisualizer.tsx +91 -0
- package/template/src/ai-agent/components/Bottombar.tsx +91 -0
- package/template/src/ai-agent/components/CustomCreate.tsx +279 -0
- package/template/src/ai-agent/components/CustomCreateNative.tsx +265 -0
- package/template/src/ai-agent/components/CustomSidePanel.tsx +135 -0
- package/template/src/ai-agent/components/FallbackLogo.tsx +80 -0
- package/template/src/ai-agent/components/LocalAudioWave.tsx +171 -0
- package/template/src/ai-agent/components/agent-chat-panel/agent-chat-ui.tsx +82 -0
- package/template/src/ai-agent/components/icons.tsx +227 -0
- package/template/src/ai-agent/components/mobile/Bottombar.tsx +47 -0
- package/template/src/ai-agent/components/mobile/MobileLayoutComponent.tsx +106 -0
- package/template/src/ai-agent/components/mobile/Topbar.tsx +62 -0
- package/template/src/ai-agent/components/react-audio-visualize/LiveAudioVisualizer/LiveAudioVisualizer.tsx +173 -0
- package/template/src/ai-agent/components/react-audio-visualize/LiveAudioVisualizer/index.ts +1 -0
- package/template/src/ai-agent/components/react-audio-visualize/LiveAudioVisualizer/utils.ts +102 -0
- package/template/src/ai-agent/components/react-audio-visualize/index.ts +1 -0
- package/template/src/ai-agent/components/utils.ts +15 -0
- package/template/src/ai-agent/index.tsx +301 -0
- package/template/src/ai-agent/routes/CustomLoginRoute.tsx +25 -0
- package/template/src/ai-agent/routes/CustomValidateRoute.tsx +25 -0
- package/template/src/ai-agent/utils.ts +78 -0
- package/template/src/assets/font-styles.css +4 -0
- package/template/src/assets/fonts/icomoon.ttf +0 -0
- package/template/src/assets/selection.json +1 -1
- package/template/src/atoms/CustomIcon.tsx +1 -0
- package/template/src/atoms/ImageIcon.tsx +3 -0
- package/template/src/atoms/ToolbarItem.tsx +0 -2
- package/template/src/components/ChatContext.ts +7 -0
- package/template/src/components/Controls.tsx +6 -1
- package/template/src/components/ErrorBoundary.tsx +37 -0
- package/template/src/components/ErrorBoundaryFallback.tsx +44 -0
- package/template/src/components/RTMConfigure.tsx +25 -20
- package/template/src/components/participants/Participant.tsx +4 -0
- package/template/src/components/participants/UserActionMenuOptions.tsx +34 -1
- package/template/src/components/precall/PermissionHelper.tsx +11 -8
- package/template/src/language/default-labels/videoCallScreenLabels.ts +8 -0
- package/template/src/logger/AppBuilderLogger.tsx +4 -1
- package/template/src/pages/Create.tsx +11 -12
- package/template/src/pages/VideoCall.tsx +1 -0
- package/template/src/pages/video-call/ActionSheet.tsx +33 -29
- package/template/src/pages/video-call/SidePanelHeader.tsx +8 -3
- package/template/src/pages/video-call/SpotlightHighlighter.tsx +91 -0
- package/template/src/pages/video-call/VideoCallMobileView.tsx +17 -6
- package/template/src/pages/video-call/VideoCallScreen.tsx +0 -1
- package/template/src/pages/video-call/VideoRenderer.tsx +32 -4
- package/template/src/rtm-events/constants.ts +2 -0
- package/template/src/subComponents/ChatBubble.tsx +34 -15
- package/template/src/subComponents/FallbackLogo.tsx +3 -1
- package/template/src/subComponents/LocalAudioMute.tsx +20 -2
- package/template/src/utils/index.tsx +3 -4
- package/template/src/utils/useJoinRoom.ts +14 -0
- package/template/src/utils/useSpotlight.ts +31 -0
- package/template/tsconfig.json +23 -18
|
@@ -31,6 +31,7 @@ export interface ImageIconProps {
|
|
|
31
31
|
// hoverEffect?: boolean;
|
|
32
32
|
// hoverEffectStyle?: ViewStyle;
|
|
33
33
|
showWarningIcon?: boolean;
|
|
34
|
+
iconParentContainerStyle?: ViewStyle;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const ImageIcon = (props: ImageIconProps) => {
|
|
@@ -46,6 +47,7 @@ const ImageIcon = (props: ImageIconProps) => {
|
|
|
46
47
|
base64TintColor = '',
|
|
47
48
|
iconType = 'round',
|
|
48
49
|
iconContainerStyle,
|
|
50
|
+
iconParentContainerStyle = {},
|
|
49
51
|
isHovered,
|
|
50
52
|
} = props;
|
|
51
53
|
return (
|
|
@@ -57,6 +59,7 @@ const ImageIcon = (props: ImageIconProps) => {
|
|
|
57
59
|
? {backgroundColor: props.iconBackgroundColor}
|
|
58
60
|
: {}
|
|
59
61
|
: {backgroundColor: 'transparent', borderRadius: 0},
|
|
62
|
+
iconParentContainerStyle,
|
|
60
63
|
]}>
|
|
61
64
|
<View
|
|
62
65
|
style={[
|
|
@@ -21,8 +21,6 @@ const ToolbarItem = (props: ToolbarItemProps) => {
|
|
|
21
21
|
const {isHorizontal, position} = useToolbar();
|
|
22
22
|
//isHorizontal true -> top/bottom bar
|
|
23
23
|
//isHorizontal false -> left/right bar
|
|
24
|
-
// todo hari - first item shouldnot contain the margin right
|
|
25
|
-
// todo hari - last item shouldnot contain the margin right
|
|
26
24
|
|
|
27
25
|
//action sheet
|
|
28
26
|
if (isMobileUA() && position === ToolbarPosition.bottom) {
|
|
@@ -15,6 +15,7 @@ import {createContext, SetStateAction} from 'react';
|
|
|
15
15
|
|
|
16
16
|
import {ChatMessageType, Reaction} from './chat-messages/useChatMessages';
|
|
17
17
|
import {createHook} from 'customization-implementation';
|
|
18
|
+
import {ViewStyle} from 'react-native';
|
|
18
19
|
|
|
19
20
|
export interface ChatBubbleProps {
|
|
20
21
|
isLocal: boolean;
|
|
@@ -35,6 +36,12 @@ export interface ChatBubbleProps {
|
|
|
35
36
|
scrollOffset?: number;
|
|
36
37
|
replyToMsgId?: string;
|
|
37
38
|
isLastMsg?: boolean;
|
|
39
|
+
remoteUIConfig?: {
|
|
40
|
+
username?: string; // Custom username for remote user
|
|
41
|
+
avatarIcon?: string;
|
|
42
|
+
bubbleStyleLayer1?: ViewStyle;
|
|
43
|
+
bubbleStyleLayer2?: ViewStyle;
|
|
44
|
+
};
|
|
38
45
|
|
|
39
46
|
render?: (
|
|
40
47
|
isLocal: boolean,
|
|
@@ -1029,7 +1029,12 @@ export const RaiseHandToolbarItem = props => {
|
|
|
1029
1029
|
export const LocalAudioToolbarItem = props => {
|
|
1030
1030
|
return (
|
|
1031
1031
|
<ToolbarItem testID="localAudio-btn" toolbarProps={props}>
|
|
1032
|
-
<LocalAudioMute
|
|
1032
|
+
<LocalAudioMute
|
|
1033
|
+
showToolTip={true}
|
|
1034
|
+
iconBGColor={props?.iconBGColor}
|
|
1035
|
+
iconSize={props?.iconSize}
|
|
1036
|
+
containerStyle={props?.containerStyle}
|
|
1037
|
+
/>
|
|
1033
1038
|
</ToolbarItem>
|
|
1034
1039
|
);
|
|
1035
1040
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {logger, LogSource} from '../logger/AppBuilderLogger';
|
|
3
|
+
|
|
4
|
+
class ErrorBoundary extends React.Component<{fallback: JSX.Element}> {
|
|
5
|
+
constructor(props) {
|
|
6
|
+
super(props);
|
|
7
|
+
this.state = {hasError: false};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static getDerivedStateFromError(error) {
|
|
11
|
+
// Update state so the next render will show the fallback UI.
|
|
12
|
+
return {hasError: true};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
componentDidCatch(error, info) {
|
|
16
|
+
logger.error(
|
|
17
|
+
LogSource.Internals,
|
|
18
|
+
'VIDEO_CALL_ROOM',
|
|
19
|
+
'Application crashed',
|
|
20
|
+
{
|
|
21
|
+
errorMessage: error?.message,
|
|
22
|
+
errorStack: info?.componentStack,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
render() {
|
|
28
|
+
if (this.state.hasError) {
|
|
29
|
+
// You can render any custom fallback UI
|
|
30
|
+
return this.props.fallback;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return this.props.children;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default ErrorBoundary;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {Text, View, StyleSheet, ScrollView} from 'react-native';
|
|
3
|
+
import Card from '../atoms/Card';
|
|
4
|
+
import ThemeConfig from '../theme';
|
|
5
|
+
|
|
6
|
+
export const ErrorBoundaryFallback = () => {
|
|
7
|
+
return (
|
|
8
|
+
<View style={style.root}>
|
|
9
|
+
<ScrollView contentContainerStyle={style.main}>
|
|
10
|
+
<Card>
|
|
11
|
+
<View>
|
|
12
|
+
<Text style={style.text}>
|
|
13
|
+
An unexpected error occurred. Please try again.
|
|
14
|
+
</Text>
|
|
15
|
+
</View>
|
|
16
|
+
</Card>
|
|
17
|
+
</ScrollView>
|
|
18
|
+
</View>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const style = StyleSheet.create({
|
|
23
|
+
logoContainerStyle: {
|
|
24
|
+
flexDirection: 'row',
|
|
25
|
+
justifyContent: 'space-between',
|
|
26
|
+
alignItems: 'center',
|
|
27
|
+
},
|
|
28
|
+
root: {
|
|
29
|
+
flex: 1,
|
|
30
|
+
},
|
|
31
|
+
main: {
|
|
32
|
+
flexGrow: 1,
|
|
33
|
+
flexDirection: 'row',
|
|
34
|
+
justifyContent: 'center',
|
|
35
|
+
},
|
|
36
|
+
text: {
|
|
37
|
+
fontSize: ThemeConfig.FontSize.large,
|
|
38
|
+
fontWeight: '400',
|
|
39
|
+
lineHeight: ThemeConfig.FontSize.large,
|
|
40
|
+
color: $config.FONT_COLOR,
|
|
41
|
+
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
42
|
+
opacity: ThemeConfig.EmphasisOpacity.high,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
@@ -114,29 +114,34 @@ const RtmConfigure = (props: any) => {
|
|
|
114
114
|
}, [defaultContent]);
|
|
115
115
|
|
|
116
116
|
React.useEffect(() => {
|
|
117
|
-
|
|
118
|
-
ev
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
window.addEventListener('pagehide', logoutRtm);
|
|
132
|
-
// cleanup this component
|
|
133
|
-
return () => {
|
|
134
|
-
window.removeEventListener(
|
|
117
|
+
if (!$config.ENABLE_CONVERSATIONAL_AI) {
|
|
118
|
+
const handBrowserClose = ev => {
|
|
119
|
+
ev.preventDefault();
|
|
120
|
+
window.setTimeout(function () {
|
|
121
|
+
window.location = `${window.location.origin}/create`;
|
|
122
|
+
}, 0);
|
|
123
|
+
return false;
|
|
124
|
+
};
|
|
125
|
+
const logoutRtm = () => {
|
|
126
|
+
engine.current.leaveChannel(rtcProps.channel);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
if (!isWebInternal()) return;
|
|
130
|
+
window.addEventListener(
|
|
135
131
|
'beforeunload',
|
|
136
132
|
isWeb() && !isSDK() ? handBrowserClose : () => {},
|
|
137
133
|
);
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
|
|
135
|
+
window.addEventListener('pagehide', logoutRtm);
|
|
136
|
+
// cleanup this component
|
|
137
|
+
return () => {
|
|
138
|
+
window.removeEventListener(
|
|
139
|
+
'beforeunload',
|
|
140
|
+
isWeb() && !isSDK() ? handBrowserClose : () => {},
|
|
141
|
+
);
|
|
142
|
+
window.removeEventListener('pagehide', logoutRtm);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
140
145
|
}, []);
|
|
141
146
|
|
|
142
147
|
const doLoginAndSetupRTM = async () => {
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
useLayout,
|
|
43
43
|
useContent,
|
|
44
44
|
useSidePanel,
|
|
45
|
+
useSpotlight,
|
|
45
46
|
} from 'customization-api';
|
|
46
47
|
import {getPinnedLayoutName} from '../../pages/video-call/DefaultLayouts';
|
|
47
48
|
import UserActionMenuOptionsOptions from './UserActionMenuOptions';
|
|
@@ -96,6 +97,7 @@ const Participant = (props: ParticipantInterface) => {
|
|
|
96
97
|
const showModal = () => {
|
|
97
98
|
setActionMenuVisible(state => !state);
|
|
98
99
|
};
|
|
100
|
+
const {setSpotlightUid, spotlightUid} = useSpotlight();
|
|
99
101
|
|
|
100
102
|
return (
|
|
101
103
|
<>
|
|
@@ -105,6 +107,8 @@ const Participant = (props: ParticipantInterface) => {
|
|
|
105
107
|
user={props.user}
|
|
106
108
|
btnRef={moreIconRef}
|
|
107
109
|
from={'partcipant'}
|
|
110
|
+
spotlightUid={spotlightUid}
|
|
111
|
+
setSpotlightUid={setSpotlightUid}
|
|
108
112
|
/>
|
|
109
113
|
<PlatformWrapper showModal={showModal} setIsHovered={setIsHovered}>
|
|
110
114
|
<View style={styles.container} ref={usercontainerRef}>
|
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
moreBtnRemoveFromRoom,
|
|
58
58
|
moreBtnRemoveFromTop,
|
|
59
59
|
moreBtnRemoveScreenShare,
|
|
60
|
+
moreBtnSpotlight,
|
|
60
61
|
moreBtnStopScreenShare,
|
|
61
62
|
moreBtnVideo,
|
|
62
63
|
moreBtnViewInLarge,
|
|
@@ -64,6 +65,7 @@ import {
|
|
|
64
65
|
userRemovedFromTheRoomToastHeading,
|
|
65
66
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
66
67
|
import {isAndroid, isIOS} from '../../utils/common';
|
|
68
|
+
import {EventNames} from '../../rtm-events';
|
|
67
69
|
|
|
68
70
|
interface UserActionMenuOptionsOptionsProps {
|
|
69
71
|
user: ContentInterface;
|
|
@@ -71,6 +73,8 @@ interface UserActionMenuOptionsOptionsProps {
|
|
|
71
73
|
setActionMenuVisible: (actionMenuVisible: boolean) => void;
|
|
72
74
|
btnRef: any;
|
|
73
75
|
from: 'partcipant' | 'screenshare-participant' | 'video-tile';
|
|
76
|
+
spotlightUid?: UidType;
|
|
77
|
+
setSpotlightUid?: (uid: UidType) => void;
|
|
74
78
|
}
|
|
75
79
|
export default function UserActionMenuOptionsOptions(
|
|
76
80
|
props: UserActionMenuOptionsOptionsProps,
|
|
@@ -85,7 +89,7 @@ export default function UserActionMenuOptionsOptions(
|
|
|
85
89
|
useState(false);
|
|
86
90
|
const [actionMenuitems, setActionMenuitems] = useState<ActionMenuItem[]>([]);
|
|
87
91
|
const {setSidePanel} = useSidePanel();
|
|
88
|
-
const {user, actionMenuVisible, setActionMenuVisible} = props;
|
|
92
|
+
const {user, actionMenuVisible, setActionMenuVisible, spotlightUid} = props;
|
|
89
93
|
const {currentLayout} = useLayout();
|
|
90
94
|
const {pinnedUid, activeUids, customContent, secondaryPinnedUid} =
|
|
91
95
|
useContent();
|
|
@@ -122,6 +126,7 @@ export default function UserActionMenuOptionsOptions(
|
|
|
122
126
|
const stopScreenShareLabel = useString(moreBtnStopScreenShare)();
|
|
123
127
|
const removeScreenShareLabel = useString(moreBtnRemoveScreenShare)();
|
|
124
128
|
const removeFromRoomLabel = useString(moreBtnRemoveFromRoom)();
|
|
129
|
+
const moreBtnSpotlightLabel = useString(moreBtnSpotlight);
|
|
125
130
|
|
|
126
131
|
useEffect(() => {
|
|
127
132
|
customEvents.on('DisableChat', data => {
|
|
@@ -212,6 +217,33 @@ export default function UserActionMenuOptionsOptions(
|
|
|
212
217
|
}
|
|
213
218
|
}
|
|
214
219
|
|
|
220
|
+
if ($config.ENABLE_SPOTLIGHT && isHost && user.type === 'rtc') {
|
|
221
|
+
items.push({
|
|
222
|
+
icon: 'spotlight',
|
|
223
|
+
title: moreBtnSpotlightLabel(user.uid == props?.spotlightUid),
|
|
224
|
+
iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
225
|
+
textColor: $config.SECONDARY_ACTION_COLOR,
|
|
226
|
+
onPress: () => {
|
|
227
|
+
if (user.uid == props?.spotlightUid) {
|
|
228
|
+
props?.setSpotlightUid(0);
|
|
229
|
+
events.send(
|
|
230
|
+
EventNames.SPOTLIGHT_USER_CHANGED,
|
|
231
|
+
JSON.stringify({user_id: 0}),
|
|
232
|
+
PersistanceLevel.Session,
|
|
233
|
+
);
|
|
234
|
+
} else {
|
|
235
|
+
props?.setSpotlightUid(user.uid);
|
|
236
|
+
events.send(
|
|
237
|
+
EventNames.SPOTLIGHT_USER_CHANGED,
|
|
238
|
+
JSON.stringify({user_id: user.uid}),
|
|
239
|
+
PersistanceLevel.Session,
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
setActionMenuVisible(false);
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
215
247
|
/**
|
|
216
248
|
* Below menu items for remote user with type rtc(not for screenshare)
|
|
217
249
|
*/
|
|
@@ -399,6 +431,7 @@ export default function UserActionMenuOptionsOptions(
|
|
|
399
431
|
disableChatUids,
|
|
400
432
|
secondaryPinnedUid,
|
|
401
433
|
currentLayout,
|
|
434
|
+
spotlightUid,
|
|
402
435
|
]);
|
|
403
436
|
|
|
404
437
|
const {width: globalWidth, height: globalHeight} = useWindowDimensions();
|
|
@@ -44,8 +44,11 @@ const PermissionHelper = () => {
|
|
|
44
44
|
),
|
|
45
45
|
])
|
|
46
46
|
.then(([cameraResult, micResult]) => {
|
|
47
|
+
const conditionCheck = $config.AUDIO_ROOM
|
|
48
|
+
? micResult.state !== 'granted'
|
|
49
|
+
: cameraResult.state !== 'granted' || micResult.state !== 'granted';
|
|
47
50
|
// Chrome
|
|
48
|
-
if (
|
|
51
|
+
if (conditionCheck) {
|
|
49
52
|
setShowPopup(true);
|
|
50
53
|
const onChangeFunc = () => {
|
|
51
54
|
if (
|
|
@@ -59,15 +62,15 @@ const PermissionHelper = () => {
|
|
|
59
62
|
}
|
|
60
63
|
})
|
|
61
64
|
.catch(e => {
|
|
62
|
-
// Firefox
|
|
63
|
-
|
|
64
|
-
setShowPopup(true);
|
|
65
|
-
}, 1000);
|
|
65
|
+
// Firefox and chrome
|
|
66
|
+
setShowPopup(true);
|
|
66
67
|
});
|
|
67
68
|
//If permission already given it will take few milliseconds to resolve the promise. it will show the popup which not required. so added timeout
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
if (permissionStatus === PermissionState.REQUESTED) {
|
|
71
|
+
setShowPopup(true);
|
|
72
|
+
}
|
|
73
|
+
}, 1000);
|
|
71
74
|
}, []);
|
|
72
75
|
//todo hari update the modal message based the veritical
|
|
73
76
|
return (
|
|
@@ -267,6 +267,7 @@ export const moreBtnRemoveFromLarge = 'moreBtnRemoveFromLarge';
|
|
|
267
267
|
export const moreBtnPinToTop = 'moreBtnPinToTop';
|
|
268
268
|
export const moreBtnRemoveFromTop = 'moreBtnRemoveFromTop';
|
|
269
269
|
export const moreBtnMessagePrivately = 'moreBtnMessagePrivately';
|
|
270
|
+
export const moreBtnSpotlight = 'moreBtnSpotlight';
|
|
270
271
|
|
|
271
272
|
export const moreBtnAudio = 'moreBtnAudio';
|
|
272
273
|
export const moreBtnVideo = 'moreBtnVideo';
|
|
@@ -380,6 +381,8 @@ export const livestreamPromoteAsCoHostToastHeading =
|
|
|
380
381
|
export const livestreamRequestAlreadyProcessed =
|
|
381
382
|
'livestreamRequestAlreadyProcessed';
|
|
382
383
|
|
|
384
|
+
export const videoRoomInTheSpotlightText =
|
|
385
|
+
`video${room}InTheSpotlightText` as const;
|
|
383
386
|
export const videoRoomUserFallbackText =
|
|
384
387
|
`video${room}UserFallbackText` as const;
|
|
385
388
|
|
|
@@ -682,6 +685,8 @@ export interface I18nVideoCallScreenLabelsInterface {
|
|
|
682
685
|
[moreBtnChangeName]?: I18nBaseType;
|
|
683
686
|
[moreBtnStopScreenShare]?: I18nBaseType;
|
|
684
687
|
[moreBtnRemoveScreenShare]?: I18nBaseType;
|
|
688
|
+
[moreBtnSpotlight]?: I18nConditionalType;
|
|
689
|
+
[videoRoomInTheSpotlightText]?: I18nBaseType;
|
|
685
690
|
|
|
686
691
|
[muteAllConfirmationPopoverContent]?: I18nBaseType<I18nMuteType>;
|
|
687
692
|
[muteAllConfirmationPopoverPrimaryBtnText]?: I18nBaseType;
|
|
@@ -1080,6 +1085,9 @@ export const VideoCallScreenLabels: I18nVideoCallScreenLabelsInterface = {
|
|
|
1080
1085
|
[moreBtnChangeName]: 'Change Name',
|
|
1081
1086
|
[moreBtnStopScreenShare]: 'Stop Screenshare',
|
|
1082
1087
|
[moreBtnRemoveScreenShare]: 'Remove Screenshare',
|
|
1088
|
+
[moreBtnSpotlight]: spotlightOn =>
|
|
1089
|
+
spotlightOn ? 'Remove Spotlight' : 'Spotlight',
|
|
1090
|
+
[videoRoomInTheSpotlightText]: 'In the Spotlight',
|
|
1083
1091
|
|
|
1084
1092
|
[muteAllConfirmationPopoverContent]: (type: I18nMuteType) =>
|
|
1085
1093
|
`Mute everyone's ${type} on the call?`,
|
|
@@ -105,7 +105,10 @@ type LogType = {
|
|
|
105
105
|
| 'recordings_get'
|
|
106
106
|
| 'recording_delete';
|
|
107
107
|
[LogSource.Events]: 'CUSTOM_EVENTS' | 'RTM_EVENTS';
|
|
108
|
-
[LogSource.CustomizationAPI]:
|
|
108
|
+
[LogSource.CustomizationAPI]:
|
|
109
|
+
| 'Log'
|
|
110
|
+
| 'AI_AGENT_CUSTOMIZATION'
|
|
111
|
+
| 'EXTERNAL_CUSTOMIZATION';
|
|
109
112
|
[LogSource.SDK]: 'Log' | 'Event';
|
|
110
113
|
};
|
|
111
114
|
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
maxInputLimit,
|
|
23
23
|
isMobileUA,
|
|
24
24
|
trimText,
|
|
25
|
+
isValidReactComponent,
|
|
25
26
|
} from '../utils/common';
|
|
26
27
|
import {useCustomization} from 'customization-implementation';
|
|
27
28
|
import {useString} from '../utils/useString';
|
|
@@ -62,24 +63,22 @@ import {
|
|
|
62
63
|
createRoomSuccessToastSubHeading,
|
|
63
64
|
} from '../language/default-labels/createScreenLabels';
|
|
64
65
|
import {LogSource, logger} from '../logger/AppBuilderLogger';
|
|
65
|
-
import {backendErrorCode} from 'src/utils/BackendErrorCode';
|
|
66
66
|
|
|
67
67
|
const Create = () => {
|
|
68
68
|
const {CreateComponent} = useCustomization(data => {
|
|
69
69
|
let components: {
|
|
70
70
|
CreateComponent?: React.ElementType;
|
|
71
71
|
} = {};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// }
|
|
72
|
+
if (
|
|
73
|
+
data?.components?.create &&
|
|
74
|
+
typeof data?.components?.create !== 'object'
|
|
75
|
+
) {
|
|
76
|
+
if (
|
|
77
|
+
data?.components?.create &&
|
|
78
|
+
isValidReactComponent(data?.components?.create)
|
|
79
|
+
)
|
|
80
|
+
components.CreateComponent = data?.components?.create;
|
|
81
|
+
}
|
|
83
82
|
return components;
|
|
84
83
|
});
|
|
85
84
|
|
|
@@ -47,7 +47,7 @@ const ActionSheet = props => {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
|
-
const {snapPointsMinMax = [100, 400]} = props;
|
|
50
|
+
const {snapPointsMinMax = [100, 400], hideDefaultActionSheet = false} = props;
|
|
51
51
|
const {setActionSheetVisible} = useToast();
|
|
52
52
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
53
53
|
const [isChatOpen, setIsChatOpen] = React.useState(false);
|
|
@@ -74,7 +74,7 @@ const ActionSheet = props => {
|
|
|
74
74
|
const {sidePanel, setSidePanel} = useSidePanel();
|
|
75
75
|
const [showOverlay, setShowOverlay] = React.useState(false);
|
|
76
76
|
const handleSheetChanges = useCallback((index: number) => {
|
|
77
|
-
bottomSheetRef
|
|
77
|
+
bottomSheetRef?.current?.snapTo(({snapPoints}) => snapPoints[index]);
|
|
78
78
|
index === 0 ? setIsExpanded(false) : setIsExpanded(true);
|
|
79
79
|
}, []);
|
|
80
80
|
|
|
@@ -161,7 +161,7 @@ const ActionSheet = props => {
|
|
|
161
161
|
};
|
|
162
162
|
const handleSpringEnd = (event: SpringEvent) => {
|
|
163
163
|
if (event.type == 'SNAP') {
|
|
164
|
-
const isMinmized = bottomSheetRef
|
|
164
|
+
const isMinmized = bottomSheetRef?.current?.height === 100;
|
|
165
165
|
isMinmized && setShowOverlay(false);
|
|
166
166
|
if (event.source === 'dragging') {
|
|
167
167
|
if (isMinmized) {
|
|
@@ -203,32 +203,36 @@ const ActionSheet = props => {
|
|
|
203
203
|
<View>
|
|
204
204
|
{/* Controls Action Sheet */}
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
lastSnap
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
206
|
+
{!hideDefaultActionSheet ? (
|
|
207
|
+
<BottomSheet
|
|
208
|
+
scrollLocking={false}
|
|
209
|
+
ref={bottomSheetRef}
|
|
210
|
+
open={true}
|
|
211
|
+
onSpringStart={handleSpringStart}
|
|
212
|
+
onSpringEnd={handleSpringEnd}
|
|
213
|
+
// skipInitialTransition={true}
|
|
214
|
+
expandOnContentDrag={true}
|
|
215
|
+
snapPoints={({maxHeight}) => snapPointsMinMax}
|
|
216
|
+
defaultSnap={({lastSnap, snapPoints}) =>
|
|
217
|
+
lastSnap ?? Math.min(...snapPoints)
|
|
218
|
+
}
|
|
219
|
+
header={
|
|
220
|
+
<>
|
|
221
|
+
<ActionSheetHandle sidePanel={SidePanelType.None} />
|
|
222
|
+
<Spacer size={12} />
|
|
223
|
+
</>
|
|
224
|
+
}
|
|
225
|
+
blocking={false}>
|
|
226
|
+
<ActionSheetContent
|
|
227
|
+
handleSheetChanges={handleSheetChanges}
|
|
228
|
+
isExpanded={isExpanded}
|
|
229
|
+
native={false}
|
|
230
|
+
{...props}
|
|
231
|
+
/>
|
|
232
|
+
</BottomSheet>
|
|
233
|
+
) : (
|
|
234
|
+
<></>
|
|
235
|
+
)}
|
|
232
236
|
{/* Chat Action Sheet */}
|
|
233
237
|
<BottomSheet
|
|
234
238
|
sibling={ToastComponentRender}
|
|
@@ -22,7 +22,7 @@ import {numFormatter} from '../../utils';
|
|
|
22
22
|
import ChatContext from '../../components/ChatContext';
|
|
23
23
|
import {useCaption} from '../../subComponents/caption/useCaption';
|
|
24
24
|
import ActionMenu, {ActionMenuItem} from '../../atoms/ActionMenu';
|
|
25
|
-
import {calculatePosition} from '../../utils/common';
|
|
25
|
+
import {calculatePosition, isMobileUA} from '../../utils/common';
|
|
26
26
|
import LanguageSelectorPopup from '../../subComponents/caption/LanguageSelectorPopup';
|
|
27
27
|
import useSTTAPI from '../../subComponents/caption/useSTTAPI';
|
|
28
28
|
import useGetName from '../../utils/useGetName';
|
|
@@ -56,7 +56,13 @@ export const SettingsHeader = props => {
|
|
|
56
56
|
centerComponent={
|
|
57
57
|
<Text style={SidePanelStyles.heading}>{settingsLabel}</Text>
|
|
58
58
|
}
|
|
59
|
-
trailingIconName=
|
|
59
|
+
trailingIconName={
|
|
60
|
+
$config.ENABLE_CONVERSATIONAL_AI
|
|
61
|
+
? isMobileUA()
|
|
62
|
+
? 'close'
|
|
63
|
+
: ''
|
|
64
|
+
: 'close'
|
|
65
|
+
}
|
|
60
66
|
trailingIconOnPress={() => {
|
|
61
67
|
props.handleClose && props.handleClose();
|
|
62
68
|
setSidePanel(SidePanelType.None);
|
|
@@ -119,7 +125,6 @@ export const ChatHeader = () => {
|
|
|
119
125
|
return (
|
|
120
126
|
<SidePanelHeader
|
|
121
127
|
isChat={true}
|
|
122
|
-
showTintedOverlay={showEmojiPicker}
|
|
123
128
|
leadingIconName={isPrivateActive ? 'back-btn' : null}
|
|
124
129
|
leadingIconOnPress={
|
|
125
130
|
isPrivateActive
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {View, StyleSheet, Text} from 'react-native';
|
|
3
|
+
import ThemeConfig from '../../theme';
|
|
4
|
+
import ImageIcon from '../../atoms/ImageIcon';
|
|
5
|
+
import {useLayout, useContent} from 'customization-api';
|
|
6
|
+
import {isMobileUA, isWeb} from '../../utils/common';
|
|
7
|
+
import {getGridLayoutName} from './DefaultLayouts';
|
|
8
|
+
import hexadecimalTransparency from '../../utils/hexadecimalTransparency';
|
|
9
|
+
import {useString} from '../../utils/useString';
|
|
10
|
+
|
|
11
|
+
const SpotlightHighligher = () => {
|
|
12
|
+
const {activeUids, customContent} = useContent();
|
|
13
|
+
const {currentLayout} = useLayout();
|
|
14
|
+
const activeUidsLen = activeUids?.filter(i => !customContent[i])?.length;
|
|
15
|
+
const reduceSpace =
|
|
16
|
+
isMobileUA() &&
|
|
17
|
+
activeUids.length > 4 &&
|
|
18
|
+
currentLayout === getGridLayoutName();
|
|
19
|
+
const spotlightText = useString('videoRoomInTheSpotlightText')();
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<View
|
|
23
|
+
style={[
|
|
24
|
+
style.container,
|
|
25
|
+
reduceSpace ? {left: 2, bottom: 2} : {},
|
|
26
|
+
reduceSpace && activeUidsLen > 12 ? {padding: 2} : {},
|
|
27
|
+
]}>
|
|
28
|
+
<ImageIcon
|
|
29
|
+
iconType="plain"
|
|
30
|
+
name={'spotlight'}
|
|
31
|
+
tintColor={$config.PRIMARY_ACTION_BRAND_COLOR}
|
|
32
|
+
iconSize={20}
|
|
33
|
+
/>
|
|
34
|
+
<PlatformWrapper>
|
|
35
|
+
<Text
|
|
36
|
+
numberOfLines={1}
|
|
37
|
+
textBreakStrategy="simple"
|
|
38
|
+
ellipsizeMode="tail"
|
|
39
|
+
style={[style.name]}>
|
|
40
|
+
{spotlightText}
|
|
41
|
+
</Text>
|
|
42
|
+
</PlatformWrapper>
|
|
43
|
+
</View>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
const PlatformWrapper = ({children}) => {
|
|
47
|
+
return isWeb() ? (
|
|
48
|
+
<div
|
|
49
|
+
style={{
|
|
50
|
+
userSelect: 'none',
|
|
51
|
+
MozUserSelect: 'none',
|
|
52
|
+
WebkitUserSelect: 'none',
|
|
53
|
+
msUserSelect: 'none',
|
|
54
|
+
alignSelf: 'center',
|
|
55
|
+
overflow: 'hidden',
|
|
56
|
+
textOverflow: 'ellipsis',
|
|
57
|
+
color: $config.VIDEO_AUDIO_TILE_TEXT_COLOR,
|
|
58
|
+
}}>
|
|
59
|
+
{children}
|
|
60
|
+
</div>
|
|
61
|
+
) : (
|
|
62
|
+
<>{children}</>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const style = StyleSheet.create({
|
|
67
|
+
container: {
|
|
68
|
+
backgroundColor:
|
|
69
|
+
$config.VIDEO_AUDIO_TILE_OVERLAY_COLOR + hexadecimalTransparency['25%'],
|
|
70
|
+
position: 'absolute',
|
|
71
|
+
alignItems: 'center',
|
|
72
|
+
padding: 8,
|
|
73
|
+
top: 8,
|
|
74
|
+
left: 8,
|
|
75
|
+
borderRadius: 4,
|
|
76
|
+
flexDirection: 'row',
|
|
77
|
+
zIndex: 999,
|
|
78
|
+
elevation: 5,
|
|
79
|
+
},
|
|
80
|
+
name: {
|
|
81
|
+
color: $config.VIDEO_AUDIO_TILE_TEXT_COLOR,
|
|
82
|
+
fontSize: ThemeConfig.FontSize.small,
|
|
83
|
+
fontWeight: '600',
|
|
84
|
+
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
85
|
+
flexShrink: 1,
|
|
86
|
+
marginLeft: 4,
|
|
87
|
+
marginRight: 2,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export default SpotlightHighligher;
|