fix(annotations): address code review findings (1-8, 10)
1. toggleVote wrapped in transaction (race condition fix) 2. FeedbackPanel fetch calls now surface errors via onError/toast 3. Extracted resolveBoard/hasCollectionRole to shared board-access.js 4. AnnotationStore uses monotonic version counter for snapshots 5. PinOverlay uses object pool instead of destroy/recreate on refresh 6. canvasObjects prop memoized with useMemo 7. PinOverlay store subscription cleaned up on unmount 8. Comment content capped at 5000 chars (backend validation) 10. anchor_type validated to 'object' or 'point'
This commit is contained in:
@@ -355,13 +355,18 @@ export function useCanvasSetup(deps: CanvasSetupDeps) {
|
||||
pinOverlayRef.current = pinOverlay;
|
||||
|
||||
// Refresh overlay on viewport move
|
||||
viewport.on('moved', () => {
|
||||
const onViewportMoved = () => {
|
||||
if (pinOverlay.visible) pinOverlay.refresh();
|
||||
});
|
||||
// Refresh on store change
|
||||
annotationStoreRef.current!.subscribe(() => {
|
||||
};
|
||||
viewport.on('moved', onViewportMoved);
|
||||
// Refresh on store change (save unsub for cleanup)
|
||||
const unsubPinOverlay = annotationStoreRef.current!.subscribe(() => {
|
||||
if (pinOverlay.visible) pinOverlay.refresh();
|
||||
});
|
||||
(pinOverlay as any)._cleanup = () => {
|
||||
viewport.off('moved', onViewportMoved);
|
||||
unsubPinOverlay();
|
||||
};
|
||||
}
|
||||
|
||||
// Setup drag/drop and paste
|
||||
@@ -394,6 +399,7 @@ export function useCanvasSetup(deps: CanvasSetupDeps) {
|
||||
dropCleanupRef.current?.();
|
||||
pasteCleanupRef.current?.();
|
||||
if (pinOverlayRef.current) {
|
||||
(pinOverlayRef.current as any)._cleanup?.();
|
||||
pinOverlayRef.current.destroy();
|
||||
pinOverlayRef.current = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user