From cb1b56f5a0eddbf77446f415f2beda57c8305f85 Mon Sep 17 00:00:00 2001
From: polwex <polwex@sortug.com>
Date: Sun, 23 Nov 2025 01:12:53 +0700
Subject: wut

---
 packages/prosody-ui/src/zoom/Paragraph.tsx | 60 ++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 packages/prosody-ui/src/zoom/Paragraph.tsx

(limited to 'packages/prosody-ui/src/zoom/Paragraph.tsx')

diff --git a/packages/prosody-ui/src/zoom/Paragraph.tsx b/packages/prosody-ui/src/zoom/Paragraph.tsx
new file mode 100644
index 0000000..c26f806
--- /dev/null
+++ b/packages/prosody-ui/src/zoom/Paragraph.tsx
@@ -0,0 +1,60 @@
+import React, { memo, useCallback, useEffect, useState } from "react";
+import { motion } from "motion/react";
+import type { ViewProps, LoadingStatus } from "./logic/types";
+import { NLP } from "sortug-ai";
+import Sentence from "./Sentence";
+import { paragraphVariants, createHoverEffect } from "./animations";
+import { useZoom } from "./hooks/useZoom";
+
+function Paragraph({ rawText, context, idx, doc }: ViewProps) {
+  const { viewState, handleElementClick } = useZoom();
+  const { level, pIndex } = viewState;
+  const selected = pIndex === idx;
+  const isFocused = level === "paragraph" && selected;
+
+  // State for sentences
+  const [loading, setLoading] = useState<LoadingStatus>("pending");
+
+  return (
+    <>
+      <motion.div
+        key={idx + rawText}
+        className={`paragraph-wrapper ${selected ? "selected" : ""}`}
+        custom={selected}
+        variants={paragraphVariants}
+        initial="text"
+        animate={level}
+        onClick={(e) => handleElementClick(e, idx)}
+        whileHover={
+          level === "text"
+            ? createHoverEffect(level, "text", "255, 255, 200")
+            : {}
+        }
+      >
+        {loading === "loading" && <div className="spinner" />}
+        {level === "text" || !selected || doc.segs.length === 0 ? (
+          <p className="paragraph">{rawText}</p>
+        ) : (
+          <div className="sentences-container">
+            {doc.segs.map((sentence, sentIdx) => (
+              <Sentence
+                key={sentence.text + sentIdx}
+                idx={sentIdx}
+                rawText={sentence.text}
+                spacy={sentence}
+                context={{
+                  idx: sentIdx,
+                  parentText: rawText,
+                  segmented: doc.segs.map((s) => s.text),
+                }}
+                doc={doc}
+              />
+            ))}
+          </div>
+        )}
+      </motion.div>
+    </>
+  );
+}
+
+export default memo(Paragraph);
-- 
cgit v1.2.3

