chore: cleanup
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
[data-component="session-turn"] {
|
[data-component="session-turn"] {
|
||||||
|
--session-turn-sticky-height: 0px;
|
||||||
|
--sticky-header-height: calc(var(--session-title-height, 0px) + var(--session-turn-sticky-height, 0px) + 12px);
|
||||||
/* flex: 1; */
|
/* flex: 1; */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
@@ -44,6 +46,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-slot="session-turn-attachments"] {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
align-self: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
[data-slot="session-turn-sticky"] {
|
[data-slot="session-turn-sticky"] {
|
||||||
width: calc(100% + 9px);
|
width: calc(100% + 9px);
|
||||||
position: sticky;
|
position: sticky;
|
||||||
@@ -331,11 +339,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[data-component="sticky-accordion-header"] {
|
[data-component="sticky-accordion-header"] {
|
||||||
top: var(--sticky-header-height, 40px);
|
top: var(--sticky-header-height, 0px);
|
||||||
&[data-expanded]::before {
|
&[data-expanded]::before {
|
||||||
top: calc(-1 * var(--sticky-header-height, 40px));
|
top: calc(-1 * var(--sticky-header-height, 0px));
|
||||||
}
|
}
|
||||||
/* position: static; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-slot="session-turn-accordion-trigger-content"] {
|
[data-slot="session-turn-accordion-trigger-content"] {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
AssistantMessage,
|
AssistantMessage,
|
||||||
|
FilePart,
|
||||||
Message as MessageType,
|
Message as MessageType,
|
||||||
Part as PartType,
|
Part as PartType,
|
||||||
type PermissionRequest,
|
type PermissionRequest,
|
||||||
@@ -29,6 +30,7 @@ import { Spinner } from "./spinner"
|
|||||||
import { createStore } from "solid-js/store"
|
import { createStore } from "solid-js/store"
|
||||||
import { DateTime, DurationUnit, Interval } from "luxon"
|
import { DateTime, DurationUnit, Interval } from "luxon"
|
||||||
import { createAutoScroll } from "../hooks"
|
import { createAutoScroll } from "../hooks"
|
||||||
|
import { createResizeObserver } from "@solid-primitives/resize-observer"
|
||||||
|
|
||||||
function computeStatusFromPart(part: PartType | undefined): string | undefined {
|
function computeStatusFromPart(part: PartType | undefined): string | undefined {
|
||||||
if (!part) return undefined
|
if (!part) return undefined
|
||||||
@@ -75,6 +77,12 @@ function same<T>(a: readonly T[], b: readonly T[]) {
|
|||||||
return a.every((x, i) => x === b[i])
|
return a.every((x, i) => x === b[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isAttachment(part: PartType | undefined) {
|
||||||
|
if (part?.type !== "file") return false
|
||||||
|
const mime = (part as FilePart).mime ?? ""
|
||||||
|
return mime.startsWith("image/") || mime === "application/pdf"
|
||||||
|
}
|
||||||
|
|
||||||
function AssistantMessageItem(props: {
|
function AssistantMessageItem(props: {
|
||||||
message: AssistantMessage
|
message: AssistantMessage
|
||||||
responsePartId: string | undefined
|
responsePartId: string | undefined
|
||||||
@@ -133,6 +141,7 @@ export function SessionTurn(
|
|||||||
|
|
||||||
const emptyMessages: MessageType[] = []
|
const emptyMessages: MessageType[] = []
|
||||||
const emptyParts: PartType[] = []
|
const emptyParts: PartType[] = []
|
||||||
|
const emptyFiles: FilePart[] = []
|
||||||
const emptyAssistant: AssistantMessage[] = []
|
const emptyAssistant: AssistantMessage[] = []
|
||||||
const emptyPermissions: PermissionRequest[] = []
|
const emptyPermissions: PermissionRequest[] = []
|
||||||
const emptyPermissionParts: { part: ToolPart; message: AssistantMessage }[] = []
|
const emptyPermissionParts: { part: ToolPart; message: AssistantMessage }[] = []
|
||||||
@@ -180,6 +189,19 @@ export function SessionTurn(
|
|||||||
return data.store.part[msg.id] ?? emptyParts
|
return data.store.part[msg.id] ?? emptyParts
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const attachmentParts = createMemo(() => {
|
||||||
|
const msgParts = parts()
|
||||||
|
if (msgParts.length === 0) return emptyFiles
|
||||||
|
return msgParts.filter((part) => isAttachment(part)) as FilePart[]
|
||||||
|
})
|
||||||
|
|
||||||
|
const stickyParts = createMemo(() => {
|
||||||
|
const msgParts = parts()
|
||||||
|
if (msgParts.length === 0) return emptyParts
|
||||||
|
if (attachmentParts().length === 0) return msgParts
|
||||||
|
return msgParts.filter((part) => !isAttachment(part))
|
||||||
|
})
|
||||||
|
|
||||||
const assistantMessages = createMemo(
|
const assistantMessages = createMemo(
|
||||||
() => {
|
() => {
|
||||||
const msg = message()
|
const msg = message()
|
||||||
@@ -331,6 +353,15 @@ export function SessionTurn(
|
|||||||
const hideResponsePart = createMemo(() => !working() && !!responsePartId())
|
const hideResponsePart = createMemo(() => !working() && !!responsePartId())
|
||||||
|
|
||||||
const [responseCopied, setResponseCopied] = createSignal(false)
|
const [responseCopied, setResponseCopied] = createSignal(false)
|
||||||
|
const [rootRef, setRootRef] = createSignal<HTMLDivElement | undefined>()
|
||||||
|
const [stickyRef, setStickyRef] = createSignal<HTMLDivElement | undefined>()
|
||||||
|
|
||||||
|
const updateStickyHeight = (height: number) => {
|
||||||
|
const root = rootRef()
|
||||||
|
if (!root) return
|
||||||
|
const next = Math.ceil(height)
|
||||||
|
root.style.setProperty("--session-turn-sticky-height", `${next}px`)
|
||||||
|
}
|
||||||
const handleCopyResponse = async () => {
|
const handleCopyResponse = async () => {
|
||||||
const content = response()
|
const content = response()
|
||||||
if (!content) return
|
if (!content) return
|
||||||
@@ -361,6 +392,24 @@ export function SessionTurn(
|
|||||||
onUserInteracted: props.onUserInteracted,
|
onUserInteracted: props.onUserInteracted,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
createResizeObserver(
|
||||||
|
() => stickyRef(),
|
||||||
|
({ height }) => {
|
||||||
|
updateStickyHeight(height)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
const root = rootRef()
|
||||||
|
if (!root) return
|
||||||
|
const sticky = stickyRef()
|
||||||
|
if (!sticky) {
|
||||||
|
root.style.setProperty("--session-turn-sticky-height", "0px")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updateStickyHeight(sticky.getBoundingClientRect().height)
|
||||||
|
})
|
||||||
|
|
||||||
const diffInit = 20
|
const diffInit = 20
|
||||||
const diffBatch = 20
|
const diffBatch = 20
|
||||||
|
|
||||||
@@ -438,7 +487,7 @@ export function SessionTurn(
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div data-component="session-turn" class={props.classes?.root}>
|
<div data-component="session-turn" class={props.classes?.root} ref={setRootRef}>
|
||||||
<div
|
<div
|
||||||
ref={autoScroll.scrollRef}
|
ref={autoScroll.scrollRef}
|
||||||
onScroll={autoScroll.handleScroll}
|
onScroll={autoScroll.handleScroll}
|
||||||
@@ -459,10 +508,15 @@ export function SessionTurn(
|
|||||||
<Part part={shellModePart()!} message={msg()} defaultOpen />
|
<Part part={shellModePart()!} message={msg()} defaultOpen />
|
||||||
</Match>
|
</Match>
|
||||||
<Match when={true}>
|
<Match when={true}>
|
||||||
<div data-slot="session-turn-sticky">
|
<Show when={attachmentParts().length > 0}>
|
||||||
|
<div data-slot="session-turn-attachments">
|
||||||
|
<Message message={msg()} parts={attachmentParts()} />
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
<div data-slot="session-turn-sticky" ref={setStickyRef}>
|
||||||
{/* User Message */}
|
{/* User Message */}
|
||||||
<div data-slot="session-turn-message-content">
|
<div data-slot="session-turn-message-content">
|
||||||
<Message message={msg()} parts={parts()} />
|
<Message message={msg()} parts={stickyParts()} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Trigger (sticky) */}
|
{/* Trigger (sticky) */}
|
||||||
|
|||||||
Reference in New Issue
Block a user