mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-12 00:17:02 +02:00
ui: tweaks
This commit is contained in:
@@ -6,8 +6,6 @@
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useCallback, useRef, memo } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import {
|
||||
Loader2,
|
||||
PanelLeft,
|
||||
@@ -42,6 +40,7 @@ import {
|
||||
import { formatTimestamp } from "@/hooks/useLocale";
|
||||
import { useGrimoire } from "@/core/state";
|
||||
import { AIProvidersViewer } from "./AIProvidersViewer";
|
||||
import { MarkdownContent } from "./nostr/MarkdownContent";
|
||||
import type { LLMMessage } from "@/types/llm";
|
||||
|
||||
const MOBILE_BREAKPOINT = 768;
|
||||
@@ -92,59 +91,8 @@ const MessageBubble = memo(function MessageBubble({
|
||||
{message.content}
|
||||
</div>
|
||||
) : (
|
||||
<div className="prose prose-invert prose-sm max-w-none [&>*:first-child]:mt-0 [&>*:last-child]:mb-0">
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
p: ({ ...props }) => (
|
||||
<p className="mb-2 last:mb-0" {...props} />
|
||||
),
|
||||
code: ({ className, children, ...props }: any) => {
|
||||
const isBlock = className?.includes("language-");
|
||||
if (isBlock) {
|
||||
return (
|
||||
<pre className="bg-background/50 p-2 rounded text-xs overflow-x-auto my-2">
|
||||
<code {...props}>{children}</code>
|
||||
</pre>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<code
|
||||
className="bg-background/50 px-1 py-0.5 rounded text-xs"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
},
|
||||
pre: ({ children }) => <>{children}</>,
|
||||
ul: ({ ...props }) => (
|
||||
<ul
|
||||
className="list-disc list-inside my-2 space-y-1"
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
ol: ({ ...props }) => (
|
||||
<ol
|
||||
className="list-decimal list-inside my-2 space-y-1"
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
a: ({ href, children, ...props }) => (
|
||||
<a
|
||||
href={href}
|
||||
className="text-accent underline"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{message.content}
|
||||
</ReactMarkdown>
|
||||
<div className="[&>article]:p-0 [&>article]:m-0">
|
||||
<MarkdownContent content={message.content} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -422,8 +370,8 @@ function ChatPanel({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex-1 overflow-y-auto p-3">
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex-1 overflow-y-auto p-3 flex justify-center">
|
||||
<div className="flex flex-col gap-3 w-full max-w-4xl">
|
||||
{displayMessages.length === 0 && !showThinking ? (
|
||||
<div className="flex items-center justify-center h-32 text-muted-foreground text-sm">
|
||||
Start a conversation
|
||||
@@ -440,8 +388,8 @@ function ChatPanel({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t p-2 flex-shrink-0">
|
||||
<div className="flex gap-2 items-end">
|
||||
<div className="border-t p-2 flex-shrink-0 flex justify-center">
|
||||
<div className="flex gap-2 items-end w-full max-w-4xl">
|
||||
<Textarea
|
||||
ref={textareaRef}
|
||||
value={input}
|
||||
|
||||
@@ -332,6 +332,26 @@ export function MarkdownContent({
|
||||
/>
|
||||
),
|
||||
hr: () => <hr className="my-4" />,
|
||||
// Footnotes (remarkGfm feature)
|
||||
sup: ({ children, ...props }) => (
|
||||
<sup className="text-xs text-accent" {...props}>
|
||||
{children}
|
||||
</sup>
|
||||
),
|
||||
section: ({ children, className, ...props }) => {
|
||||
// Style footnotes section at the bottom
|
||||
if (className === "footnotes") {
|
||||
return (
|
||||
<section
|
||||
className="mt-8 pt-4 border-t border-border text-xs text-muted-foreground"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
return <section {...props}>{children}</section>;
|
||||
},
|
||||
}}
|
||||
>
|
||||
{content.replace(/\\n/g, "\n")}
|
||||
|
||||
Reference in New Issue
Block a user