mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 16:23:41 +08:00 
			
		
		
		
	feat: artifacts style
This commit is contained in:
		@@ -1,8 +1,26 @@
 | 
			
		||||
.artifact {
 | 
			
		||||
  display: block;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  &-header {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    height: 36px;
 | 
			
		||||
    padding: 20px;
 | 
			
		||||
    background: var(--second);
 | 
			
		||||
  }
 | 
			
		||||
  &-title {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    font-size: 24px;
 | 
			
		||||
  }
 | 
			
		||||
  &-content {
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
    padding: 0 20px 20px 20px;
 | 
			
		||||
    background-color: var(--second);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.artifact-iframe {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ import styles from "./artifact.module.scss";
 | 
			
		||||
export function HTMLPreview(props: {
 | 
			
		||||
  code: string;
 | 
			
		||||
  autoHeight?: boolean;
 | 
			
		||||
  height?: number;
 | 
			
		||||
  height?: number | string;
 | 
			
		||||
  onLoad?: (title?: string) => void;
 | 
			
		||||
}) {
 | 
			
		||||
  const ref = useRef<HTMLIFrameElement>(null);
 | 
			
		||||
@@ -185,7 +185,6 @@ export function Artifact() {
 | 
			
		||||
  const [code, setCode] = useState("");
 | 
			
		||||
  const [loading, setLoading] = useState(true);
 | 
			
		||||
  const [fileName, setFileName] = useState("");
 | 
			
		||||
  const { height } = useWindowSize();
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (id) {
 | 
			
		||||
@@ -205,27 +204,21 @@ export function Artifact() {
 | 
			
		||||
  }, [id]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={styles.artifact}>
 | 
			
		||||
      <div
 | 
			
		||||
        style={{
 | 
			
		||||
          height: 36,
 | 
			
		||||
          display: "flex",
 | 
			
		||||
          alignItems: "center",
 | 
			
		||||
          padding: 12,
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
    <div className={styles["artifact"]}>
 | 
			
		||||
      <div className={styles["artifact-header"]}>
 | 
			
		||||
        <a href={REPO_URL} target="_blank" rel="noopener noreferrer">
 | 
			
		||||
          <IconButton bordered icon={<GithubIcon />} shadow />
 | 
			
		||||
        </a>
 | 
			
		||||
        <div style={{ flex: 1, textAlign: "center" }}>NextChat Artifact</div>
 | 
			
		||||
        <div className={styles["artifact-title"]}>NextChat Artifact</div>
 | 
			
		||||
        <ArtifactShareButton id={id} getCode={() => code} fileName={fileName} />
 | 
			
		||||
      </div>
 | 
			
		||||
      <div className={styles["artifact-content"]}>
 | 
			
		||||
        {loading && <Loading />}
 | 
			
		||||
        {code && (
 | 
			
		||||
          <HTMLPreview
 | 
			
		||||
            code={code}
 | 
			
		||||
            autoHeight={false}
 | 
			
		||||
          height={height - 36}
 | 
			
		||||
            height={"100%"}
 | 
			
		||||
            onLoad={(title) => {
 | 
			
		||||
              setFileName(title as string);
 | 
			
		||||
              setLoading(false);
 | 
			
		||||
@@ -233,5 +226,6 @@ export function Artifact() {
 | 
			
		||||
          />
 | 
			
		||||
        )}
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -641,12 +641,13 @@ export function ChatActions(props: {
 | 
			
		||||
          ]}
 | 
			
		||||
          onClose={() => setShowPluginSelector(false)}
 | 
			
		||||
          onSelection={(s) => {
 | 
			
		||||
            if (s.length === 0) return;
 | 
			
		||||
            const plugin = s[0];
 | 
			
		||||
            chatStore.updateCurrentSession((session) => {
 | 
			
		||||
              session.mask.plugin = s;
 | 
			
		||||
            });
 | 
			
		||||
            if (plugin) {
 | 
			
		||||
              showToast(plugin);
 | 
			
		||||
            }
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
      )}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,8 @@ import React from "react";
 | 
			
		||||
import { useDebouncedCallback } from "use-debounce";
 | 
			
		||||
import { showImageModal, FullScreen } from "./ui-lib";
 | 
			
		||||
import { ArtifactShareButton, HTMLPreview } from "./artifact";
 | 
			
		||||
 | 
			
		||||
import { Plugin } from "../constant";
 | 
			
		||||
import { useChatStore } from "../store";
 | 
			
		||||
export function Mermaid(props: { code: string }) {
 | 
			
		||||
  const ref = useRef<HTMLDivElement>(null);
 | 
			
		||||
  const [hasError, setHasError] = useState(false);
 | 
			
		||||
@@ -67,6 +68,9 @@ export function PreCode(props: { children: any }) {
 | 
			
		||||
  const [mermaidCode, setMermaidCode] = useState("");
 | 
			
		||||
  const [htmlCode, setHtmlCode] = useState("");
 | 
			
		||||
  const { height } = useWindowSize();
 | 
			
		||||
  const chatStore = useChatStore();
 | 
			
		||||
  const session = chatStore.currentSession();
 | 
			
		||||
  const plugins = session.mask?.plugin;
 | 
			
		||||
 | 
			
		||||
  const renderArtifacts = useDebouncedCallback(() => {
 | 
			
		||||
    if (!ref.current) return;
 | 
			
		||||
@@ -87,6 +91,11 @@ export function PreCode(props: { children: any }) {
 | 
			
		||||
    // eslint-disable-next-line react-hooks/exhaustive-deps
 | 
			
		||||
  }, [refText]);
 | 
			
		||||
 | 
			
		||||
  const enableArtifacts = useMemo(
 | 
			
		||||
    () => plugins?.includes(Plugin.Artifact),
 | 
			
		||||
    [plugins],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <pre ref={ref}>
 | 
			
		||||
@@ -104,7 +113,7 @@ export function PreCode(props: { children: any }) {
 | 
			
		||||
      {mermaidCode.length > 0 && (
 | 
			
		||||
        <Mermaid code={mermaidCode} key={mermaidCode} />
 | 
			
		||||
      )}
 | 
			
		||||
      {htmlCode.length > 0 && (
 | 
			
		||||
      {htmlCode.length > 0 && enableArtifacts && (
 | 
			
		||||
        <FullScreen className="no-dark html" right={70}>
 | 
			
		||||
          <ArtifactShareButton
 | 
			
		||||
            style={{ position: "absolute", right: 20, top: 10 }}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user