Files
Hiren Kangad e9509ef7b0 feat(refboard): canvas polish — transform box sync, dot grid, snap tuning, perf fixes
- Fix transform box not updating after alignment/arrangement/normalize/flip operations
  (shortcuts, context menu, and selection toolbar all fixed with DRY _opUpdate helper)
- Replace 100ms polling loop with event-driven viewport updates (moved + wheel-scroll)
- Add adaptive dot grid background that responds to zoom/pan
- Reduce snap guide threshold from 8px to 4px for subtler snapping
- Remove PresenceOverlay (remote selection highlighting) — too heavy for minimal benefit
- Offset multiple dropped images so they don't overlap
- Add new canvas modules: SnapGuides, clipboard, grouping, FrameSprite, DrawingSprite,
  LaserPointer, context-menu-items, SelectionToolbar, Minimap
- Extract Editor hooks into dedicated files (useBoardLoader, useCanvasSetup,
  useShortcutHandler, useLayerPanel, useSaveManager, useFollowMode)
- Sync improvements: real-time transform broadcast, board rooms, viewport sync
2026-03-10 03:58:53 +05:30

49 lines
1.6 KiB
JavaScript

/**
* Viewport sync relay — broadcasts user viewport positions for follow mode.
* Each user periodically emits their viewport state; this relays it to
* everyone else in the same board room so followers can track in real-time.
*
* Kept separate from board-room.js to avoid conflicts.
*/
function getRoomName(boardId) {
return `board:${boardId}`;
}
function setupViewportSync(io, socket) {
// Relay viewport position to other users in the same board room
socket.on('viewport:sync', (data) => {
if (!socket.currentBoardId) return;
const roomName = getRoomName(socket.currentBoardId);
socket.volatile.to(roomName).emit('viewport:sync', {
...data,
userId: socket.userId,
});
});
// follow:start / follow:stop are informational — the server doesn't need
// to gate viewport:sync relay (all users broadcast always, clients filter).
// These events exist so the UI can show "X is following you" if desired.
socket.on('follow:start', (data) => {
if (!socket.currentBoardId) return;
const roomName = getRoomName(socket.currentBoardId);
socket.to(roomName).emit('follow:start', {
boardId: data.boardId,
followerId: socket.userId,
followerName: socket.userDisplayName,
targetUserId: data.targetUserId,
});
});
socket.on('follow:stop', (data) => {
if (!socket.currentBoardId) return;
const roomName = getRoomName(socket.currentBoardId);
socket.to(roomName).emit('follow:stop', {
boardId: data.boardId,
followerId: socket.userId,
});
});
}
module.exports = { setupViewportSync };