Skip to content

Conversation

@mattdawkins
Copy link
Member

Defer annotation layer creation to onMounted with nextTick and requestAnimationFrame to ensure GeoJS viewer is fully initialized before creating layers. This fixes an intermittent bug where annotations would not display on first load but would appear correctly after exiting and re-entering the viewer.

Changes:

  • Add layersInitialized ref to track initialization state
  • Move layer creation to initializeLayers() called in onMounted
  • Use nextTick + requestAnimationFrame to ensure GeoJS render cycle completes before layer creation
  • Add guards in updateLayers() and updateAttributes() to prevent calls before initialization
  • Move event listener setup to setupEventListeners() called after layer initialization

Addresses: #365

Defer annotation layer creation to onMounted with nextTick and
requestAnimationFrame to ensure GeoJS viewer is fully initialized
before creating layers. This fixes an intermittent bug where
annotations would not display on first load but would appear
correctly after exiting and re-entering the viewer.

Changes:
- Add layersInitialized ref to track initialization state
- Move layer creation to initializeLayers() called in onMounted
- Use nextTick + requestAnimationFrame to ensure GeoJS render cycle
  completes before layer creation
- Add guards in updateLayers() and updateAttributes() to prevent
  calls before initialization
- Move event listener setup to setupEventListeners() called after
  layer initialization

Addresses: #365

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Collaborator

@BryonLewis BryonLewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a fix at all, a ton of rearranging code that doesn't do anything to address the reference issue. Doesn't fix #365 at all because if I remove the second updateLayers call it does the same thing asif I removed the [0,1].forEach(() => updateLayers());

Comment on lines 420 to 431
requestAnimationFrame(() => {
updateLayers(
frameNumberRef.value,
editingModeRef.value,
selectedTrackIdRef.value,
multiSeletListRef.value,
enabledTracksRef.value,
visibleModesRef.value,
selectedKeyRef.value,
props.colorBy,
);
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all this code it doesn't fix a thing. It's still calling a double updateLayers to draw the first version. I pulled and checked this. This is not the solution to the related bug.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, the previous approach was flawed. I've updated the fix to properly address the root cause.

The Problem:
The original code (and my first attempt) used timing heuristics (onMountednextTickrequestAnimationFrame) hoping the GeoJS viewer would be ready. But the viewer is created asynchronously in the annotator when the first image loads - there's no guarantee timing-based approaches will work.

The Actual Fix:
Instead of guessing with timing, LayerManager now watches annotator.ready.value:

watch(
  () => annotator.ready.value,
  (ready) => {
    if (ready && !layersInitialized.value) {
      initializeLayers();
      updateLayers(...);
    }
  },
  { immediate: true },
);

This required exposing the existing state.ready property through the MediaController interface. The annotator components already set ready=true only after initializeViewer() completes, so this properly synchronizes layer creation with viewer initialization.

I also removed the double updateLayers() call since, as you pointed out, it was cargo cult code that never actually fixed anything.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still doesn't fix the issue of first time rendering when loading data and introduces more issues, including issues with the geoJS layer annotation-clicked handler. That state.ready variable is true before the watcher is even run so it never has a chance to be false inside of the LayerManager either.

Copy link
Member Author

@mattdawkins mattdawkins Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damnit claude.

This issue came about when I noticed some annotations still didn't show in the viewer the first time I went into them (but showed in the list). The initial commit seemed to make it go away, but it's a non-deterministic issue so hard to say.

@mattdawkins mattdawkins force-pushed the fix/annotation-layer-initialization-race branch from f3d0ac0 to 255b12e Compare January 25, 2026 21:19
The previous commit used timing heuristics (onMounted + nextTick +
requestAnimationFrame) which cannot reliably wait for the GeoJS viewer
since it's initialized asynchronously when the first image/video loads.

This commit properly synchronizes layer creation with viewer initialization:

- Add `ready` property to MediaController interface
- Expose existing state.ready through the mediaController object
- Replace timing heuristics in LayerManager with a watch on
  annotator.ready.value that triggers layer initialization only when
  the viewer is actually ready
- Remove redundant double-call to updateLayers()

The annotator components set ready=true only after initializeViewer()
completes, guaranteeing geoViewerRef.value is initialized before use.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mattdawkins mattdawkins force-pushed the fix/annotation-layer-initialization-race branch from 255b12e to a8abca5 Compare January 25, 2026 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants