Spaces:
Running
Running
fix height of assistance card
Browse files
src/lib/components/chat/Assistant.svelte
CHANGED
|
@@ -6,6 +6,8 @@
|
|
| 6 |
type NodeProps,
|
| 7 |
useNodes,
|
| 8 |
useEdges,
|
|
|
|
|
|
|
| 9 |
type Edge,
|
| 10 |
type Node
|
| 11 |
} from '@xyflow/svelte';
|
|
@@ -27,6 +29,8 @@
|
|
| 27 |
const nodeData = useNodesData(id);
|
| 28 |
const { update: updateNodes } = useNodes();
|
| 29 |
const { update: updateEdges } = useEdges();
|
|
|
|
|
|
|
| 30 |
|
| 31 |
let selectedModel = $derived((nodeData.current?.data.selectedModel as string) ?? '');
|
| 32 |
let messages = $derived((nodeData.current?.data.messages as ChatMessage[]) ?? []);
|
|
@@ -42,8 +46,8 @@
|
|
| 42 |
} as unknown as ChatMessage)
|
| 43 |
: null
|
| 44 |
);
|
| 45 |
-
let rowHeight = $derived((nodeData.current?.data.rowHeight as number) ?? null);
|
| 46 |
let containerRef: HTMLDivElement | null = $state(null);
|
|
|
|
| 47 |
let selectedText = $state<string | null>(null);
|
| 48 |
let selectedTextPosition = $state<{ y: number } | null>(null);
|
| 49 |
|
|
@@ -113,14 +117,34 @@
|
|
| 113 |
updateEdges((currentEdges) => [...currentEdges, ...newEdges]);
|
| 114 |
}
|
| 115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
$effect(() => {
|
| 117 |
console.log(message);
|
| 118 |
});
|
| 119 |
</script>
|
| 120 |
|
| 121 |
<article
|
|
|
|
| 122 |
class="group/assistant relative flex w-[calc(100dvw-2rem)] flex-col rounded-3xl border border-border bg-background p-5 shadow-lg/5 lg:w-[600px]"
|
| 123 |
-
style={rowHeight ? `min-height: ${rowHeight}px` : ''}
|
| 124 |
>
|
| 125 |
<div class="nodrag pointer-events-auto flex flex-1 cursor-auto flex-col justify-between">
|
| 126 |
<div>
|
|
|
|
| 6 |
type NodeProps,
|
| 7 |
useNodes,
|
| 8 |
useEdges,
|
| 9 |
+
useUpdateNodeInternals,
|
| 10 |
+
useSvelteFlow,
|
| 11 |
type Edge,
|
| 12 |
type Node
|
| 13 |
} from '@xyflow/svelte';
|
|
|
|
| 29 |
const nodeData = useNodesData(id);
|
| 30 |
const { update: updateNodes } = useNodes();
|
| 31 |
const { update: updateEdges } = useEdges();
|
| 32 |
+
const updateNodeInternals = useUpdateNodeInternals();
|
| 33 |
+
const { fitView } = useSvelteFlow();
|
| 34 |
|
| 35 |
let selectedModel = $derived((nodeData.current?.data.selectedModel as string) ?? '');
|
| 36 |
let messages = $derived((nodeData.current?.data.messages as ChatMessage[]) ?? []);
|
|
|
|
| 46 |
} as unknown as ChatMessage)
|
| 47 |
: null
|
| 48 |
);
|
|
|
|
| 49 |
let containerRef: HTMLDivElement | null = $state(null);
|
| 50 |
+
let articleRef: HTMLElement | null = $state(null);
|
| 51 |
let selectedText = $state<string | null>(null);
|
| 52 |
let selectedTextPosition = $state<{ y: number } | null>(null);
|
| 53 |
|
|
|
|
| 117 |
updateEdges((currentEdges) => [...currentEdges, ...newEdges]);
|
| 118 |
}
|
| 119 |
|
| 120 |
+
let fitViewTimeout: ReturnType<typeof setTimeout>;
|
| 121 |
+
|
| 122 |
+
$effect(() => {
|
| 123 |
+
if (!articleRef) return;
|
| 124 |
+
|
| 125 |
+
const observer = new ResizeObserver(() => {
|
| 126 |
+
updateNodeInternals(id);
|
| 127 |
+
clearTimeout(fitViewTimeout);
|
| 128 |
+
fitViewTimeout = setTimeout(() => {
|
| 129 |
+
fitView({ duration: 300 });
|
| 130 |
+
}, 150);
|
| 131 |
+
});
|
| 132 |
+
|
| 133 |
+
observer.observe(articleRef);
|
| 134 |
+
return () => {
|
| 135 |
+
observer.disconnect();
|
| 136 |
+
clearTimeout(fitViewTimeout);
|
| 137 |
+
};
|
| 138 |
+
});
|
| 139 |
+
|
| 140 |
$effect(() => {
|
| 141 |
console.log(message);
|
| 142 |
});
|
| 143 |
</script>
|
| 144 |
|
| 145 |
<article
|
| 146 |
+
bind:this={articleRef}
|
| 147 |
class="group/assistant relative flex w-[calc(100dvw-2rem)] flex-col rounded-3xl border border-border bg-background p-5 shadow-lg/5 lg:w-[600px]"
|
|
|
|
| 148 |
>
|
| 149 |
<div class="nodrag pointer-events-auto flex flex-1 cursor-auto flex-col justify-between">
|
| 150 |
<div>
|
src/lib/components/chat/markdown/think/Blockquote.svelte
CHANGED
|
@@ -3,8 +3,6 @@
|
|
| 3 |
let { children }: { children?: Snippet } = $props();
|
| 4 |
</script>
|
| 5 |
|
| 6 |
-
<blockquote
|
| 7 |
-
class="my-2 border-l-2 border-muted-foreground/25 pl-2.5 text-muted-foreground/80 italic"
|
| 8 |
-
>
|
| 9 |
{@render children?.()}
|
| 10 |
</blockquote>
|
|
|
|
| 3 |
let { children }: { children?: Snippet } = $props();
|
| 4 |
</script>
|
| 5 |
|
| 6 |
+
<blockquote class="my-3 border-l-2 border-muted-foreground/30 pl-3 text-muted-foreground italic">
|
|
|
|
|
|
|
| 7 |
{@render children?.()}
|
| 8 |
</blockquote>
|
src/lib/components/chat/markdown/think/Heading.svelte
CHANGED
|
@@ -5,19 +5,19 @@
|
|
| 5 |
</script>
|
| 6 |
|
| 7 |
{#if depth === 1}
|
| 8 |
-
<h1 class="mt-
|
| 9 |
{@render children?.()}
|
| 10 |
</h1>
|
| 11 |
{:else if depth === 2}
|
| 12 |
-
<h2 class="mt-
|
| 13 |
{@render children?.()}
|
| 14 |
</h2>
|
| 15 |
{:else if depth === 3}
|
| 16 |
-
<h3 class="mt-
|
| 17 |
{@render children?.()}
|
| 18 |
</h3>
|
| 19 |
{:else}
|
| 20 |
-
<h4 class="mt-
|
| 21 |
{@render children?.()}
|
| 22 |
</h4>
|
| 23 |
{/if}
|
|
|
|
| 5 |
</script>
|
| 6 |
|
| 7 |
{#if depth === 1}
|
| 8 |
+
<h1 class="mt-4 mb-2 text-2xl font-semibold text-foreground first:mt-0">
|
| 9 |
{@render children?.()}
|
| 10 |
</h1>
|
| 11 |
{:else if depth === 2}
|
| 12 |
+
<h2 class="mt-3.5 mb-2 text-xl font-semibold text-foreground first:mt-0">
|
| 13 |
{@render children?.()}
|
| 14 |
</h2>
|
| 15 |
{:else if depth === 3}
|
| 16 |
+
<h3 class="mt-3 mb-1.5 text-lg font-semibold text-foreground first:mt-0">
|
| 17 |
{@render children?.()}
|
| 18 |
</h3>
|
| 19 |
{:else}
|
| 20 |
+
<h4 class="mt-2.5 mb-1 text-base font-semibold text-foreground first:mt-0">
|
| 21 |
{@render children?.()}
|
| 22 |
</h4>
|
| 23 |
{/if}
|
src/lib/components/flow/FitViewOnResize.svelte
CHANGED
|
@@ -265,7 +265,6 @@
|
|
| 265 |
// ββ Phase 2: assign positions top-down ββββββββββββββββββββββββββ
|
| 266 |
|
| 267 |
const positions = new Map<string, { x: number; y: number }>();
|
| 268 |
-
const rowHeightMap = new Map<string, number>();
|
| 269 |
|
| 270 |
function placeSubtree(nodeId: string, allocX: number, y: number) {
|
| 271 |
const node = nodeMap.get(nodeId);
|
|
@@ -292,19 +291,7 @@
|
|
| 292 |
belowTotalW += extents.get(belowIds[i])!.width;
|
| 293 |
}
|
| 294 |
|
| 295 |
-
|
| 296 |
-
...belowIds.map((id) => {
|
| 297 |
-
const n = nodeMap.get(id);
|
| 298 |
-
return n ? getMeasuredHeight(n) : DEFAULT_HEIGHT;
|
| 299 |
-
})
|
| 300 |
-
);
|
| 301 |
-
for (const cid of belowIds) {
|
| 302 |
-
if (nodeMap.get(cid)?.type === 'assistant') {
|
| 303 |
-
rowHeightMap.set(cid, rowHeight);
|
| 304 |
-
}
|
| 305 |
-
}
|
| 306 |
-
|
| 307 |
-
const childY = y + nodeH + V_SPACING;
|
| 308 |
let childX = allocX + (blockAWidth - belowTotalW) / 2;
|
| 309 |
|
| 310 |
for (const cid of belowIds) {
|
|
@@ -362,9 +349,7 @@
|
|
| 362 |
|
| 363 |
return nodes.map((n) => {
|
| 364 |
const pos = positions.get(n.id) ?? { x: 0, y: 0 };
|
| 365 |
-
|
| 366 |
-
n.type === 'assistant' ? { ...n.data, rowHeight: rowHeightMap.get(n.id) } : n.data;
|
| 367 |
-
return { ...n, position: pos, data };
|
| 368 |
});
|
| 369 |
}
|
| 370 |
|
|
|
|
| 265 |
// ββ Phase 2: assign positions top-down ββββββββββββββββββββββββββ
|
| 266 |
|
| 267 |
const positions = new Map<string, { x: number; y: number }>();
|
|
|
|
| 268 |
|
| 269 |
function placeSubtree(nodeId: string, allocX: number, y: number) {
|
| 270 |
const node = nodeMap.get(nodeId);
|
|
|
|
| 291 |
belowTotalW += extents.get(belowIds[i])!.width;
|
| 292 |
}
|
| 293 |
|
| 294 |
+
const childY = y + nodeH + V_SPACING;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
let childX = allocX + (blockAWidth - belowTotalW) / 2;
|
| 296 |
|
| 297 |
for (const cid of belowIds) {
|
|
|
|
| 349 |
|
| 350 |
return nodes.map((n) => {
|
| 351 |
const pos = positions.get(n.id) ?? { x: 0, y: 0 };
|
| 352 |
+
return { ...n, position: pos };
|
|
|
|
|
|
|
| 353 |
});
|
| 354 |
}
|
| 355 |
|