From 21ef9a4567ec4f61a4d0db26f0e23815bb0f7924 Mon Sep 17 00:00:00 2001
From: Dogtiti <499960698@qq.com>
Date: Thu, 25 Jul 2024 17:37:21 +0800
Subject: [PATCH 1/2] feat: artifacts style
---
.gitignore | 2 ++
app/components/artifact.module.scss | 12 +++++++++
app/components/artifact.tsx | 25 +++++++++---------
app/components/markdown.tsx | 4 +--
app/components/ui-lib.module.scss | 1 +
app/components/ui-lib.tsx | 39 +++++++++++++++++++++--------
6 files changed, 58 insertions(+), 25 deletions(-)
create mode 100644 app/components/artifact.module.scss
diff --git a/.gitignore b/.gitignore
index a24c6e047..2ff556f64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,5 @@ dev
*.key
*.key.pub
+
+masks.json
diff --git a/app/components/artifact.module.scss b/app/components/artifact.module.scss
new file mode 100644
index 000000000..1e166f418
--- /dev/null
+++ b/app/components/artifact.module.scss
@@ -0,0 +1,12 @@
+.artifact {
+ display: block;
+ width: 100%;
+ height: 100%;
+ position: relative;
+}
+
+.artifact-iframe {
+ width: 100%;
+ border: var(--border-in-light);
+ border-radius: 6px;
+}
diff --git a/app/components/artifact.tsx b/app/components/artifact.tsx
index c06573b09..64a6ad652 100644
--- a/app/components/artifact.tsx
+++ b/app/components/artifact.tsx
@@ -13,6 +13,7 @@ import { Modal, showToast } from "./ui-lib";
import { copyToClipboard, downloadAs } from "../utils";
import { Path, ApiPath, REPO_URL } from "@/app/constant";
import { Loading } from "./home";
+import styles from "./artifact.module.scss";
export function HTMLPreview(props: {
code: string;
@@ -61,17 +62,22 @@ export function HTMLPreview(props: {
return props.code + script;
}, [props.code]);
+ const handleOnLoad = () => {
+ if (props?.onLoad) {
+ props.onLoad(title);
+ }
+ };
+
return (
+ onLoad={handleOnLoad}
+ />
);
}
@@ -186,14 +192,7 @@ export function Artifact() {
}, [id]);
return (
-
+
)}
{htmlCode.length > 0 && (
-
+
htmlCode}
/>
void;
+ onClick?: (e: React.MouseEvent) => void;
}) {
return (
(props: {
onClose?: () => void;
multiple?: boolean;
}) {
+ const [selectedValues, setSelectedValues] = useState
(
+ Array.isArray(props.defaultSelectedValue)
+ ? props.defaultSelectedValue
+ : props.defaultSelectedValue !== undefined
+ ? [props.defaultSelectedValue]
+ : [],
+ );
+
+ const handleSelection = (
+ e: React.MouseEvent,
+ value: T,
+ ) => {
+ if (props.multiple) {
+ e.stopPropagation();
+ const newSelectedValues = selectedValues.includes(value)
+ ? selectedValues.filter((v) => v !== value)
+ : [...selectedValues, value];
+ setSelectedValues(newSelectedValues);
+ props.onSelection?.(newSelectedValues);
+ } else {
+ setSelectedValues([value]);
+ props.onSelection?.([value]);
+ props.onClose?.();
+ }
+ };
+
return (
props.onClose?.()}>
{props.items.map((item, i) => {
- const selected = props.multiple
- ? // @ts-ignore
- props.defaultSelectedValue?.includes(item.value)
- : props.defaultSelectedValue === item.value;
+ const selected = selectedValues.includes(item.value);
return (
{
- props.onSelection?.([item.value]);
- props.onClose?.();
- }}
+ onClick={(e) => handleSelection(e, item.value)}
>
{selected ? (
(props: {
);
}
-
export function FullScreen(props: any) {
const { children, right = 10, top = 10, ...rest } = props;
const ref = useRef();
From c27ef6ffbf94be6bab2f6ba7cc9237b1125627a2 Mon Sep 17 00:00:00 2001
From: Dogtiti <499960698@qq.com>
Date: Thu, 25 Jul 2024 23:29:29 +0800
Subject: [PATCH 2/2] feat: artifacts style
---
app/components/artifact.module.scss | 22 +++++++++++++--
app/components/artifact.tsx | 42 +++++++++++++----------------
app/components/chat.tsx | 5 ++--
app/components/markdown.tsx | 13 +++++++--
4 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/app/components/artifact.module.scss b/app/components/artifact.module.scss
index 1e166f418..2909008b0 100644
--- a/app/components/artifact.module.scss
+++ b/app/components/artifact.module.scss
@@ -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 {
diff --git a/app/components/artifact.tsx b/app/components/artifact.tsx
index b378cba37..3006fe012 100644
--- a/app/components/artifact.tsx
+++ b/app/components/artifact.tsx
@@ -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(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,33 +204,28 @@ export function Artifact() {
}, [id]);
return (
-
-
+
+
} shadow />
-
NextChat Artifact
+
NextChat Artifact
code} fileName={fileName} />
- {loading &&
}
- {code && (
-
{
- setFileName(title as string);
- setLoading(false);
- }}
- />
- )}
+
+ {loading && }
+ {code && (
+ {
+ setFileName(title as string);
+ setLoading(false);
+ }}
+ />
+ )}
+
);
}
diff --git a/app/components/chat.tsx b/app/components/chat.tsx
index 6bfd99b53..33956e6bc 100644
--- a/app/components/chat.tsx
+++ b/app/components/chat.tsx
@@ -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;
});
- showToast(plugin);
+ if (plugin) {
+ showToast(plugin);
+ }
}}
/>
)}
diff --git a/app/components/markdown.tsx b/app/components/markdown.tsx
index 219c4c868..36c742902 100644
--- a/app/components/markdown.tsx
+++ b/app/components/markdown.tsx
@@ -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
(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 (
<>
@@ -104,7 +113,7 @@ export function PreCode(props: { children: any }) {
{mermaidCode.length > 0 && (
)}
- {htmlCode.length > 0 && (
+ {htmlCode.length > 0 && enableArtifacts && (