agora-appbuilder-core 4.1.10-beta.1 → 4.1.11
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/Utils/isBotUser.ts +1 -1
- package/template/android/app/build.gradle +0 -7
- package/template/bridge/rtc/webNg/RtcEngine.ts +2 -2
- package/template/bridge/rtm/web/Types.ts +0 -183
- package/template/bridge/rtm/web/index.ts +488 -450
- package/template/customization-api/typeDefinition.ts +0 -1
- package/template/defaultConfig.js +3 -4
- package/template/global.d.ts +0 -1
- package/template/ios/Podfile +0 -41
- package/template/package.json +5 -5
- package/template/src/AppRoutes.tsx +3 -3
- package/template/src/ai-agent/components/ControlButtons.tsx +1 -1
- package/template/src/assets/font-styles.css +1 -33
- 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 -8
- package/template/src/atoms/DropDownMulti.tsx +80 -29
- package/template/src/atoms/Dropdown.tsx +0 -5
- package/template/src/atoms/Input.tsx +2 -1
- package/template/src/atoms/TertiaryButton.tsx +1 -1
- package/template/src/atoms/UserAvatar.tsx +1 -1
- package/template/src/components/ChatContext.ts +3 -5
- package/template/src/components/Controls.tsx +167 -208
- package/template/src/components/DeviceConfigure.tsx +1 -1
- package/template/src/components/EventsConfigure.tsx +168 -118
- package/template/src/components/Navbar.tsx +11 -14
- package/template/src/components/RTMConfigure.tsx +819 -32
- package/template/src/components/beauty-effect/useBeautyEffects.tsx +13 -50
- package/template/src/components/chat/chatConfigure.tsx +1 -7
- package/template/src/components/chat-messages/useChatMessages.tsx +11 -43
- package/template/src/components/controls/useControlPermissionMatrix.tsx +4 -32
- package/template/src/components/participants/AllHostParticipants.tsx +2 -10
- package/template/src/components/participants/Participant.tsx +1 -7
- package/template/src/components/participants/UserActionMenuOptions.tsx +2 -12
- 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 +16 -15
- package/template/src/components/precall/joinWaitingRoomBtn.tsx +31 -17
- package/template/src/components/precall/textInput.tsx +45 -22
- package/template/src/components/precall/usePreCall.tsx +7 -0
- package/template/src/components/recordings/RecordingsDateTable.tsx +2 -3
- package/template/src/components/room-info/useRoomInfo.tsx +5 -0
- package/template/src/components/useUserPreference.tsx +12 -39
- package/template/src/components/virtual-background/useVB.tsx +0 -18
- package/template/src/components/whiteboard/WhiteboardConfigure.tsx +0 -27
- package/template/src/language/default-labels/videoCallScreenLabels.ts +27 -11
- package/template/src/logger/AppBuilderLogger.tsx +3 -11
- package/template/src/pages/VideoCall.tsx +518 -171
- package/template/src/pages/video-call/ActionSheetContent.tsx +77 -77
- package/template/src/pages/video-call/SidePanelHeader.tsx +81 -53
- package/template/src/pages/video-call/VideoCallScreen.tsx +0 -18
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +1 -0
- package/template/src/rtm/RTMEngine.ts +37 -262
- package/template/src/rtm/utils.ts +1 -68
- package/template/src/rtm-events/constants.ts +7 -40
- package/template/src/rtm-events-api/Events.ts +39 -158
- package/template/src/subComponents/ChatBubble.tsx +3 -3
- package/template/src/subComponents/ChatContainer.tsx +9 -19
- package/template/src/subComponents/LocalAudioMute.tsx +2 -2
- package/template/src/subComponents/LocalVideoMute.tsx +2 -2
- package/template/src/subComponents/SidePanelEnum.tsx +0 -1
- 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 +754 -11
- 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/subComponents/chat/ChatSendButton.tsx +0 -1
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +0 -16
- package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +1 -1
- package/template/src/subComponents/waiting-rooms/WaitingRoomControls.tsx +4 -7
- package/template/src/utils/SdkEvents.ts +3 -0
- package/template/src/utils/useEndCall.ts +4 -4
- package/template/src/utils/useMuteToggleLocal.ts +10 -14
- package/template/src/utils/useSpeechToText.ts +31 -20
- package/template/bridge/rtm/web/index-legacy.ts +0 -540
- package/template/src/components/RTMConfigure-legacy.tsx +0 -848
- package/template/src/components/UserGlobalPreferenceProvider.tsx +0 -227
- package/template/src/components/breakout-room/BreakoutRoomPanel.tsx +0 -58
- package/template/src/components/breakout-room/context/BreakoutRoomContext.tsx +0 -2508
- package/template/src/components/breakout-room/events/BreakoutRoomEventsConfigure.tsx +0 -272
- package/template/src/components/breakout-room/events/constants.ts +0 -17
- package/template/src/components/breakout-room/hoc/BreakoutRoomNameRenderer.tsx +0 -68
- package/template/src/components/breakout-room/hooks/useBreakoutRoomExit.ts +0 -49
- package/template/src/components/breakout-room/state/reducer.ts +0 -522
- package/template/src/components/breakout-room/state/types.ts +0 -54
- package/template/src/components/breakout-room/ui/BreakoutMeetingTitle.tsx +0 -60
- package/template/src/components/breakout-room/ui/BreakoutRoomActionMenu.tsx +0 -136
- package/template/src/components/breakout-room/ui/BreakoutRoomAnnouncementModal.tsx +0 -135
- package/template/src/components/breakout-room/ui/BreakoutRoomGroupSettings.tsx +0 -588
- package/template/src/components/breakout-room/ui/BreakoutRoomMainRoomUsers.tsx +0 -142
- package/template/src/components/breakout-room/ui/BreakoutRoomMemberActionMenu.tsx +0 -122
- package/template/src/components/breakout-room/ui/BreakoutRoomParticipants.tsx +0 -124
- package/template/src/components/breakout-room/ui/BreakoutRoomRaiseHand.tsx +0 -65
- package/template/src/components/breakout-room/ui/BreakoutRoomRenameModal.tsx +0 -227
- package/template/src/components/breakout-room/ui/BreakoutRoomSettings.tsx +0 -140
- package/template/src/components/breakout-room/ui/BreakoutRoomTransition.tsx +0 -52
- package/template/src/components/breakout-room/ui/BreakoutRoomView.tsx +0 -193
- package/template/src/components/breakout-room/ui/ExitBreakoutRoomIconButton.tsx +0 -79
- package/template/src/components/breakout-room/ui/ParticipantManualAssignmentModal.tsx +0 -638
- package/template/src/components/breakout-room/ui/SelectParticipantAssignmentStrategy.tsx +0 -57
- package/template/src/components/common/Dividers.tsx +0 -53
- package/template/src/components/controls/toolbar-items/ExitBreakoutRoomToolbarItem.tsx +0 -13
- package/template/src/components/raise-hand/RaiseHandButton.tsx +0 -50
- package/template/src/components/raise-hand/RaiseHandProvider.tsx +0 -308
- package/template/src/components/raise-hand/index.ts +0 -14
- package/template/src/components/room-info/useCurrentRoomInfo.tsx +0 -42
- package/template/src/components/room-info/useSetBreakoutRoomInfo.tsx +0 -64
- package/template/src/pages/video-call/BreakoutVideoCall.tsx +0 -213
- package/template/src/pages/video-call/VideoCallContent.tsx +0 -211
- package/template/src/pages/video-call/VideoCallStateWrapper.tsx +0 -495
- package/template/src/rtm/RTMConfigureBreakoutRoomProvider.tsx +0 -882
- package/template/src/rtm/RTMConfigureMainRoomProvider.tsx +0 -757
- package/template/src/rtm/RTMCoreProvider.tsx +0 -419
- package/template/src/rtm/RTMGlobalStateProvider.tsx +0 -706
- package/template/src/rtm/RTMStatusBanner.tsx +0 -99
- package/template/src/rtm/constants.ts +0 -12
- package/template/src/rtm/hooks/useMainRoomUserDisplayName.ts +0 -45
- package/template/src/rtm/rtm-presence-utils.ts +0 -344
- package/template/src/subComponents/chat/ChatAnnouncementView.tsx +0 -65
- package/template/src/utils/useDebouncedCallback.tsx +0 -20
|
@@ -1,706 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
********************************************
|
|
3
|
-
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
-
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
-
(the "Materials") are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
-
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
-
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
-
any purpose competitive to Agora Lab, Inc.'s business) is strictly prohibited. For more
|
|
9
|
-
information visit https://appbuilder.agora.io.
|
|
10
|
-
*********************************************
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import React, {useState, useEffect, useRef} from 'react';
|
|
14
|
-
import {
|
|
15
|
-
type PresenceEvent,
|
|
16
|
-
type StorageEvent,
|
|
17
|
-
type SetOrUpdateUserMetadataOptions,
|
|
18
|
-
type MessageEvent,
|
|
19
|
-
} from 'agora-react-native-rtm';
|
|
20
|
-
import {timeNow, hasJsonStructure} from '../rtm/utils';
|
|
21
|
-
import {EventsQueue} from '../rtm-events';
|
|
22
|
-
import {PersistanceLevel} from '../rtm-events-api';
|
|
23
|
-
import RTMEngine from '../rtm/RTMEngine';
|
|
24
|
-
import {useRTMCore} from './RTMCoreProvider';
|
|
25
|
-
import {RtcPropsInterface, UidType} from '../../agora-rn-uikit';
|
|
26
|
-
import {
|
|
27
|
-
nativePresenceEventTypeMapping,
|
|
28
|
-
nativeStorageEventTypeMapping,
|
|
29
|
-
} from '../../bridge/rtm/web/Types';
|
|
30
|
-
import {RTM_ROOMS} from './constants';
|
|
31
|
-
import {
|
|
32
|
-
fetchOnlineMembersWithRetries,
|
|
33
|
-
fetchUserAttributesWithRetries,
|
|
34
|
-
mapUserAttributesToState,
|
|
35
|
-
fetchChannelAttributesWithRetries,
|
|
36
|
-
processUserAttributeForQueue,
|
|
37
|
-
} from './rtm-presence-utils';
|
|
38
|
-
import {SDKEvents} from '../utils/eventEmitter';
|
|
39
|
-
|
|
40
|
-
export enum UserType {
|
|
41
|
-
ScreenShare = 'screenshare',
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// RTM-specific user data interface
|
|
45
|
-
export interface RTMUserData {
|
|
46
|
-
uid?: UidType;
|
|
47
|
-
screenUid?: number; // Screen sharing UID reference (stored in RTM user metadata)
|
|
48
|
-
parentUid?: UidType; // Only available for screenshare
|
|
49
|
-
type: 'rtc' | 'screenshare' | 'bot';
|
|
50
|
-
name?: string; // User's display name (stored in RTM user metadata)
|
|
51
|
-
offline: boolean; // User online/offline status (managed through RTM presence events)
|
|
52
|
-
lastMessageTimeStamp: number; // Timestamp of last message (RTM message tracking)
|
|
53
|
-
isInWaitingRoom?: boolean; // Waiting room status (RTM-based feature state)
|
|
54
|
-
isHost: string; // Host privileges (stored in RTM user metadata as 'isHost')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
interface RTMGlobalStateProviderProps {
|
|
58
|
-
children: React.ReactNode;
|
|
59
|
-
rtmLoginInfo: {
|
|
60
|
-
uid: UidType;
|
|
61
|
-
channel: string;
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Context for message and storage handler registration
|
|
66
|
-
const RTMGlobalStateContext = React.createContext<{
|
|
67
|
-
mainRoomRTMUsers: {[uid: number]: RTMUserData};
|
|
68
|
-
setMainRoomRTMUsers: React.Dispatch<
|
|
69
|
-
React.SetStateAction<{[uid: number]: RTMUserData}>
|
|
70
|
-
>;
|
|
71
|
-
// Custom state for developer features (main room scope, cross-room accessible)
|
|
72
|
-
customRTMMainRoomData: {[key: string]: any};
|
|
73
|
-
setCustomRTMMainRoomData: React.Dispatch<
|
|
74
|
-
React.SetStateAction<{[key: string]: any}>
|
|
75
|
-
>;
|
|
76
|
-
registerMainChannelMessageHandler: (
|
|
77
|
-
handler: (message: MessageEvent) => void,
|
|
78
|
-
) => void;
|
|
79
|
-
unregisterMainChannelMessageHandler: () => void;
|
|
80
|
-
registerMainChannelStorageHandler: (
|
|
81
|
-
handler: (storage: StorageEvent) => void,
|
|
82
|
-
) => void;
|
|
83
|
-
unregisterMainChannelStorageHandler: () => void;
|
|
84
|
-
}>({
|
|
85
|
-
mainRoomRTMUsers: {},
|
|
86
|
-
setMainRoomRTMUsers: () => {},
|
|
87
|
-
customRTMMainRoomData: {},
|
|
88
|
-
setCustomRTMMainRoomData: () => {},
|
|
89
|
-
registerMainChannelMessageHandler: () => {},
|
|
90
|
-
unregisterMainChannelMessageHandler: () => {},
|
|
91
|
-
registerMainChannelStorageHandler: () => {},
|
|
92
|
-
unregisterMainChannelStorageHandler: () => {},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
const RTMGlobalStateProvider: React.FC<RTMGlobalStateProviderProps> = ({
|
|
96
|
-
children,
|
|
97
|
-
rtmLoginInfo,
|
|
98
|
-
}) => {
|
|
99
|
-
const mainChannelName = rtmLoginInfo.channel;
|
|
100
|
-
const localUid = rtmLoginInfo.uid;
|
|
101
|
-
const {client, isLoggedIn, registerCallbacks, unregisterCallbacks} =
|
|
102
|
-
useRTMCore();
|
|
103
|
-
// Main room RTM users (RTM-specific data only)
|
|
104
|
-
const [mainRoomRTMUsers, setMainRoomRTMUsers] = useState<{
|
|
105
|
-
[uid: number]: RTMUserData;
|
|
106
|
-
}>({});
|
|
107
|
-
|
|
108
|
-
// Custom state for developer features (main room scope, cross-room accessible)
|
|
109
|
-
const [customRTMMainRoomData, setCustomRTMMainRoomData] = useState<{
|
|
110
|
-
[key: string]: any;
|
|
111
|
-
}>({});
|
|
112
|
-
useEffect(() => {
|
|
113
|
-
console.log('mainRoomRTMUsers user-attributes changed', mainRoomRTMUsers);
|
|
114
|
-
}, [mainRoomRTMUsers]);
|
|
115
|
-
|
|
116
|
-
// Timeout Refs
|
|
117
|
-
const isRTMMounted = useRef(true);
|
|
118
|
-
const hasInitRef = useRef(false);
|
|
119
|
-
|
|
120
|
-
const subscribeTimerRef: any = useRef(5);
|
|
121
|
-
const subscribeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(
|
|
122
|
-
null,
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const channelAttributesTimerRef: any = useRef(5);
|
|
126
|
-
const channelAttributesTimeoutRef = useRef<ReturnType<
|
|
127
|
-
typeof setTimeout
|
|
128
|
-
> | null>(null);
|
|
129
|
-
|
|
130
|
-
const membersTimerRef: any = useRef(5);
|
|
131
|
-
const membersTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
132
|
-
|
|
133
|
-
// Message handler registration for main channel
|
|
134
|
-
const messageHandlerRef = useRef<((message: MessageEvent) => void) | null>(
|
|
135
|
-
null,
|
|
136
|
-
);
|
|
137
|
-
const registerMainChannelMessageHandler = (
|
|
138
|
-
handler: (message: MessageEvent) => void,
|
|
139
|
-
) => {
|
|
140
|
-
console.log(
|
|
141
|
-
'rudra-core-client: RTM registering main channel message handler',
|
|
142
|
-
);
|
|
143
|
-
if (messageHandlerRef.current) {
|
|
144
|
-
console.warn(
|
|
145
|
-
'RTMGlobalStateProvider: Overwriting an existing main channel message handler!',
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
messageHandlerRef.current = handler;
|
|
149
|
-
};
|
|
150
|
-
const unregisterMainChannelMessageHandler = () => {
|
|
151
|
-
console.log(
|
|
152
|
-
'rudra-core-client: RTM unregistering main channel message handler',
|
|
153
|
-
);
|
|
154
|
-
messageHandlerRef.current = null;
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
// Storage handler registration for main channel
|
|
158
|
-
const storageHandlerRef = useRef<((storage: StorageEvent) => void) | null>(
|
|
159
|
-
null,
|
|
160
|
-
);
|
|
161
|
-
const registerMainChannelStorageHandler = (
|
|
162
|
-
handler: (storage: StorageEvent) => void,
|
|
163
|
-
) => {
|
|
164
|
-
console.log(
|
|
165
|
-
'rudra-core-client: RTM registering main channel storage handler',
|
|
166
|
-
);
|
|
167
|
-
if (storageHandlerRef.current) {
|
|
168
|
-
console.warn(
|
|
169
|
-
'RTMGlobalStateProvider: Overwriting an existing main channel storage handler!',
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
storageHandlerRef.current = handler;
|
|
173
|
-
};
|
|
174
|
-
const unregisterMainChannelStorageHandler = () => {
|
|
175
|
-
console.log(
|
|
176
|
-
'rudra-core-client: RTM unregistering main channel storage handler',
|
|
177
|
-
);
|
|
178
|
-
storageHandlerRef.current = null;
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
// Update main rtm users state
|
|
182
|
-
const updateMainRoomUser = (uid: number, data: RTMUserData) => {
|
|
183
|
-
setMainRoomRTMUsers(prev => ({
|
|
184
|
-
...prev,
|
|
185
|
-
[uid]: {...(prev[uid] || {}), ...data},
|
|
186
|
-
}));
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
// Init cycle starts
|
|
190
|
-
const init = async () => {
|
|
191
|
-
try {
|
|
192
|
-
console.log('rudra-core-client: Starting RTM init for main channel');
|
|
193
|
-
await subscribeChannel();
|
|
194
|
-
await getMembersWithAttributes();
|
|
195
|
-
await getChannelAttributes();
|
|
196
|
-
console.log('rudra-core-client: RTM init completed successfully');
|
|
197
|
-
} catch (error) {
|
|
198
|
-
console.log('rudra-core-client: RTM init failed', error);
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
const subscribeChannel = async () => {
|
|
203
|
-
try {
|
|
204
|
-
if (RTMEngine.getInstance().allChannelIds.includes(mainChannelName)) {
|
|
205
|
-
console.log('rudra- main channel already subsribed');
|
|
206
|
-
} else {
|
|
207
|
-
console.log('rudra- subscribing...');
|
|
208
|
-
await client.subscribe(mainChannelName, {
|
|
209
|
-
withMessage: true,
|
|
210
|
-
withPresence: true,
|
|
211
|
-
withMetadata: true,
|
|
212
|
-
withLock: false,
|
|
213
|
-
});
|
|
214
|
-
console.log('rudra- subscribed main channel', mainChannelName);
|
|
215
|
-
|
|
216
|
-
RTMEngine.getInstance().addChannel(RTM_ROOMS.MAIN, mainChannelName);
|
|
217
|
-
RTMEngine.getInstance().setActiveChannelName(RTM_ROOMS.MAIN);
|
|
218
|
-
SDKEvents.emit('_rtm-joined', mainChannelName);
|
|
219
|
-
|
|
220
|
-
subscribeTimerRef.current = 5;
|
|
221
|
-
// Clear any pending retry timeout since we succeeded
|
|
222
|
-
if (subscribeTimeoutRef.current) {
|
|
223
|
-
clearTimeout(subscribeTimeoutRef.current);
|
|
224
|
-
subscribeTimeoutRef.current = null;
|
|
225
|
-
}
|
|
226
|
-
console.log('rudra- added to rtm engine');
|
|
227
|
-
}
|
|
228
|
-
} catch (error) {
|
|
229
|
-
console.log(
|
|
230
|
-
'rudra-core-client: RTM subscribeChannel failed..Trying again',
|
|
231
|
-
error,
|
|
232
|
-
);
|
|
233
|
-
subscribeTimeoutRef.current = setTimeout(async () => {
|
|
234
|
-
// Cap the timer to prevent excessive delays (max 30 seconds)
|
|
235
|
-
subscribeTimerRef.current = Math.min(subscribeTimerRef.current * 2, 30);
|
|
236
|
-
subscribeChannel();
|
|
237
|
-
}, subscribeTimerRef.current * 1000);
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
const getMembersWithAttributes = async () => {
|
|
242
|
-
try {
|
|
243
|
-
console.log(
|
|
244
|
-
'rudra-core-client: RTM presence.getOnlineUsers(getMembers) start',
|
|
245
|
-
);
|
|
246
|
-
const {allMembers, totalOccupancy} = await fetchOnlineMembersWithRetries(
|
|
247
|
-
client,
|
|
248
|
-
mainChannelName,
|
|
249
|
-
{
|
|
250
|
-
onPage: async ({occupants, total, pageToken}) => {
|
|
251
|
-
console.log(
|
|
252
|
-
'rudra-core-client: fetching user attributes for page: ',
|
|
253
|
-
pageToken,
|
|
254
|
-
occupants,
|
|
255
|
-
);
|
|
256
|
-
await Promise.all(
|
|
257
|
-
occupants.map(async member => {
|
|
258
|
-
try {
|
|
259
|
-
const userAttributes = await fetchUserAttributesWithRetries(
|
|
260
|
-
client,
|
|
261
|
-
member.userId,
|
|
262
|
-
{
|
|
263
|
-
isMounted: () => isRTMMounted.current,
|
|
264
|
-
// called later if name arrives
|
|
265
|
-
onNameFound: async retryAttr =>
|
|
266
|
-
mapUserAttributesToState(
|
|
267
|
-
retryAttr,
|
|
268
|
-
member.userId,
|
|
269
|
-
updateMainRoomUser,
|
|
270
|
-
),
|
|
271
|
-
},
|
|
272
|
-
);
|
|
273
|
-
console.log(
|
|
274
|
-
`supriya rtm backoffAttributes user-attributes for ${member.userId}`,
|
|
275
|
-
userAttributes,
|
|
276
|
-
);
|
|
277
|
-
mapUserAttributesToState(
|
|
278
|
-
userAttributes,
|
|
279
|
-
member.userId,
|
|
280
|
-
updateMainRoomUser,
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
userAttributes?.items?.forEach(item => {
|
|
284
|
-
processUserAttributeForQueue(
|
|
285
|
-
item,
|
|
286
|
-
member.userId,
|
|
287
|
-
RTM_ROOMS.MAIN,
|
|
288
|
-
(eventKey, value, userId) => {
|
|
289
|
-
const data = {evt: eventKey, value};
|
|
290
|
-
console.log(
|
|
291
|
-
'supriya-session-test adding to queue',
|
|
292
|
-
data,
|
|
293
|
-
);
|
|
294
|
-
EventsQueue.enqueue({
|
|
295
|
-
data,
|
|
296
|
-
uid: userId,
|
|
297
|
-
ts: timeNow(),
|
|
298
|
-
});
|
|
299
|
-
},
|
|
300
|
-
);
|
|
301
|
-
});
|
|
302
|
-
} catch (e) {
|
|
303
|
-
console.log(
|
|
304
|
-
'rudra-core-client: RTM Could not retrieve name of',
|
|
305
|
-
member.userId,
|
|
306
|
-
e,
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
}),
|
|
310
|
-
);
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
);
|
|
314
|
-
|
|
315
|
-
membersTimerRef.current = 5;
|
|
316
|
-
// Clear any pending retry timeout since we succeeded
|
|
317
|
-
if (membersTimeoutRef.current) {
|
|
318
|
-
clearTimeout(membersTimeoutRef.current);
|
|
319
|
-
membersTimeoutRef.current = null;
|
|
320
|
-
}
|
|
321
|
-
console.log(
|
|
322
|
-
'rudra-core-client: RTM fetched all data and user attr...RTM init done',
|
|
323
|
-
);
|
|
324
|
-
// });
|
|
325
|
-
} catch (error) {
|
|
326
|
-
membersTimeoutRef.current = setTimeout(async () => {
|
|
327
|
-
// Cap the timer to prevent excessive delays (max 30 seconds)
|
|
328
|
-
membersTimerRef.current = Math.min(membersTimerRef.current * 2, 30);
|
|
329
|
-
await getMembersWithAttributes();
|
|
330
|
-
}, membersTimerRef.current * 1000);
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
const getChannelAttributes = async () => {
|
|
335
|
-
try {
|
|
336
|
-
await fetchChannelAttributesWithRetries(
|
|
337
|
-
client,
|
|
338
|
-
mainChannelName,
|
|
339
|
-
eventData => EventsQueue.enqueue(eventData),
|
|
340
|
-
);
|
|
341
|
-
channelAttributesTimerRef.current = 5;
|
|
342
|
-
// Clear any pending retry timeout since we succeeded
|
|
343
|
-
if (channelAttributesTimeoutRef.current) {
|
|
344
|
-
clearTimeout(channelAttributesTimeoutRef.current);
|
|
345
|
-
channelAttributesTimeoutRef.current = null;
|
|
346
|
-
}
|
|
347
|
-
} catch (error) {
|
|
348
|
-
console.log(
|
|
349
|
-
'rudra-core-client: RTM getchannelattributes failed..Trying again',
|
|
350
|
-
error,
|
|
351
|
-
);
|
|
352
|
-
channelAttributesTimeoutRef.current = setTimeout(async () => {
|
|
353
|
-
// Cap the timer to prevent excessive delays (max 30 seconds)
|
|
354
|
-
channelAttributesTimerRef.current = Math.min(
|
|
355
|
-
channelAttributesTimerRef.current * 2,
|
|
356
|
-
30,
|
|
357
|
-
);
|
|
358
|
-
getChannelAttributes();
|
|
359
|
-
}, channelAttributesTimerRef.current * 1000);
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
// Listeners
|
|
364
|
-
const handleMainChannelPresenceEvent = async (presence: PresenceEvent) => {
|
|
365
|
-
console.log(
|
|
366
|
-
'rudra-core-client: RTM presence event received for different channel',
|
|
367
|
-
presence.channelName,
|
|
368
|
-
'expected:',
|
|
369
|
-
mainChannelName,
|
|
370
|
-
);
|
|
371
|
-
if (presence.channelName !== mainChannelName) {
|
|
372
|
-
console.log(
|
|
373
|
-
'rudra-core-client: RTM presence event received for different channel',
|
|
374
|
-
presence.channelName,
|
|
375
|
-
'expected:',
|
|
376
|
-
mainChannelName,
|
|
377
|
-
);
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// remoteJoinChannel
|
|
382
|
-
if (presence.type === nativePresenceEventTypeMapping.REMOTE_JOIN) {
|
|
383
|
-
console.log(
|
|
384
|
-
'rudra-core-client: RTM main room user joined',
|
|
385
|
-
presence.publisher,
|
|
386
|
-
);
|
|
387
|
-
try {
|
|
388
|
-
const userAttributes = await fetchUserAttributesWithRetries(
|
|
389
|
-
client,
|
|
390
|
-
presence.publisher,
|
|
391
|
-
{
|
|
392
|
-
isMounted: () => isRTMMounted.current,
|
|
393
|
-
// This is called later if name arrives and hence we process that attribute
|
|
394
|
-
onNameFound: retriedAttributes =>
|
|
395
|
-
mapUserAttributesToState(
|
|
396
|
-
retriedAttributes,
|
|
397
|
-
presence.publisher,
|
|
398
|
-
updateMainRoomUser,
|
|
399
|
-
),
|
|
400
|
-
},
|
|
401
|
-
);
|
|
402
|
-
// This is called as soon as we receive any attributes
|
|
403
|
-
mapUserAttributesToState(
|
|
404
|
-
userAttributes,
|
|
405
|
-
presence.publisher,
|
|
406
|
-
updateMainRoomUser,
|
|
407
|
-
);
|
|
408
|
-
} catch (error) {
|
|
409
|
-
console.log(
|
|
410
|
-
'rudra-core-client: RTM Failed to process user who joined main room',
|
|
411
|
-
presence.publisher,
|
|
412
|
-
error,
|
|
413
|
-
);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// remoteLeaveChannel
|
|
418
|
-
if (presence.type === nativePresenceEventTypeMapping.REMOTE_LEAVE) {
|
|
419
|
-
console.log(
|
|
420
|
-
'rudra-core-client: RTM main room user left',
|
|
421
|
-
presence.publisher,
|
|
422
|
-
);
|
|
423
|
-
const uid = presence?.publisher
|
|
424
|
-
? parseInt(presence.publisher, 10)
|
|
425
|
-
: undefined;
|
|
426
|
-
|
|
427
|
-
if (!uid) {
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
SDKEvents.emit('_rtm-left', uid);
|
|
431
|
-
// Mark user as offline (matching legacy channelMemberLeft behavior)
|
|
432
|
-
setMainRoomRTMUsers(prev => {
|
|
433
|
-
const updated = {...prev};
|
|
434
|
-
|
|
435
|
-
if (updated[uid]) {
|
|
436
|
-
updated[uid] = {
|
|
437
|
-
...updated[uid],
|
|
438
|
-
offline: true,
|
|
439
|
-
};
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
// Also mark screenshare as offline if exists
|
|
443
|
-
// const screenUid = prev[uid]?.screenUid;
|
|
444
|
-
// if (screenUid && updated[screenUid]) {
|
|
445
|
-
// updated[screenUid] = {
|
|
446
|
-
// ...updated[screenUid],
|
|
447
|
-
// offline: true,
|
|
448
|
-
// };
|
|
449
|
-
// }
|
|
450
|
-
|
|
451
|
-
console.log(
|
|
452
|
-
'rudra-core-client: RTM marked user as offline in main room',
|
|
453
|
-
uid,
|
|
454
|
-
);
|
|
455
|
-
return updated;
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
|
|
460
|
-
const handleMainChannelStorageEvent = async (storage: StorageEvent) => {
|
|
461
|
-
console.log(
|
|
462
|
-
'rudra-core-client: RTM global storage event received',
|
|
463
|
-
storage,
|
|
464
|
-
);
|
|
465
|
-
|
|
466
|
-
// Only handle SET/UPDATE events for metadata persistence
|
|
467
|
-
if (
|
|
468
|
-
storage.eventType === nativeStorageEventTypeMapping.SET ||
|
|
469
|
-
storage.eventType === nativeStorageEventTypeMapping.UPDATE
|
|
470
|
-
) {
|
|
471
|
-
const storageTypeStr = storage.storageType === 1 ? 'user' : 'channel';
|
|
472
|
-
const eventTypeStr = storage.eventType === 2 ? 'SET' : 'UPDATE';
|
|
473
|
-
console.log(
|
|
474
|
-
`rudra-core-client: RTM processing ${eventTypeStr} ${storageTypeStr} metadata`,
|
|
475
|
-
);
|
|
476
|
-
|
|
477
|
-
// // STEP 1: Handle metadata persistence FIRST (core RTM functionality)
|
|
478
|
-
// try {
|
|
479
|
-
// if (storage.data?.items && Array.isArray(storage.data.items)) {
|
|
480
|
-
// for (const item of storage.data.items) {
|
|
481
|
-
// try {
|
|
482
|
-
// if (!item || !item.key) {
|
|
483
|
-
// console.log(
|
|
484
|
-
// 'rudra-core-client: RTM invalid storage item:',
|
|
485
|
-
// item,
|
|
486
|
-
// );
|
|
487
|
-
// continue;
|
|
488
|
-
// }
|
|
489
|
-
|
|
490
|
-
// const {key, value, authorUserId, updateTs} = item;
|
|
491
|
-
|
|
492
|
-
// // Parse the value to check persistLevel
|
|
493
|
-
// let parsedValue;
|
|
494
|
-
// try {
|
|
495
|
-
// parsedValue =
|
|
496
|
-
// typeof value === 'string' ? JSON.parse(value) : value;
|
|
497
|
-
// } catch (parseError) {
|
|
498
|
-
// console.log(
|
|
499
|
-
// 'rudra-core-client: RTM failed to parse storage event value:',
|
|
500
|
-
// parseError,
|
|
501
|
-
// );
|
|
502
|
-
// continue;
|
|
503
|
-
// }
|
|
504
|
-
|
|
505
|
-
// const {persistLevel} = parsedValue;
|
|
506
|
-
|
|
507
|
-
// // Handle metadata persistence for Session level events
|
|
508
|
-
// if (persistLevel === PersistanceLevel.Session) {
|
|
509
|
-
// console.log(
|
|
510
|
-
// 'rudra-core-client: RTM setting user metadata for key:',
|
|
511
|
-
// key,
|
|
512
|
-
// );
|
|
513
|
-
|
|
514
|
-
// const rtmAttribute = {key: key, value: value};
|
|
515
|
-
// const options: SetOrUpdateUserMetadataOptions = {
|
|
516
|
-
// userId: `${localUid}`,
|
|
517
|
-
// };
|
|
518
|
-
|
|
519
|
-
// try {
|
|
520
|
-
// await client.storage.setUserMetadata(
|
|
521
|
-
// {items: [rtmAttribute]},
|
|
522
|
-
// options,
|
|
523
|
-
// );
|
|
524
|
-
// console.log(
|
|
525
|
-
// 'rudra-core-client: RTM successfully set user metadata for key:',
|
|
526
|
-
// key,
|
|
527
|
-
// );
|
|
528
|
-
// } catch (setMetadataError) {
|
|
529
|
-
// console.log(
|
|
530
|
-
// 'rudra-core-client: RTM failed to set user metadata:',
|
|
531
|
-
// setMetadataError,
|
|
532
|
-
// );
|
|
533
|
-
// }
|
|
534
|
-
// }
|
|
535
|
-
// } catch (itemError) {
|
|
536
|
-
// console.log(
|
|
537
|
-
// 'rudra-core-client: RTM failed to process storage item:',
|
|
538
|
-
// item,
|
|
539
|
-
// itemError,
|
|
540
|
-
// );
|
|
541
|
-
// }
|
|
542
|
-
// }
|
|
543
|
-
// }
|
|
544
|
-
// } catch (error) {
|
|
545
|
-
// console.log(
|
|
546
|
-
// 'rudra-core-client: RTM error processing storage event:',
|
|
547
|
-
// error,
|
|
548
|
-
// );
|
|
549
|
-
// }
|
|
550
|
-
|
|
551
|
-
// STEP 2: Forward to application logic AFTER metadata persistence
|
|
552
|
-
if (storageHandlerRef.current) {
|
|
553
|
-
try {
|
|
554
|
-
storageHandlerRef.current(storage);
|
|
555
|
-
console.log(
|
|
556
|
-
'rudra-core-client: RTM forwarded storage event to registered handler',
|
|
557
|
-
);
|
|
558
|
-
} catch (error) {
|
|
559
|
-
console.log(
|
|
560
|
-
'rudra-core-client: RTM error forwarding storage event:',
|
|
561
|
-
error,
|
|
562
|
-
);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
};
|
|
567
|
-
|
|
568
|
-
const handleMainChannelMessageEvent = async (message: MessageEvent) => {
|
|
569
|
-
console.log(
|
|
570
|
-
'rudra-core-client: RTM main channel message event received',
|
|
571
|
-
message,
|
|
572
|
-
);
|
|
573
|
-
|
|
574
|
-
// Check if this is a SESSION-level event and persist it
|
|
575
|
-
try {
|
|
576
|
-
if (hasJsonStructure(message.message)) {
|
|
577
|
-
const parsed = JSON.parse(message.message);
|
|
578
|
-
const {evt, value} = parsed;
|
|
579
|
-
|
|
580
|
-
if (value && hasJsonStructure(value)) {
|
|
581
|
-
const parsedValue = JSON.parse(value);
|
|
582
|
-
const {persistLevel, _channelId} = parsedValue;
|
|
583
|
-
|
|
584
|
-
// If this is a SESSION-level event from main channel, store it on local user's attributes
|
|
585
|
-
if (
|
|
586
|
-
persistLevel === PersistanceLevel.Session &&
|
|
587
|
-
_channelId === mainChannelName
|
|
588
|
-
) {
|
|
589
|
-
// const roomAwareKey = `${RTM_ROOMS.MAIN}__${evt}`;
|
|
590
|
-
const rtmAttribute = {key: evt, value: value};
|
|
591
|
-
|
|
592
|
-
const options: SetOrUpdateUserMetadataOptions = {
|
|
593
|
-
userId: `${localUid}`,
|
|
594
|
-
};
|
|
595
|
-
await client.storage.setUserMetadata(
|
|
596
|
-
{items: [rtmAttribute]},
|
|
597
|
-
options,
|
|
598
|
-
);
|
|
599
|
-
// console.log(
|
|
600
|
-
// 'rudra-core-client: Stored SESSION attribute cross-room',
|
|
601
|
-
// roomAwareKey,
|
|
602
|
-
// );
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
} catch (error) {
|
|
607
|
-
console.log(
|
|
608
|
-
'rudra-core-client: RTM error storing session attribute:',
|
|
609
|
-
error,
|
|
610
|
-
);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// Forward to registered message handler (RTMConfigure)
|
|
614
|
-
if (messageHandlerRef.current) {
|
|
615
|
-
try {
|
|
616
|
-
messageHandlerRef.current(message);
|
|
617
|
-
console.log(
|
|
618
|
-
'rudra-core-client: RTM forwarded message event to registered handler',
|
|
619
|
-
);
|
|
620
|
-
} catch (error) {
|
|
621
|
-
console.log(
|
|
622
|
-
'rudra-core-client: RTM error forwarding message event:',
|
|
623
|
-
error,
|
|
624
|
-
);
|
|
625
|
-
}
|
|
626
|
-
} else {
|
|
627
|
-
console.log(
|
|
628
|
-
'rudra-core-client: RTM no message handler registered for main channel',
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
};
|
|
632
|
-
|
|
633
|
-
// Main initialization effect
|
|
634
|
-
useEffect(() => {
|
|
635
|
-
if (!client || !isLoggedIn || !mainChannelName || hasInitRef.current) {
|
|
636
|
-
return;
|
|
637
|
-
}
|
|
638
|
-
hasInitRef.current = true;
|
|
639
|
-
console.log('RTMGlobalStateProvider: Client ready, starting init');
|
|
640
|
-
// Register presence, storage, and message event callbacks for main channel
|
|
641
|
-
registerCallbacks(mainChannelName, {
|
|
642
|
-
presence: handleMainChannelPresenceEvent,
|
|
643
|
-
storage: handleMainChannelStorageEvent,
|
|
644
|
-
message: handleMainChannelMessageEvent,
|
|
645
|
-
});
|
|
646
|
-
console.log(
|
|
647
|
-
'rudra-core-client: RTM registered presence, storage, and message callbacks for main channel',
|
|
648
|
-
);
|
|
649
|
-
init();
|
|
650
|
-
return () => {
|
|
651
|
-
console.log('rudra-core-client: main state cleanup');
|
|
652
|
-
hasInitRef.current = false;
|
|
653
|
-
isRTMMounted.current = false;
|
|
654
|
-
if (mainChannelName) {
|
|
655
|
-
unregisterCallbacks(mainChannelName);
|
|
656
|
-
if (RTMEngine.getInstance().hasChannel(mainChannelName)) {
|
|
657
|
-
client?.unsubscribe(mainChannelName).catch(() => {});
|
|
658
|
-
RTMEngine.getInstance().removeChannel(RTM_ROOMS.MAIN);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// Clear timer-based retry timeouts
|
|
663
|
-
if (subscribeTimeoutRef.current) {
|
|
664
|
-
clearTimeout(subscribeTimeoutRef.current);
|
|
665
|
-
subscribeTimeoutRef.current = null;
|
|
666
|
-
}
|
|
667
|
-
if (membersTimeoutRef.current) {
|
|
668
|
-
clearTimeout(membersTimeoutRef.current);
|
|
669
|
-
membersTimeoutRef.current = null;
|
|
670
|
-
}
|
|
671
|
-
if (channelAttributesTimeoutRef.current) {
|
|
672
|
-
clearTimeout(channelAttributesTimeoutRef.current);
|
|
673
|
-
channelAttributesTimeoutRef.current = null;
|
|
674
|
-
}
|
|
675
|
-
};
|
|
676
|
-
}, [client, isLoggedIn, mainChannelName]);
|
|
677
|
-
|
|
678
|
-
return (
|
|
679
|
-
<RTMGlobalStateContext.Provider
|
|
680
|
-
value={{
|
|
681
|
-
mainRoomRTMUsers,
|
|
682
|
-
setMainRoomRTMUsers,
|
|
683
|
-
customRTMMainRoomData,
|
|
684
|
-
setCustomRTMMainRoomData,
|
|
685
|
-
registerMainChannelMessageHandler,
|
|
686
|
-
unregisterMainChannelMessageHandler,
|
|
687
|
-
registerMainChannelStorageHandler,
|
|
688
|
-
unregisterMainChannelStorageHandler,
|
|
689
|
-
}}>
|
|
690
|
-
{children}
|
|
691
|
-
</RTMGlobalStateContext.Provider>
|
|
692
|
-
);
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
// Hook to use main channel message registration
|
|
696
|
-
export const useRTMGlobalState = () => {
|
|
697
|
-
const context = React.useContext(RTMGlobalStateContext);
|
|
698
|
-
if (!context) {
|
|
699
|
-
throw new Error(
|
|
700
|
-
'useRTMMainChannel must be used within RTMGlobalStateProvider',
|
|
701
|
-
);
|
|
702
|
-
}
|
|
703
|
-
return context;
|
|
704
|
-
};
|
|
705
|
-
|
|
706
|
-
export default RTMGlobalStateProvider;
|