From 4e71b439444ec98f09d82a1cd490761f9d275b2b Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Wed, 5 Jul 2023 15:33:53 +0200
Subject: [PATCH] fix: annotation: export and render

---
 docs/releases/v2.12.2.md                              |  2 +-
 src/atlasComponents/annotations/annotation.service.ts | 10 +++++-----
 src/atlasComponents/userAnnotations/tools/service.ts  | 10 +++-------
 src/util/fn.ts                                        | 11 +++++++++++
 4 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/docs/releases/v2.12.2.md b/docs/releases/v2.12.2.md
index 92ec10a5c..8043ff609 100644
--- a/docs/releases/v2.12.2.md
+++ b/docs/releases/v2.12.2.md
@@ -4,4 +4,4 @@
 
 - fixes screenshot in fsaverage
 - on hover region label in fsaverage now display properly
-- fixes annotation mode (export annotations)
+- fixes annotation mode (export annotations, annotations fail to render in viewer on startup (via shared link, local storage etc))
diff --git a/src/atlasComponents/annotations/annotation.service.ts b/src/atlasComponents/annotations/annotation.service.ts
index 543271a3a..d133671c3 100644
--- a/src/atlasComponents/annotations/annotation.service.ts
+++ b/src/atlasComponents/annotations/annotation.service.ts
@@ -1,6 +1,6 @@
 import { BehaviorSubject, Observable } from "rxjs";
 import { distinctUntilChanged } from "rxjs/operators";
-import { getUuid } from "src/util/fn";
+import { getUuid, waitFor } from "src/util/fn";
 import { PeriodicSvc } from "src/util/periodic.service";
 
 export type TNgAnnotationEv = {
@@ -144,8 +144,8 @@ export class AnnotationLayer {
       return false
     })
   }
-  removeAnnotation(spec: { id: string }) {
-    if (!this.nglayer) return
+  async removeAnnotation(spec: { id: string }) {
+    await waitFor(() => !!this.nglayer?.layer?.localAnnotations)
     const { localAnnotations } = this.nglayer.layer
     this.idset.delete(spec.id)
     const ref = localAnnotations.references.get(spec.id)
@@ -155,8 +155,8 @@ export class AnnotationLayer {
     }
   }
   async updateAnnotation(spec: AnnotationSpec) {
-    const localAnnotations = this.nglayer?.layer?.localAnnotations
-    if (!localAnnotations) return
+    await waitFor(() => !!this.nglayer?.layer?.localAnnotations)
+    const { localAnnotations } = this.nglayer.layer
     const ref = localAnnotations.references.get(spec.id)
     const _spec = this.parseNgSpecType(spec)
     if (ref) {
diff --git a/src/atlasComponents/userAnnotations/tools/service.ts b/src/atlasComponents/userAnnotations/tools/service.ts
index 847abe0c2..9ef8d363a 100644
--- a/src/atlasComponents/userAnnotations/tools/service.ts
+++ b/src/atlasComponents/userAnnotations/tools/service.ts
@@ -410,13 +410,9 @@ export class ModularUserAnnotationToolService implements OnDestroy{
         })),
       )
     ]).pipe(
-      map(([_, annts]) => {
-        const out = []
-        for (const ann of annts) {
-          out.push(...ann.toNgAnnotation())
-        }
-        return out
-      }),
+      map(([_, annts]) => 
+        annts.map(ann => ann.toNgAnnotation()).flatMap(v => v)
+      ),
       shareReplay(1),
     )
     this.subscription.push(
diff --git a/src/util/fn.ts b/src/util/fn.ts
index a859bad08..4830a09ba 100644
--- a/src/util/fn.ts
+++ b/src/util/fn.ts
@@ -419,3 +419,14 @@ export function wait(ms: number){
     rs(null)
   }, ms))
 }
+
+/**
+ * @description Wait until predicate returns true. Tries once every 16 ms.
+ * @param predicate 
+ */
+export async function waitFor(predicate: () => boolean) {
+  while (true) {
+    if (predicate()) break
+    await wait(16)
+  }
+}
-- 
GitLab