From caf212045a8f4d1f349f2ae11c38f29e81c79cf0 Mon Sep 17 00:00:00 2001
From: Tilman Vatteroth <git@tilmanvatteroth.de>
Date: Thu, 29 Dec 2022 12:27:38 +0100
Subject: [PATCH] fix(async-loading): show async loaded components only if
 value is present

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
---
 .../hooks/use-load-note-from-server.ts                    | 3 ++-
 .../common/user-avatar/user-avatar-for-username.tsx       | 8 ++------
 .../editor-page/document-bar/revisions/revision-list.tsx  | 2 +-
 .../document-bar/revisions/revision-viewer.tsx            | 2 +-
 .../src/components/intro-page/intro-custom-content.tsx    | 2 +-
 .../src/extensions/extra-integrations/abcjs/abc-frame.tsx | 2 +-
 .../extensions/extra-integrations/flowchart/flowchart.tsx | 2 +-
 .../extra-integrations/graphviz/graphviz-frame.tsx        | 2 +-
 .../highlighted-code-fence/highlighted-code.tsx           | 2 +-
 .../extra-integrations/vega-lite/vega-lite-chart.tsx      | 2 +-
 frontend/src/pages/new.tsx                                | 2 +-
 11 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts b/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts
index 85a0809af..6d566e352 100644
--- a/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts
+++ b/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts
@@ -14,7 +14,7 @@ import type { AsyncState } from 'react-use/lib/useAsyncFn'
  *
  * @return An {@link AsyncState async state} that represents the current state of the loading process.
  */
-export const useLoadNoteFromServer = (): [AsyncState<void>, () => void] => {
+export const useLoadNoteFromServer = (): [AsyncState<boolean>, () => void] => {
   const id = useSingleStringUrlParameter('noteId', undefined)
 
   return useAsyncFn(async () => {
@@ -23,5 +23,6 @@ export const useLoadNoteFromServer = (): [AsyncState<void>, () => void] => {
     }
     const noteFromServer = await getNote(id)
     setNoteDataFromServer(noteFromServer)
+    return true
   }, [id])
 }
diff --git a/frontend/src/components/common/user-avatar/user-avatar-for-username.tsx b/frontend/src/components/common/user-avatar/user-avatar-for-username.tsx
index a778fecbb..a4a26329e 100644
--- a/frontend/src/components/common/user-avatar/user-avatar-for-username.tsx
+++ b/frontend/src/components/common/user-avatar/user-avatar-for-username.tsx
@@ -38,13 +38,9 @@ export const UserAvatarForUsername: React.FC<UserAvatarForUsernameProps> = ({ us
     }
   }, [username, t])
 
-  if (!value) {
-    return null
-  }
-
   return (
-    <AsyncLoadingBoundary loading={loading} error={error} componentName={'UserAvatarForUsername'}>
-      <UserAvatar user={value} {...props} />
+    <AsyncLoadingBoundary loading={loading || !value} error={error} componentName={'UserAvatarForUsername'}>
+      <UserAvatar user={value as UserInfo} {...props} />
     </AsyncLoadingBoundary>
   )
 }
diff --git a/frontend/src/components/editor-page/document-bar/revisions/revision-list.tsx b/frontend/src/components/editor-page/document-bar/revisions/revision-list.tsx
index c85b73561..ace3a2926 100644
--- a/frontend/src/components/editor-page/document-bar/revisions/revision-list.tsx
+++ b/frontend/src/components/editor-page/document-bar/revisions/revision-list.tsx
@@ -55,7 +55,7 @@ export const RevisionList: React.FC<RevisionListProps> = ({ selectedRevisionId,
   }, [loading, onRevisionSelect, revisions, selectedRevisionId])
 
   return (
-    <AsyncLoadingBoundary loading={loading} error={error} componentName={'revision list'}>
+    <AsyncLoadingBoundary loading={loading || !revisions} error={error} componentName={'revision list'}>
       <ListGroup>{revisionList}</ListGroup>
     </AsyncLoadingBoundary>
   )
diff --git a/frontend/src/components/editor-page/document-bar/revisions/revision-viewer.tsx b/frontend/src/components/editor-page/document-bar/revisions/revision-viewer.tsx
index 03c2a9804..f3fed0d1f 100644
--- a/frontend/src/components/editor-page/document-bar/revisions/revision-viewer.tsx
+++ b/frontend/src/components/editor-page/document-bar/revisions/revision-viewer.tsx
@@ -51,7 +51,7 @@ export const RevisionViewer: React.FC<RevisionViewerProps> = ({ selectedRevision
   }
 
   return (
-    <AsyncLoadingBoundary loading={loading} componentName={'RevisionViewer'} error={error}>
+    <AsyncLoadingBoundary loading={loading || !value} componentName={'RevisionViewer'} error={error}>
       <ReactDiffViewer
         oldValue={previousRevisionContent ?? ''}
         newValue={value?.content ?? ''}
diff --git a/frontend/src/components/intro-page/intro-custom-content.tsx b/frontend/src/components/intro-page/intro-custom-content.tsx
index 83e357b1b..ddbc8ad40 100644
--- a/frontend/src/components/intro-page/intro-custom-content.tsx
+++ b/frontend/src/components/intro-page/intro-custom-content.tsx
@@ -26,7 +26,7 @@ export const IntroCustomContent: React.FC = () => {
   }, [error])
 
   return (
-    <AsyncLoadingBoundary loading={loading} error={error} componentName={'custom intro content'}>
+    <AsyncLoadingBoundary loading={loading || !value} error={error} componentName={'custom intro content'}>
       <RenderIframe
         frameClasses={'w-100 overflow-y-hidden'}
         markdownContentLines={value as string[]}
diff --git a/frontend/src/extensions/extra-integrations/abcjs/abc-frame.tsx b/frontend/src/extensions/extra-integrations/abcjs/abc-frame.tsx
index 10da79e35..4530e06f6 100644
--- a/frontend/src/extensions/extra-integrations/abcjs/abc-frame.tsx
+++ b/frontend/src/extensions/extra-integrations/abcjs/abc-frame.tsx
@@ -49,7 +49,7 @@ export const AbcFrame: React.FC<CodeProps> = ({ code }) => {
   }, [code, abcLib])
 
   return (
-    <AsyncLoadingBoundary loading={loading} error={!!loadingError} componentName={'abc.js'}>
+    <AsyncLoadingBoundary loading={loading || !abcLib} error={!!loadingError} componentName={'abc.js'}>
       <ShowIf condition={!!renderError}>
         <Alert variant={'danger'}>
           <Trans i18nKey={'editor.embeddings.abcJs.errorWhileRendering'} />
diff --git a/frontend/src/extensions/extra-integrations/flowchart/flowchart.tsx b/frontend/src/extensions/extra-integrations/flowchart/flowchart.tsx
index 8e0434abc..12dfe36c4 100644
--- a/frontend/src/extensions/extra-integrations/flowchart/flowchart.tsx
+++ b/frontend/src/extensions/extra-integrations/flowchart/flowchart.tsx
@@ -70,7 +70,7 @@ export const FlowChart: React.FC<CodeProps> = ({ code }) => {
   }, [code, darkModeActivated, flowchartLib])
 
   return (
-    <AsyncLoadingBoundary loading={loading} componentName={'flowchart.js'} error={!!libLoadingError}>
+    <AsyncLoadingBoundary loading={loading || !flowchartLib} componentName={'flowchart.js'} error={!!libLoadingError}>
       <ShowIf condition={syntaxError}>
         <Alert variant={'danger'}>
           <Trans i18nKey={'renderer.flowchart.invalidSyntax'} />
diff --git a/frontend/src/extensions/extra-integrations/graphviz/graphviz-frame.tsx b/frontend/src/extensions/extra-integrations/graphviz/graphviz-frame.tsx
index 0233fee58..3da421078 100644
--- a/frontend/src/extensions/extra-integrations/graphviz/graphviz-frame.tsx
+++ b/frontend/src/extensions/extra-integrations/graphviz/graphviz-frame.tsx
@@ -61,7 +61,7 @@ export const GraphvizFrame: React.FC<CodeProps> = ({ code }) => {
   }, [code, basePath, showError, graphvizImport])
 
   return (
-    <AsyncLoadingBoundary loading={isLibLoading} componentName={'graphviz'} error={libLoadingError}>
+    <AsyncLoadingBoundary loading={isLibLoading || !graphvizImport} componentName={'graphviz'} error={libLoadingError}>
       <ShowIf condition={!!error}>
         <Alert variant={'warning'}>{error}</Alert>
       </ShowIf>
diff --git a/frontend/src/extensions/extra-integrations/highlighted-code-fence/highlighted-code.tsx b/frontend/src/extensions/extra-integrations/highlighted-code-fence/highlighted-code.tsx
index 8b4cc81d5..2b92ad9aa 100644
--- a/frontend/src/extensions/extra-integrations/highlighted-code-fence/highlighted-code.tsx
+++ b/frontend/src/extensions/extra-integrations/highlighted-code-fence/highlighted-code.tsx
@@ -36,7 +36,7 @@ export const HighlightedCode: React.FC<HighlightedCodeProps> = ({ code, language
   const wrappedDomLines = useAttachLineNumbers(codeDom, startLineNumber)
 
   return (
-    <AsyncLoadingBoundary loading={loading} error={!!error} componentName={'highlight.js'}>
+    <AsyncLoadingBoundary loading={loading || !hljsApi} error={!!error} componentName={'highlight.js'}>
       <div className={styles['code-highlighter']} {...cypressId('highlighted-code-block')}>
         <code
           {...testId('code-highlighter')}
diff --git a/frontend/src/extensions/extra-integrations/vega-lite/vega-lite-chart.tsx b/frontend/src/extensions/extra-integrations/vega-lite/vega-lite-chart.tsx
index 58fe1f839..10b2ebbb5 100644
--- a/frontend/src/extensions/extra-integrations/vega-lite/vega-lite-chart.tsx
+++ b/frontend/src/extensions/extra-integrations/vega-lite/vega-lite-chart.tsx
@@ -58,7 +58,7 @@ export const VegaLiteChart: React.FC<CodeProps> = ({ code }) => {
   }, [renderingError])
 
   return (
-    <AsyncLoadingBoundary loading={libLoading} error={libLoadingError} componentName={'Vega Lite'}>
+    <AsyncLoadingBoundary loading={libLoading || !vegaEmbed} error={libLoadingError} componentName={'Vega Lite'}>
       <ShowIf condition={!!renderingError}>
         <Alert variant={'danger'}>
           <Trans i18nKey={'renderer.vega-lite.errorJson'} />
diff --git a/frontend/src/pages/new.tsx b/frontend/src/pages/new.tsx
index 938427f5a..86e24c13b 100644
--- a/frontend/src/pages/new.tsx
+++ b/frontend/src/pages/new.tsx
@@ -24,7 +24,7 @@ export const NewNotePage: NextPage = () => {
 
   return (
     <CustomAsyncLoadingBoundary
-      loading={loading}
+      loading={loading || !value}
       error={error}
       loadingComponent={<LoadingScreen />}
       errorComponent={