merge main

This commit is contained in:
bracesproul
2025-03-05 10:29:51 -08:00
6 changed files with 2535 additions and 4032 deletions

View File

@@ -10,6 +10,7 @@ import {
SheetHeader,
SheetTitle,
} from "@/components/ui/sheet";
import { Skeleton } from "@/components/ui/skeleton";
function ThreadList({
threads,
@@ -55,8 +56,19 @@ function ThreadList({
);
}
function ThreadHistoryLoading() {
return (
<div className="h-full flex flex-col gap-2 items-start justify-start overflow-y-scroll [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-gray-300 [&::-webkit-scrollbar-track]:bg-transparent">
{Array.from({ length: 30 }).map((_, i) => (
<Skeleton key={`skeleton-${i}`} className="w-[264px] h-10" />
))}
</div>
);
}
export default function ThreadHistory() {
const [threads, setThreads] = useState<Thread[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [chatHistoryOpen, setChatHistoryOpen] = useQueryParam(
"chatHistoryOpen",
BooleanParam,
@@ -65,14 +77,19 @@ export default function ThreadHistory() {
const { getThreads } = useThreads();
useEffect(() => {
getThreads().then(setThreads).catch(console.error);
if (typeof window === "undefined") return;
setLoading(true);
getThreads()
.then(setThreads)
.catch(console.error)
.finally(() => setLoading(false));
}, []);
return (
<>
<div className="hidden lg:flex flex-col border-r-[1px] border-slate-300 items-start justify-start gap-6 h-screen w-[300px] shrink-0 px-2 py-4 shadow-inner-right">
<h1 className="text-2xl font-medium pl-4">Thread History</h1>
<ThreadList threads={threads} />
{loading ? <ThreadHistoryLoading /> : <ThreadList threads={threads} />}
</div>
<Sheet open={!!chatHistoryOpen} onOpenChange={setChatHistoryOpen}>
<SheetContent side="left" className="lg:hidden flex">

View File

@@ -9,15 +9,24 @@ import {
} from "@assistant-ui/react-markdown";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import rehypeKatex from "rehype-katex";
import remarkMath from "remark-math";
import { FC, memo, useState } from "react";
import { CheckIcon, CopyIcon } from "lucide-react";
import { SyntaxHighlighter } from "@/components/thread/syntax-highlighter";
import { TooltipIconButton } from "@/components/thread/tooltip-icon-button";
import { cn } from "@/lib/utils";
import "katex/dist/katex.min.css";
const MarkdownTextImpl = ({ children }: { children: string }) => {
return (
<ReactMarkdown remarkPlugins={[remarkGfm]} components={defaultComponents}>
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeKatex]}
components={defaultComponents}
>
{children}
</ReactMarkdown>
);
@@ -195,7 +204,7 @@ const defaultComponents = memoizeMarkdownComponents({
pre: ({ className, ...props }) => (
<pre
className={cn(
"overflow-x-auto rounded-b-lg bg-black p-4 text-white",
"overflow-x-auto rounded-b-lg bg-black p-4 text-white max-w-4xl",
className,
)}
{...props}
@@ -211,4 +220,5 @@ const defaultComponents = memoizeMarkdownComponents({
);
},
CodeHeader,
SyntaxHighlighter,
});

View File

@@ -0,0 +1,24 @@
import { PrismAsyncLight } from "react-syntax-highlighter";
import { makePrismAsyncLightSyntaxHighlighter } from "@assistant-ui/react-syntax-highlighter";
import tsx from "react-syntax-highlighter/dist/esm/languages/prism/tsx";
import python from "react-syntax-highlighter/dist/esm/languages/prism/python";
import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
// register languages you want to support
PrismAsyncLight.registerLanguage("js", tsx);
PrismAsyncLight.registerLanguage("jsx", tsx);
PrismAsyncLight.registerLanguage("ts", tsx);
PrismAsyncLight.registerLanguage("tsx", tsx);
PrismAsyncLight.registerLanguage("python", python);
export const SyntaxHighlighter = makePrismAsyncLightSyntaxHighlighter({
style: coldarkDark,
customStyle: {
margin: 0,
width: "100%",
background: "transparent",
padding: "1.5rem 1rem",
},
});

View File

@@ -0,0 +1,13 @@
import { cn } from "@/lib/utils";
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="skeleton"
className={cn("bg-primary/10 animate-pulse rounded-md", className)}
{...props}
/>
);
}
export { Skeleton };