- 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
64 lines
1.6 KiB
JavaScript
64 lines
1.6 KiB
JavaScript
const { Server } = require('socket.io');
|
|
const { verifyToken } = require('../auth');
|
|
const { getUserById } = require('../db');
|
|
const { setupBoardRoom } = require('./board-room');
|
|
const { setupViewportSync } = require('./viewport-sync');
|
|
|
|
/**
|
|
* Set up Socket.IO on the given HTTP server.
|
|
* Returns the io instance.
|
|
*/
|
|
function setupSocket(httpServer) {
|
|
const io = new Server(httpServer, {
|
|
cors: {
|
|
origin: process.env.CORS_ORIGIN || '*',
|
|
methods: ['GET', 'POST'],
|
|
},
|
|
pingInterval: 25000,
|
|
pingTimeout: 60000,
|
|
});
|
|
|
|
// JWT authentication middleware
|
|
io.use((socket, next) => {
|
|
try {
|
|
const token = socket.handshake.auth?.token;
|
|
if (!token) {
|
|
return next(new Error('Authentication required'));
|
|
}
|
|
|
|
const decoded = verifyToken(token);
|
|
const user = getUserById(decoded.id);
|
|
if (!user) {
|
|
return next(new Error('User not found'));
|
|
}
|
|
|
|
// Store user info on socket
|
|
socket.userId = user.id;
|
|
socket.userEmail = user.email;
|
|
socket.userDisplayName = user.display_name;
|
|
socket.userRole = user.role;
|
|
|
|
next();
|
|
} catch (err) {
|
|
next(new Error('Invalid token'));
|
|
}
|
|
});
|
|
|
|
// Handle connections
|
|
io.on('connection', (socket) => {
|
|
console.log(`[socket] User connected: ${socket.userDisplayName} (${socket.userId})`);
|
|
|
|
// Set up board room handlers
|
|
setupBoardRoom(io, socket);
|
|
setupViewportSync(io, socket);
|
|
|
|
socket.on('disconnect', (reason) => {
|
|
console.log(`[socket] User disconnected: ${socket.userDisplayName} (${reason})`);
|
|
});
|
|
});
|
|
|
|
return io;
|
|
}
|
|
|
|
module.exports = { setupSocket };
|