agora-appbuilder-core 4.1.0-beta-2 → 4.1.0-beta-3

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 (26) hide show
  1. package/package.json +1 -1
  2. package/template/customization-api/atoms.ts +1 -0
  3. package/template/customization-api/sub-components.ts +2 -0
  4. package/template/src/ai-agent/components/AgentControls/AgentContext.tsx +16 -1
  5. package/template/src/ai-agent/components/AgentControls/const.ts +38 -5
  6. package/template/src/ai-agent/components/AgentControls/index.tsx +40 -23
  7. package/template/src/ai-agent/components/AudioVisualizer.tsx +32 -20
  8. package/template/src/ai-agent/components/Bottombar.tsx +113 -48
  9. package/template/src/ai-agent/components/{CustomSidePanel.tsx → CustomChatPanel.tsx} +3 -3
  10. package/template/src/ai-agent/components/CustomCreate.tsx +7 -185
  11. package/template/src/ai-agent/components/CustomSettingsPanel.tsx +155 -0
  12. package/template/src/ai-agent/components/SelectAiAgent.tsx +71 -0
  13. package/template/src/ai-agent/components/SelectAiAgentVoice.tsx +68 -0
  14. package/template/src/ai-agent/components/agent-chat-panel/agent-chat-ui.tsx +3 -3
  15. package/template/src/ai-agent/components/mobile/MobileLayoutComponent.tsx +1 -1
  16. package/template/src/ai-agent/components/mobile/Topbar.tsx +10 -26
  17. package/template/src/ai-agent/index.tsx +48 -199
  18. package/template/src/atoms/Dropdown.tsx +1 -1
  19. package/template/src/components/SettingsView.tsx +7 -3
  20. package/template/src/components/room-info/useRoomInfo.tsx +10 -0
  21. package/template/src/pages/video-call/VideoCallScreen.tsx +18 -3
  22. package/template/src/subComponents/FallbackLogo.tsx +1 -3
  23. package/template/src/subComponents/SelectDevice.tsx +7 -7
  24. package/template/src/subComponents/SidePanelHeader.tsx +2 -2
  25. package/template/src/utils/useJoinRoom.ts +6 -0
  26. package/template/src/ai-agent/components/CustomCreateNative.tsx +0 -265
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agora-appbuilder-core",
3
- "version": "4.1.0-beta-2",
3
+ "version": "4.1.0-beta-3",
4
4
  "description": "React Native template for RTE app builder",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -7,3 +7,4 @@ export {default as PrimaryButton} from '../src/atoms/PrimaryButton';
7
7
  export {default as TertiaryButton} from '../src/atoms/TertiaryButton';
8
8
  export {default as ActionMenu} from '../src/atoms/ActionMenu';
9
9
  export {default as IconButton} from '../src/atoms/IconButton';
10
+ export {default as Dropdown} from '../src/atoms/Dropdown';
@@ -91,3 +91,5 @@ export {default as Loading} from '../src/subComponents/Loading';
91
91
  export {default as UserAvatar} from '../src/atoms/UserAvatar';
92
92
  export {default as Card} from '../src/atoms/Card';
93
93
  export {default as ThemeConfig} from '../src/theme';
94
+ export {default as SelectDevice} from '../src/subComponents/SelectDevice';
95
+ export {EditName} from '../src/components/SettingsView';
@@ -1,7 +1,7 @@
1
1
  import React, {createContext, useState} from 'react';
2
2
  import {AIAgentState, AgentState} from './const';
3
3
  import {UidType} from 'customization-api';
4
-
4
+ import {AI_AGENT_VOICE} from './const';
5
5
  export interface ChatItem {
6
6
  id: string;
7
7
  uid: UidType;
@@ -22,6 +22,10 @@ export interface AgentContextInterface {
22
22
  setAgentUID: (uid: UidType | null) => void;
23
23
  chatItems: ChatItem[];
24
24
  addChatItem: (newItem: ChatItem) => void;
25
+ agentId: string;
26
+ setAgentId: (id: string) => void;
27
+ agentVoice?: keyof typeof AI_AGENT_VOICE | '';
28
+ setAgentVoice: (voice: keyof typeof AI_AGENT_VOICE) => void;
25
29
  }
26
30
 
27
31
  export const AgentContext = createContext<AgentContextInterface>({
@@ -35,6 +39,10 @@ export const AgentContext = createContext<AgentContextInterface>({
35
39
  setAgentUID: () => {},
36
40
  chatItems: [],
37
41
  addChatItem: () => {}, // Default no-op
42
+ agentVoice: '',
43
+ setAgentVoice: () => {},
44
+ agentId: '',
45
+ setAgentId: () => {},
38
46
  });
39
47
 
40
48
  /**
@@ -74,6 +82,9 @@ export const AgentProvider: React.FC<{children: React.ReactNode}> = ({
74
82
  const [agentUID, setAgentUID] = useState<UidType | null>(null);
75
83
  const [isSubscribedForStreams, setIsSubscribedForStreams] = useState(false);
76
84
  const [chatItems, setChatItems] = useState<ChatItem[]>([]);
85
+ const [agentId, setAgentId] = useState('');
86
+ const [agentVoice, setAgentVoice] =
87
+ useState<AgentContextInterface['agentVoice']>('');
77
88
 
78
89
  /**
79
90
  * Adds a new chat item to the chat state while ensuring:
@@ -155,6 +166,10 @@ export const AgentProvider: React.FC<{children: React.ReactNode}> = ({
155
166
  setAgentUID,
156
167
  chatItems,
157
168
  addChatItem, // Expose the function in the context
169
+ agentId,
170
+ setAgentId,
171
+ agentVoice,
172
+ setAgentVoice,
158
173
  };
159
174
 
160
175
  return (
@@ -1,16 +1,16 @@
1
1
  import {isMobileUA} from '../../../utils/common';
2
2
 
3
3
  export const AI_AGENT_STATE = {
4
- NOT_CONNECTED: 'Start Call',
5
- REQUEST_SENT: isMobileUA() ? 'Start Call' : 'Requesting agent join..', // loading - reg
6
- AWAITING_JOIN: isMobileUA() ? 'Start Call' : 'Agent will join shortly..', // loading
4
+ NOT_CONNECTED: 'Join Call',
5
+ REQUEST_SENT: isMobileUA() ? 'Join Call' : 'Requesting agent join..', // loading - reg
6
+ AWAITING_JOIN: isMobileUA() ? 'Join Call' : 'Agent will join shortly..', // loading
7
7
  AGENT_CONNECTED: 'End Call',
8
- AGENT_REQUEST_FAILED: 'Start Call',
8
+ AGENT_REQUEST_FAILED: 'Join Call',
9
9
  AGENT_DISCONNECT_REQUEST: isMobileUA()
10
10
  ? 'End Call'
11
11
  : 'Disconnecting agent...', // loading - req
12
12
  AGENT_DISCONNECT_FAILED: 'End Call',
13
- AWAITING_LEAVE: 'Start Call', // loading
13
+ AWAITING_LEAVE: 'Join Call', // loading
14
14
  } as const;
15
15
 
16
16
  export type AIAgentState = keyof typeof AI_AGENT_STATE;
@@ -56,3 +56,36 @@ export const AGORA_SSO_LOGIN_PATH = '/api/v0/oauth/authorize';
56
56
  export const AGORA_SSO_LOGOUT_PATH = '/api/v0/logout';
57
57
 
58
58
  export const AGORA_SSO_CLIENT_ID = 'openai_agora';
59
+
60
+ export const AI_AGENT_VOICE = {
61
+ 'en-US-AvaMultilingualNeural': 'en-US-AvaMultilingualNeural',
62
+ 'en-US-AndrewMultilingualNeural': 'en-US-AndrewMultilingualNeural',
63
+ 'en-US-EmmaMultilingualNeural': 'en-US-EmmaMultilingualNeural',
64
+ 'en-US-BrianMultilingualNeural': 'en-US-BrianMultilingualNeural',
65
+ 'en-US-AvaNeural': 'en-US-AvaNeural',
66
+ 'en-US-AndrewNeural': 'en-US-AndrewNeural',
67
+ 'en-US-EmmaNeural': 'en-US-EmmaNeural',
68
+ 'en-US-BrianNeural': 'en-US-BrianNeural',
69
+ 'en-US-JennyNeural': 'en-US-JennyNeural',
70
+ 'en-US-GuyNeural': 'en-US-GuyNeural',
71
+ 'en-US-AriaNeural': 'en-US-AriaNeural',
72
+ 'en-US-DavisNeural': 'en-US-DavisNeural',
73
+ 'en-US-JaneNeural': 'en-US-JaneNeural',
74
+ 'en-US-JasonNeural': 'en-US-JasonNeural',
75
+ 'en-US-SaraNeural': 'en-US-SaraNeural',
76
+ 'en-US-TonyNeural': 'en-US-TonyNeural',
77
+ 'en-US-NancyNeural': 'en-US-NancyNeural',
78
+ 'en-US-AmberNeural': 'en-US-AmberNeural',
79
+ 'en-US-AnaNeural': 'en-US-AnaNeural',
80
+ 'en-US-AshleyNeural': 'en-US-AshleyNeural',
81
+ 'en-US-BrandonNeural': 'en-US-BrandonNeural',
82
+ 'en-US-ChristopherNeural': 'en-US-ChristopherNeural',
83
+ 'en-US-CoraNeural': 'en-US-CoraNeural',
84
+ 'en-US-ElizabethNeural': 'en-US-ElizabethNeural',
85
+ 'en-US-EricNeural': 'en-US-EricNeural',
86
+ 'en-US-JacobNeural': 'en-US-JacobNeural',
87
+ 'en-US-JennyMultilingualNeural4': 'en-US-JennyMultilingualNeural4',
88
+ 'en-US-MichelleNeural': 'en-US-MichelleNeural',
89
+ 'en-US-MonicaNeural': 'en-US-MonicaNeural',
90
+ 'en-US-RogerNeural': 'en-US-RogerNeural',
91
+ };
@@ -8,7 +8,6 @@ import {
8
8
  useContent,
9
9
  useEndCall,
10
10
  useLocalUid,
11
- useHistory,
12
11
  useStorageContext,
13
12
  Toast,
14
13
  } from 'customization-api';
@@ -20,6 +19,7 @@ const connectToAIAgent = async (
20
19
  channel_name: string,
21
20
  localUid: UidType,
22
21
  agentAuthToken: string,
22
+ data?: {agent_id: string; agent_voice: string},
23
23
  ): Promise<{}> => {
24
24
  // const apiUrl = '/api/proxy';
25
25
  const apiUrl = $config.BACKEND_ENDPOINT + '/v1/convoai';
@@ -27,6 +27,14 @@ const connectToAIAgent = async (
27
27
  channel_name: channel_name,
28
28
  uid: localUid, // user uid // localUid or 0
29
29
  };
30
+
31
+ if (data && data.agent_id) {
32
+ requestBody['ai_agent_id'] = data.agent_id;
33
+ }
34
+ if (data && data.agent_voice) {
35
+ requestBody['voice'] = data.agent_voice;
36
+ }
37
+
30
38
  console.log({requestBody});
31
39
  const headers: HeadersInit = {
32
40
  'Content-Type': 'application/json',
@@ -70,12 +78,13 @@ export const AgentControl: React.FC<{channel_name: string}> = ({
70
78
  setAgentAuthToken,
71
79
  agentUID,
72
80
  setAgentUID,
81
+ agentVoice,
82
+ agentId,
73
83
  } = useContext(AgentContext);
74
84
  // console.log("X-Client-ID state", clientId)
75
85
  // const { users } = useContext(UserContext)
76
86
  const {activeUids: users} = useContent();
77
87
  const endcall = useEndCall();
78
- const history = useHistory();
79
88
  const {store} = useStorageContext();
80
89
  const localUid = useLocalUid();
81
90
 
@@ -103,6 +112,10 @@ export const AgentControl: React.FC<{channel_name: string}> = ({
103
112
  channel_name,
104
113
  localUid,
105
114
  store.token,
115
+ {
116
+ agent_id: agentId,
117
+ agent_voice: agentVoice,
118
+ },
106
119
  );
107
120
  // console.log("response X-Client-ID", newClientId, typeof newClientId)
108
121
  // @ts-ignore
@@ -170,7 +183,10 @@ export const AgentControl: React.FC<{channel_name: string}> = ({
170
183
  }
171
184
  try {
172
185
  setAgentConnectionState(AgentState.AGENT_DISCONNECT_REQUEST);
173
- await connectToAIAgent('stop', channel_name, localUid, store.token);
186
+ await connectToAIAgent('stop', channel_name, localUid, store.token, {
187
+ agent_id: agentId,
188
+ agent_voice: agentVoice,
189
+ });
174
190
  setAgentConnectionState(AgentState.AWAITING_LEAVE);
175
191
 
176
192
  Toast.show({
@@ -209,6 +225,7 @@ export const AgentControl: React.FC<{channel_name: string}> = ({
209
225
  console.log('agent contrl', {users});
210
226
  // welcome agent
211
227
  const aiAgentUID = users.filter(item => item === agentUID);
228
+
212
229
  if (
213
230
  aiAgentUID.length &&
214
231
  agentConnectionState === AgentState.AWAITING_JOIN
@@ -249,12 +266,11 @@ export const AgentControl: React.FC<{channel_name: string}> = ({
249
266
  agentConnectionState === AgentState.AGENT_CONNECTED ||
250
267
  agentConnectionState === AgentState.AGENT_DISCONNECT_FAILED;
251
268
 
252
- const backgroundColorStyle = isMobileUA()
253
- ? {backgroundColor: isEndAgent ? '#FF414D' : '#00C2FF', height: 72}
254
- : {};
255
- const fontcolorStyle = isMobileUA()
256
- ? {color: '#FFF'}
257
- : {color: isEndAgent ? '#FF414D' : '#00C2FF'};
269
+ const backgroundColorStyle = {
270
+ backgroundColor: isEndAgent ? $config.SEMANTIC_ERROR : '#0097D4',
271
+ };
272
+ const fontcolorStyle = {color: $config.FONT_COLOR};
273
+
258
274
  return (
259
275
  <TouchableOpacity
260
276
  style={{
@@ -265,29 +281,30 @@ export const AgentControl: React.FC<{channel_name: string}> = ({
265
281
  alignItems: 'center',
266
282
  gap: 8,
267
283
  borderRadius: 40,
268
- borderWidth: isMobileUA() ? 0 : 1,
269
- borderColor: isEndAgent ? '#FF414D' : '#00C2FF',
270
284
  flexDirection: 'row',
271
285
  ...backgroundColorStyle,
272
286
  }}
273
287
  onPress={handleConnectionToggle}
274
288
  disabled={isLoading}>
275
289
  {isLoading ? (
276
- <ActivityIndicator
277
- size="small"
278
- color={isMobileUA() ? '#FFFFFF' : '#00C2FF'}
279
- />
290
+ <ActivityIndicator size="small" color={$config.FONT_COLOR} />
280
291
  ) : isStartAgent ? (
281
- <CallIcon fill={isMobileUA() ? '#FFFFFF' : '#00C2FF'} />
292
+ <CallIcon fill={$config.FONT_COLOR} />
282
293
  ) : (
283
- <EndCall fill={isMobileUA() ? '#FFFFFF' : '#FF414D'} />
294
+ <EndCall fill={$config.FONT_COLOR} />
295
+ )}
296
+ {!(agentConnectionState === 'AGENT_CONNECTED') ? (
297
+ <Text
298
+ style={{
299
+ fontFamily: ThemeConfig.FontFamily.sansPro,
300
+ fontSize: 18,
301
+ lineHeight: 18,
302
+ fontWeight: '600',
303
+ ...fontcolorStyle,
304
+ }}>{`${AI_AGENT_STATE[agentConnectionState]}`}</Text>
305
+ ) : (
306
+ <></>
284
307
  )}
285
-
286
- <Text
287
- style={{
288
- fontFamily: ThemeConfig.FontFamily.sansPro,
289
- ...fontcolorStyle,
290
- }}>{`${AI_AGENT_STATE[agentConnectionState]}`}</Text>
291
308
  </TouchableOpacity>
292
309
  );
293
310
  };
@@ -1,34 +1,46 @@
1
1
  import React from 'react';
2
- import {Text, View} from 'react-native';
2
+ import {Text, View, StyleSheet} from 'react-native';
3
3
  import {LiveAudioVisualizer} from './react-audio-visualize';
4
- import {DisconnectedIconDesktop, DisconnectedIconMobile} from './icons';
5
- import {isMobileUA} from '../../utils/common';
4
+ import ThemeConfig from '../../theme';
5
+ import hexadecimalTransparency from '../../utils/hexadecimalTransparency';
6
+ import {Spacer} from 'customization-api';
6
7
 
7
8
  export const DisconnectedView = ({isConnected}) => {
8
9
  return (
9
- <View
10
- style={{
11
- flex: 1,
12
- backgroundColor: '#222',
13
- display: 'flex',
14
- alignItems: 'center',
15
- justifyContent: 'center',
16
- }}>
17
- {/* big circle that covers the parent view */}
18
- {isMobileUA() ? <DisconnectedIconMobile /> : <DisconnectedIconDesktop />}
19
- <Text
20
- style={{
21
- color: '#B3B3B3',
22
- fontSize: 20,
23
- fontWeight: '400',
24
- marginTop: 20,
25
- }}>
10
+ <View style={DisconnectedViewStyles.container}>
11
+ <View style={DisconnectedViewStyles.circleView} />
12
+ <Spacer size={16} />
13
+ <Text style={DisconnectedViewStyles.textStyle}>
26
14
  {isConnected ? '' : 'Not Joined'}
27
15
  </Text>
28
16
  </View>
29
17
  );
30
18
  };
31
19
 
20
+ const DisconnectedViewStyles = StyleSheet.create({
21
+ container: {
22
+ flex: 1,
23
+ backgroundColor: $config.VIDEO_AUDIO_TILE_COLOR,
24
+ display: 'flex',
25
+ alignItems: 'center',
26
+ justifyContent: 'center',
27
+ },
28
+ circleView: {
29
+ width: 210,
30
+ height: 210,
31
+ borderRadius: 210 / 2,
32
+ borderWidth: 15,
33
+ borderColor: $config.SEMANTIC_NEUTRAL,
34
+ },
35
+ textStyle: {
36
+ color: $config.FONT_COLOR + hexadecimalTransparency['40%'],
37
+ fontSize: 16,
38
+ lineHeight: 18,
39
+ fontWeight: '400',
40
+ fontFamily: ThemeConfig.FontFamily.sansPro,
41
+ },
42
+ });
43
+
32
44
  function createSilentAudioTrack(): MediaStreamTrack {
33
45
  const audioContext = new (window.AudioContext ||
34
46
  (window as any).webkitAudioContext)();
@@ -3,49 +3,113 @@ import {
3
3
  ToolbarComponents,
4
4
  useSidePanel,
5
5
  useRoomInfo,
6
+ IconButton,
7
+ SidePanelType,
8
+ useActionSheet,
9
+ IconButtonProps,
10
+ ToolbarItem,
6
11
  } from 'customization-api';
7
- import ThemeConfig from '../../theme';
8
12
  import {isMobileUA} from '../../utils/common';
9
- import React, {useEffect, useState} from 'react';
10
- import {Text, View} from 'react-native';
13
+ import React, {useEffect} from 'react';
11
14
  import {AgentControl} from './AgentControls';
12
- import {LogoIcon} from './icons';
13
15
 
14
- export const LogoComponent = () => {
16
+ const CustomSettingButton = () => {
17
+ const {sidePanel, setSidePanel} = useSidePanel();
18
+
19
+ const isPanelActive = sidePanel === 'custom-settings-panel';
20
+ const onPress = () => {
21
+ isPanelActive
22
+ ? setSidePanel(SidePanelType.None)
23
+ : setSidePanel('custom-settings-panel');
24
+ };
25
+ const {isOnActionSheet} = useActionSheet();
26
+ let iconButtonProps: IconButtonProps = {
27
+ onPress: onPress,
28
+
29
+ iconProps: {
30
+ name: 'settings',
31
+ tintColor: isPanelActive
32
+ ? $config.PRIMARY_ACTION_TEXT_COLOR
33
+ : $config.SECONDARY_ACTION_COLOR,
34
+ iconBackgroundColor: isPanelActive
35
+ ? $config.PRIMARY_ACTION_BRAND_COLOR
36
+ : '',
37
+ },
38
+ btnTextProps: {
39
+ text: '',
40
+ textColor: $config.FONT_COLOR,
41
+ },
42
+ };
43
+ iconButtonProps.isOnActionSheet = isOnActionSheet;
44
+ if (isOnActionSheet) {
45
+ iconButtonProps.btnTextProps.textStyle = {
46
+ color: $config.FONT_COLOR,
47
+ marginTop: 8,
48
+ fontSize: 12,
49
+ fontWeight: '400',
50
+ fontFamily: 'Source Sans Pro',
51
+ textAlign: 'center',
52
+ };
53
+ }
54
+ return (
55
+ <ToolbarItem>
56
+ {' '}
57
+ <IconButton {...iconButtonProps} />{' '}
58
+ </ToolbarItem>
59
+ );
60
+ };
61
+
62
+ const CustomTranscriptButton = () => {
63
+ const {sidePanel, setSidePanel} = useSidePanel();
64
+
65
+ const isPanelActive = sidePanel === 'agent-transcript-panel';
66
+ const onPress = () => {
67
+ isPanelActive
68
+ ? setSidePanel(SidePanelType.None)
69
+ : setSidePanel('agent-transcript-panel');
70
+ };
71
+ const {isOnActionSheet} = useActionSheet();
72
+ let iconButtonProps: IconButtonProps = {
73
+ onPress: onPress,
74
+
75
+ iconProps: {
76
+ icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIpSURBVHgB7dv/TcJAFAfwL8b/ZYRzA5lA3AAmECcAJkAnQCaQDYQJqBPIBnQD2KC+S4+kIem9El+l1O8nuZTQpxzf/r4WgIiIiIiIiKhhOlULsyzryqQv7QHXbdvpdFawJOEMpO2z9thJG1T57uoaFP7RJ9ppqK1NVQLaycShnQ7S7iWkQ1nBTeyvw9rj0F5+v/oYK4gGhOvfIVfRi83UAvr3GJCCASkYkIIBKRiQggEpGJCCASkYkIIBKRiQ4ha2UmlvYTqWFhuUWkhLkA85WHHSZjAcgbAO6EnGVtLwOpHhkj3yIYVTS6mboAbymYlMdjBiuYmlhXCO1iW1X6hJ6EMKI5YBOVl67uS9ssGo6CDVb4Q+OBix3sQ20sFpeP2M8o6OpM7ve9aw5TfnOQxZB+RQfYB/Elqj8TCvYEAKBqRgQAoGpLA+inkJDE/UkB+6/f05F6nxpwyrUNOHIeuApnIm+w5jWf5kyQblNzJ7x7N4qR3J5ANGLDexQx3heOHe+aJk9rp4iSOvl2jopUbduiXv351RezbLgLqyes9Qg3B9NS6Z3Zf5k0Kt74NZQNb7oNfQWcsxHs8p8+eFhWMWjlfHUawL406e8bnmeB6kYEAKBqRgQAoGpNAC2qL9vmMzo48Bh2sgfwvlEoftv+DvxNzHCqJrULgGekF7TbUCdR8UnkQfwnYI49L8glefsvcq/5jFCw+WX/2PWaQlsafriYiIiIiIiBrtB7K/UdV6QM6CAAAAAElFTkSuQmCC',
77
+ tintColor: isPanelActive
78
+ ? $config.PRIMARY_ACTION_TEXT_COLOR
79
+ : $config.SECONDARY_ACTION_COLOR,
80
+ iconBackgroundColor: isPanelActive
81
+ ? $config.PRIMARY_ACTION_BRAND_COLOR
82
+ : '',
83
+ },
84
+ btnTextProps: {
85
+ text: '',
86
+ textColor: $config.FONT_COLOR,
87
+ },
88
+ };
89
+ iconButtonProps.isOnActionSheet = isOnActionSheet;
90
+ if (isOnActionSheet) {
91
+ iconButtonProps.btnTextProps.textStyle = {
92
+ color: $config.FONT_COLOR,
93
+ marginTop: 8,
94
+ fontSize: 12,
95
+ fontWeight: '400',
96
+ fontFamily: 'Source Sans Pro',
97
+ textAlign: 'center',
98
+ };
99
+ }
15
100
  return (
16
- <View
17
- style={{
18
- flexDirection: 'row',
19
- alignItems: 'center',
20
- justifyContent: 'center',
21
- gap: 8,
22
- marginRight: 20,
23
- }}>
24
- <LogoIcon />
25
- <Text
26
- style={{
27
- color: '#C3C3C3',
28
- textAlign: 'center',
29
- fontSize: 18,
30
- fontStyle: 'normal',
31
- fontWeight: '600',
32
- lineHeight: 18,
33
- fontFamily: ThemeConfig.FontFamily.sansPro,
34
- }}>
35
- AI Builder Demo
36
- </Text>
37
- </View>
101
+ <ToolbarItem>
102
+ <IconButton {...iconButtonProps} />
103
+ </ToolbarItem>
38
104
  );
39
105
  };
40
106
 
41
107
  const Bottombar = () => {
42
- const {MeetingTitleToolbarItem, ParticipantCountToolbarItem} =
43
- ToolbarComponents;
108
+ const {MeetingTitleToolbarItem} = ToolbarComponents;
44
109
  const {setSidePanel} = useSidePanel();
45
110
  const {data} = useRoomInfo();
46
- const [clientId, setClientId] = useState<string | null>(null);
47
111
  useEffect(() => {
48
- !isMobileUA() && setSidePanel('agent-transcript-panel');
112
+ !isMobileUA() && setSidePanel('custom-settings-panel');
49
113
  }, []);
50
114
  return (
51
115
  <ToolbarPreset
@@ -54,35 +118,36 @@ const Bottombar = () => {
54
118
  layout: {hide: true},
55
119
  invite: {hide: true},
56
120
  more: {hide: true},
57
- logo: {
58
- align: 'start',
59
- order: 0,
60
- component: () => <LogoComponent />,
61
- },
62
121
  'meeting-title': {
63
122
  align: 'start',
64
123
  component: MeetingTitleToolbarItem,
65
124
  order: 1,
66
- hide: true,
125
+ hide: false,
67
126
  },
68
127
  'participant-count': {
69
- align: 'start',
70
- component: ParticipantCountToolbarItem,
71
- order: 2,
72
128
  hide: true,
73
129
  },
74
-
130
+ 'local-video': {hide: true},
131
+ 'local-audio': {align: 'center', order: 1},
132
+ screenshare: {hide: true},
133
+ recording: {hide: true},
75
134
  'connect-agent': {
76
- align: 'end',
135
+ align: 'center',
77
136
  label: 'Agent',
78
137
  component: () => <AgentControl channel_name={data.channel} />,
79
- order: 3,
138
+ order: 2,
139
+ },
140
+ 'end-call': {align: 'center', order: 3, hide: true},
141
+ 'custom-transcript': {
142
+ align: 'end',
143
+ order: 0,
144
+ component: CustomTranscriptButton,
145
+ },
146
+ 'custom-settings': {
147
+ align: 'end',
148
+ order: 2,
149
+ component: CustomSettingButton,
80
150
  },
81
- 'local-video': {hide: true},
82
- screenshare: {hide: true},
83
- recording: {hide: true},
84
- 'local-audio': {align: 'end', order: 1},
85
- 'end-call': {align: 'end', order: 2, hide: true},
86
151
  }}
87
152
  />
88
153
  );
@@ -1,4 +1,4 @@
1
- import {StyleSheet} from 'react-native';
1
+ import {StyleSheet, View} from 'react-native';
2
2
  import React, {useContext} from 'react';
3
3
  import {useRtc} from 'customization-api';
4
4
  import {AgentContext} from './AgentControls/AgentContext';
@@ -118,9 +118,9 @@ const CustomSidePanel = () => {
118
118
  };
119
119
 
120
120
  return (
121
- <div style={styles.container}>
121
+ <View style={styles.container}>
122
122
  <ChatScreen />
123
- </div>
123
+ </View>
124
124
  );
125
125
  };
126
126