agora-appbuilder-core 4.1.12 → 4.1.13-beta.1

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": "4.1.12",
3
+ "version": "4.1.13-beta.1",
4
4
  "description": "React Native template for RTE app builder",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -16,7 +16,15 @@ import {useCaption} from '../src/subComponents/caption/useCaption';
16
16
  import useMuteToggleLocal, {
17
17
  MUTE_LOCAL_TYPE,
18
18
  } from '../src/utils/useMuteToggleLocal';
19
- import {RoomPhase} from 'white-web-sdk';
19
+ // import {RoomPhase} from 'white-web-sdk';
20
+ // Commented out for fastboard migration
21
+ enum RoomPhase {
22
+ Connecting = 'connecting',
23
+ Connected = 'connected',
24
+ Reconnecting = 'reconnecting',
25
+ Disconnecting = 'disconnecting',
26
+ Disconnected = 'disconnected',
27
+ }
20
28
  import {useScreenContext} from '../src/components/contexts/ScreenShareContext';
21
29
  import {filterObject} from '../src/utils/index';
22
30
  import {useToggleWhiteboard} from '../src/components/Controls';
@@ -77,8 +77,8 @@ const DefaultConfig = {
77
77
  CHAT_ORG_NAME: '',
78
78
  CHAT_APP_NAME: '',
79
79
  CHAT_URL: '',
80
- CLI_VERSION: '3.1.11',
81
- CORE_VERSION: '4.1.11',
80
+ CLI_VERSION: '3.1.13-beta.1',
81
+ CORE_VERSION: '4.1.13-beta.1',
82
82
  DISABLE_LANDSCAPE_MODE: false,
83
83
  STT_AUTO_START: false,
84
84
  CLOUD_RECORDING_AUTO_START: false,
@@ -112,7 +112,7 @@
112
112
  "rn-emoji-keyboard": "^1.7.0",
113
113
  "rn-fetch-blob": "0.12.0",
114
114
  "text-encoding": "^0.7.0",
115
- "white-web-sdk": "2.16.42"
115
+ "@netless/fastboard-react": "^1.1.2"
116
116
  },
117
117
  "devDependencies": {
118
118
  "@babel/core": "^7.20.0",
@@ -82,7 +82,15 @@ import {
82
82
  } from '../atoms/ToolbarPreset';
83
83
 
84
84
  import {whiteboardContext} from './whiteboard/WhiteboardConfigure';
85
- import {RoomPhase} from 'white-web-sdk';
85
+ // import {RoomPhase} from 'white-web-sdk';
86
+ // Commented out for fastboard migration
87
+ enum RoomPhase {
88
+ Connecting = 'connecting',
89
+ Connected = 'connected',
90
+ Reconnecting = 'reconnecting',
91
+ Disconnecting = 'disconnecting',
92
+ Disconnected = 'disconnected',
93
+ }
86
94
  import {useNoiseSupression} from '../app-state/useNoiseSupression';
87
95
 
88
96
  import {useVB} from './virtual-background/useVB';
@@ -0,0 +1,227 @@
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, {useRef, useEffect} from 'react';
14
+ import {StyleSheet, View, Text} from 'react-native';
15
+ import {useRoomInfo} from 'customization-api';
16
+ import {useString} from '../../utils/useString';
17
+ import {whiteboardInitializingText} from '../../language/default-labels/videoCallScreenLabels';
18
+ import {useFastboard, Fastboard, createFastboard, FastboardApp} from '@netless/fastboard-react/full';
19
+
20
+ import {useLocalUid} from '../../../agora-rn-uikit';
21
+ import useUserName from '../../utils/useUserName';
22
+
23
+ interface FastBoardViewProps {
24
+ showToolbox?: boolean;
25
+ }
26
+
27
+ /**
28
+ * Technical Note: Why we are not using the 'useFastboard' hook?
29
+ *
30
+ * We replaced the standard 'useFastboard' hook with a manual 'FastboardManager' implementation
31
+ * to solve a critical race condition in React 18+ Strict Mode.
32
+ *
33
+ * Issue: "[WindowManager]: Already created cannot be created again"
34
+ *
35
+ * In Strict Mode, React intentionally mounts, unmounts, and remounts components rapidly
36
+ * to detect side-effects. The standard hook attempts to initialize the Fastboard singleton
37
+ * twice in parallel. The first initialization is still "pending" when the second one starts,
38
+ * causing the underlying WindowManager to crash because it doesn't support concurrent init calls.
39
+ *
40
+ * Solution: The 'FastboardManager' below uses Reference Counting and Singleton pattern to:
41
+ * 1. Deduplicate initialization requests (reusing the same Promise).
42
+ * 2. Delay cleanup slightly to handle the rapid Unmount -> Mount cycle without destroying the instance.
43
+ */
44
+ const FastBoardView: React.FC<FastBoardViewProps> = ({showToolbox = true}) => {
45
+ const {
46
+ data: {whiteboard: {room_token, room_uuid} = {}, isHost},
47
+ } = useRoomInfo();
48
+
49
+ const localUid = useLocalUid();
50
+ const [name] = useUserName();
51
+
52
+ const whiteboardInitializing = useString(whiteboardInitializingText)();
53
+
54
+ // Generate stable UID - only once
55
+ // Use local user's name or fallback to UID if name is not available
56
+ const uidRef = useRef<string>(name || String(localUid));
57
+ const [fastboard, setFastboard] = React.useState<FastboardApp | null>(null);
58
+
59
+ // Configuration object - Memoize stringified version to detect changes
60
+ const config = React.useMemo(() => ({
61
+ sdkConfig: {
62
+ appIdentifier: 'EEJBQPVbEe2Bao8ZShuoHQ/hgB5eo0qcDbVig',
63
+ region: 'us-sv',
64
+ },
65
+ joinRoom: {
66
+ uid: uidRef.current,
67
+ uuid: room_uuid,
68
+ roomToken: room_token,
69
+ },
70
+ }), [room_uuid, room_token]);
71
+
72
+ const configStr = JSON.stringify(config);
73
+
74
+ useEffect(() => {
75
+ let isMounted = true;
76
+
77
+ const initFastboard = async () => {
78
+ try {
79
+ const app = await FastboardManager.acquire(configStr, config);
80
+ if (isMounted) {
81
+ setFastboard(app);
82
+ }
83
+ } catch (error) {
84
+ console.error("Fastboard initialization failed:", error);
85
+ }
86
+ };
87
+
88
+ initFastboard();
89
+
90
+ return () => {
91
+ isMounted = false;
92
+ FastboardManager.release(configStr);
93
+ };
94
+ }, [configStr, config]);
95
+
96
+ // Show loading if fastboard not ready yet
97
+ if (!fastboard) {
98
+ return (
99
+ <View style={styles.container}>
100
+ <View style={styles.placeholder}>
101
+ <Text style={styles.placeholderText}>{whiteboardInitializing}</Text>
102
+ </View>
103
+ </View>
104
+ );
105
+ }
106
+
107
+ return (
108
+ <View style={styles.container}>
109
+ <div style={divStyles.fastboardContainer}>
110
+ <Fastboard app={fastboard} />
111
+ </div>
112
+ </View>
113
+ );
114
+ };
115
+
116
+ // Global Manager to handle Strict Mode and Singleton constraints
117
+ const FastboardManager = {
118
+ activeConfig: null as string | null,
119
+ instance: null as FastboardApp | null,
120
+ promise: null as Promise<FastboardApp> | null,
121
+ subscribers: 0,
122
+
123
+ acquire: async (configStr: string, config: any): Promise<FastboardApp> => {
124
+ FastboardManager.subscribers++;
125
+
126
+ // If config matches and we have an instance/promise, reuse it
127
+ if (FastboardManager.activeConfig === configStr) {
128
+ if (FastboardManager.instance) return FastboardManager.instance;
129
+ if (FastboardManager.promise) return FastboardManager.promise;
130
+ }
131
+
132
+ // Config mismatch! We must cleanup the previous board before creating a new one.
133
+ // This happens if component remounts with new UID (e.g. Pin to Top).
134
+
135
+ // 1. If there's a pending loading operation, wait for it and destroy the result.
136
+ if (FastboardManager.promise) {
137
+ try {
138
+ const oldApp = await FastboardManager.promise;
139
+ // Double check if it wasn't already destroyed or reassigned
140
+ if (oldApp) oldApp.destroy();
141
+ } catch (e) {
142
+ console.warn("Error cleaning up previous pending Fastboard:", e);
143
+ }
144
+ }
145
+
146
+ // 2. If there's an active instance, destroy it.
147
+ if (FastboardManager.instance) {
148
+ try {
149
+ FastboardManager.instance.destroy();
150
+ } catch (e) {
151
+ console.warn("Error cleaning up previous active Fastboard:", e);
152
+ }
153
+ }
154
+
155
+ // Reset state
156
+ FastboardManager.instance = null;
157
+ FastboardManager.promise = null;
158
+ FastboardManager.activeConfig = configStr;
159
+
160
+ // 3. Create new instance
161
+ FastboardManager.promise = createFastboard(config).then(app => {
162
+ // Check if we are still the active config
163
+ if (FastboardManager.activeConfig === configStr) {
164
+ FastboardManager.instance = app;
165
+ return app;
166
+ } else {
167
+ // Config changed while loading
168
+ app.destroy();
169
+ throw new Error("Fastboard config changed during initialization");
170
+ }
171
+ });
172
+
173
+ return FastboardManager.promise;
174
+ },
175
+
176
+ release: (configStr: string) => {
177
+ FastboardManager.subscribers--;
178
+
179
+ // Delayed cleanup to handle Strict Mode "Unmount -> Mount" flicker
180
+ setTimeout(() => {
181
+ if (FastboardManager.subscribers === 0 && FastboardManager.activeConfig === configStr) {
182
+ if (FastboardManager.instance) {
183
+ FastboardManager.instance.destroy();
184
+ FastboardManager.instance = null;
185
+ }
186
+ FastboardManager.promise = null;
187
+ FastboardManager.activeConfig = null;
188
+ }
189
+ }, 200);
190
+ }
191
+ };
192
+
193
+ const styles = StyleSheet.create({
194
+ container: {
195
+ flex: 1,
196
+ position: 'relative',
197
+ backgroundColor: '#ffffff',
198
+ },
199
+ placeholder: {
200
+ position: 'absolute',
201
+ width: '100%',
202
+ height: '100%',
203
+ backgroundColor: '#f5f5f5',
204
+ display: 'flex',
205
+ justifyContent: 'center',
206
+ alignItems: 'center',
207
+ },
208
+ placeholderText: {
209
+ color: '#666666',
210
+ fontSize: 16,
211
+ },
212
+ errorText: {
213
+ color: '#ff4444',
214
+ fontSize: 16,
215
+ },
216
+ });
217
+
218
+ const divStyles = {
219
+ fastboardContainer: {
220
+ width: '100%',
221
+ height: '100%',
222
+ borderRadius: 4,
223
+ overflow: 'hidden' as const,
224
+ },
225
+ };
226
+
227
+ export default FastBoardView;
@@ -1,6 +1,10 @@
1
1
  import * as React from 'react';
2
2
  //import './StrokeWidthTool.less';
3
- import {Color, Room, RoomState} from 'white-web-sdk';
3
+ // import {Color, Room, RoomState} from 'white-web-sdk';
4
+ // Commented out for fastboard migration
5
+ type Color = [number, number, number];
6
+ type Room = any;
7
+ type RoomState = any;
4
8
  import {View, Text} from 'react-native';
5
9
  import ThemeConfig from '../../theme';
6
10
  import hexadecimalTransparency from '../../utils/hexadecimalTransparency';
@@ -7,7 +7,15 @@ import {
7
7
  useRoomInfo,
8
8
  } from 'customization-api';
9
9
  import {whiteboardContext} from './WhiteboardConfigure';
10
- import {RoomPhase} from 'white-web-sdk';
10
+ // import {RoomPhase} from 'white-web-sdk';
11
+ // Commented out for fastboard migration
12
+ enum RoomPhase {
13
+ Connecting = 'connecting',
14
+ Connected = 'connected',
15
+ Reconnecting = 'reconnecting',
16
+ Disconnecting = 'disconnecting',
17
+ Disconnected = 'disconnected',
18
+ }
11
19
  import IconButton from '../../atoms/IconButton';
12
20
  import {EventNames} from '../../rtm-events';
13
21
 
@@ -17,7 +17,15 @@ import {
17
17
  whiteboardPaper,
18
18
  } from './WhiteboardConfigure';
19
19
  import {StyleSheet, View, Text} from 'react-native';
20
- import {RoomPhase, ApplianceNames} from 'white-web-sdk';
20
+ // import {RoomPhase, ApplianceNames} from 'white-web-sdk';
21
+ // Commented out for fastboard migration
22
+ enum RoomPhase {
23
+ Connecting = 'connecting',
24
+ Connected = 'connected',
25
+ Reconnecting = 'reconnecting',
26
+ Disconnecting = 'disconnecting',
27
+ Disconnected = 'disconnected',
28
+ }
21
29
  import WhiteboardToolBox from './WhiteboardToolBox';
22
30
  import WhiteboardWidget from './WhiteboardWidget';
23
31
 
@@ -8,11 +8,22 @@ import {
8
8
  randomIntFromInterval,
9
9
  randomString,
10
10
  } from '../../utils/common';
11
- import {WhiteWebSdk, RoomPhase, Room, ViewMode} from 'white-web-sdk';
11
+ // import {WhiteWebSdk, RoomPhase, Room, ViewMode} from 'white-web-sdk';
12
+ // Commented out for fastboard migration - types defined locally
13
+ type Room = any;
14
+ type ViewMode = any;
15
+ type WhiteWebSdk = any;
16
+ enum RoomPhase {
17
+ Connecting = 'connecting',
18
+ Connected = 'connected',
19
+ Reconnecting = 'reconnecting',
20
+ Disconnecting = 'disconnecting',
21
+ Disconnected = 'disconnected',
22
+ }
12
23
  import LocalEventEmitter, {
13
24
  LocalEventsEnum,
14
25
  } from '../../rtm-events-api/LocalEvents';
15
- import {CursorTool} from './WhiteboardCursor';
26
+ // import {CursorTool} from './WhiteboardCursor'; // Disabled for fastboard migration
16
27
  import useUserName from '../../utils/useUserName';
17
28
  import {DefaultLayouts} from '../../pages/video-call/DefaultLayouts';
18
29
  import events, {PersistanceLevel} from '../../rtm-events-api';
@@ -117,23 +128,24 @@ const WhiteboardConfigure: React.FC<WhiteboardPropsInterface> = props => {
117
128
  const whiteboardRoom = useRef({} as Room);
118
129
  const {pinnedUid, activeUids} = useContent();
119
130
  const prevImageUploadHeightRef = useRef(0);
120
- const cursorAdapter = new CursorTool();
131
+ // const cursorAdapter = new CursorTool(); // Disabled for fastboard migration
121
132
  const uploadPendingRef = useRef(false);
122
133
 
123
- useEffect(() => {
124
- if (
125
- whiteboardRoomState === RoomPhase.Connected &&
126
- pinnedUid &&
127
- pinnedUid == whiteboardUidRef.current
128
- ) {
129
- whiteboardRoom?.current?.moveCamera &&
130
- whiteboardRoom?.current?.moveCamera({
131
- centerX: 0,
132
- centerY: 0,
133
- scale: 1,
134
- });
135
- }
136
- }, [pinnedUid, whiteboardRoomState]);
134
+ // Disabled for fastboard migration - FastBoardView handles camera
135
+ // useEffect(() => {
136
+ // if (
137
+ // whiteboardRoomState === RoomPhase.Connected &&
138
+ // pinnedUid &&
139
+ // pinnedUid == whiteboardUidRef.current
140
+ // ) {
141
+ // whiteboardRoom?.current?.moveCamera &&
142
+ // whiteboardRoom?.current?.moveCamera({
143
+ // centerX: 0,
144
+ // centerY: 0,
145
+ // scale: 1,
146
+ // });
147
+ // }
148
+ // }, [pinnedUid, whiteboardRoomState]);
137
149
 
138
150
  const [name] = useUserName();
139
151
  const {
@@ -143,34 +155,35 @@ const WhiteboardConfigure: React.FC<WhiteboardPropsInterface> = props => {
143
155
  } = useRoomInfo();
144
156
  const {currentLayout} = useLayout();
145
157
 
146
- useEffect(() => {
147
- try {
148
- if (
149
- whiteboardRoomState === RoomPhase.Connected &&
150
- isHost &&
151
- !isMobileUA()
152
- ) {
153
- if (
154
- currentLayout === DefaultLayouts[1].name &&
155
- activeUids &&
156
- activeUids?.length &&
157
- (activeUids[0] === getWhiteboardUid() ||
158
- pinnedUid === getWhiteboardUid())
159
- ) {
160
- whiteboardRoom?.current?.setWritable(true);
161
- } else {
162
- whiteboardRoom?.current?.setWritable(false);
163
- }
164
- }
165
- } catch (error) {
166
- logger.error(
167
- LogSource.Internals,
168
- 'WHITEBOARD',
169
- 'error on whiteboard setWritable',
170
- error,
171
- );
172
- }
173
- }, [currentLayout, isHost, whiteboardRoomState, activeUids, pinnedUid]);
158
+ // Disabled for fastboard migration - FastBoardView handles writable state
159
+ // useEffect(() => {
160
+ // try {
161
+ // if (
162
+ // whiteboardRoomState === RoomPhase.Connected &&
163
+ // isHost &&
164
+ // !isMobileUA()
165
+ // ) {
166
+ // if (
167
+ // currentLayout === DefaultLayouts[1].name &&
168
+ // activeUids &&
169
+ // activeUids?.length &&
170
+ // (activeUids[0] === getWhiteboardUid() ||
171
+ // pinnedUid === getWhiteboardUid())
172
+ // ) {
173
+ // whiteboardRoom?.current?.setWritable(true);
174
+ // } else {
175
+ // whiteboardRoom?.current?.setWritable(false);
176
+ // }
177
+ // }
178
+ // } catch (error) {
179
+ // logger.error(
180
+ // LogSource.Internals,
181
+ // 'WHITEBOARD',
182
+ // 'error on whiteboard setWritable',
183
+ // error,
184
+ // );
185
+ // }
186
+ // }, [currentLayout, isHost, whiteboardRoomState, activeUids, pinnedUid]);
174
187
 
175
188
  const BoardColorChangedCallBack = ({boardColor}) => {
176
189
  setBoardColor(boardColor);
@@ -213,94 +226,20 @@ const WhiteboardConfigure: React.FC<WhiteboardPropsInterface> = props => {
213
226
  };
214
227
  }, []);
215
228
 
216
- const fileUploadCallBack = images => {
217
- if (uploadPendingRef.current) {
218
- let prevImageWidth = 0;
219
- let prevImageHeight = prevImageUploadHeightRef.current;
220
- let count = 0;
221
- let focus = {
222
- x: 0,
223
- y: 0,
224
- };
225
- for (const key in images) {
226
- if (Object.prototype.hasOwnProperty.call(images, key)) {
227
- const element = images[key];
228
- const uuid = key + ' ' + randomString();
229
- const x = 0 + prevImageWidth + 50;
230
- const y = 0 + prevImageUploadHeightRef?.current + 50;
231
- whiteboardRoom.current?.insertImage({
232
- centerX: x,
233
- centerY: y,
234
- height: dummyHeight,
235
- width: dummyWidth,
236
- uuid: uuid,
237
- locked: false,
238
- });
239
- if (count === 0) {
240
- focus.x = x;
241
- focus.y = y;
242
- }
243
- setTimeout(() => {
244
- whiteboardRoom.current?.completeImageUpload(uuid, element.url);
245
- }, 1000);
246
- prevImageWidth = prevImageWidth + 50 + dummyWidth;
247
- if ((count + 1) % 4 === 0) {
248
- prevImageUploadHeightRef.current =
249
- prevImageUploadHeightRef.current + 50 + dummyHeight;
250
- prevImageWidth = 0;
251
- } else {
252
- prevImageHeight = dummyHeight;
253
- }
254
- count = count + 1;
255
- }
256
- }
257
-
258
- //for next image upload
259
- if ((count + 1) % 4 !== 0) {
260
- prevImageUploadHeightRef.current =
261
- prevImageUploadHeightRef.current + 50 + prevImageHeight;
262
- }
263
- uploadPendingRef.current = false;
264
-
265
- //focus the uploaded doc/image
266
- whiteboardRoom.current?.moveCamera({
267
- centerX: focus.x,
268
- centerY: focus.y,
269
- });
270
- sendLastImageUploadPositionToRemoteUsers(
271
- prevImageUploadHeightRef.current,
272
- );
273
- }
229
+ // Disabled for fastboard migration - file upload not supported yet
230
+ const fileUploadCallBack = (images: any) => {
231
+ // TODO: Implement file upload for fastboard if needed
232
+ console.log('File upload not yet implemented for fastboard');
274
233
  };
275
234
 
276
235
  const setUploadRef = () => {
277
236
  uploadPendingRef.current = true;
278
237
  };
279
238
 
280
- const insertImageIntoWhiteboard = url => {
281
- if (!url) {
282
- return;
283
- }
284
- const uuid = randomString();
285
- const y = 0 + prevImageUploadHeightRef?.current + 50;
286
- whiteboardRoom.current?.insertImage({
287
- centerX: 0,
288
- centerY: y,
289
- height: 300,
290
- width: 300,
291
- uuid: uuid,
292
- locked: false,
293
- });
294
- setTimeout(() => {
295
- whiteboardRoom.current?.completeImageUpload(uuid, url);
296
- }, 1000);
297
- whiteboardRoom.current?.moveCamera({
298
- centerX: 0,
299
- centerY: y,
300
- });
301
- prevImageUploadHeightRef.current =
302
- prevImageUploadHeightRef.current + 50 + 300 + 100;
303
- sendLastImageUploadPositionToRemoteUsers(prevImageUploadHeightRef.current);
239
+ // Disabled for fastboard migration - image insert not supported yet
240
+ const insertImageIntoWhiteboard = (url: string) => {
241
+ // TODO: Implement image insert for fastboard if needed
242
+ console.log('Image insert not yet implemented for fastboard');
304
243
  };
305
244
 
306
245
  const sendLastImageUploadPositionToRemoteUsers = (height: number) => {
@@ -326,79 +265,9 @@ const WhiteboardConfigure: React.FC<WhiteboardPropsInterface> = props => {
326
265
  };
327
266
  }, []);
328
267
 
329
- const join = () => {
330
- const InitState = whiteboardRoomState;
331
- try {
332
- const index = randomIntFromInterval(0, 9);
333
- setWhiteboardRoomState(RoomPhase.Connecting);
334
- logger.log(LogSource.Internals, 'WHITEBOARD', 'Trying to join room');
335
- whiteWebSdkClient.current
336
- .joinRoom({
337
- cursorAdapter: cursorAdapter,
338
- uid: `${whiteboardUidRef.current}`,
339
- uuid: room_uuid,
340
- roomToken: room_token,
341
- floatBar: true,
342
- isWritable: isHost && !isMobileUA(),
343
- userPayload: {
344
- cursorName: name,
345
- cursorColor: CursorColor[index].cursorColor,
346
- textColor: CursorColor[index].textColor,
347
- },
348
- })
349
- .then(room => {
350
- logger.log(LogSource.Internals, 'WHITEBOARD', 'Join room successful');
351
- whiteboardRoom.current = room;
352
- cursorAdapter.setRoom(room);
353
- whiteboardRoom.current?.setViewMode(ViewMode.Freedom);
354
- whiteboardRoom.current?.bindHtmlElement(whiteboardPaper);
355
- if (isHost && !isMobileUA()) {
356
- whiteboardRoom.current?.setMemberState({
357
- strokeColor: [0, 0, 0],
358
- });
359
- }
360
- setWhiteboardRoomState(RoomPhase.Connected);
361
- })
362
- .catch(err => {
363
- setWhiteboardRoomState(InitState);
364
- logger.error(
365
- LogSource.Internals,
366
- 'WHITEBOARD',
367
- 'Join room error',
368
- err,
369
- );
370
- });
371
- } catch (err) {
372
- setWhiteboardRoomState(InitState);
373
- logger.error(LogSource.Internals, 'WHITEBOARD', 'Join room error', err);
374
- }
375
- };
376
-
377
- const leave = () => {
378
- const InitState = whiteboardRoomState;
379
- try {
380
- setWhiteboardRoomState(RoomPhase.Disconnecting);
381
- whiteboardRoom.current
382
- ?.disconnect()
383
- .then(() => {
384
- whiteboardUidRef.current = Date.now();
385
- whiteboardRoom.current?.bindHtmlElement(null);
386
- setWhiteboardRoomState(RoomPhase.Disconnected);
387
- })
388
- .catch(err => {
389
- setWhiteboardRoomState(InitState);
390
- logger.error(
391
- LogSource.Internals,
392
- 'WHITEBOARD',
393
- 'leave room error',
394
- err,
395
- );
396
- });
397
- } catch (err) {
398
- setWhiteboardRoomState(InitState);
399
- logger.error(LogSource.Internals, 'WHITEBOARD', 'leave room error', err);
400
- }
401
- };
268
+ // Disabled for fastboard migration - FastBoardView handles join/leave
269
+ // const join = () => { ... };
270
+ // const leave = () => { ... };
402
271
 
403
272
  const joinWhiteboardRoom = () => {
404
273
  setWhiteboardActive(true);
@@ -408,24 +277,35 @@ const WhiteboardConfigure: React.FC<WhiteboardPropsInterface> = props => {
408
277
  setWhiteboardActive(false);
409
278
  };
410
279
 
280
+ // Disabled for fastboard migration - FastBoardView handles its own connection
281
+ // useEffect(() => {
282
+ // if (!whiteWebSdkClient.current.joinRoom && whiteboardActive) {
283
+ // const appIdentifier = $config.WHITEBOARD_APPIDENTIFIER;
284
+ // whiteWebSdkClient.current = new WhiteWebSdk({
285
+ // appIdentifier: appIdentifier,
286
+ // region: $config.WHITEBOARD_REGION,
287
+ // });
288
+ // join();
289
+ // setWhiteboardStartedFirst(true);
290
+ // } else if (whiteboardActive) {
291
+ // join();
292
+ // } else {
293
+ // if (
294
+ // whiteboardRoom.current &&
295
+ // Object.keys(whiteboardRoom.current)?.length
296
+ // ) {
297
+ // leave();
298
+ // }
299
+ // }
300
+ // }, [whiteboardActive]);
301
+
302
+ // For fastboard: just set whiteboardStartedFirst when active
411
303
  useEffect(() => {
412
- if (!whiteWebSdkClient.current.joinRoom && whiteboardActive) {
413
- const appIdentifier = $config.WHITEBOARD_APPIDENTIFIER;
414
- whiteWebSdkClient.current = new WhiteWebSdk({
415
- appIdentifier: appIdentifier,
416
- region: $config.WHITEBOARD_REGION,
417
- });
418
- join();
304
+ if (whiteboardActive) {
419
305
  setWhiteboardStartedFirst(true);
420
- } else if (whiteboardActive) {
421
- join();
306
+ setWhiteboardRoomState(RoomPhase.Connected);
422
307
  } else {
423
- if (
424
- whiteboardRoom.current &&
425
- Object.keys(whiteboardRoom.current)?.length
426
- ) {
427
- leave();
428
- }
308
+ setWhiteboardRoomState(RoomPhase.Disconnected);
429
309
  }
430
310
  }, [whiteboardActive]);
431
311
 
@@ -1,13 +1,21 @@
1
1
  import * as React from 'react';
2
- import {
3
- Cursor,
4
- CursorAdapter,
5
- CursorDescription,
6
- Player,
7
- Room,
8
- RoomMember,
9
- RoomState,
10
- } from 'white-web-sdk';
2
+ // import {
3
+ // Cursor,
4
+ // CursorAdapter,
5
+ // CursorDescription,
6
+ // Player,
7
+ // Room,
8
+ // RoomMember,
9
+ // RoomState,
10
+ // } from 'white-web-sdk';
11
+ // Commented out for fastboard migration - types defined locally
12
+ type Cursor = any;
13
+ type CursorAdapter = any;
14
+ type CursorDescription = {x: number; y: number; width: number; height: number};
15
+ type Player = any;
16
+ type Room = any;
17
+ type RoomMember = any;
18
+ type RoomState = any;
11
19
 
12
20
  export type CursorComponentProps = {
13
21
  roomMember: RoomMember;
@@ -13,7 +13,21 @@
13
13
  import React, {useContext, useEffect, useState} from 'react';
14
14
  import {StyleSheet, View, Pressable} from 'react-native';
15
15
  import {hexToRgb, isMobileUA, isWeb, randomString} from '../../utils/common';
16
- import {ApplianceNames} from 'white-web-sdk';
16
+ // import {ApplianceNames} from 'white-web-sdk';
17
+ // Commented out for fastboard migration
18
+ const ApplianceNames = {
19
+ selector: 'selector',
20
+ pencil: 'pencil',
21
+ rectangle: 'rectangle',
22
+ ellipse: 'ellipse',
23
+ straight: 'straight',
24
+ arrow: 'arrow',
25
+ hand: 'hand',
26
+ laserPointer: 'laserPointer',
27
+ eraser: 'eraser',
28
+ text: 'text',
29
+ pencilEraser: 'pencilEraser',
30
+ } as const;
17
31
  import StorageContext from '../../components/StorageContext';
18
32
  import {useRoomInfo} from '../room-info/useRoomInfo';
19
33
  import Toast from '../../../react-native-toast-message';
@@ -13,7 +13,15 @@
13
13
  import React, {useRef, useEffect, useContext, useState} from 'react';
14
14
  import {whiteboardContext} from './WhiteboardConfigure';
15
15
  import {StyleSheet, View, Text} from 'react-native';
16
- import {RoomPhase, ApplianceNames} from 'white-web-sdk';
16
+ // import {RoomPhase, ApplianceNames} from 'white-web-sdk';
17
+ // Commented out for fastboard migration
18
+ enum RoomPhase {
19
+ Connecting = 'connecting',
20
+ Connected = 'connected',
21
+ Reconnecting = 'reconnecting',
22
+ Disconnecting = 'disconnecting',
23
+ Disconnected = 'disconnected',
24
+ }
17
25
  import WhiteboardToolBox from './WhiteboardToolBox';
18
26
  import WhiteboardCanvas from './WhiteboardCanvas';
19
27
  import {useContent, useLayout} from 'customization-api';
@@ -12,7 +12,10 @@
12
12
 
13
13
  import React, {useContext, useState} from 'react';
14
14
  import {StyleSheet, View, TouchableOpacity, Text} from 'react-native';
15
- import {Room, RoomState} from 'white-web-sdk';
15
+ // import {Room, RoomState} from 'white-web-sdk';
16
+ // Commented out for fastboard migration
17
+ type Room = any;
18
+ type RoomState = any;
16
19
  import {
17
20
  IconButton,
18
21
  useContent,
@@ -2,7 +2,8 @@ import React, {useContext} from 'react';
2
2
  import {whiteboardContext} from './WhiteboardConfigure';
3
3
  import VideoRenderer from '../../pages/video-call/VideoRenderer';
4
4
  import {useContent} from 'customization-api';
5
- import WhiteboardView from './WhiteboardView';
5
+ // import WhiteboardView from './WhiteboardView';
6
+ import FastBoardView from './FastBoardView';
6
7
 
7
8
  const WhiteboardWrapper = () => {
8
9
  const {getWhiteboardUid} = useContext(whiteboardContext);
@@ -28,7 +29,7 @@ const WhiteboardWrapper = () => {
28
29
  name: 'Whiteboard',
29
30
  muted: undefined,
30
31
  }}
31
- CustomChild={WhiteboardView}
32
+ CustomChild={FastBoardView}
32
33
  />
33
34
  );
34
35
  }