From 71bab45065a2ace8ea2f59d4f4856136ffd1b157 Mon Sep 17 00:00:00 2001
From: Jay V <air@live.ca>
Date: Wed, 28 May 2025 14:10:15 -0400
Subject: styling share

---
 app/packages/web/src/components/Share.tsx | 68 +++++++++++++++++++++++++++++--
 1 file changed, 64 insertions(+), 4 deletions(-)

(limited to 'app/packages/web/src/components/Share.tsx')

diff --git a/app/packages/web/src/components/Share.tsx b/app/packages/web/src/components/Share.tsx
index 30a915d60..292921ec7 100644
--- a/app/packages/web/src/components/Share.tsx
+++ b/app/packages/web/src/components/Share.tsx
@@ -6,6 +6,7 @@ import {
   onMount,
   onCleanup,
   createMemo,
+  createEffect,
   createSignal,
 } from "solid-js"
 import { DateTime } from "luxon"
@@ -42,6 +43,16 @@ type SessionInfo = {
   }
 }
 
+function getPartTitle(role: string, type: string): string | undefined {
+  return role === "system"
+    ? role
+    : role === "user"
+      ? undefined
+      : type === "text"
+        ? "AI"
+        : type
+}
+
 function getStatusText(status: [Status, string?]): string {
   switch (status[0]) {
     case "connected": return "Connected"
@@ -53,10 +64,47 @@ function getStatusText(status: [Status, string?]): string {
   }
 }
 
-function TextPart(props: { text: string }) {
+function TextPart(props: { text: string, highlight?: boolean }) {
+  const [expanded, setExpanded] = createSignal(false)
+  const [overflowed, setOverflowed] = createSignal(false);
+  let preEl: HTMLPreElement | undefined;
+
+  const checkOverflow = () => {
+    if (preEl) {
+      setOverflowed(preEl.scrollHeight > preEl.clientHeight + 1);
+    }
+  };
+
+  onMount(() => {
+    checkOverflow();
+    window.addEventListener('resize', checkOverflow);
+  });
+
+  createEffect(() => {
+    props.text;
+    setTimeout(checkOverflow, 0);
+  });
+
+  onCleanup(() => {
+    window.removeEventListener('resize', checkOverflow);
+  });
+
   return (
-    <div data-element-message-text>
-      <pre>{props.text}</pre>
+    <div
+      data-element-message-text
+      data-expanded={expanded()}
+      data-highlight={props.highlight}
+    >
+      <pre ref={el => (preEl = el)}>{props.text}</pre>
+      {overflowed() &&
+        <button
+          type="button"
+          data-element-button-text
+          onClick={() => setExpanded(e => !e)}
+        >
+          {expanded() ? "Show less" : "Show more"}
+        </button>
+      }
     </div>
   )
 }
@@ -270,7 +318,19 @@ export default function Share(props: { api: string }) {
                         <div></div>
                       </div>
                       <div data-section="content">
-                        <TextPart text={JSON.stringify(part, null, 2)} />
+                        {getPartTitle(msg.role, part.type)
+                          ? <span data-element-label>
+                            {getPartTitle(msg.role, part.type)}
+                          </span>
+                          : null
+                        }
+                        {part.type === "text"
+                          ? <TextPart
+                            text={part.text}
+                            highlight={msg.role === "user"}
+                          />
+                          : <TextPart text={JSON.stringify(part, null, 2)} />
+                        }
                         {renderTime(
                           msg.metadata?.time.completed
                           || msg.metadata?.time.created
-- 
cgit v1.2.3

