agora-appbuilder-core 2.3.0-beta.13 → 2.3.0-beta.14

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agora-appbuilder-core",
3
- "version": "2.3.0-beta.13",
3
+ "version": "2.3.0-beta.14",
4
4
  "description": "React Native template for RTE app builder",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -11,7 +11,7 @@
11
11
  */
12
12
  // @ts-nocheck
13
13
  import React, {useState, useContext, useEffect, useRef} from 'react';
14
- import RtmEngine, {RtmAttribute} from 'agora-react-native-rtm';
14
+ import RtmEngine from 'agora-react-native-rtm';
15
15
  import {PropsContext, useLocalUid} from '../../agora-rn-uikit';
16
16
  import ChatContext, {controlMessageEnum} from './ChatContext';
17
17
  import {RtcContext} from '../../agora-rn-uikit';
@@ -20,7 +20,6 @@ import {Platform} from 'react-native';
20
20
  import {backOff} from 'exponential-backoff';
21
21
  import {useString} from '../utils/useString';
22
22
  import {isAndroid, isWeb} from '../utils/common';
23
- import StorageContext from './StorageContext';
24
23
  import {useRenderContext} from 'fpe-api';
25
24
  import {
26
25
  safeJsonParse,
@@ -33,8 +32,6 @@ import {
33
32
  import {EventUtils, EventsQueue, eventMessageType} from '../rtm-events';
34
33
  import RTMEngine from '../rtm/RTMEngine';
35
34
  import {filterObject} from '../utils';
36
- import CustomEvents, {EventLevel} from '../custom-events';
37
- import {EventNames} from '../rtm-events';
38
35
  import useLocalScreenShareUid from '../utils/useLocalShareScreenUid';
39
36
 
40
37
  export enum UserType {
@@ -139,7 +136,9 @@ const RtmConfigure = (props: any) => {
139
136
  try {
140
137
  await engine.current.setLocalUserAttributes(rtmAttributes);
141
138
  timerValueRef.current = 5;
142
- joinChannel();
139
+ await joinChannel();
140
+ setHasUserJoinedRTM(true);
141
+ await runQueuedCustomEvents();
143
142
  } catch (error) {
144
143
  setTimeout(async () => {
145
144
  timerValueRef.current = timerValueRef.current + timerValueRef.current;
@@ -153,8 +152,6 @@ const RtmConfigure = (props: any) => {
153
152
  await engine.current.joinChannel(rtcProps.channel);
154
153
  timerValueRef.current = 5;
155
154
  await getMembers();
156
- setHasUserJoinedRTM(true);
157
- await runQueuedCustomEvents();
158
155
  } catch (error) {
159
156
  setTimeout(async () => {
160
157
  timerValueRef.current = timerValueRef.current + timerValueRef.current;
@@ -446,22 +443,12 @@ const RtmConfigure = (props: any) => {
446
443
 
447
444
  const runQueuedCustomEvents = async () => {
448
445
  try {
449
- const eventsInQueue = EventsQueue.printQueue();
450
- if (eventsInQueue.length !== 0) {
451
- for (const queuedEvents of eventsInQueue) {
452
- await customEventDispatcher(
453
- queuedEvents.data,
454
- queuedEvents.uid,
455
- queuedEvents.ts,
456
- );
457
- // EventsQueue.dequeue();
458
- }
446
+ while (!EventsQueue.isEmpty()) {
447
+ const currEvt = EventsQueue.dequeue();
448
+ await customEventDispatcher(currEvt.data, currEvt.uid, currEvt.ts);
459
449
  }
460
450
  } catch (error) {
461
- throw Error(
462
- 'CUSTOM_EVENTS_API: error while running queued events ',
463
- error,
464
- );
451
+ console.log('CUSTOM_EVENT_API: error while running queue events', error);
465
452
  }
466
453
  };
467
454
 
@@ -486,7 +473,7 @@ const RtmConfigure = (props: any) => {
486
473
  }
487
474
  // Step 2: Emit the event
488
475
  try {
489
- console.log('CUSTOM_EVENT_API: emiting event: ');
476
+ console.log('CUSTOM_EVENT_API: emiting event..: ');
490
477
  EventUtils.emitEvent(evt, {payload, sender, ts});
491
478
  } catch (error) {
492
479
  console.log('CUSTOM_EVENT_API: error while emiting event: ', error);
@@ -554,8 +541,9 @@ const RtmConfigure = (props: any) => {
554
541
 
555
542
  const end = async () => {
556
543
  callActive
557
- ? (await (engine.current as RtmEngine).logout(),
558
- await (engine.current as RtmEngine).destroyClient(),
544
+ ? (RTMEngine.getInstance().destroy(),
545
+ EventUtils.clear(),
546
+ setHasUserJoinedRTM(false),
559
547
  // setLogin(false),
560
548
  console.log('RTM cleanup done'))
561
549
  : {};
@@ -63,9 +63,20 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
63
63
  const {renderList} = useRenderContext();
64
64
  const localUid = useLocalUid();
65
65
  const {setSidePanel} = useSidePanel();
66
- const {groupActive, selectedChatUserId, setGroupActive} = useChatUIControl();
67
- const {setUnreadGroupMessageCount, setUnreadIndividualMessageCount} =
68
- useChatNotification();
66
+ const {
67
+ groupActive,
68
+ selectedChatUserId,
69
+ setGroupActive,
70
+ setPrivateActive,
71
+ setSelectedChatUserId,
72
+ } = useChatUIControl();
73
+ const {
74
+ setUnreadGroupMessageCount,
75
+ setUnreadIndividualMessageCount,
76
+ unreadPrivateMessageCount,
77
+ unreadIndividualMessageCount,
78
+ setUnreadPrivateMessageCount,
79
+ } = useChatNotification();
69
80
  const [messageStore, setMessageStore] = useState<messageStoreInterface[]>([]);
70
81
  const [privateMessageStore, setPrivateMessageStore] = useState<{
71
82
  [key: string]: messageStoreInterface[];
@@ -91,18 +102,41 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
91
102
  }, [selectedChatUserId]);
92
103
 
93
104
  React.useEffect(() => {
94
- const showMessageNotification = (msg: string, uid: string) => {
105
+ const showMessageNotification = (
106
+ msg: string,
107
+ uid: string,
108
+ isPrivateMessage: boolean = false,
109
+ ) => {
110
+ const uidAsNumber = parseInt(uid);
95
111
  Toast.show({
96
112
  type: 'success',
97
113
  text1: msg.length > 30 ? msg.slice(0, 30) + '...' : msg,
98
- text2: renderListRef.current.renderList[parseInt(uid)]?.name
99
- ? fromText(renderListRef.current.renderList[parseInt(uid)]?.name)
114
+ text2: renderListRef.current.renderList[uidAsNumber]?.name
115
+ ? fromText(renderListRef.current.renderList[uidAsNumber]?.name)
100
116
  : '',
101
117
  visibilityTime: 1000,
102
118
  onPress: () => {
119
+ if (isPrivateMessage) {
120
+ setUnreadPrivateMessageCount(
121
+ unreadPrivateMessageCount -
122
+ (unreadIndividualMessageCount[uidAsNumber] || 0),
123
+ );
124
+ setUnreadIndividualMessageCount((prevState) => {
125
+ return {
126
+ ...prevState,
127
+ [uidAsNumber]: 0,
128
+ };
129
+ });
130
+ setGroupActive(false);
131
+ setSelectedChatUserId(uidAsNumber);
132
+ setPrivateActive(true);
133
+ } else {
134
+ setUnreadGroupMessageCount(0);
135
+ setPrivateActive(false);
136
+ setSelectedChatUserId(0);
137
+ setGroupActive(true);
138
+ }
103
139
  setSidePanel(SidePanelType.Chat);
104
- setUnreadGroupMessageCount(0);
105
- setGroupActive(true);
106
140
  },
107
141
  });
108
142
  };
@@ -174,7 +208,7 @@ const ChatMessagesProvider = (props: ChatMessagesProviderProps) => {
174
208
 
175
209
  switch (data?.payload?.action) {
176
210
  case ChatMessageActionEnum.Create:
177
- showMessageNotification(messageData.msg, data.sender);
211
+ showMessageNotification(messageData.msg, data.sender, true);
178
212
  addMessageToPrivateStore(
179
213
  parseInt(data.sender),
180
214
  {
@@ -201,12 +201,12 @@ const VideoCall: React.FC = () => {
201
201
  <DeviceConfigure>
202
202
  <ChatUIControlProvider>
203
203
  <ChatNotificationProvider>
204
- <ChatMessagesProvider>
205
- <SidePanelProvider
206
- value={{
207
- sidePanel,
208
- setSidePanel,
209
- }}>
204
+ <SidePanelProvider
205
+ value={{
206
+ sidePanel,
207
+ setSidePanel,
208
+ }}>
209
+ <ChatMessagesProvider>
210
210
  <ScreenShareProvider>
211
211
  <RtmConfigure
212
212
  setRecordingActive={setRecordingActive}
@@ -260,8 +260,8 @@ const VideoCall: React.FC = () => {
260
260
  </UserPreferenceProvider>
261
261
  </RtmConfigure>
262
262
  </ScreenShareProvider>
263
- </SidePanelProvider>
264
- </ChatMessagesProvider>
263
+ </ChatMessagesProvider>
264
+ </SidePanelProvider>
265
265
  </ChatNotificationProvider>
266
266
  </ChatUIControlProvider>
267
267
  </DeviceConfigure>
@@ -30,6 +30,11 @@ class RTMEngine {
30
30
  await this.engine.createClient($config.APP_ID);
31
31
  }
32
32
 
33
+ private async destroyClientInstance() {
34
+ await this.engine.logout();
35
+ await this.engine.destroyClient();
36
+ }
37
+
33
38
  private constructor() {
34
39
  if (RTMEngine._instance) {
35
40
  return RTMEngine._instance;
@@ -53,6 +58,14 @@ class RTMEngine {
53
58
  get channelUid() {
54
59
  return this.channelId;
55
60
  }
61
+ destroy() {
62
+ try {
63
+ this.destroyClientInstance();
64
+ RTMEngine._instance = null;
65
+ } catch (error) {
66
+ console.log('Error destroying instance error: ', error);
67
+ }
68
+ }
56
69
  }
57
70
 
58
71
  export default RTMEngine;
@@ -245,6 +245,9 @@ const EventUtils = (function () {
245
245
  }
246
246
  return this;
247
247
  },
248
+ clear() {
249
+ _events = {};
250
+ },
248
251
  // 1. To add multiple listeners
249
252
  // addListeners(evt: string, listeners: any) {
250
253
  // if (Array.isArray(listeners)) {
@@ -27,10 +27,16 @@ const EventsQueue = (function () {
27
27
  },
28
28
  dequeue() {
29
29
  if (_eventsQueue.length == 0) return;
30
- _eventsQueue.shift();
30
+ return _eventsQueue.pop();
31
31
  },
32
- printQueue() {
33
- return _eventsQueue;
32
+ isEmpty() {
33
+ return _eventsQueue.length === 0;
34
+ },
35
+ size() {
36
+ return _eventsQueue.length;
37
+ },
38
+ clear() {
39
+ _eventsQueue = [];
34
40
  },
35
41
  };
36
42
  })();
@@ -91,7 +91,7 @@ const RecordingProvider = (props: RecordingProviderProps) => {
91
91
  //const recordingStartedText = useString<boolean>('recordingNotificationLabel');
92
92
  const recordingStartedText = (active: boolean) =>
93
93
  active ? 'Recording Started' : 'Recording Stopped';
94
- const {executePresenterQuery} = useRecordingLayoutQuery();
94
+ const {executePresenterQuery, executeNormalQuery} = useRecordingLayoutQuery();
95
95
  const {localUid} = useContext(ChatContext);
96
96
  const {screenShareData} = useScreenContext();
97
97
 
@@ -156,9 +156,14 @@ const RecordingProvider = (props: RecordingProviderProps) => {
156
156
  // 2. set the local recording state to true to update the UI
157
157
  setRecordingActive(true);
158
158
  // 3. set the presenter mode if screen share is active
159
- if (Object.values(screenShareData).some((item) => item.isActive)) {
160
- console.log('Executing presenter query');
161
- executePresenterQuery();
159
+ const activeScreenshareUid = Object.keys(screenShareData).find(
160
+ (key) => screenShareData[key]?.isActive,
161
+ );
162
+ if (activeScreenshareUid) {
163
+ console.log('screenshare: Executing presenter query');
164
+ executePresenterQuery(parseInt(activeScreenshareUid));
165
+ } else {
166
+ executeNormalQuery();
162
167
  }
163
168
  }
164
169
  })
@@ -1,8 +1,8 @@
1
- import React, {useContext} from 'react';
1
+ import React from 'react';
2
2
  import {useParams} from '../../components/Router';
3
3
 
4
4
  import {gql, useMutation} from '@apollo/client';
5
- import {PropsContext} from '../../../agora-rn-uikit';
5
+ import {UidType} from '../../../agora-rn-uikit';
6
6
 
7
7
  const SET_PRESENTER = gql`
8
8
  mutation setPresenter($uid: Int!, $passphrase: String!) {
@@ -19,10 +19,9 @@ const SET_NORMAL = gql`
19
19
  function useRecordingLayoutQuery() {
20
20
  const [setPresenterQuery] = useMutation(SET_PRESENTER);
21
21
  const [setNormalQuery] = useMutation(SET_NORMAL);
22
- const {screenShareUid} = useContext(PropsContext).rtcProps;
23
22
  const {phrase} = useParams<any>();
24
23
 
25
- const executePresenterQuery = () => {
24
+ const executePresenterQuery = (screenShareUid: UidType) => {
26
25
  setPresenterQuery({
27
26
  variables: {
28
27
  uid: screenShareUid,
@@ -99,9 +99,10 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
99
99
  }, []);
100
100
 
101
101
  const executeRecordingQuery = (isScreenActive: boolean) => {
102
- if (!isScreenActive) {
102
+ if (isScreenActive) {
103
+ console.log('screenshare: Executing presenter query');
103
104
  // If screen share is not going on, start the screen share by executing the graphql query
104
- executePresenterQuery();
105
+ executePresenterQuery(screenShareUid);
105
106
  } else {
106
107
  // If recording is already going on, stop the recording by executing the graphql query.
107
108
  executeNormalQuery();
@@ -134,16 +135,28 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
134
135
  encryption as unknown as any,
135
136
  );
136
137
  isActive && setScreenshareActive(true);
138
+
137
139
  if (isActive) {
140
+ // 1. Set local state
141
+ setScreenShareData((prevState) => {
142
+ return {
143
+ ...prevState,
144
+ [screenShareUid]: {
145
+ name: renderListRef.current.renderList[screenShareUid]?.name,
146
+ isActive: true,
147
+ },
148
+ };
149
+ });
150
+ // 2. Inform everyone in the channel screenshare is actice
138
151
  CustomEvents.send(EventNames.SCREENSHARE_ATTRIBUTE, {
139
152
  value: `${true}`,
140
153
  level: EventLevel.LEVEL2,
141
154
  });
142
- //if local user started the screenshare then change layout to pinned
155
+ //3 . if local user started the screenshare then change layout to pinned
143
156
  triggerChangeLayout(true, screenShareUid);
144
157
  }
145
158
  } catch (e) {
146
- console.error("supriya an't start the screen share", e);
159
+ console.error("can't start the screen share", e);
147
160
  executeNormalQuery();
148
161
  }
149
162
  };