fix: 对话区域显示问题修复

This commit is contained in:
ZyGuo committed 2026-06-02 11:26:28 +08:00
1 parent 2e6eff43ad
commit 49cfc687f9
4 files changed
+76 -32

No files matched your search

@@ -118,6 +118,7 @@ function useArtifactResolver(threadId: string): (path: string) => string {
export function MessageListItem({ export function MessageListItem({
className, className,
fitRowToContent = false,
message, message,
isLoading, isLoading,
threadId, threadId,
@@ -126,6 +127,7 @@ export function MessageListItem({
extraRehypePlugins, extraRehypePlugins,
}: { }: {
className?: string; className?: string;
fitRowToContent?: boolean;
message: Message; message: Message;
isLoading?: boolean; isLoading?: boolean;
threadId: string; threadId: string;
@@ -140,7 +142,12 @@ export function MessageListItem({
""; "";
return ( return (
<AIElementMessage <AIElementMessage
className={cn("group/conversation-message relative w-full", className)} className={cn(
"group/conversation-message relative",
fitRowToContent ? "max-w-full w-fit" : "w-full",
isHuman && fitRowToContent && "ml-auto",
className,
)}
from={isHuman ? "user" : "assistant"} from={isHuman ? "user" : "assistant"}
> >
<MessageContent <MessageContent
@@ -343,16 +350,16 @@ function MessageContent_({
</AIElementMessageResponse> </AIElementMessageResponse>
) : null; ) : null;
return ( return (
<div className={cn("ml-auto flex flex-col gap-2", className)}> <div className={cn("ml-auto flex max-w-full min-w-0 flex-col items-end gap-2", className)}>
{filesList} {filesList}
{parsedHumanContent.pageContext ? (
<EmbeddedPageContextCard pageContext={parsedHumanContent.pageContext} />
) : null}
{messageResponse && ( {messageResponse && (
<AIElementMessageContent className="w-fit"> <AIElementMessageContent className="min-w-0 max-w-full w-fit">
{messageResponse} {messageResponse}
</AIElementMessageContent> </AIElementMessageContent>
)} )}
{parsedHumanContent.pageContext ? (
<EmbeddedPageContextCard pageContext={parsedHumanContent.pageContext} />
) : null}
<MessageTimeStamp time={messageTime} align="right" /> <MessageTimeStamp time={messageTime} align="right" />
</div> </div>
); );
@@ -388,29 +395,18 @@ function EmbeddedPageContextCard({
}: { }: {
pageContext: EmbeddedPageContext; pageContext: EmbeddedPageContext;
}) { }) {
const previewText = [pageContext.title, pageContext.url, pageContext.content]
.filter(Boolean)
.join(" | ");
return ( return (
<div className="bg-muted/70 ml-auto flex max-w-sm flex-col gap-2 rounded-2xl border px-3 py-2 text-sm shadow-sm"> <div className="bg-muted/70 ml-auto flex w-fit min-w-0 max-w-[min(24rem,calc(100vw-2rem),100%)] flex-col gap-2 rounded-2xl border px-3 py-2 text-sm shadow-sm">
{pageContext.title ? ( <div
<div className="truncate font-medium" title={pageContext.title}> className="text-muted-foreground line-clamp-2 min-w-0 [overflow-wrap:anywhere] break-words text-xs"
{pageContext.title} title={previewText}
</div> >
) : null} {previewText}
{pageContext.url ? ( </div>
<a
className="text-muted-foreground block truncate text-xs underline underline-offset-2"
href={pageContext.url}
target="_blank"
rel="noopener noreferrer"
title={pageContext.url}
>
{pageContext.url}
</a>
) : null}
{pageContext.content ? (
<div className="text-muted-foreground truncate text-xs" title={pageContext.content}>
{pageContext.content}
</div>
) : null}
</div> </div>
); );
} }
@@ -506,7 +502,7 @@ function isImageFile(filename: string): boolean {
* Format bytes to human-readable size string * Format bytes to human-readable size string
*/ */
function formatBytes(bytes: number): string { function formatBytes(bytes: number): string {
if (bytes === 0) return "—"; if (bytes === 0) return "0 B";
const kb = bytes / 1024; const kb = bytes / 1024;
if (kb < 1024) return `${kb.toFixed(1)} KB`; if (kb < 1024) return `${kb.toFixed(1)} KB`;
return `${(kb / 1024).toFixed(1)} MB`; return `${(kb / 1024).toFixed(1)} MB`;
@@ -795,3 +791,4 @@ function groupDisplaySources(sources: RuntimeDisplaySource[]) {
function normalizeName(name: string) { function normalizeName(name: string) {
return name.toLowerCase().replace(/[^a-z0-9]+/g, ""); return name.toLowerCase().replace(/[^a-z0-9]+/g, "");
} }
@@ -52,6 +52,8 @@ export const MESSAGE_LIST_FOLLOWUPS_EXTRA_PADDING_BOTTOM = 80;
export function MessageList({ export function MessageList({
className, className,
contentClassName,
fitMessageRowsToContent = false,
threadId, threadId,
thread, thread,
paddingBottom = MESSAGE_LIST_DEFAULT_PADDING_BOTTOM, paddingBottom = MESSAGE_LIST_DEFAULT_PADDING_BOTTOM,
@@ -62,6 +64,8 @@ export function MessageList({
onSetupAgentReject, onSetupAgentReject,
}: { }: {
className?: string; className?: string;
contentClassName?: string;
fitMessageRowsToContent?: boolean;
threadId: string; threadId: string;
thread: BaseStream<AgentThreadState>; thread: BaseStream<AgentThreadState>;
paddingBottom?: number; paddingBottom?: number;
@@ -217,7 +221,12 @@ export function MessageList({
<Conversation <Conversation
className={cn("flex size-full flex-col justify-center", className)} className={cn("flex size-full flex-col justify-center", className)}
> >
<ConversationContent className="mx-auto w-full max-w-(--container-width-lg) gap-8 pt-12"> <ConversationContent
className={cn(
"mx-auto w-full max-w-(--container-width-lg) gap-8 pt-12",
contentClassName,
)}
>
<MessageMetricsProvider messages={messages} isLoading={thread.isLoading}> <MessageMetricsProvider messages={messages} isLoading={thread.isLoading}>
{groupMessages(messages, (group) => { {groupMessages(messages, (group) => {
if (group.type === "human" || group.type === "assistant") { if (group.type === "human" || group.type === "assistant") {
@@ -235,6 +244,7 @@ export function MessageList({
return ( return (
<MessageListItem <MessageListItem
key={`${group.id}/${msg.id}`} key={`${group.id}/${msg.id}`}
fitRowToContent={fitMessageRowsToContent}
message={msg} message={msg}
isLoading={thread.isLoading} isLoading={thread.isLoading}
threadId={threadId} threadId={threadId}
+3 -2
View File
@@ -313,10 +313,11 @@ export default function IframeChatPage() {
</div> </div>
</header> </header>
<main className="flex min-h-0 max-w-full grow flex-col overflow-hidden"> <main className="flex min-h-0 max-w-full grow flex-col overflow-hidden">
<div className="flex size-full justify-center"> <div className="flex size-full min-w-0">
{!isLandingState && ( {!isLandingState && (
<MessageList <MessageList
className={cn("size-full", "pt-10")} className={cn("size-full", "pt-10")}
contentClassName="mx-0 max-w-full px-3 sm:px-4"
threadId={threadId} threadId={threadId}
thread={thread} thread={thread}
paddingBottom={messageListPaddingBottom} paddingBottom={messageListPaddingBottom}
@@ -332,7 +333,7 @@ export default function IframeChatPage() {
isLandingState && "-translate-y-[calc(50vh-96px)]", isLandingState && "-translate-y-[calc(50vh-96px)]",
isLandingState isLandingState
? "max-w-(--container-width-md)" ? "max-w-(--container-width-md)"
: "max-w-(--container-width-lg)", : "max-w-full",
)} )}
> >
<div className="absolute -top-4 right-0 left-0 z-0"> <div className="absolute -top-4 right-0 left-0 z-0">
@@ -43,6 +43,14 @@ import RoundtablePlanningPage from '@/roundtable-planning/pages/RoundtablePlanni
import '@/roundtable-planning/styles/roundtable-planning.css'; import '@/roundtable-planning/styles/roundtable-planning.css';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
function isInIframe(): boolean {
try {
return window.self !== window.top;
} catch {
return true;
}
}
export function WorkspaceLayout({ export function WorkspaceLayout({
children, children,
pageSidebarCollapsed, pageSidebarCollapsed,
@@ -116,6 +124,30 @@ export function ChatRuntime({ children }: { children: ReactNode }) {
); );
} }
function NewChatEntryRoute({
layoutProps,
}: {
layoutProps: {
pageSidebarCollapsed: boolean;
pageSidebarHidden: boolean;
headerHidden: boolean;
compactWorkspaceSidebar: boolean;
pageSidebarDark: boolean;
};
}) {
if (isInIframe()) {
return <Navigate to="/page/workspace/chats_iframe/new" replace />;
}
return (
<WorkspaceLayout {...layoutProps}>
<ChatRuntime>
<ChatPage />
</ChatRuntime>
</WorkspaceLayout>
);
}
export default function WorkspaceRoutes({ export default function WorkspaceRoutes({
pageSidebarCollapsed = false, pageSidebarCollapsed = false,
pageSidebarHidden = false, pageSidebarHidden = false,
@@ -149,6 +181,10 @@ export default function WorkspaceRoutes({
</WorkspaceLayout> </WorkspaceLayout>
} }
/> />
<Route
path="chats/new"
element={<NewChatEntryRoute layoutProps={layoutProps} />}
/>
<Route <Route
path="chats/:thread_id" path="chats/:thread_id"
element={ element={