- 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
45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { getBoard } from '../api';
|
|
|
|
interface BoardLoaderResult {
|
|
boardData: any;
|
|
loading: boolean;
|
|
error: string;
|
|
}
|
|
|
|
/**
|
|
* Loads board data by ID with cancellation support.
|
|
*/
|
|
export function useBoardLoader(boardId: string | undefined): BoardLoaderResult {
|
|
const [boardData, setBoardData] = useState<any>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState('');
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
async function load() {
|
|
try {
|
|
if (!boardId) {
|
|
setError('No board specified');
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
const res = await getBoard(boardId);
|
|
if (!cancelled) {
|
|
setBoardData(res.data);
|
|
setLoading(false);
|
|
}
|
|
} catch (err: any) {
|
|
if (!cancelled) {
|
|
setError(err.response?.data?.error || 'Failed to load board');
|
|
setLoading(false);
|
|
}
|
|
}
|
|
}
|
|
load();
|
|
return () => { cancelled = true; };
|
|
}, [boardId]);
|
|
|
|
return { boardData, loading, error };
|
|
}
|