@ngenux/ngage-whiteboarding 1.0.8 → 1.0.9
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +106 -91
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +113 -90
- package/dist/index.js.map +1 -1
- package/dist/src/components/Whiteboard/index.d.ts.map +1 -1
- package/dist/src/context/WhiteboardContext.d.ts.map +1 -1
- package/dist/src/utils/socket-utility.d.ts +6 -1
- package/dist/src/utils/socket-utility.d.ts.map +1 -1
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/socket-utility.esm.js +168 -0
- package/dist/utils/socket-utility.esm.js.map +1 -0
- package/dist/utils/socket-utility.js +177 -0
- package/dist/utils/socket-utility.js.map +1 -0
- package/dist/utils/src/components/Shapes/Arrow.d.ts +11 -0
- package/dist/utils/src/components/Shapes/Arrow.d.ts.map +1 -0
- package/dist/utils/src/components/Shapes/Ellipse.d.ts +11 -0
- package/dist/utils/src/components/Shapes/Ellipse.d.ts.map +1 -0
- package/dist/utils/src/components/Shapes/ErasedShape.d.ts +11 -0
- package/dist/utils/src/components/Shapes/ErasedShape.d.ts.map +1 -0
- package/dist/utils/src/components/Shapes/FreehandDrawing.d.ts +11 -0
- package/dist/utils/src/components/Shapes/FreehandDrawing.d.ts.map +1 -0
- package/dist/utils/src/components/Shapes/Line.d.ts +11 -0
- package/dist/utils/src/components/Shapes/Line.d.ts.map +1 -0
- package/dist/utils/src/components/Shapes/Rectangle.d.ts +11 -0
- package/dist/utils/src/components/Shapes/Rectangle.d.ts.map +1 -0
- package/dist/utils/src/components/Whiteboard/Board.d.ts +15 -0
- package/dist/utils/src/components/Whiteboard/Board.d.ts.map +1 -0
- package/dist/utils/src/components/Whiteboard/Toolbar.d.ts +21 -0
- package/dist/utils/src/components/Whiteboard/Toolbar.d.ts.map +1 -0
- package/dist/utils/src/components/Whiteboard/index.d.ts +11 -0
- package/dist/utils/src/components/Whiteboard/index.d.ts.map +1 -0
- package/dist/utils/src/context/WhiteboardContext.d.ts +128 -0
- package/dist/utils/src/context/WhiteboardContext.d.ts.map +1 -0
- package/dist/utils/src/hooks/useCapture.d.ts +4 -0
- package/dist/utils/src/hooks/useCapture.d.ts.map +1 -0
- package/dist/utils/src/hooks/useCollaborativeWhiteboard.d.ts +27 -0
- package/dist/utils/src/hooks/useCollaborativeWhiteboard.d.ts.map +1 -0
- package/dist/utils/src/lib/utils.d.ts +3 -0
- package/dist/utils/src/lib/utils.d.ts.map +1 -0
- package/dist/utils/src/types/index.d.ts +123 -0
- package/dist/utils/src/types/index.d.ts.map +1 -0
- package/dist/utils/src/utils/compression.d.ts +14 -0
- package/dist/utils/src/utils/compression.d.ts.map +1 -0
- package/dist/utils/src/utils/socket-utility.d.ts +11 -0
- package/dist/utils/src/utils/socket-utility.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35275,12 +35275,16 @@ const WhiteboardProvider = ({ children, webSocketUrl }) => {
|
|
|
35275
35275
|
};
|
|
35276
35276
|
const requestStateFromPeers = () => {
|
|
35277
35277
|
if (currentQueueAction) {
|
|
35278
|
-
|
|
35279
|
-
|
|
35280
|
-
|
|
35281
|
-
|
|
35282
|
-
|
|
35283
|
-
|
|
35278
|
+
setTimeout(() => {
|
|
35279
|
+
if (currentQueueAction) {
|
|
35280
|
+
currentQueueAction({
|
|
35281
|
+
type: 'request_state',
|
|
35282
|
+
payload: '',
|
|
35283
|
+
requesterId: state.userId,
|
|
35284
|
+
timestamp: Date.now(),
|
|
35285
|
+
});
|
|
35286
|
+
}
|
|
35287
|
+
}, 2000);
|
|
35284
35288
|
}
|
|
35285
35289
|
else {
|
|
35286
35290
|
console.warn('[STATE_SYNC] No queue action available for state request');
|
|
@@ -37089,32 +37093,6 @@ const Eraser = createLucideIcon("Eraser", [
|
|
|
37089
37093
|
*/
|
|
37090
37094
|
|
|
37091
37095
|
|
|
37092
|
-
const LockOpen = createLucideIcon("LockOpen", [
|
|
37093
|
-
["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2", key: "1w4ew1" }],
|
|
37094
|
-
["path", { d: "M7 11V7a5 5 0 0 1 9.9-1", key: "1mm8w8" }]
|
|
37095
|
-
]);
|
|
37096
|
-
|
|
37097
|
-
/**
|
|
37098
|
-
* @license lucide-react v0.460.0 - ISC
|
|
37099
|
-
*
|
|
37100
|
-
* This source code is licensed under the ISC license.
|
|
37101
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
37102
|
-
*/
|
|
37103
|
-
|
|
37104
|
-
|
|
37105
|
-
const Lock = createLucideIcon("Lock", [
|
|
37106
|
-
["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2", key: "1w4ew1" }],
|
|
37107
|
-
["path", { d: "M7 11V7a5 5 0 0 1 10 0v4", key: "fwvmzm" }]
|
|
37108
|
-
]);
|
|
37109
|
-
|
|
37110
|
-
/**
|
|
37111
|
-
* @license lucide-react v0.460.0 - ISC
|
|
37112
|
-
*
|
|
37113
|
-
* This source code is licensed under the ISC license.
|
|
37114
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
37115
|
-
*/
|
|
37116
|
-
|
|
37117
|
-
|
|
37118
37096
|
const Minus = createLucideIcon("Minus", [["path", { d: "M5 12h14", key: "1ays0h" }]]);
|
|
37119
37097
|
|
|
37120
37098
|
/**
|
|
@@ -37195,7 +37173,7 @@ const Undo2 = createLucideIcon("Undo2", [
|
|
|
37195
37173
|
]);
|
|
37196
37174
|
|
|
37197
37175
|
// Top Toolbar Component
|
|
37198
|
-
const TopToolbar = ({ queueAction, handleExportImage, handleClear, handleLockToggle, isAdmin = false, hasToolAccess = false, isGloballyUnlocked =
|
|
37176
|
+
const TopToolbar = ({ queueAction, handleExportImage, handleClear, handleLockToggle, isAdmin = false, hasToolAccess = false, isGloballyUnlocked = true, shouldBeOpenByDefault = true, hasVideoBackground = false }) => {
|
|
37199
37177
|
const { state, dispatch } = useWhiteboard();
|
|
37200
37178
|
const [isVisible, setIsVisible] = React.useState(shouldBeOpenByDefault);
|
|
37201
37179
|
const [isInitialized, setIsInitialized] = React.useState(false);
|
|
@@ -37271,9 +37249,7 @@ const TopToolbar = ({ queueAction, handleExportImage, handleClear, handleLockTog
|
|
|
37271
37249
|
if (!isInitialized) {
|
|
37272
37250
|
return null;
|
|
37273
37251
|
}
|
|
37274
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "absolute top-5 left-1/2 transform -translate-x-1/2 flex flex-col items-center z-10", children: [!isVisible && (jsxRuntime.jsx("button", { className: "w-10 h-10 flex items-center justify-center bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-300", onClick: handleToggleVisibility, title: "Show Tools", children: jsxRuntime.jsx(ChevronDown, { size: 16, className: "text-current" }) })), isVisible && (jsxRuntime.jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-1 p-1", children: [
|
|
37275
|
-
? 'bg-green-100 dark:bg-green-900/50 text-green-600 dark:text-green-400 hover:bg-green-200 dark:hover:bg-green-900/70'
|
|
37276
|
-
: 'bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'}`, onClick: handleLockToggle, title: isGloballyUnlocked ? 'Whiteboard unlocked for all users - Click to lock' : 'Whiteboard locked - Click to unlock for all users', children: isGloballyUnlocked ? jsxRuntime.jsx(LockOpen, { size: 16, className: "text-current" }) : jsxRuntime.jsx(Lock, { size: 16, className: "text-current" }) })), jsxRuntime.jsx("button", { className: `w-10 h-10 flex items-center justify-center rounded ${hasToolAccess ? 'hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-300' : 'opacity-50 cursor-not-allowed text-gray-400 dark:text-gray-600'}`, onClick: handleUndo, disabled: !hasToolAccess, title: hasToolAccess ? 'Undo' : 'Access restricted', children: jsxRuntime.jsx(Undo2, { size: 16, className: "text-current" }) }), jsxRuntime.jsx("button", { className: `w-10 h-10 flex items-center justify-center rounded ${hasToolAccess ? 'hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-300' : 'opacity-50 cursor-not-allowed text-gray-400 dark:text-gray-600'}`, onClick: handleRedo, disabled: !hasToolAccess, title: hasToolAccess ? 'Redo' : 'Access restricted', children: jsxRuntime.jsx(Redo2, { size: 16, className: "text-current" }) }), jsxRuntime.jsx("div", { className: "w-px h-6 bg-gray-300 dark:bg-gray-600 mx-1" }), tools.map((tool) => (jsxRuntime.jsx("button", { className: `w-10 h-10 flex items-center justify-center rounded transition-colors ${!hasToolAccess
|
|
37252
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "absolute top-5 left-1/2 transform -translate-x-1/2 flex flex-col items-center z-10", children: [!isVisible && (jsxRuntime.jsx("button", { className: "w-10 h-10 flex items-center justify-center bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-300", onClick: handleToggleVisibility, title: "Show Tools", children: jsxRuntime.jsx(ChevronDown, { size: 16, className: "text-current" }) })), isVisible && (jsxRuntime.jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-1 p-1", children: [jsxRuntime.jsx("button", { className: `w-10 h-10 flex items-center justify-center rounded ${hasToolAccess ? 'hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-300' : 'opacity-50 cursor-not-allowed text-gray-400 dark:text-gray-600'}`, onClick: handleUndo, disabled: !hasToolAccess, title: hasToolAccess ? 'Undo' : 'Access restricted', children: jsxRuntime.jsx(Undo2, { size: 16, className: "text-current" }) }), jsxRuntime.jsx("button", { className: `w-10 h-10 flex items-center justify-center rounded ${hasToolAccess ? 'hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-300' : 'opacity-50 cursor-not-allowed text-gray-400 dark:text-gray-600'}`, onClick: handleRedo, disabled: !hasToolAccess, title: hasToolAccess ? 'Redo' : 'Access restricted', children: jsxRuntime.jsx(Redo2, { size: 16, className: "text-current" }) }), jsxRuntime.jsx("div", { className: "w-px h-6 bg-gray-300 dark:bg-gray-600 mx-1" }), tools.map((tool) => (jsxRuntime.jsx("button", { className: `w-10 h-10 flex items-center justify-center rounded transition-colors ${!hasToolAccess
|
|
37277
37253
|
? 'opacity-50 cursor-not-allowed text-gray-400 dark:text-gray-600'
|
|
37278
37254
|
: state.tool === tool.type
|
|
37279
37255
|
? 'bg-purple-100 dark:bg-purple-900/50 text-purple-600 dark:text-purple-300'
|
|
@@ -42331,6 +42307,7 @@ Object.assign(lookup, {
|
|
|
42331
42307
|
let socket = null;
|
|
42332
42308
|
const joinedRooms = new Set();
|
|
42333
42309
|
const setupCallbacks = new Map();
|
|
42310
|
+
const statusChangeCallbacks = new Set();
|
|
42334
42311
|
let currentWebSocketUrl = undefined;
|
|
42335
42312
|
// Initialize socket connection
|
|
42336
42313
|
const initializeSocket = (webSocketUrl) => {
|
|
@@ -42346,7 +42323,6 @@ const initializeSocket = (webSocketUrl) => {
|
|
|
42346
42323
|
setupCallbacks.clear();
|
|
42347
42324
|
}
|
|
42348
42325
|
currentWebSocketUrl = webSocketUrl;
|
|
42349
|
-
console.log('[SOCKET] Using socket server URL:', socketServerUrl);
|
|
42350
42326
|
if (!socketServerUrl) {
|
|
42351
42327
|
console.error('[SOCKET] No socket server URL provided');
|
|
42352
42328
|
}
|
|
@@ -42357,29 +42333,21 @@ const initializeSocket = (webSocketUrl) => {
|
|
|
42357
42333
|
reconnectionDelay: 1000,
|
|
42358
42334
|
});
|
|
42359
42335
|
socket.on('connect', () => {
|
|
42360
|
-
|
|
42361
|
-
// Re-join all rooms after reconnection
|
|
42336
|
+
statusChangeCallbacks.forEach(callback => callback(true));
|
|
42362
42337
|
joinedRooms.forEach(roomId => {
|
|
42363
42338
|
socket.emit('join-room', roomId);
|
|
42364
|
-
console.log('[SOCKET] Re-joined room:', roomId);
|
|
42365
42339
|
});
|
|
42366
42340
|
});
|
|
42367
42341
|
socket.on('disconnect', () => {
|
|
42368
|
-
|
|
42342
|
+
statusChangeCallbacks.forEach(callback => callback(false));
|
|
42369
42343
|
});
|
|
42370
|
-
socket.on('connect_error', (
|
|
42371
|
-
|
|
42344
|
+
socket.on('connect_error', () => {
|
|
42345
|
+
// Connection error handled by Socket.IO reconnection logic
|
|
42372
42346
|
});
|
|
42373
42347
|
// Set up the global receive-message listener once
|
|
42374
42348
|
socket.on('receive-message', (message) => {
|
|
42375
42349
|
const callback = setupCallbacks.get(message.roomId);
|
|
42376
42350
|
if (callback) {
|
|
42377
|
-
console.log('[SOCKET] Received message from room:', message.roomId, {
|
|
42378
|
-
compression: message.data.compressionType,
|
|
42379
|
-
originalSize: message.data.originalSize,
|
|
42380
|
-
compressedSize: message.data.compressedSize,
|
|
42381
|
-
from: message.from
|
|
42382
|
-
});
|
|
42383
42351
|
callback(message.data);
|
|
42384
42352
|
}
|
|
42385
42353
|
});
|
|
@@ -42413,18 +42381,23 @@ const onSend = (roomId, data, webSocketUrl) => {
|
|
|
42413
42381
|
console.error('[SOCKET] Error sending message:', error);
|
|
42414
42382
|
}
|
|
42415
42383
|
};
|
|
42416
|
-
const onReceive = (roomId, callback, webSocketUrl) => {
|
|
42384
|
+
const onReceive = (roomId, callback, webSocketUrl, onRoomJoined) => {
|
|
42417
42385
|
const socketInstance = initializeSocket(webSocketUrl);
|
|
42418
42386
|
// Store the callback for this room
|
|
42419
42387
|
setupCallbacks.set(roomId, callback);
|
|
42420
|
-
// Only join the room if we haven't already
|
|
42421
42388
|
if (!joinedRooms.has(roomId)) {
|
|
42422
42389
|
socketInstance.emit('join-room', roomId);
|
|
42423
42390
|
joinedRooms.add(roomId);
|
|
42424
|
-
|
|
42391
|
+
if (onRoomJoined) {
|
|
42392
|
+
setTimeout(() => {
|
|
42393
|
+
onRoomJoined();
|
|
42394
|
+
}, 100);
|
|
42395
|
+
}
|
|
42425
42396
|
}
|
|
42426
42397
|
else {
|
|
42427
|
-
|
|
42398
|
+
if (onRoomJoined) {
|
|
42399
|
+
onRoomJoined();
|
|
42400
|
+
}
|
|
42428
42401
|
}
|
|
42429
42402
|
};
|
|
42430
42403
|
const leaveRoom = (roomId) => {
|
|
@@ -42441,20 +42414,66 @@ const disconnectSocket = () => {
|
|
|
42441
42414
|
socket = null;
|
|
42442
42415
|
joinedRooms.clear();
|
|
42443
42416
|
setupCallbacks.clear();
|
|
42444
|
-
console.log('[SOCKET] Socket disconnected and cleaned up');
|
|
42445
42417
|
}
|
|
42446
42418
|
};
|
|
42419
|
+
// Get current socket connection status
|
|
42420
|
+
const isSocketConnected = () => {
|
|
42421
|
+
return socket?.connected ?? false;
|
|
42422
|
+
};
|
|
42423
|
+
// Get current socket instance
|
|
42424
|
+
const getSocket = () => {
|
|
42425
|
+
return socket;
|
|
42426
|
+
};
|
|
42427
|
+
// Subscribe to connection status changes
|
|
42428
|
+
const onSocketStatusChange = (callback) => {
|
|
42429
|
+
const socketInstance = socket || initializeSocket();
|
|
42430
|
+
statusChangeCallbacks.add(callback);
|
|
42431
|
+
callback(socketInstance.connected);
|
|
42432
|
+
return () => {
|
|
42433
|
+
statusChangeCallbacks.delete(callback);
|
|
42434
|
+
};
|
|
42435
|
+
};
|
|
42436
|
+
const waitForSocket = (webSocketUrl, timeoutMs = 5000) => {
|
|
42437
|
+
return new Promise((resolve) => {
|
|
42438
|
+
const socketInstance = initializeSocket(webSocketUrl);
|
|
42439
|
+
if (socketInstance.connected) {
|
|
42440
|
+
resolve();
|
|
42441
|
+
return;
|
|
42442
|
+
}
|
|
42443
|
+
const handleConnect = () => {
|
|
42444
|
+
socketInstance.off('connect', handleConnect);
|
|
42445
|
+
clearTimeout(timeoutHandle);
|
|
42446
|
+
resolve();
|
|
42447
|
+
};
|
|
42448
|
+
socketInstance.on('connect', handleConnect);
|
|
42449
|
+
const timeoutHandle = setTimeout(() => {
|
|
42450
|
+
socketInstance.off('connect', handleConnect);
|
|
42451
|
+
resolve();
|
|
42452
|
+
}, timeoutMs);
|
|
42453
|
+
});
|
|
42454
|
+
};
|
|
42447
42455
|
|
|
42448
42456
|
const Whiteboard = ({ roomId, isAdmin = false, allowedUsers = [], userId, transparentBackground = false, videoStream }) => {
|
|
42449
42457
|
const { state, dispatch, setQueueAction, requestStateFromPeers, webSocketUrl } = useWhiteboard();
|
|
42450
42458
|
const [lastCollaborativeAction, setLastCollaborativeAction] = React.useState(null);
|
|
42451
42459
|
const [hasRequestedState, setHasRequestedState] = React.useState(false);
|
|
42452
42460
|
const [lastStateRequestTime, setLastStateRequestTime] = React.useState(0);
|
|
42453
|
-
const [
|
|
42461
|
+
const [isSocketConnected, setIsSocketConnected] = React.useState(false);
|
|
42462
|
+
const [isRoomJoined, setIsRoomJoined] = React.useState(false);
|
|
42463
|
+
const [isGloballyUnlocked, setIsGloballyUnlocked] = React.useState(true); // Global unlock status
|
|
42454
42464
|
const [syncedAllowedUsers, setSyncedAllowedUsers] = React.useState(allowedUsers); // Synced allowed users from collaboration
|
|
42455
42465
|
const isCollaborativeUpdateRef = React.useRef(false); // Track if update came from collaboration
|
|
42456
42466
|
const lastClearTimeRef = React.useRef(0); // Track when last clear happened
|
|
42457
42467
|
const boardRef = React.useRef(null);
|
|
42468
|
+
React.useEffect(() => {
|
|
42469
|
+
const unsubscribe = onSocketStatusChange((connected) => {
|
|
42470
|
+
setIsSocketConnected(connected);
|
|
42471
|
+
});
|
|
42472
|
+
return () => {
|
|
42473
|
+
console.log('[WHITEBOARD] Unsubscribing from socket status listener');
|
|
42474
|
+
unsubscribe();
|
|
42475
|
+
};
|
|
42476
|
+
}, []); // Empty dependencies - single listener for component lifecycle
|
|
42458
42477
|
// Set userId in context when component mounts or userId changes
|
|
42459
42478
|
React.useEffect(() => {
|
|
42460
42479
|
dispatch({ type: 'SET_USER_ID', payload: userId });
|
|
@@ -42535,7 +42554,9 @@ const Whiteboard = ({ roomId, isAdmin = false, allowedUsers = [], userId, transp
|
|
|
42535
42554
|
setHasRequestedState(false);
|
|
42536
42555
|
}
|
|
42537
42556
|
callback(data);
|
|
42538
|
-
}, webSocketUrl)
|
|
42557
|
+
}, webSocketUrl, () => {
|
|
42558
|
+
setIsRoomJoined(true);
|
|
42559
|
+
});
|
|
42539
42560
|
}, [roomId, webSocketUrl]);
|
|
42540
42561
|
// Initialize the collaborative whiteboard hook
|
|
42541
42562
|
const collaborativeConfig = React.useMemo(() => ({
|
|
@@ -42572,48 +42593,42 @@ const Whiteboard = ({ roomId, isAdmin = false, allowedUsers = [], userId, transp
|
|
|
42572
42593
|
});
|
|
42573
42594
|
}
|
|
42574
42595
|
}, [allowedUsers, queueAction, userId, syncedAllowedUsers]);
|
|
42575
|
-
// Request state from peers when
|
|
42596
|
+
// Request state from peers when room is successfully joined AND socket is connected
|
|
42597
|
+
// Need both conditions to ensure message can actually be sent
|
|
42576
42598
|
React.useEffect(() => {
|
|
42577
|
-
if (
|
|
42578
|
-
|
|
42579
|
-
const now = Date.now();
|
|
42580
|
-
if (now - lastClearTimeRef.current < 10000) {
|
|
42581
|
-
return;
|
|
42582
|
-
}
|
|
42583
|
-
if (now - lastStateRequestTime > 5000) {
|
|
42584
|
-
requestStateFromPeers();
|
|
42585
|
-
setHasRequestedState(true);
|
|
42586
|
-
setLastStateRequestTime(now);
|
|
42587
|
-
}
|
|
42588
|
-
}, 500);
|
|
42589
|
-
return () => clearTimeout(requestTimer);
|
|
42599
|
+
if (!isRoomJoined || !isSocketConnected || hasRequestedState || state.shapes.length > 0 || !queueAction) {
|
|
42600
|
+
return;
|
|
42590
42601
|
}
|
|
42591
|
-
|
|
42602
|
+
const now = Date.now();
|
|
42603
|
+
if (now - lastClearTimeRef.current < 10000) {
|
|
42604
|
+
return;
|
|
42605
|
+
}
|
|
42606
|
+
requestStateFromPeers();
|
|
42607
|
+
setHasRequestedState(true);
|
|
42608
|
+
setLastStateRequestTime(Date.now());
|
|
42609
|
+
}, [isRoomJoined, isSocketConnected, state.shapes.length, hasRequestedState, queueAction, requestStateFromPeers, userId, roomId]);
|
|
42592
42610
|
// Reset request flag when room changes
|
|
42593
42611
|
React.useEffect(() => {
|
|
42594
42612
|
setHasRequestedState(false);
|
|
42595
42613
|
setLastStateRequestTime(0);
|
|
42614
|
+
setIsRoomJoined(false);
|
|
42596
42615
|
}, [roomId]);
|
|
42597
|
-
//
|
|
42616
|
+
// Retry state request if canvas is still empty after 3 seconds
|
|
42598
42617
|
React.useEffect(() => {
|
|
42599
|
-
if (queueAction
|
|
42600
|
-
|
|
42601
|
-
|
|
42602
|
-
|
|
42603
|
-
|
|
42604
|
-
|
|
42605
|
-
|
|
42606
|
-
}
|
|
42607
|
-
if (now - lastStateRequestTime > 10000) {
|
|
42608
|
-
const reconnectTimer = setTimeout(() => {
|
|
42609
|
-
requestStateFromPeers();
|
|
42610
|
-
setHasRequestedState(true);
|
|
42611
|
-
setLastStateRequestTime(now);
|
|
42612
|
-
}, 2000);
|
|
42613
|
-
return () => clearTimeout(reconnectTimer);
|
|
42614
|
-
}
|
|
42618
|
+
if (!isRoomJoined || !isSocketConnected || hasRequestedState || state.shapes.length > 0 || !queueAction) {
|
|
42619
|
+
return;
|
|
42620
|
+
}
|
|
42621
|
+
const now = Date.now();
|
|
42622
|
+
// Don't retry if we recently cleared
|
|
42623
|
+
if (now - lastClearTimeRef.current < 10000) {
|
|
42624
|
+
return;
|
|
42615
42625
|
}
|
|
42616
|
-
|
|
42626
|
+
const retryTimer = setTimeout(() => {
|
|
42627
|
+
requestStateFromPeers();
|
|
42628
|
+
setLastStateRequestTime(Date.now());
|
|
42629
|
+
}, 3000);
|
|
42630
|
+
return () => clearTimeout(retryTimer);
|
|
42631
|
+
}, [isRoomJoined, isSocketConnected, state.shapes.length, queueAction, requestStateFromPeers, lastStateRequestTime, userId]);
|
|
42617
42632
|
// Cleanup stale active drawings periodically
|
|
42618
42633
|
React.useEffect(() => {
|
|
42619
42634
|
const cleanupInterval = setInterval(() => {
|
|
@@ -42815,7 +42830,7 @@ const Whiteboard = ({ roomId, isAdmin = false, allowedUsers = [], userId, transp
|
|
|
42815
42830
|
});
|
|
42816
42831
|
}
|
|
42817
42832
|
};
|
|
42818
|
-
}, [isAdmin,
|
|
42833
|
+
}, [isAdmin, userId, dispatch]);
|
|
42819
42834
|
// Global cleanup on app unmount
|
|
42820
42835
|
React.useEffect(() => {
|
|
42821
42836
|
const handleBeforeUnload = () => {
|
|
@@ -45861,5 +45876,13 @@ function cn(...inputs) {
|
|
|
45861
45876
|
exports.Whiteboard = Whiteboard;
|
|
45862
45877
|
exports.WhiteboardProvider = WhiteboardProvider;
|
|
45863
45878
|
exports.cn = cn;
|
|
45879
|
+
exports.disconnectSocket = disconnectSocket;
|
|
45880
|
+
exports.getSocket = getSocket;
|
|
45881
|
+
exports.isSocketConnected = isSocketConnected;
|
|
45882
|
+
exports.leaveRoom = leaveRoom;
|
|
45883
|
+
exports.onReceive = onReceive;
|
|
45884
|
+
exports.onSend = onSend;
|
|
45885
|
+
exports.onSocketStatusChange = onSocketStatusChange;
|
|
45864
45886
|
exports.useWhiteboardStream = useCapture;
|
|
45887
|
+
exports.waitForSocket = waitForSocket;
|
|
45865
45888
|
//# sourceMappingURL=index.js.map
|