agora-appbuilder-core 4.1.9 → 4.1.11-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/src/Contexts/PropsContext.tsx +1 -3
- package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +1 -2
- package/template/agora-rn-uikit/src/Reducer/index.ts +0 -2
- package/template/agora-rn-uikit/src/Rtc/Join.tsx +11 -25
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +1 -14
- package/template/agora-rn-uikit/src/Utils/isBotUser.ts +1 -1
- package/template/android/app/build.gradle +0 -7
- package/template/bridge/rtm/web/Types.ts +0 -183
- package/template/bridge/rtm/web/index.ts +491 -423
- package/template/defaultConfig.js +3 -3
- package/template/ios/Podfile +0 -41
- package/template/package.json +5 -5
- 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/ActionMenu.tsx +93 -13
- package/template/src/atoms/CustomIcon.tsx +1 -0
- package/template/src/atoms/DropDownMulti.tsx +80 -29
- package/template/src/atoms/Input.tsx +2 -1
- package/template/src/components/Controls.tsx +148 -143
- package/template/src/components/EventsConfigure.tsx +152 -97
- package/template/src/components/RTMConfigure.tsx +426 -644
- package/template/src/components/precall/joinCallBtn.native.tsx +7 -2
- package/template/src/components/precall/joinCallBtn.tsx +7 -2
- package/template/src/components/precall/joinWaitingRoomBtn.native.tsx +8 -3
- package/template/src/components/precall/joinWaitingRoomBtn.tsx +22 -4
- package/template/src/components/precall/textInput.tsx +45 -22
- package/template/src/components/precall/usePreCall.tsx +7 -0
- package/template/src/components/room-info/useRoomInfo.tsx +5 -0
- package/template/src/language/default-labels/videoCallScreenLabels.ts +27 -4
- package/template/src/pages/video-call/ActionSheetContent.tsx +77 -77
- package/template/src/pages/video-call/SidePanelHeader.tsx +81 -36
- package/template/src/rtm/RTMEngine.ts +33 -130
- package/template/src/rtm-events/constants.ts +6 -0
- package/template/src/rtm-events-api/Events.ts +30 -106
- package/template/src/subComponents/caption/Caption.tsx +48 -7
- package/template/src/subComponents/caption/CaptionContainer.tsx +324 -51
- package/template/src/subComponents/caption/CaptionIcon.tsx +35 -34
- package/template/src/subComponents/caption/CaptionText.tsx +103 -2
- package/template/src/subComponents/caption/LanguageSelectorPopup.tsx +179 -69
- package/template/src/subComponents/caption/Transcript.tsx +46 -11
- package/template/src/subComponents/caption/TranscriptIcon.tsx +27 -35
- package/template/src/subComponents/caption/TranscriptText.tsx +78 -3
- package/template/src/subComponents/caption/proto/ptoto.js +38 -4
- package/template/src/subComponents/caption/proto/test.proto +34 -19
- package/template/src/subComponents/caption/useCaption.tsx +753 -10
- package/template/src/subComponents/caption/useSTTAPI.tsx +118 -205
- package/template/src/subComponents/caption/useStreamMessageUtils.native.ts +152 -33
- package/template/src/subComponents/caption/useStreamMessageUtils.ts +165 -34
- package/template/src/subComponents/caption/utils.ts +171 -3
- package/template/src/utils/SdkEvents.ts +3 -0
- package/template/src/utils/useEndCall.ts +3 -5
- package/template/src/utils/useSpeechToText.ts +31 -20
- package/template/agora-rn-uikit/src/Reducer/Spotlight.ts +0 -11
- package/template/agora-rn-uikit/src/Reducer/UserBanned.ts +0 -11
- package/template/bridge/rtm/web/index-legacy.ts +0 -540
- package/template/src/components/RTMConfigure-legacy.tsx +0 -848
|
@@ -20,13 +20,20 @@ import {
|
|
|
20
20
|
} from '../../components/chat-ui/useChatUIControls';
|
|
21
21
|
import {numFormatter} from '../../utils';
|
|
22
22
|
import ChatContext from '../../components/ChatContext';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
LanguageTranslationConfig,
|
|
25
|
+
useCaption,
|
|
26
|
+
} from '../../subComponents/caption/useCaption';
|
|
24
27
|
import ActionMenu, {ActionMenuItem} from '../../atoms/ActionMenu';
|
|
25
28
|
import {calculatePosition, isMobileUA} from '../../utils/common';
|
|
26
29
|
import LanguageSelectorPopup from '../../subComponents/caption/LanguageSelectorPopup';
|
|
27
30
|
import useSTTAPI from '../../subComponents/caption/useSTTAPI';
|
|
28
31
|
import useGetName from '../../utils/useGetName';
|
|
29
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
LanguageType,
|
|
34
|
+
mergeTranslationConfigs,
|
|
35
|
+
TranslateConfig,
|
|
36
|
+
} from '../../subComponents/caption/utils';
|
|
30
37
|
import {useRoomInfo, usePreCall} from 'customization-api';
|
|
31
38
|
import useTranscriptDownload from '../../subComponents/caption/useTranscriptDownload';
|
|
32
39
|
import {useVB} from '../../components/virtual-background/useVB';
|
|
@@ -42,10 +49,13 @@ import {
|
|
|
42
49
|
chatPanelPrivateTabText,
|
|
43
50
|
peoplePanelHeaderText,
|
|
44
51
|
sttChangeSpokenLanguageText,
|
|
52
|
+
sttChangeTranslationLanguageText,
|
|
45
53
|
sttDownloadTranscriptBtnText,
|
|
54
|
+
sttStopTranslationText,
|
|
46
55
|
sttTranscriptPanelHeaderText,
|
|
47
56
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
48
57
|
import {logger, LogSource} from '../../logger/AppBuilderLogger';
|
|
58
|
+
import {TranslateActionMenu} from '../../subComponents/caption/CaptionContainer';
|
|
49
59
|
|
|
50
60
|
export const SettingsHeader = props => {
|
|
51
61
|
const {setSidePanel} = useSidePanel();
|
|
@@ -262,7 +272,7 @@ const TranscriptHeaderActionMenu = (props: TranscriptHeaderActionMenuProps) => {
|
|
|
262
272
|
language: prevLang,
|
|
263
273
|
meetingTranscript,
|
|
264
274
|
isLangChangeInProgress,
|
|
265
|
-
|
|
275
|
+
selectedTranslationLanguage,
|
|
266
276
|
} = useCaption();
|
|
267
277
|
const {downloadTranscript} = useTranscriptDownload();
|
|
268
278
|
const [modalPosition, setModalPosition] = React.useState({});
|
|
@@ -270,29 +280,67 @@ const TranscriptHeaderActionMenu = (props: TranscriptHeaderActionMenuProps) => {
|
|
|
270
280
|
const {width: globalWidth, height: globalHeight} = useWindowDimensions();
|
|
271
281
|
const [isLanguagePopupOpen, setLanguagePopup] =
|
|
272
282
|
React.useState<boolean>(false);
|
|
283
|
+
const [isTranslateMenuOpen, setTranslateMenuOpen] =
|
|
284
|
+
React.useState<boolean>(false);
|
|
273
285
|
const {restart} = useSTTAPI();
|
|
274
286
|
const username = useGetName();
|
|
275
287
|
const actionMenuitems: ActionMenuItem[] = [];
|
|
276
288
|
const {
|
|
277
289
|
data: {isHost},
|
|
290
|
+
sttLanguage,
|
|
278
291
|
} = useRoomInfo();
|
|
279
|
-
|
|
292
|
+
const {handleTranslateConfigChange, updateSTTBotSession, translationConfig} =
|
|
293
|
+
useCaption();
|
|
280
294
|
const downloadTranscriptLabel = useString(sttDownloadTranscriptBtnText)();
|
|
281
295
|
const changeSpokenLanguage = useString<boolean>(
|
|
282
296
|
sttChangeSpokenLanguageText,
|
|
283
297
|
)();
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
298
|
+
const sttStopTranslationLabel = useString<boolean>(sttStopTranslationText)();
|
|
299
|
+
const changeTranslationLanguage = useString<boolean>(
|
|
300
|
+
sttChangeTranslationLanguageText,
|
|
301
|
+
)();
|
|
302
|
+
|
|
303
|
+
// isHost &&
|
|
304
|
+
actionMenuitems.push({
|
|
305
|
+
icon: 'globe',
|
|
306
|
+
iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
307
|
+
textColor: $config.FONT_COLOR,
|
|
308
|
+
title: changeSpokenLanguage + ' ',
|
|
309
|
+
disabled: isLangChangeInProgress,
|
|
310
|
+
onPress: () => {
|
|
311
|
+
setActionMenuVisible(false);
|
|
312
|
+
setLanguagePopup(true);
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// actionMenuitems.push({
|
|
317
|
+
// icon: 'lang-select',
|
|
318
|
+
// iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
319
|
+
// textColor: $config.FONT_COLOR,
|
|
320
|
+
// title: changeTranslationLanguage,
|
|
321
|
+
// disabled: false,
|
|
322
|
+
// onPress: () => {
|
|
323
|
+
// setActionMenuVisible(false);
|
|
324
|
+
// setTranslateMenuOpen(true);
|
|
325
|
+
// },
|
|
326
|
+
// });
|
|
327
|
+
|
|
328
|
+
actionMenuitems.push({
|
|
329
|
+
icon: 'lang-select',
|
|
330
|
+
iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
331
|
+
textColor: $config.FONT_COLOR,
|
|
332
|
+
title: sttStopTranslationLabel,
|
|
333
|
+
disabled: false,
|
|
334
|
+
onPress: async () => {
|
|
335
|
+
setActionMenuVisible(false);
|
|
336
|
+
// Keep source language same, just clear target languages
|
|
337
|
+
// This stops translation but keeps transcription running
|
|
338
|
+
await updateSTTBotSession({
|
|
339
|
+
source: translationConfig.source, // Keep current source
|
|
340
|
+
targets: [], // Empty targets = no translation
|
|
341
|
+
});
|
|
342
|
+
},
|
|
343
|
+
});
|
|
296
344
|
|
|
297
345
|
actionMenuitems.push({
|
|
298
346
|
icon: 'download',
|
|
@@ -306,27 +354,18 @@ const TranscriptHeaderActionMenu = (props: TranscriptHeaderActionMenuProps) => {
|
|
|
306
354
|
},
|
|
307
355
|
});
|
|
308
356
|
|
|
309
|
-
const onLanguageChange = (
|
|
357
|
+
const onLanguageChange = async (
|
|
358
|
+
inputTranslateConfig: LanguageTranslationConfig,
|
|
359
|
+
) => {
|
|
360
|
+
console.log(
|
|
361
|
+
'[STT_PER_USER_BOT] SidePanelHeader TranscriptHeaderActionMenu - onLanguageChange - sourceLanguage , targetLanguage:',
|
|
362
|
+
inputTranslateConfig,
|
|
363
|
+
);
|
|
310
364
|
setLanguagePopup(false);
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
LogSource.Internals,
|
|
316
|
-
'STT',
|
|
317
|
-
'stt restarted successfully',
|
|
318
|
-
);
|
|
319
|
-
})
|
|
320
|
-
.catch(error => {
|
|
321
|
-
logger.error(
|
|
322
|
-
LogSource.Internals,
|
|
323
|
-
'STT',
|
|
324
|
-
'Error in restarting',
|
|
325
|
-
error,
|
|
326
|
-
);
|
|
327
|
-
// Handle the error case
|
|
328
|
-
});
|
|
329
|
-
}
|
|
365
|
+
// Update caption with new language configuration\
|
|
366
|
+
try {
|
|
367
|
+
await handleTranslateConfigChange(inputTranslateConfig);
|
|
368
|
+
} catch (error) {}
|
|
330
369
|
};
|
|
331
370
|
|
|
332
371
|
React.useEffect(() => {
|
|
@@ -370,6 +409,12 @@ const TranscriptHeaderActionMenu = (props: TranscriptHeaderActionMenuProps) => {
|
|
|
370
409
|
setModalVisible={setLanguagePopup}
|
|
371
410
|
onConfirm={onLanguageChange}
|
|
372
411
|
/>
|
|
412
|
+
|
|
413
|
+
<TranslateActionMenu
|
|
414
|
+
actionMenuVisible={isTranslateMenuOpen}
|
|
415
|
+
setActionMenuVisible={setTranslateMenuOpen}
|
|
416
|
+
btnRef={btnRef}
|
|
417
|
+
/>
|
|
373
418
|
</>
|
|
374
419
|
);
|
|
375
420
|
};
|
|
@@ -10,71 +10,57 @@
|
|
|
10
10
|
*********************************************
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import
|
|
14
|
-
createAgoraRtmClient,
|
|
15
|
-
RtmConfig,
|
|
16
|
-
type RTMClient,
|
|
17
|
-
} from 'agora-react-native-rtm';
|
|
13
|
+
import RtmEngine from 'agora-react-native-rtm';
|
|
18
14
|
import {isAndroid, isIOS} from '../utils/common';
|
|
19
15
|
|
|
20
16
|
class RTMEngine {
|
|
21
|
-
|
|
17
|
+
engine!: RtmEngine;
|
|
22
18
|
private localUID: string = '';
|
|
23
19
|
private channelId: string = '';
|
|
24
20
|
|
|
25
21
|
private static _instance: RTMEngine | null = null;
|
|
26
22
|
|
|
27
|
-
private constructor() {
|
|
28
|
-
if (RTMEngine._instance) {
|
|
29
|
-
return RTMEngine._instance;
|
|
30
|
-
}
|
|
31
|
-
RTMEngine._instance = this;
|
|
32
|
-
return RTMEngine._instance;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
23
|
public static getInstance() {
|
|
36
|
-
// We are only creating the instance but not creating the rtm client yet
|
|
37
24
|
if (!RTMEngine._instance) {
|
|
38
|
-
|
|
25
|
+
return new RTMEngine();
|
|
39
26
|
}
|
|
40
27
|
return RTMEngine._instance;
|
|
41
28
|
}
|
|
42
29
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
30
|
+
private async createClientInstance() {
|
|
31
|
+
await this.engine.createClient($config.APP_ID);
|
|
32
|
+
}
|
|
47
33
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
);
|
|
34
|
+
private async destroyClientInstance() {
|
|
35
|
+
await this.engine.logout();
|
|
36
|
+
if (isIOS() || isAndroid()) {
|
|
37
|
+
await this.engine.destroyClient();
|
|
53
38
|
}
|
|
39
|
+
}
|
|
54
40
|
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
`RTMEngine: Cannot change UID from '${this.localUID}' to '${newUID}' while engine is active. ` +
|
|
59
|
-
`Please call destroy() first, then setLocalUID() with the new UID.`,
|
|
60
|
-
);
|
|
41
|
+
private constructor() {
|
|
42
|
+
if (RTMEngine._instance) {
|
|
43
|
+
return RTMEngine._instance;
|
|
61
44
|
}
|
|
45
|
+
RTMEngine._instance = this;
|
|
46
|
+
this.engine = new RtmEngine();
|
|
47
|
+
this.localUID = '';
|
|
48
|
+
this.channelId = '';
|
|
49
|
+
this.createClientInstance();
|
|
62
50
|
|
|
63
|
-
|
|
51
|
+
return RTMEngine._instance;
|
|
52
|
+
}
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
54
|
+
setLocalUID(localUID: string) {
|
|
55
|
+
this.localUID = localUID;
|
|
68
56
|
}
|
|
69
57
|
|
|
70
58
|
setChannelId(channelID: string) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
throw new Error('setChannelId: channelID must be a non-empty string');
|
|
77
|
-
}
|
|
59
|
+
this.channelId = channelID;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
setLoginInfo(localUID: string, channelID: string) {
|
|
63
|
+
this.localUID = localUID;
|
|
78
64
|
this.channelId = channelID;
|
|
79
65
|
}
|
|
80
66
|
|
|
@@ -86,99 +72,16 @@ class RTMEngine {
|
|
|
86
72
|
return this.channelId;
|
|
87
73
|
}
|
|
88
74
|
|
|
89
|
-
get isEngineReady() {
|
|
90
|
-
return !!this._engine && !!this.localUID;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
get engine(): RTMClient {
|
|
94
|
-
this.ensureEngineReady();
|
|
95
|
-
return this._engine!;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
private ensureEngineReady() {
|
|
99
|
-
if (!this.isEngineReady) {
|
|
100
|
-
throw new Error(
|
|
101
|
-
'RTM Engine not ready. Please call setLocalUID() with a valid UID first.',
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
private createClientInstance() {
|
|
107
|
-
try {
|
|
108
|
-
if (!this.localUID || this.localUID.trim() === '') {
|
|
109
|
-
throw new Error('Cannot create RTM client: localUID is not set');
|
|
110
|
-
}
|
|
111
|
-
if (!$config.APP_ID) {
|
|
112
|
-
throw new Error('Cannot create RTM client: APP_ID is not configured');
|
|
113
|
-
}
|
|
114
|
-
const rtmConfig = new RtmConfig({
|
|
115
|
-
appId: $config.APP_ID,
|
|
116
|
-
userId: this.localUID,
|
|
117
|
-
});
|
|
118
|
-
this._engine = createAgoraRtmClient(rtmConfig);
|
|
119
|
-
} catch (error) {
|
|
120
|
-
const contextError = new Error(
|
|
121
|
-
`Failed to create RTM client instance for userId: ${
|
|
122
|
-
this.localUID
|
|
123
|
-
}, appId: ${$config.APP_ID}. Error: ${error.message || error}`,
|
|
124
|
-
);
|
|
125
|
-
console.error('RTMEngine createClientInstance error:', contextError);
|
|
126
|
-
throw contextError;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private async destroyClientInstance() {
|
|
131
|
-
try {
|
|
132
|
-
if (this._engine) {
|
|
133
|
-
// 1. Unsubscribe from channel if we have one
|
|
134
|
-
if (this.channelId) {
|
|
135
|
-
try {
|
|
136
|
-
await this._engine.unsubscribe(this.channelId);
|
|
137
|
-
} catch (error) {
|
|
138
|
-
console.warn(
|
|
139
|
-
`Failed to unsubscribe from channel '${this.channelId}':`,
|
|
140
|
-
error,
|
|
141
|
-
);
|
|
142
|
-
// Continue with cleanup even if unsubscribe fails
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// 2. Remove all listeners
|
|
146
|
-
try {
|
|
147
|
-
this._engine.removeAllListeners?.();
|
|
148
|
-
} catch (error) {
|
|
149
|
-
console.warn('Failed to remove listeners:', error);
|
|
150
|
-
}
|
|
151
|
-
// 3. Logout
|
|
152
|
-
try {
|
|
153
|
-
await this._engine.logout();
|
|
154
|
-
if (isAndroid() || isIOS()) {
|
|
155
|
-
this._engine.release();
|
|
156
|
-
}
|
|
157
|
-
} catch (error) {
|
|
158
|
-
console.warn('Failed to logout:', error);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
} catch (error) {
|
|
162
|
-
console.error('Error during client instance destruction:', error);
|
|
163
|
-
// Don't re-throw - we want cleanup to complete
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
75
|
async destroy() {
|
|
168
76
|
try {
|
|
169
|
-
if (!this._engine) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
77
|
await this.destroyClientInstance();
|
|
174
|
-
|
|
78
|
+
if (isIOS() || isAndroid()) {
|
|
79
|
+
RTMEngine._instance = null;
|
|
80
|
+
}
|
|
175
81
|
this.localUID = '';
|
|
176
|
-
this.
|
|
177
|
-
RTMEngine._instance = null;
|
|
82
|
+
this.channelId = '';
|
|
178
83
|
} catch (error) {
|
|
179
|
-
console.
|
|
180
|
-
// Don't re-throw - destruction should be a best-effort cleanup
|
|
181
|
-
// Re-throwing could prevent proper cleanup in calling code
|
|
84
|
+
console.log('Error destroying instance error: ', error);
|
|
182
85
|
}
|
|
183
86
|
}
|
|
184
87
|
}
|
|
@@ -30,6 +30,9 @@ const VIDEO_MEETING_ATTENDEE = 'VIDEO_MEETING_ATTENDEE';
|
|
|
30
30
|
// 6. STT
|
|
31
31
|
const STT_ACTIVE = 'STT_IS_ACTIVE';
|
|
32
32
|
const STT_LANGUAGE = 'STT_LANGUAGE_CHANGED';
|
|
33
|
+
const STT_TRANSLATE_LANGUAGE = 'STT_TRANSLATE_LANGUAGE_CHANGED';
|
|
34
|
+
const STT_SPOKEN_LANGUAGE = 'STT_SPOKEN_LANGUAGE';
|
|
35
|
+
const USER_STOPPED_TRANSLATION = 'USER_STOPPED_TRANSLATION';
|
|
33
36
|
// 7. WAITING ROOM
|
|
34
37
|
const WAITING_ROOM_REQUEST = 'WAITING_ROOM_REQUEST';
|
|
35
38
|
const WAITING_ROOM_RESPONSE = 'WAITING_ROOM_RESPONSE';
|
|
@@ -53,6 +56,9 @@ const EventNames = {
|
|
|
53
56
|
VIDEO_MEETING_ATTENDEE,
|
|
54
57
|
STT_ACTIVE,
|
|
55
58
|
STT_LANGUAGE,
|
|
59
|
+
STT_TRANSLATE_LANGUAGE,
|
|
60
|
+
STT_SPOKEN_LANGUAGE,
|
|
61
|
+
USER_STOPPED_TRANSLATION,
|
|
56
62
|
WAITING_ROOM_REQUEST,
|
|
57
63
|
WAITING_ROOM_RESPONSE,
|
|
58
64
|
WAITING_ROOM_STATUS_UPDATE,
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
('use strict');
|
|
14
|
-
import
|
|
14
|
+
import RtmEngine from 'agora-react-native-rtm';
|
|
15
15
|
import RTMEngine from '../rtm/RTMEngine';
|
|
16
16
|
import {EventUtils} from '../rtm-events';
|
|
17
17
|
import {
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
} from './types';
|
|
24
24
|
import {adjustUID} from '../rtm/utils';
|
|
25
25
|
import {LogSource, logger} from '../logger/AppBuilderLogger';
|
|
26
|
-
import {nativeChannelTypeMapping} from '../../bridge/rtm/web/Types';
|
|
27
26
|
|
|
28
27
|
class Events {
|
|
29
28
|
private source: EventSource = EventSource.core;
|
|
@@ -42,17 +41,11 @@ class Events {
|
|
|
42
41
|
* @api private
|
|
43
42
|
*/
|
|
44
43
|
private _persist = async (evt: string, payload: string) => {
|
|
45
|
-
const rtmEngine:
|
|
46
|
-
const userId = RTMEngine.getInstance().localUid;
|
|
44
|
+
const rtmEngine: RtmEngine = RTMEngine.getInstance().engine;
|
|
47
45
|
try {
|
|
48
46
|
const rtmAttribute = {key: evt, value: payload};
|
|
49
47
|
// Step 1: Call RTM API to update local attributes
|
|
50
|
-
await rtmEngine.
|
|
51
|
-
{items: [rtmAttribute]},
|
|
52
|
-
{
|
|
53
|
-
userId,
|
|
54
|
-
},
|
|
55
|
-
);
|
|
48
|
+
await rtmEngine.addOrUpdateLocalUserAttributes([rtmAttribute]);
|
|
56
49
|
} catch (error) {
|
|
57
50
|
logger.error(
|
|
58
51
|
LogSource.Events,
|
|
@@ -75,8 +68,8 @@ class Events {
|
|
|
75
68
|
`CUSTOM_EVENT_API Event name cannot be of type ${typeof evt}`,
|
|
76
69
|
);
|
|
77
70
|
}
|
|
78
|
-
if (evt.trim()
|
|
79
|
-
throw Error(
|
|
71
|
+
if (evt.trim() == '') {
|
|
72
|
+
throw Error(`CUSTOM_EVENT_API Name or function cannot be empty`);
|
|
80
73
|
}
|
|
81
74
|
return true;
|
|
82
75
|
};
|
|
@@ -110,15 +103,10 @@ class Events {
|
|
|
110
103
|
rtmPayload: RTMAttributePayload,
|
|
111
104
|
toUid?: ReceiverUid,
|
|
112
105
|
) => {
|
|
113
|
-
const to = typeof toUid
|
|
106
|
+
const to = typeof toUid == 'string' ? parseInt(toUid) : toUid;
|
|
107
|
+
const rtmEngine: RtmEngine = RTMEngine.getInstance().engine;
|
|
114
108
|
|
|
115
109
|
const text = JSON.stringify(rtmPayload);
|
|
116
|
-
|
|
117
|
-
if (!RTMEngine.getInstance().isEngineReady) {
|
|
118
|
-
throw new Error('RTM Engine is not ready. Call setLocalUID() first.');
|
|
119
|
-
}
|
|
120
|
-
const rtmEngine: RTMClient = RTMEngine.getInstance().engine;
|
|
121
|
-
|
|
122
110
|
// Case 1: send to channel
|
|
123
111
|
if (
|
|
124
112
|
typeof to === 'undefined' ||
|
|
@@ -132,16 +120,7 @@ class Events {
|
|
|
132
120
|
);
|
|
133
121
|
try {
|
|
134
122
|
const channelId = RTMEngine.getInstance().channelUid;
|
|
135
|
-
|
|
136
|
-
throw new Error(
|
|
137
|
-
'Channel ID is not set. Cannot send channel attributes.',
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
await rtmEngine.publish(channelId, text, {
|
|
141
|
-
channelType: nativeChannelTypeMapping.MESSAGE, // 1 is message
|
|
142
|
-
customType: 'PlainText',
|
|
143
|
-
messageType: 1,
|
|
144
|
-
});
|
|
123
|
+
await rtmEngine.sendMessageByChannelId(channelId, text);
|
|
145
124
|
} catch (error) {
|
|
146
125
|
logger.error(
|
|
147
126
|
LogSource.Events,
|
|
@@ -161,10 +140,10 @@ class Events {
|
|
|
161
140
|
);
|
|
162
141
|
const adjustedUID = adjustUID(to);
|
|
163
142
|
try {
|
|
164
|
-
await rtmEngine.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
143
|
+
await rtmEngine.sendMessageToPeer({
|
|
144
|
+
peerId: `${adjustedUID}`,
|
|
145
|
+
offline: false,
|
|
146
|
+
text,
|
|
168
147
|
});
|
|
169
148
|
} catch (error) {
|
|
170
149
|
logger.error(
|
|
@@ -185,32 +164,14 @@ class Events {
|
|
|
185
164
|
to,
|
|
186
165
|
);
|
|
187
166
|
try {
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
);
|
|
197
|
-
response.forEach((result, index) => {
|
|
198
|
-
const uid = to[index];
|
|
199
|
-
if (result.status === 'rejected') {
|
|
200
|
-
logger.error(
|
|
201
|
-
LogSource.Events,
|
|
202
|
-
'CUSTOM_EVENTS',
|
|
203
|
-
`Failed to publish to user ${uid}:`,
|
|
204
|
-
result.reason,
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
// for (const uid of to) {
|
|
209
|
-
// const adjustedUID = adjustUID(uid);
|
|
210
|
-
// await rtmEngine.publish(`${adjustedUID}`, text, {
|
|
211
|
-
// channelType: 3, // user
|
|
212
|
-
// });
|
|
213
|
-
// }
|
|
167
|
+
for (const uid of to) {
|
|
168
|
+
const adjustedUID = adjustUID(uid);
|
|
169
|
+
await rtmEngine.sendMessageToPeer({
|
|
170
|
+
peerId: `${adjustedUID}`,
|
|
171
|
+
offline: false,
|
|
172
|
+
text,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
214
175
|
} catch (error) {
|
|
215
176
|
logger.error(
|
|
216
177
|
LogSource.Events,
|
|
@@ -231,31 +192,13 @@ class Events {
|
|
|
231
192
|
'updating channel attributes',
|
|
232
193
|
);
|
|
233
194
|
try {
|
|
234
|
-
|
|
235
|
-
if (!RTMEngine.getInstance().isEngineReady) {
|
|
236
|
-
throw new Error('RTM Engine is not ready. Call setLocalUID() first.');
|
|
237
|
-
}
|
|
238
|
-
const rtmEngine: RTMClient = RTMEngine.getInstance().engine;
|
|
239
|
-
|
|
195
|
+
const rtmEngine: RtmEngine = RTMEngine.getInstance().engine;
|
|
240
196
|
const channelId = RTMEngine.getInstance().channelUid;
|
|
241
|
-
if (!channelId || channelId.trim() === '') {
|
|
242
|
-
throw new Error(
|
|
243
|
-
'Channel ID is not set. Cannot send channel attributes.',
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
197
|
const rtmAttribute = [{key: rtmPayload.evt, value: rtmPayload.value}];
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
items: rtmAttribute,
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
addUserId: true,
|
|
256
|
-
addTimeStamp: true,
|
|
257
|
-
},
|
|
258
|
-
);
|
|
198
|
+
// Step 1: Call RTM API to update local attributes
|
|
199
|
+
await rtmEngine.addOrUpdateChannelAttributes(channelId, rtmAttribute, {
|
|
200
|
+
enableNotificationToChannelMembers: true,
|
|
201
|
+
});
|
|
259
202
|
} catch (error) {
|
|
260
203
|
logger.error(
|
|
261
204
|
LogSource.Events,
|
|
@@ -280,8 +223,7 @@ class Events {
|
|
|
280
223
|
on = (eventName: string, listener: EventCallback): Function => {
|
|
281
224
|
try {
|
|
282
225
|
if (!this._validateEvt(eventName) || !this._validateListener(listener)) {
|
|
283
|
-
|
|
284
|
-
return () => {};
|
|
226
|
+
return;
|
|
285
227
|
}
|
|
286
228
|
EventUtils.addListener(eventName, listener, this.source);
|
|
287
229
|
console.log('CUSTOM_EVENT_API event listener registered', eventName);
|
|
@@ -296,8 +238,6 @@ class Events {
|
|
|
296
238
|
'Error: events.on',
|
|
297
239
|
error,
|
|
298
240
|
);
|
|
299
|
-
// Return no-op function on error to prevent undefined issues
|
|
300
|
-
return () => {};
|
|
301
241
|
}
|
|
302
242
|
};
|
|
303
243
|
|
|
@@ -313,11 +253,7 @@ class Events {
|
|
|
313
253
|
off = (eventName?: string, listener?: EventCallback) => {
|
|
314
254
|
try {
|
|
315
255
|
if (listener) {
|
|
316
|
-
if (
|
|
317
|
-
eventName &&
|
|
318
|
-
this._validateListener(listener) &&
|
|
319
|
-
this._validateEvt(eventName)
|
|
320
|
-
) {
|
|
256
|
+
if (this._validateListener(listener) && this._validateEvt(eventName)) {
|
|
321
257
|
// listen off an event by eventName and listener
|
|
322
258
|
//@ts-ignore
|
|
323
259
|
EventUtils.removeListener(eventName, listener, this.source);
|
|
@@ -359,18 +295,8 @@ class Events {
|
|
|
359
295
|
persistLevel: PersistanceLevel = PersistanceLevel.None,
|
|
360
296
|
receiver: ReceiverUid = -1,
|
|
361
297
|
) => {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
} catch (error) {
|
|
367
|
-
logger.error(
|
|
368
|
-
LogSource.Events,
|
|
369
|
-
'CUSTOM_EVENTS',
|
|
370
|
-
'Event validation failed',
|
|
371
|
-
error,
|
|
372
|
-
);
|
|
373
|
-
return; // Don't throw - just log and return
|
|
298
|
+
if (!this._validateEvt(eventName)) {
|
|
299
|
+
return;
|
|
374
300
|
}
|
|
375
301
|
|
|
376
302
|
const persistValue = JSON.stringify({
|
|
@@ -392,7 +318,6 @@ class Events {
|
|
|
392
318
|
await this._persist(eventName, persistValue);
|
|
393
319
|
} catch (error) {
|
|
394
320
|
logger.error(LogSource.Events, 'CUSTOM_EVENTS', 'persist error', error);
|
|
395
|
-
// don't throw - just log the error, application should continue running
|
|
396
321
|
}
|
|
397
322
|
}
|
|
398
323
|
try {
|
|
@@ -411,10 +336,9 @@ class Events {
|
|
|
411
336
|
logger.error(
|
|
412
337
|
LogSource.Events,
|
|
413
338
|
'CUSTOM_EVENTS',
|
|
414
|
-
|
|
339
|
+
'sending event failed',
|
|
415
340
|
error,
|
|
416
341
|
);
|
|
417
|
-
// don't throw - just log the error, application should continue running
|
|
418
342
|
}
|
|
419
343
|
};
|
|
420
344
|
}
|