From 67a05450cf2cf82e0472d4a412f9cb49a3b7e771 Mon Sep 17 00:00:00 2001
From: Lim Chee Aun <cheeaun@gmail.com>
Date: Tue, 26 Mar 2024 16:35:02 +0800
Subject: [PATCH] Test this lazy shazam

---
 src/components/lazy-shazam.jsx | 46 ++++++++++++++++++++++++++++++++++
 src/components/status.jsx      | 31 ++++++++++++-----------
 2 files changed, 63 insertions(+), 14 deletions(-)
 create mode 100644 src/components/lazy-shazam.jsx

diff --git a/src/components/lazy-shazam.jsx b/src/components/lazy-shazam.jsx
new file mode 100644
index 00000000..dfd2db7b
--- /dev/null
+++ b/src/components/lazy-shazam.jsx
@@ -0,0 +1,46 @@
+/*
+  Rendered but hidden. Only show when visible
+*/
+import { useLayoutEffect, useRef, useState } from 'preact/hooks';
+import { useInView } from 'react-intersection-observer';
+
+export default function LazyShazam({ children }) {
+  const containerRef = useRef();
+  const [visible, setVisible] = useState(false);
+  const [visibleStart, setVisibleStart] = useState(false);
+
+  const { ref } = useInView({
+    root: null,
+    trackVisibility: true,
+    delay: 1000,
+    onChange: (inView) => {
+      if (inView) {
+        setVisible(true);
+      }
+    },
+    triggerOnce: true,
+    skip: visibleStart || visible,
+  });
+
+  useLayoutEffect(() => {
+    if (!containerRef.current) return;
+    const rect = containerRef.current.getBoundingClientRect();
+    if (rect.bottom > 0) {
+      setVisibleStart(true);
+    }
+  }, []);
+
+  if (visibleStart) return children;
+
+  return (
+    <div
+      ref={containerRef}
+      class="shazam-container no-animation"
+      hidden={!visible}
+    >
+      <div ref={ref} class="shazam-container-inner">
+        {children}
+      </div>
+    </div>
+  );
+}
diff --git a/src/components/status.jsx b/src/components/status.jsx
index 2cb54af8..be42f27e 100644
--- a/src/components/status.jsx
+++ b/src/components/status.jsx
@@ -26,6 +26,7 @@ import { useSnapshot } from 'valtio';
 
 import CustomEmoji from '../components/custom-emoji';
 import EmojiText from '../components/emoji-text';
+import LazyShazam from '../components/lazy-shazam';
 import Loader from '../components/loader';
 import Menu2 from '../components/menu2';
 import MenuConfirm from '../components/menu-confirm';
@@ -3128,20 +3129,22 @@ const QuoteStatuses = memo(({ id, instance, level = 0 }) => {
 
   return uniqueQuotes.map((q) => {
     return (
-      <Link
-        key={q.instance + q.id}
-        to={`${q.instance ? `/${q.instance}` : ''}/s/${q.id}`}
-        class="status-card-link"
-        data-read-more="Read more →"
-      >
-        <Status
-          statusID={q.id}
-          instance={q.instance}
-          size="s"
-          quoted={level + 1}
-          enableCommentHint
-        />
-      </Link>
+      <LazyShazam>
+        <Link
+          key={q.instance + q.id}
+          to={`${q.instance ? `/${q.instance}` : ''}/s/${q.id}`}
+          class="status-card-link"
+          data-read-more="Read more →"
+        >
+          <Status
+            statusID={q.id}
+            instance={q.instance}
+            size="s"
+            quoted={level + 1}
+            enableCommentHint
+          />
+        </Link>
+      </LazyShazam>
     );
   });
 });