diff options
| -rw-r--r-- | app/packages/web/astro.config.mjs | 3 | ||||
| -rw-r--r-- | app/packages/web/src/components/Header.astro | 5 | ||||
| -rw-r--r-- | app/packages/web/src/components/Share.tsx | 68 | ||||
| -rw-r--r-- | app/packages/web/src/components/share.module.css | 72 | ||||
| -rw-r--r-- | app/packages/web/src/styles/custom.css | 4 |
5 files changed, 140 insertions, 12 deletions
diff --git a/app/packages/web/astro.config.mjs b/app/packages/web/astro.config.mjs index 78ddcdea8..5b0c3416e 100644 --- a/app/packages/web/astro.config.mjs +++ b/app/packages/web/astro.config.mjs @@ -34,6 +34,9 @@ export default defineConfig({ markdown: { headingLinks: false, }, + customCss: [ + "./src/styles/custom.css", + ], logo: { light: "./src/assets/logo-light.svg", dark: "./src/assets/logo-dark.svg", diff --git a/app/packages/web/src/components/Header.astro b/app/packages/web/src/components/Header.astro index f027d7274..a45899ff8 100644 --- a/app/packages/web/src/components/Header.astro +++ b/app/packages/web/src/components/Header.astro @@ -54,4 +54,9 @@ const links = config.social || []; } } </style> +<style is:global> +body > div.page > header { + border-color: var(--sl-color-divider); +} +</style> 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 diff --git a/app/packages/web/src/components/share.module.css b/app/packages/web/src/components/share.module.css index 13c73607a..63a6232bc 100644 --- a/app/packages/web/src/components/share.module.css +++ b/app/packages/web/src/components/share.module.css @@ -6,6 +6,19 @@ line-height: 1; } +[data-element-button-text] { + cursor: pointer; + appearance: none; + background-color: transparent; + border: none; + padding: 0; + color: var(--sl-color-text-secondary); + + &:hover { + color: var(--sl-color-text); + } +} + [data-element-label] { text-transform: uppercase; letter-spacing: 0.05em; @@ -39,11 +52,11 @@ font-size: 0.75rem; span:first-child { - color: var(--sl-color-gray-5); + color: var(--sl-color-divider); &[data-status="connected"] { color: var(--sl-color-green); } &[data-status="connecting"] { color: var(--sl-color-orange); } - &[data-status="disconnected"] { color: var(--sl-color-gray-5); } + &[data-status="disconnected"] { color: var(--sl-color-divider); } &[data-status="reconnecting"] { color: var(--sl-color-orange); } &[data-status="error"] { color: var(--sl-color-red); } } @@ -118,12 +131,15 @@ } [data-section="content"] { - flex: 1 1 auto; - padding: 0.125rem 0 0.375rem; + padding: 3px 0 0.375rem; display: flex; flex-direction: column; gap: 0.5rem; + span:first-child { + font-size: 0.75rem; + } + span:last-child { font-size: 0.75rem; color: var(--sl-color-text-dimmed); @@ -132,13 +148,53 @@ } [data-element-message-text] { + background-color: var(--sl-color-bg-surface); + padding: 0.5rem calc(0.5rem + 3px); + border-radius: 0.25rem; + display: flex; + flex-direction: column; + align-items: flex-start; + color: var(--sl-color-text); + gap: 1rem; + pre { + line-height: 1.5; font-size: 0.875rem; - color: var(--sl-color-text); - background-color: var(--sl-color-bg-nav); - padding: 0.5rem; - border-radius: 0.5rem; white-space: pre-wrap; overflow-wrap: anywhere; } + + button { + flex: 0 0 auto; + padding: 2px 0; + font-size: 0.75rem; + } + + &[data-highlight="true"] { + background-color: var(--sl-color-blue-high); + color: var(--sl-color-text-invert); + + button { + opacity: 0.85; + color: var(--sl-color-text-invert); + + &:hover { + opacity: 1; + } + } + } + + &[data-expanded="true"] { + pre { + display: block; + } + } + &[data-expanded="false"] { + pre { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + } + } } diff --git a/app/packages/web/src/styles/custom.css b/app/packages/web/src/styles/custom.css new file mode 100644 index 000000000..450be4319 --- /dev/null +++ b/app/packages/web/src/styles/custom.css @@ -0,0 +1,4 @@ +:root { + --sl-color-bg-surface: var(--sl-color-bg-nav); + --sl-color-divider: var(--sl-color-gray-5); +} |
