fix(workspace): 修复线程与预览布局问题

This commit is contained in:
肖应宇 2026-03-31 12:35:01 +08:00
parent 8cb49f68b5
commit fbe52a7780
5 changed files with 41 additions and 26 deletions

View File

@ -6,7 +6,6 @@ import { useCallback, useEffect, useMemo, useState } from "react";
import { ConversationEmptyState } from "@/components/ai-elements/conversation"; import { ConversationEmptyState } from "@/components/ai-elements/conversation";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { import {
DevDialog, DevDialog,
DevDialogContent, DevDialogContent,
@ -15,6 +14,7 @@ import {
DevDialogTitle, DevDialogTitle,
} from "@/components/ui/dev-dialog"; } from "@/components/ui/dev-dialog";
import { useSidebar } from "@/components/ui/sidebar"; import { useSidebar } from "@/components/ui/sidebar";
import { Skeleton } from "@/components/ui/skeleton";
import { import {
ArtifactFileDetail, ArtifactFileDetail,
ArtifactFileList, ArtifactFileList,

View File

@ -9,9 +9,9 @@ import {
useRef, useRef,
useState, useState,
} from "react"; } from "react";
import { Toaster } from "@/components/ui/sonner";
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"; import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
import { Toaster } from "@/components/ui/sonner";
import { CommandPalette } from "@/components/workspace/command-palette"; import { CommandPalette } from "@/components/workspace/command-palette";
import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar"; import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar";
import { getLocalSettings, useLocalSettings } from "@/core/settings"; import { getLocalSettings, useLocalSettings } from "@/core/settings";

View File

@ -140,8 +140,8 @@ export const ArtifactContent = ({
className, className,
...props ...props
}: ArtifactContentProps) => ( }: ArtifactContentProps) => (
<div className="min-h-0 flex-1 overflow-auto rounded-[10px]"> <div className="min-h-0 flex-1 overflow-auto rounded-[10px]" {...props} >
{/* <div className={cn("mb-[207px]! p-4", className)} {...props} /> */} {/* <div className={cn("mb-[207px]! p-4", className)} {...props} /> */}
<div className={cn("mb-[150px] min-h-full p-4", className)} {...props} /> {/* <div className={cn("mb-[150px] min-h-full p-4", className)} /> */}
</div> </div>
); );

View File

@ -198,7 +198,7 @@ export function ArtifactFileDetail({
// 给滚动遮挡头部定位relative // 给滚动遮挡头部定位relative
<Artifact <Artifact
className={cn( className={cn(
"bg-background relative overflow-hidden rounded-2xl", "bg-background relative h-full overflow-hidden rounded-2xl",
className, className,
)} )}
> >
@ -480,33 +480,39 @@ export function ArtifactFileDetail({
</ArtifactActions> </ArtifactActions>
</div> </div>
</ArtifactHeader> </ArtifactHeader>
<ArtifactContent className="rounded-b-[10px] bg-white p-0"> <ArtifactContent>
{/* 遮挡多余的滚动顶部 */} {/* 遮挡多余的滚动顶部 */}
{/* <div className="absolute w-[calc(100%-40px)] bg-white z-20 h-5 rounded-t-[10px] top-[57px]"></div> */} {/* <div className="absolute w-[calc(100%-40px)] bg-white z-20 h-5 rounded-t-[10px] top-[57px]"></div> */}
{previewable && {previewable &&
viewMode === "preview" && viewMode === "preview" &&
(language === "markdown" || language === "html") && ( (language === "markdown" || language === "html") && (
<ArtifactFilePreview <div className="min-h-full mb-[150px] rounded-b-[10px] bg-white p-0 mb-0">
content={displayContent} <ArtifactFilePreview
language={language ?? "text"} content={displayContent}
zoom={zoom} language={language ?? "text"}
/> zoom={zoom}
/>
</div>
)} )}
{isCodeFile && viewMode === "code" && ( {isCodeFile && viewMode === "code" && (
<CodeEditor <div className="min-h-full mb-[150px] rounded-b-[10px] bg-white p-0 mb-0">
className="size-full resize-none rounded-none border-none py-[20px]" <CodeEditor
value={displayContent ?? ""} className="size-full resize-none rounded-none border-none py-[20px]"
zoom={zoom} value={displayContent ?? ""}
readonly zoom={zoom}
/> readonly
/>
</div>
)} )}
{!isCodeFile && ( {!isCodeFile && (
<iframe <div className="h-full mb-[150px] ">
className="size-full border-0" <iframe
srcDoc={artifactViewerSrcDoc} className="size-full border-0"
sandbox="allow-same-origin allow-scripts allow-downloads" srcDoc={artifactViewerSrcDoc}
title={`Artifact preview: ${fileName}`} sandbox="allow-same-origin allow-scripts allow-downloads"
/> title={`Artifact preview: ${fileName}`}
/>
</div>
)} )}
</ArtifactContent> </ArtifactContent>
</Artifact> </Artifact>
@ -527,7 +533,7 @@ export function ArtifactFilePreview({
if (language === "markdown") { if (language === "markdown") {
return ( return (
<div <div
className={cn("w-full p-[20px]")} className={cn("w-full mb-[207px] p-[20px]")}
style={{ "--zoom-scale": zoomScale } as React.CSSProperties} style={{ "--zoom-scale": zoomScale } as React.CSSProperties}
> >
<Streamdown <Streamdown
@ -617,6 +623,8 @@ function buildArtifactViewerSrcDoc({
</div>`; </div>`;
})(); })();
const bodyClass = kind === "image" ? "fullbleed" : "";
return `<!doctype html> return `<!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
@ -648,8 +656,12 @@ function buildArtifactViewerSrcDoc({
overflow: hidden; overflow: hidden;
padding: 12px; padding: 12px;
} }
body.fullbleed {
padding: 0;
}
.preview { .preview {
width: 100%; width: 100%;
height: 100%;
border: 1px solid var(--line); border: 1px solid var(--line);
border-radius: var(--radius); border-radius: var(--radius);
background: var(--panel); background: var(--panel);
@ -715,7 +727,7 @@ function buildArtifactViewerSrcDoc({
.link:hover { text-decoration: underline; } .link:hover { text-decoration: underline; }
</style> </style>
</head> </head>
<body> <body class="${bodyClass}">
${content} ${content}
</body> </body>
</html>`; </html>`;

View File

@ -23,7 +23,10 @@ import { useThread } from "../messages/context";
const CLOSE_MODE = { chat: 100, artifacts: 0 }; const CLOSE_MODE = { chat: 100, artifacts: 0 };
const OPEN_MODE = { chat: 60, artifacts: 40 }; const OPEN_MODE = { chat: 60, artifacts: 40 };
const ChatBox: React.FC<{ children: React.ReactNode; threadId: string }> = ({ const ChatBox: React.FC<{
children: React.ReactNode;
threadId: string | undefined;
}> = ({
children, children,
threadId, threadId,
}) => { }) => {