@malette/agent-sdk 0.1.3-beta.11 → 0.1.3-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +854 -116
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +855 -117
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +11 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { create } from 'zustand';
|
|
|
4
4
|
import { devtools } from 'zustand/middleware';
|
|
5
5
|
import * as React16 from 'react';
|
|
6
6
|
import React16__default, { createContext, memo, useState, useEffect, useCallback, useMemo, useRef, useImperativeHandle, useContext } from 'react';
|
|
7
|
-
import { Image, X, Check, Copy, FileText, Code2, FileJson, FileCode, CheckCheck, Eye, ExternalLink, Download, ChevronUp, ChevronDown, Maximize2, Loader2, Clock, Sparkles, Bot, AlertTriangle, Play, Pencil, AlertCircle, Square, RotateCcw, SkipForward, Zap, ChevronRight, CheckCircle2, XCircle, Ban, Users, Volume2, Pause, VolumeX, Lightbulb, RefreshCw, BookmarkPlus, Trash2, PenLine, ImageIcon, GripVertical, Minimize2, Smartphone, Tablet, Monitor, Globe, FileImage, Minus, Plus, Maximize, Video, ChevronLeft, LayoutGrid, Undo2, Redo2, Save, PanelLeft, ArrowLeft, Settings, UserCheck, ShieldCheck, Shield, User, Lock, Share2, PanelLeftClose, Search, MessageSquare, Unlink, ImagePlus, BookOpen, Send, HelpCircle, Calendar, Link, Tag, EyeOff, Folder, Wand2, Mic, CheckCircle, ListOrdered, FileEdit, Edit, ArrowRight } from 'lucide-react';
|
|
7
|
+
import { Image, X, Check, Copy, FileText, Code2, FileJson, FileCode, CheckCheck, Eye, ExternalLink, Download, ChevronUp, ChevronDown, Maximize2, Loader2, Clock, Sparkles, Bot, AlertTriangle, Play, Pencil, AlertCircle, Square, RotateCcw, SkipForward, Zap, ChevronRight, CheckCircle2, XCircle, Ban, Users, Volume2, Pause, VolumeX, Lightbulb, RefreshCw, BookmarkPlus, Trash2, PenLine, ImageIcon, GripVertical, Minimize2, Smartphone, Tablet, Monitor, Globe, FileImage, Minus, Plus, Maximize, Video, ChevronLeft, LayoutGrid, Undo2, Redo2, Save, PanelLeft, ArrowLeft, Settings, UserCheck, ShieldCheck, Shield, User, Lock, Share2, PanelLeftClose, Search, MessageSquare, Unlink, ImagePlus, BookOpen, Send, HelpCircle, Calendar, Link, Tag, EyeOff, Folder, Wand2, Mic, CheckCircle, ListOrdered, FileEdit, Edit, MonitorPlay, ArrowRight } from 'lucide-react';
|
|
8
8
|
import ReactMarkdown from 'react-markdown';
|
|
9
9
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
import ReactDOM, { createPortal } from 'react-dom';
|
|
@@ -470,10 +470,16 @@ var artifactService = {
|
|
|
470
470
|
/**
|
|
471
471
|
* 更新产物内容(用户编辑后保存)
|
|
472
472
|
*/
|
|
473
|
-
updateContent: async (artifactId, content) => {
|
|
473
|
+
updateContent: async (artifactId, content, options) => {
|
|
474
474
|
return fetcher(`${API_BASE}/artifacts/${artifactId}/content`, {
|
|
475
475
|
method: "PUT",
|
|
476
|
-
body: JSON.stringify({
|
|
476
|
+
body: JSON.stringify({
|
|
477
|
+
artifactId,
|
|
478
|
+
content,
|
|
479
|
+
...options?.type && { type: options.type },
|
|
480
|
+
...options?.language !== void 0 && { language: options.language },
|
|
481
|
+
...options?.title !== void 0 && { title: options.title }
|
|
482
|
+
})
|
|
477
483
|
});
|
|
478
484
|
},
|
|
479
485
|
/**
|
|
@@ -1678,6 +1684,25 @@ var useAgentStore = create()(
|
|
|
1678
1684
|
false,
|
|
1679
1685
|
"updateArtifactVisibility"
|
|
1680
1686
|
),
|
|
1687
|
+
updateArtifactType: (artifactId, type, language) => set(
|
|
1688
|
+
(state) => {
|
|
1689
|
+
const existing = state.artifacts[artifactId];
|
|
1690
|
+
if (!existing) return state;
|
|
1691
|
+
return {
|
|
1692
|
+
artifacts: {
|
|
1693
|
+
...state.artifacts,
|
|
1694
|
+
[artifactId]: {
|
|
1695
|
+
...existing,
|
|
1696
|
+
type,
|
|
1697
|
+
language: language ?? existing.language,
|
|
1698
|
+
gmtModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
};
|
|
1702
|
+
},
|
|
1703
|
+
false,
|
|
1704
|
+
"updateArtifactType"
|
|
1705
|
+
),
|
|
1681
1706
|
// ============ 复合操作 ============
|
|
1682
1707
|
startNewChat: (sessionId) => {
|
|
1683
1708
|
set(
|
|
@@ -7780,6 +7805,104 @@ var resolveAssetForDisplay = async (asset, config) => {
|
|
|
7780
7805
|
}
|
|
7781
7806
|
return null;
|
|
7782
7807
|
};
|
|
7808
|
+
var resolveHtmlAssetUrls = (html2) => {
|
|
7809
|
+
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
7810
|
+
const resolveSrc = (src, isVideo) => {
|
|
7811
|
+
if (!src.trim()) return src;
|
|
7812
|
+
if (/^(data:|blob:|javascript:|#)/i.test(src)) return src;
|
|
7813
|
+
if (src.includes("${")) return src;
|
|
7814
|
+
if (/^https?:/i.test(src)) {
|
|
7815
|
+
if (src.includes("industryai")) {
|
|
7816
|
+
return src.split("?")[0];
|
|
7817
|
+
}
|
|
7818
|
+
return src;
|
|
7819
|
+
}
|
|
7820
|
+
const resolved = isVideo ? getHDImageUrl(src) : getImageUrl(src);
|
|
7821
|
+
return resolved.startsWith("http") ? resolved : `${origin}${resolved}`;
|
|
7822
|
+
};
|
|
7823
|
+
const processHtmlPart = (part) => {
|
|
7824
|
+
let result = part.replace(
|
|
7825
|
+
/(<(?:img|video|source)\s[^>]*?\bsrc\s*=\s*["'])([^"']*)(["'])/gi,
|
|
7826
|
+
(match, prefix, src, suffix) => {
|
|
7827
|
+
const tagMatch = match.match(/^<(\w+)/i);
|
|
7828
|
+
const tag = tagMatch?.[1]?.toLowerCase() ?? "";
|
|
7829
|
+
const isVideo = tag === "video" || tag === "source";
|
|
7830
|
+
return `${prefix}${resolveSrc(src, isVideo)}${suffix}`;
|
|
7831
|
+
}
|
|
7832
|
+
);
|
|
7833
|
+
result = result.replace(
|
|
7834
|
+
/(<video\s[^>]*?\bposter\s*=\s*["'])([^"']*)(["'])/gi,
|
|
7835
|
+
(match, prefix, src, suffix) => `${prefix}${resolveSrc(src, false)}${suffix}`
|
|
7836
|
+
);
|
|
7837
|
+
return result;
|
|
7838
|
+
};
|
|
7839
|
+
const parts = html2.split(/(<script\b[\s\S]*?<\/script>)/gi);
|
|
7840
|
+
return parts.map((part, i) => i % 2 === 1 ? part : processHtmlPart(part)).join("");
|
|
7841
|
+
};
|
|
7842
|
+
var resolveHtmlAssetUrlsAsync = async (html2, config) => {
|
|
7843
|
+
if (!config?.asset) return resolveHtmlAssetUrls(html2);
|
|
7844
|
+
const srcPattern = /(<(?:img|video|source)\s[^>]*?\bsrc\s*=\s*["'])([^"']*)(["'])/gi;
|
|
7845
|
+
const posterPattern = /(<video\s[^>]*?\bposter\s*=\s*["'])([^"']*)(["'])/gi;
|
|
7846
|
+
const scriptSplitPattern = /(<script\b[\s\S]*?<\/script>)/gi;
|
|
7847
|
+
const parts = html2.split(scriptSplitPattern);
|
|
7848
|
+
const nonScriptHtml = parts.filter((_, i) => i % 2 === 0).join("");
|
|
7849
|
+
const urlsToResolve = /* @__PURE__ */ new Map();
|
|
7850
|
+
const collectUrl = (src) => {
|
|
7851
|
+
if (!src.trim()) return;
|
|
7852
|
+
if (/^(data:|blob:|javascript:|#)/i.test(src)) return;
|
|
7853
|
+
if (src.includes("${")) return;
|
|
7854
|
+
urlsToResolve.set(src, src);
|
|
7855
|
+
};
|
|
7856
|
+
let match;
|
|
7857
|
+
const srcRe = new RegExp(srcPattern.source, srcPattern.flags);
|
|
7858
|
+
while ((match = srcRe.exec(nonScriptHtml)) !== null) {
|
|
7859
|
+
collectUrl(match[2]);
|
|
7860
|
+
}
|
|
7861
|
+
const posterRe = new RegExp(posterPattern.source, posterPattern.flags);
|
|
7862
|
+
while ((match = posterRe.exec(nonScriptHtml)) !== null) {
|
|
7863
|
+
collectUrl(match[2]);
|
|
7864
|
+
}
|
|
7865
|
+
await Promise.all(
|
|
7866
|
+
Array.from(urlsToResolve.keys()).map(async (src) => {
|
|
7867
|
+
const tagMatch = nonScriptHtml.match(
|
|
7868
|
+
new RegExp(`<(img|video|source)[^>]*(?:src|poster)=["']${src.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}["']`, "i")
|
|
7869
|
+
);
|
|
7870
|
+
const tag = tagMatch?.[1]?.toLowerCase() ?? "";
|
|
7871
|
+
const isVideo = tag === "video" || tag === "source";
|
|
7872
|
+
const type = isVideo ? "video" : "image";
|
|
7873
|
+
const isHttp = /^https?:/i.test(src);
|
|
7874
|
+
const asset = createAssetFromSource({
|
|
7875
|
+
fileId: !isHttp ? src : void 0,
|
|
7876
|
+
fileUrl: isHttp ? src : void 0,
|
|
7877
|
+
type
|
|
7878
|
+
});
|
|
7879
|
+
if (!asset) return;
|
|
7880
|
+
const resolved = await resolveAssetForDisplay(asset, config);
|
|
7881
|
+
if (resolved) {
|
|
7882
|
+
urlsToResolve.set(src, resolved.url);
|
|
7883
|
+
}
|
|
7884
|
+
})
|
|
7885
|
+
);
|
|
7886
|
+
const processedParts = parts.map((part, i) => {
|
|
7887
|
+
if (i % 2 === 1) return part;
|
|
7888
|
+
let result = part.replace(
|
|
7889
|
+
/(<(?:img|video|source)\s[^>]*?\bsrc\s*=\s*["'])([^"']*)(["'])/gi,
|
|
7890
|
+
(m, prefix, src, suffix) => {
|
|
7891
|
+
const resolved = urlsToResolve.get(src);
|
|
7892
|
+
return resolved && resolved !== src ? `${prefix}${resolved}${suffix}` : m;
|
|
7893
|
+
}
|
|
7894
|
+
);
|
|
7895
|
+
result = result.replace(
|
|
7896
|
+
/(<video\s[^>]*?\bposter\s*=\s*["'])([^"']*)(["'])/gi,
|
|
7897
|
+
(m, prefix, src, suffix) => {
|
|
7898
|
+
const resolved = urlsToResolve.get(src);
|
|
7899
|
+
return resolved && resolved !== src ? `${prefix}${resolved}${suffix}` : m;
|
|
7900
|
+
}
|
|
7901
|
+
);
|
|
7902
|
+
return result;
|
|
7903
|
+
});
|
|
7904
|
+
return processedParts.join("");
|
|
7905
|
+
};
|
|
7783
7906
|
var ComponentContext = createContext(void 0);
|
|
7784
7907
|
var ComponentProvider = ({
|
|
7785
7908
|
components = {},
|
|
@@ -16231,10 +16354,10 @@ var Observer = class {
|
|
|
16231
16354
|
});
|
|
16232
16355
|
}
|
|
16233
16356
|
};
|
|
16234
|
-
this.custom = (
|
|
16357
|
+
this.custom = (jsx68, data) => {
|
|
16235
16358
|
const id = (data == null ? void 0 : data.id) || toastsCounter++;
|
|
16236
16359
|
this.create({
|
|
16237
|
-
jsx:
|
|
16360
|
+
jsx: jsx68(id),
|
|
16238
16361
|
id,
|
|
16239
16362
|
...data
|
|
16240
16363
|
});
|
|
@@ -21743,15 +21866,24 @@ var CodeBlock3 = memo(function CodeBlock4({
|
|
|
21743
21866
|
] }, i)) }) }) })
|
|
21744
21867
|
] });
|
|
21745
21868
|
});
|
|
21746
|
-
var HtmlPreview3 = memo(function HtmlPreview4({
|
|
21869
|
+
var HtmlPreview3 = memo(function HtmlPreview4({
|
|
21870
|
+
content,
|
|
21871
|
+
config
|
|
21872
|
+
}) {
|
|
21747
21873
|
const [scale, setScale] = useState(1);
|
|
21748
21874
|
const [deviceMode, setDeviceMode] = useState("responsive");
|
|
21749
21875
|
const [isLoading, setIsLoading] = useState(true);
|
|
21750
21876
|
const [iframeHeight, setIframeHeight] = useState(600);
|
|
21751
21877
|
const iframeRef = useRef(null);
|
|
21752
21878
|
const containerRef = useRef(null);
|
|
21753
|
-
const blobUrl =
|
|
21754
|
-
|
|
21879
|
+
const [blobUrl, setBlobUrl] = useState("");
|
|
21880
|
+
useEffect(() => {
|
|
21881
|
+
let active = true;
|
|
21882
|
+
let currentUrl = "";
|
|
21883
|
+
const buildBlobUrl = async () => {
|
|
21884
|
+
const processed = config?.asset ? await resolveHtmlAssetUrlsAsync(content, config) : resolveHtmlAssetUrls(content);
|
|
21885
|
+
if (!active) return;
|
|
21886
|
+
const styleInjection = `
|
|
21755
21887
|
<style>
|
|
21756
21888
|
html, body {
|
|
21757
21889
|
margin: 0;
|
|
@@ -21765,24 +21897,26 @@ var HtmlPreview3 = memo(function HtmlPreview4({ content }) {
|
|
|
21765
21897
|
}
|
|
21766
21898
|
</style>
|
|
21767
21899
|
`;
|
|
21768
|
-
|
|
21769
|
-
|
|
21770
|
-
|
|
21771
|
-
|
|
21772
|
-
|
|
21773
|
-
|
|
21774
|
-
|
|
21775
|
-
|
|
21776
|
-
|
|
21777
|
-
|
|
21778
|
-
|
|
21779
|
-
|
|
21780
|
-
|
|
21781
|
-
|
|
21900
|
+
let modifiedContent = processed;
|
|
21901
|
+
if (processed.includes("<head>")) {
|
|
21902
|
+
modifiedContent = processed.replace("<head>", "<head>" + styleInjection);
|
|
21903
|
+
} else if (processed.includes("<html>")) {
|
|
21904
|
+
modifiedContent = processed.replace("<html>", "<html><head>" + styleInjection + "</head>");
|
|
21905
|
+
} else if (processed.includes("<!DOCTYPE") || processed.includes("<!doctype")) {
|
|
21906
|
+
modifiedContent = processed.replace(/(<!DOCTYPE[^>]*>|<!doctype[^>]*>)/i, "$1<html><head>" + styleInjection + "</head><body>") + "</body></html>";
|
|
21907
|
+
} else {
|
|
21908
|
+
modifiedContent = `<!DOCTYPE html><html><head>${styleInjection}</head><body>${processed}</body></html>`;
|
|
21909
|
+
}
|
|
21910
|
+
const blob = new Blob([modifiedContent], { type: "text/html" });
|
|
21911
|
+
currentUrl = URL.createObjectURL(blob);
|
|
21912
|
+
setBlobUrl(currentUrl);
|
|
21913
|
+
};
|
|
21914
|
+
buildBlobUrl();
|
|
21782
21915
|
return () => {
|
|
21783
|
-
|
|
21916
|
+
active = false;
|
|
21917
|
+
if (currentUrl) URL.revokeObjectURL(currentUrl);
|
|
21784
21918
|
};
|
|
21785
|
-
}, [
|
|
21919
|
+
}, [content, config]);
|
|
21786
21920
|
const deviceConfig = {
|
|
21787
21921
|
desktop: { width: "100%", maxWidth: "1400px", height: 800, icon: Monitor, label: "Desktop" },
|
|
21788
21922
|
tablet: { width: "768px", height: 1024, icon: Tablet, label: "Tablet" },
|
|
@@ -21937,7 +22071,7 @@ var HtmlPreview3 = memo(function HtmlPreview4({ content }) {
|
|
|
21937
22071
|
},
|
|
21938
22072
|
children: [
|
|
21939
22073
|
deviceMode === "mobile" && /* @__PURE__ */ jsx("div", { className: "h-6 bg-zinc-900 agent-sdk-light:bg-zinc-200 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-16 h-4 bg-zinc-800 agent-sdk-light:bg-zinc-300 rounded-full" }) }),
|
|
21940
|
-
/* @__PURE__ */ jsx(
|
|
22074
|
+
blobUrl && /* @__PURE__ */ jsx(
|
|
21941
22075
|
"iframe",
|
|
21942
22076
|
{
|
|
21943
22077
|
ref: iframeRef,
|
|
@@ -23834,6 +23968,237 @@ function ArtifactDeleteButton({
|
|
|
23834
23968
|
modal
|
|
23835
23969
|
] });
|
|
23836
23970
|
}
|
|
23971
|
+
var CHANGEABLE_TYPES = ["code", "html", "svg", "markdown", "json", "text"];
|
|
23972
|
+
function ArtifactTypeSelector({
|
|
23973
|
+
currentType,
|
|
23974
|
+
currentLanguage,
|
|
23975
|
+
onTypeChange,
|
|
23976
|
+
disabled = false
|
|
23977
|
+
}) {
|
|
23978
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
23979
|
+
const [isChanging, setIsChanging] = useState(false);
|
|
23980
|
+
const dropdownRef = useRef(null);
|
|
23981
|
+
const typeConfig2 = artifactTypeConfig[currentType] || artifactTypeConfig.text;
|
|
23982
|
+
const isChangeable = CHANGEABLE_TYPES.includes(currentType);
|
|
23983
|
+
useEffect(() => {
|
|
23984
|
+
if (!isOpen) return;
|
|
23985
|
+
const handleClickOutside = (e) => {
|
|
23986
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
23987
|
+
setIsOpen(false);
|
|
23988
|
+
}
|
|
23989
|
+
};
|
|
23990
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
23991
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
23992
|
+
}, [isOpen]);
|
|
23993
|
+
const handleSelectType = useCallback(async (newType) => {
|
|
23994
|
+
if (newType === currentType || isChanging) return;
|
|
23995
|
+
setIsChanging(true);
|
|
23996
|
+
try {
|
|
23997
|
+
await onTypeChange(newType);
|
|
23998
|
+
setIsOpen(false);
|
|
23999
|
+
} finally {
|
|
24000
|
+
setIsChanging(false);
|
|
24001
|
+
}
|
|
24002
|
+
}, [currentType, isChanging, onTypeChange]);
|
|
24003
|
+
if (!isChangeable) {
|
|
24004
|
+
return /* @__PURE__ */ jsx("div", { className: `w-7 h-7 rounded-lg ${typeConfig2.bgColor} flex items-center justify-center flex-shrink-0`, children: /* @__PURE__ */ jsx(typeConfig2.icon, { size: 14, className: typeConfig2.color }) });
|
|
24005
|
+
}
|
|
24006
|
+
const availableTypes = CHANGEABLE_TYPES.filter((t) => t !== currentType);
|
|
24007
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", ref: dropdownRef, children: [
|
|
24008
|
+
/* @__PURE__ */ jsxs(
|
|
24009
|
+
"button",
|
|
24010
|
+
{
|
|
24011
|
+
onClick: () => !disabled && !isChanging && setIsOpen(!isOpen),
|
|
24012
|
+
disabled: disabled || isChanging,
|
|
24013
|
+
className: cn3(
|
|
24014
|
+
"flex items-center gap-1 p-1 rounded-lg transition-colors",
|
|
24015
|
+
"hover:bg-zinc-800 agent-sdk-light:hover:bg-zinc-200",
|
|
24016
|
+
(disabled || isChanging) && "opacity-50 cursor-not-allowed"
|
|
24017
|
+
),
|
|
24018
|
+
title: "\u5207\u6362\u4EA7\u7269\u7C7B\u578B",
|
|
24019
|
+
children: [
|
|
24020
|
+
/* @__PURE__ */ jsx("div", { className: `w-7 h-7 rounded-lg ${typeConfig2.bgColor} flex items-center justify-center flex-shrink-0`, children: isChanging ? /* @__PURE__ */ jsx(Loader2, { size: 14, className: `${typeConfig2.color} animate-spin` }) : /* @__PURE__ */ jsx(typeConfig2.icon, { size: 14, className: typeConfig2.color }) }),
|
|
24021
|
+
/* @__PURE__ */ jsx(ChevronDown, { size: 10, className: "text-zinc-500" })
|
|
24022
|
+
]
|
|
24023
|
+
}
|
|
24024
|
+
),
|
|
24025
|
+
isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute left-0 top-full mt-1 z-50 w-44 bg-zinc-900 agent-sdk-light:bg-white border border-zinc-700/50 agent-sdk-light:border-zinc-200 rounded-lg shadow-xl overflow-hidden", children: [
|
|
24026
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 border-b border-zinc-800/50 agent-sdk-light:border-zinc-100", children: /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-zinc-500 agent-sdk-light:text-zinc-400", children: "\u5207\u6362\u7C7B\u578B" }) }),
|
|
24027
|
+
/* @__PURE__ */ jsx("div", { className: "p-1", children: availableTypes.map((type) => {
|
|
24028
|
+
const config = artifactTypeConfig[type];
|
|
24029
|
+
const TypeIcon = config.icon;
|
|
24030
|
+
return /* @__PURE__ */ jsxs(
|
|
24031
|
+
"button",
|
|
24032
|
+
{
|
|
24033
|
+
onClick: () => handleSelectType(type),
|
|
24034
|
+
disabled: isChanging,
|
|
24035
|
+
className: cn3(
|
|
24036
|
+
"flex items-center gap-2.5 px-2 py-1.5 text-xs rounded-md transition-all w-full text-left",
|
|
24037
|
+
"text-zinc-300 agent-sdk-light:text-zinc-700",
|
|
24038
|
+
"hover:bg-zinc-800/70 agent-sdk-light:hover:bg-zinc-100",
|
|
24039
|
+
isChanging && "opacity-50 cursor-not-allowed"
|
|
24040
|
+
),
|
|
24041
|
+
children: [
|
|
24042
|
+
/* @__PURE__ */ jsx("div", { className: cn3("w-5 h-5 rounded flex items-center justify-center flex-shrink-0", config.bgColor), children: /* @__PURE__ */ jsx(TypeIcon, { size: 11, className: config.color }) }),
|
|
24043
|
+
/* @__PURE__ */ jsx("span", { children: config.label })
|
|
24044
|
+
]
|
|
24045
|
+
},
|
|
24046
|
+
type
|
|
24047
|
+
);
|
|
24048
|
+
}) })
|
|
24049
|
+
] })
|
|
24050
|
+
] });
|
|
24051
|
+
}
|
|
24052
|
+
var COMMON_LANGUAGES = [
|
|
24053
|
+
"javascript",
|
|
24054
|
+
"typescript",
|
|
24055
|
+
"python",
|
|
24056
|
+
"java",
|
|
24057
|
+
"go",
|
|
24058
|
+
"rust",
|
|
24059
|
+
"c",
|
|
24060
|
+
"cpp",
|
|
24061
|
+
"csharp",
|
|
24062
|
+
"ruby",
|
|
24063
|
+
"php",
|
|
24064
|
+
"swift",
|
|
24065
|
+
"kotlin",
|
|
24066
|
+
"sql",
|
|
24067
|
+
"shell",
|
|
24068
|
+
"html",
|
|
24069
|
+
"css",
|
|
24070
|
+
"json",
|
|
24071
|
+
"yaml",
|
|
24072
|
+
"xml",
|
|
24073
|
+
"markdown"
|
|
24074
|
+
];
|
|
24075
|
+
function ArtifactLanguageSelector({
|
|
24076
|
+
currentLanguage,
|
|
24077
|
+
onLanguageChange,
|
|
24078
|
+
disabled = false
|
|
24079
|
+
}) {
|
|
24080
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
24081
|
+
const [isChanging, setIsChanging] = useState(false);
|
|
24082
|
+
const [search, setSearch] = useState("");
|
|
24083
|
+
const dropdownRef = useRef(null);
|
|
24084
|
+
const inputRef = useRef(null);
|
|
24085
|
+
useEffect(() => {
|
|
24086
|
+
if (!isOpen) return;
|
|
24087
|
+
const handleClickOutside = (e) => {
|
|
24088
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
24089
|
+
setIsOpen(false);
|
|
24090
|
+
setSearch("");
|
|
24091
|
+
}
|
|
24092
|
+
};
|
|
24093
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
24094
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
24095
|
+
}, [isOpen]);
|
|
24096
|
+
useEffect(() => {
|
|
24097
|
+
if (isOpen && inputRef.current) {
|
|
24098
|
+
inputRef.current.focus();
|
|
24099
|
+
}
|
|
24100
|
+
}, [isOpen]);
|
|
24101
|
+
const handleSelect = useCallback(async (language) => {
|
|
24102
|
+
if (language === currentLanguage || isChanging) return;
|
|
24103
|
+
setIsChanging(true);
|
|
24104
|
+
try {
|
|
24105
|
+
await onLanguageChange(language);
|
|
24106
|
+
setIsOpen(false);
|
|
24107
|
+
setSearch("");
|
|
24108
|
+
} finally {
|
|
24109
|
+
setIsChanging(false);
|
|
24110
|
+
}
|
|
24111
|
+
}, [currentLanguage, isChanging, onLanguageChange]);
|
|
24112
|
+
const handleKeyDown = useCallback((e) => {
|
|
24113
|
+
if (e.key === "Enter" && search.trim()) {
|
|
24114
|
+
e.preventDefault();
|
|
24115
|
+
handleSelect(search.trim().toLowerCase());
|
|
24116
|
+
} else if (e.key === "Escape") {
|
|
24117
|
+
setIsOpen(false);
|
|
24118
|
+
setSearch("");
|
|
24119
|
+
}
|
|
24120
|
+
}, [search, handleSelect]);
|
|
24121
|
+
const filteredLanguages = search.trim() ? COMMON_LANGUAGES.filter((lang) => lang.includes(search.trim().toLowerCase())) : COMMON_LANGUAGES;
|
|
24122
|
+
const showCustomOption = search.trim() && !COMMON_LANGUAGES.includes(search.trim().toLowerCase()) && search.trim().toLowerCase() !== currentLanguage;
|
|
24123
|
+
if (!currentLanguage) return null;
|
|
24124
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", ref: dropdownRef, children: [
|
|
24125
|
+
/* @__PURE__ */ jsx(
|
|
24126
|
+
"button",
|
|
24127
|
+
{
|
|
24128
|
+
onClick: () => !disabled && !isChanging && setIsOpen(!isOpen),
|
|
24129
|
+
disabled: disabled || isChanging,
|
|
24130
|
+
className: cn3(
|
|
24131
|
+
"text-zinc-500 agent-sdk-light:text-zinc-500 ml-1 text-xs transition-colors",
|
|
24132
|
+
"hover:text-zinc-300 agent-sdk-light:hover:text-zinc-700",
|
|
24133
|
+
(disabled || isChanging) && "opacity-50 cursor-not-allowed",
|
|
24134
|
+
!disabled && !isChanging && "cursor-pointer"
|
|
24135
|
+
),
|
|
24136
|
+
children: isChanging ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
24137
|
+
/* @__PURE__ */ jsx(Loader2, { size: 10, className: "animate-spin" }),
|
|
24138
|
+
currentLanguage
|
|
24139
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
24140
|
+
"\u2022 ",
|
|
24141
|
+
currentLanguage
|
|
24142
|
+
] })
|
|
24143
|
+
}
|
|
24144
|
+
),
|
|
24145
|
+
isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute left-0 top-full mt-1 z-50 w-48 bg-zinc-900 agent-sdk-light:bg-white border border-zinc-700/50 agent-sdk-light:border-zinc-200 rounded-lg shadow-xl overflow-hidden", children: [
|
|
24146
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 border-b border-zinc-800/50 agent-sdk-light:border-zinc-100", children: /* @__PURE__ */ jsx(
|
|
24147
|
+
"input",
|
|
24148
|
+
{
|
|
24149
|
+
ref: inputRef,
|
|
24150
|
+
type: "text",
|
|
24151
|
+
value: search,
|
|
24152
|
+
onChange: (e) => setSearch(e.target.value),
|
|
24153
|
+
onKeyDown: handleKeyDown,
|
|
24154
|
+
placeholder: "\u641C\u7D22\u8BED\u8A00...",
|
|
24155
|
+
className: "w-full px-2 py-1.5 text-xs bg-zinc-800 agent-sdk-light:bg-zinc-100 text-zinc-200 agent-sdk-light:text-zinc-800 rounded-md border border-zinc-700/50 agent-sdk-light:border-zinc-200 outline-none focus:border-zinc-500 agent-sdk-light:focus:border-zinc-400 placeholder-zinc-600 agent-sdk-light:placeholder-zinc-400"
|
|
24156
|
+
}
|
|
24157
|
+
) }),
|
|
24158
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-48 overflow-y-auto p-1", children: [
|
|
24159
|
+
showCustomOption && /* @__PURE__ */ jsxs(
|
|
24160
|
+
"button",
|
|
24161
|
+
{
|
|
24162
|
+
onClick: () => handleSelect(search.trim().toLowerCase()),
|
|
24163
|
+
disabled: isChanging,
|
|
24164
|
+
className: cn3(
|
|
24165
|
+
"flex items-center justify-between px-2 py-1.5 text-xs rounded-md transition-all w-full text-left",
|
|
24166
|
+
"text-zinc-300 agent-sdk-light:text-zinc-700",
|
|
24167
|
+
"hover:bg-zinc-800/70 agent-sdk-light:hover:bg-zinc-100",
|
|
24168
|
+
isChanging && "opacity-50 cursor-not-allowed"
|
|
24169
|
+
),
|
|
24170
|
+
children: [
|
|
24171
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
24172
|
+
'"',
|
|
24173
|
+
search.trim().toLowerCase(),
|
|
24174
|
+
'"'
|
|
24175
|
+
] }),
|
|
24176
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-zinc-600 agent-sdk-light:text-zinc-400", children: "\u56DE\u8F66\u786E\u8BA4" })
|
|
24177
|
+
]
|
|
24178
|
+
}
|
|
24179
|
+
),
|
|
24180
|
+
filteredLanguages.map((lang) => /* @__PURE__ */ jsxs(
|
|
24181
|
+
"button",
|
|
24182
|
+
{
|
|
24183
|
+
onClick: () => handleSelect(lang),
|
|
24184
|
+
disabled: isChanging,
|
|
24185
|
+
className: cn3(
|
|
24186
|
+
"flex items-center justify-between px-2 py-1.5 text-xs rounded-md transition-all w-full text-left",
|
|
24187
|
+
lang === currentLanguage ? "text-zinc-100 agent-sdk-light:text-zinc-900 bg-zinc-800/50 agent-sdk-light:bg-zinc-100" : "text-zinc-300 agent-sdk-light:text-zinc-700 hover:bg-zinc-800/70 agent-sdk-light:hover:bg-zinc-100",
|
|
24188
|
+
isChanging && "opacity-50 cursor-not-allowed"
|
|
24189
|
+
),
|
|
24190
|
+
children: [
|
|
24191
|
+
/* @__PURE__ */ jsx("span", { children: lang }),
|
|
24192
|
+
lang === currentLanguage && /* @__PURE__ */ jsx(Check, { size: 12, className: "text-green-400 agent-sdk-light:text-green-600 flex-shrink-0" })
|
|
24193
|
+
]
|
|
24194
|
+
},
|
|
24195
|
+
lang
|
|
24196
|
+
)),
|
|
24197
|
+
filteredLanguages.length === 0 && !showCustomOption && /* @__PURE__ */ jsx("div", { className: "px-2 py-3 text-xs text-zinc-600 agent-sdk-light:text-zinc-400 text-center", children: "\u65E0\u5339\u914D\u7ED3\u679C" })
|
|
24198
|
+
] })
|
|
24199
|
+
] })
|
|
24200
|
+
] });
|
|
24201
|
+
}
|
|
23837
24202
|
var ArtifactViewer = memo(function ArtifactViewer2({
|
|
23838
24203
|
artifact,
|
|
23839
24204
|
isOpen,
|
|
@@ -23851,13 +24216,20 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
23851
24216
|
onContentChange,
|
|
23852
24217
|
onSave,
|
|
23853
24218
|
onVisibilityChange,
|
|
23854
|
-
onDelete
|
|
24219
|
+
onDelete,
|
|
24220
|
+
onTypeChange,
|
|
24221
|
+
onLanguageChange,
|
|
24222
|
+
onTitleChange
|
|
23855
24223
|
}) {
|
|
23856
24224
|
const [viewMode, setViewMode] = useState(defaultView);
|
|
23857
24225
|
const [isEditing, setIsEditing] = useState(false);
|
|
23858
24226
|
const [editContent, setEditContent] = useState("");
|
|
23859
24227
|
const [undoStack, setUndoStack] = useState([]);
|
|
23860
24228
|
const [redoStack, setRedoStack] = useState([]);
|
|
24229
|
+
const [isEditingTitle, setIsEditingTitle] = useState(false);
|
|
24230
|
+
const [editingTitle, setEditingTitle] = useState("");
|
|
24231
|
+
const [isSavingTitle, setIsSavingTitle] = useState(false);
|
|
24232
|
+
const titleInputRef = useRef(null);
|
|
23861
24233
|
useEffect(() => {
|
|
23862
24234
|
if (artifact) {
|
|
23863
24235
|
if (artifact.type === "html" || artifact.type === "markdown" || artifact.type === "svg") {
|
|
@@ -23869,8 +24241,9 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
23869
24241
|
setEditContent(artifact.content);
|
|
23870
24242
|
setUndoStack([]);
|
|
23871
24243
|
setRedoStack([]);
|
|
24244
|
+
setIsEditingTitle(false);
|
|
23872
24245
|
}
|
|
23873
|
-
}, [artifact?.id]);
|
|
24246
|
+
}, [artifact?.id, artifact?.type]);
|
|
23874
24247
|
useEffect(() => {
|
|
23875
24248
|
if (artifact && !isEditing) {
|
|
23876
24249
|
setEditContent(artifact.content);
|
|
@@ -23883,6 +24256,7 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
23883
24256
|
const handleStartEdit = () => {
|
|
23884
24257
|
setEditContent(artifact.content);
|
|
23885
24258
|
setUndoStack([artifact.content]);
|
|
24259
|
+
handleStartEditTitle();
|
|
23886
24260
|
setRedoStack([]);
|
|
23887
24261
|
setIsEditing(true);
|
|
23888
24262
|
setViewMode("code");
|
|
@@ -23917,6 +24291,43 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
23917
24291
|
setEditContent(artifact.content);
|
|
23918
24292
|
setIsEditing(false);
|
|
23919
24293
|
};
|
|
24294
|
+
const handleStartEditTitle = useCallback(() => {
|
|
24295
|
+
if (!onTitleChange || isEditing || isSavingTitle) return;
|
|
24296
|
+
setEditingTitle(artifact.title);
|
|
24297
|
+
setIsEditingTitle(true);
|
|
24298
|
+
}, [onTitleChange, isEditing, isSavingTitle, artifact.title]);
|
|
24299
|
+
const handleSaveTitle = useCallback(async () => {
|
|
24300
|
+
const trimmed = editingTitle.trim();
|
|
24301
|
+
if (!trimmed || trimmed === artifact.title) {
|
|
24302
|
+
setIsEditingTitle(false);
|
|
24303
|
+
return;
|
|
24304
|
+
}
|
|
24305
|
+
setIsSavingTitle(true);
|
|
24306
|
+
try {
|
|
24307
|
+
await onTitleChange?.(artifact.id, trimmed);
|
|
24308
|
+
} finally {
|
|
24309
|
+
setIsSavingTitle(false);
|
|
24310
|
+
setIsEditingTitle(false);
|
|
24311
|
+
}
|
|
24312
|
+
}, [editingTitle, artifact.title, artifact.id, onTitleChange]);
|
|
24313
|
+
const handleCancelEditTitle = useCallback(() => {
|
|
24314
|
+
setIsEditingTitle(false);
|
|
24315
|
+
}, []);
|
|
24316
|
+
const handleTitleKeyDown = useCallback((e) => {
|
|
24317
|
+
if (e.key === "Enter") {
|
|
24318
|
+
e.preventDefault();
|
|
24319
|
+
handleSaveTitle();
|
|
24320
|
+
} else if (e.key === "Escape") {
|
|
24321
|
+
e.preventDefault();
|
|
24322
|
+
handleCancelEditTitle();
|
|
24323
|
+
}
|
|
24324
|
+
}, [handleSaveTitle, handleCancelEditTitle]);
|
|
24325
|
+
useEffect(() => {
|
|
24326
|
+
if (isEditingTitle && titleInputRef.current) {
|
|
24327
|
+
titleInputRef.current.focus();
|
|
24328
|
+
titleInputRef.current.select();
|
|
24329
|
+
}
|
|
24330
|
+
}, [isEditingTitle]);
|
|
23920
24331
|
const displayContent = isEditing ? editContent : artifact.content;
|
|
23921
24332
|
const renderContent = () => {
|
|
23922
24333
|
if (isEditing) {
|
|
@@ -23957,7 +24368,7 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
23957
24368
|
switch (artifact.type) {
|
|
23958
24369
|
case "html":
|
|
23959
24370
|
case "svg":
|
|
23960
|
-
return /* @__PURE__ */ jsx(HtmlPreview3, { content: displayContent });
|
|
24371
|
+
return /* @__PURE__ */ jsx(HtmlPreview3, { content: displayContent, config });
|
|
23961
24372
|
case "markdown":
|
|
23962
24373
|
return /* @__PURE__ */ jsx(MarkdownPreview, { content: displayContent, config });
|
|
23963
24374
|
default:
|
|
@@ -23974,15 +24385,56 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
23974
24385
|
return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col bg-zinc-900 agent-sdk-light:bg-white relative", children: [
|
|
23975
24386
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-zinc-800/50 agent-sdk-light:border-zinc-200 bg-zinc-900/95 agent-sdk-light:bg-zinc-50 backdrop-blur-sm flex-shrink-0", children: [
|
|
23976
24387
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
23977
|
-
|
|
24388
|
+
onTypeChange ? /* @__PURE__ */ jsx(
|
|
24389
|
+
ArtifactTypeSelector,
|
|
24390
|
+
{
|
|
24391
|
+
currentType: artifact.type,
|
|
24392
|
+
currentLanguage: artifact.language,
|
|
24393
|
+
onTypeChange: (newType, language) => onTypeChange(artifact.id, newType, language),
|
|
24394
|
+
disabled: isEditing
|
|
24395
|
+
}
|
|
24396
|
+
) : /* @__PURE__ */ jsx("div", { className: `w-7 h-7 rounded-lg ${typeConfig2.bgColor} flex items-center justify-center flex-shrink-0`, children: /* @__PURE__ */ jsx(typeConfig2.icon, { size: 14, className: typeConfig2.color }) }),
|
|
23978
24397
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
23979
|
-
/* @__PURE__ */
|
|
24398
|
+
isEditingTitle ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
24399
|
+
/* @__PURE__ */ jsx(
|
|
24400
|
+
"input",
|
|
24401
|
+
{
|
|
24402
|
+
ref: titleInputRef,
|
|
24403
|
+
type: "text",
|
|
24404
|
+
value: editingTitle,
|
|
24405
|
+
onChange: (e) => setEditingTitle(e.target.value),
|
|
24406
|
+
onKeyDown: handleTitleKeyDown,
|
|
24407
|
+
onBlur: handleSaveTitle,
|
|
24408
|
+
disabled: isSavingTitle,
|
|
24409
|
+
className: "text-sm font-medium text-zinc-100 agent-sdk-light:text-zinc-900 bg-zinc-800 agent-sdk-light:bg-zinc-100 border border-zinc-600 agent-sdk-light:border-zinc-300 rounded px-1.5 py-0.5 outline-none focus:border-zinc-400 agent-sdk-light:focus:border-zinc-500 w-full min-w-0"
|
|
24410
|
+
}
|
|
24411
|
+
),
|
|
24412
|
+
isSavingTitle && /* @__PURE__ */ jsx(Loader2, { size: 12, className: "text-zinc-500 animate-spin flex-shrink-0" })
|
|
24413
|
+
] }) : /* @__PURE__ */ jsx(
|
|
24414
|
+
"h3",
|
|
24415
|
+
{
|
|
24416
|
+
className: cn3(
|
|
24417
|
+
"text-sm font-medium text-zinc-100 agent-sdk-light:text-zinc-900 truncate",
|
|
24418
|
+
onTitleChange && !isEditing && "cursor-pointer hover:text-zinc-300 agent-sdk-light:hover:text-zinc-600"
|
|
24419
|
+
),
|
|
24420
|
+
onDoubleClick: handleStartEditTitle,
|
|
24421
|
+
title: onTitleChange && !isEditing ? "\u53CC\u51FB\u7F16\u8F91\u6807\u9898" : void 0,
|
|
24422
|
+
children: artifact.title
|
|
24423
|
+
}
|
|
24424
|
+
),
|
|
23980
24425
|
/* @__PURE__ */ jsxs("p", { className: `text-xs ${typeConfig2.color}`, children: [
|
|
23981
24426
|
typeConfig2.label,
|
|
23982
|
-
artifact.language && artifact.language !== artifact.type && /* @__PURE__ */
|
|
24427
|
+
artifact.language && artifact.language !== artifact.type && (onLanguageChange ? /* @__PURE__ */ jsx(
|
|
24428
|
+
ArtifactLanguageSelector,
|
|
24429
|
+
{
|
|
24430
|
+
currentLanguage: artifact.language,
|
|
24431
|
+
onLanguageChange: (lang) => onLanguageChange(artifact.id, lang),
|
|
24432
|
+
disabled: isEditing
|
|
24433
|
+
}
|
|
24434
|
+
) : /* @__PURE__ */ jsxs("span", { className: "text-zinc-500 agent-sdk-light:text-zinc-500 ml-1", children: [
|
|
23983
24435
|
"\u2022 ",
|
|
23984
24436
|
artifact.language
|
|
23985
|
-
] })
|
|
24437
|
+
] }))
|
|
23986
24438
|
] })
|
|
23987
24439
|
] })
|
|
23988
24440
|
] }),
|
|
@@ -24107,15 +24559,54 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
24107
24559
|
isOpen,
|
|
24108
24560
|
onClose,
|
|
24109
24561
|
title: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
24110
|
-
|
|
24111
|
-
|
|
24562
|
+
onTypeChange ? /* @__PURE__ */ jsx(
|
|
24563
|
+
ArtifactTypeSelector,
|
|
24564
|
+
{
|
|
24565
|
+
currentType: artifact.type,
|
|
24566
|
+
currentLanguage: artifact.language,
|
|
24567
|
+
onTypeChange: (newType, language) => onTypeChange(artifact.id, newType, language),
|
|
24568
|
+
disabled: isEditing
|
|
24569
|
+
}
|
|
24570
|
+
) : /* @__PURE__ */ jsx("div", { className: `w-6 h-6 rounded-md ${typeConfig2.bgColor} flex items-center justify-center`, children: /* @__PURE__ */ jsx(typeConfig2.icon, { size: 14, className: typeConfig2.color }) }),
|
|
24571
|
+
isEditingTitle ? /* @__PURE__ */ jsx(
|
|
24572
|
+
"input",
|
|
24573
|
+
{
|
|
24574
|
+
ref: titleInputRef,
|
|
24575
|
+
type: "text",
|
|
24576
|
+
value: editingTitle,
|
|
24577
|
+
onChange: (e) => setEditingTitle(e.target.value),
|
|
24578
|
+
onKeyDown: handleTitleKeyDown,
|
|
24579
|
+
onBlur: handleSaveTitle,
|
|
24580
|
+
disabled: isSavingTitle,
|
|
24581
|
+
className: "text-sm font-medium text-zinc-100 agent-sdk-light:text-zinc-900 bg-zinc-800 agent-sdk-light:bg-zinc-100 border border-zinc-600 agent-sdk-light:border-zinc-300 rounded px-1.5 py-0.5 outline-none focus:border-zinc-400 agent-sdk-light:focus:border-zinc-500 min-w-0 flex-1"
|
|
24582
|
+
}
|
|
24583
|
+
) : /* @__PURE__ */ jsx(
|
|
24584
|
+
"span",
|
|
24585
|
+
{
|
|
24586
|
+
className: cn3(
|
|
24587
|
+
"truncate",
|
|
24588
|
+
onTitleChange && !isEditing && "cursor-pointer hover:text-zinc-300 agent-sdk-light:hover:text-zinc-600"
|
|
24589
|
+
),
|
|
24590
|
+
onDoubleClick: handleStartEditTitle,
|
|
24591
|
+
title: onTitleChange && !isEditing ? "\u53CC\u51FB\u7F16\u8F91\u6807\u9898" : void 0,
|
|
24592
|
+
children: artifact.title
|
|
24593
|
+
}
|
|
24594
|
+
),
|
|
24595
|
+
isSavingTitle && /* @__PURE__ */ jsx(Loader2, { size: 12, className: "text-zinc-500 animate-spin flex-shrink-0" })
|
|
24112
24596
|
] }),
|
|
24113
24597
|
subtitle: /* @__PURE__ */ jsxs("span", { className: typeConfig2.color, children: [
|
|
24114
24598
|
typeConfig2.label,
|
|
24115
|
-
artifact.language && artifact.language !== artifact.type && /* @__PURE__ */
|
|
24599
|
+
artifact.language && artifact.language !== artifact.type && (onLanguageChange ? /* @__PURE__ */ jsx(
|
|
24600
|
+
ArtifactLanguageSelector,
|
|
24601
|
+
{
|
|
24602
|
+
currentLanguage: artifact.language,
|
|
24603
|
+
onLanguageChange: (lang) => onLanguageChange(artifact.id, lang),
|
|
24604
|
+
disabled: isEditing
|
|
24605
|
+
}
|
|
24606
|
+
) : /* @__PURE__ */ jsxs("span", { className: "text-zinc-500 agent-sdk-light:text-zinc-500 ml-1", children: [
|
|
24116
24607
|
"\u2022 ",
|
|
24117
24608
|
artifact.language
|
|
24118
|
-
] })
|
|
24609
|
+
] }))
|
|
24119
24610
|
] }),
|
|
24120
24611
|
isFullscreen,
|
|
24121
24612
|
onFullscreenToggle,
|
|
@@ -25028,7 +25519,7 @@ function useArtifactPanel({ currentSessionId }) {
|
|
|
25028
25519
|
const existingArtifact = Object.values(artifacts).find(
|
|
25029
25520
|
(a) => {
|
|
25030
25521
|
const sameContent = a.currentContent === data.content && a.type === data.type;
|
|
25031
|
-
const sameId = a?.metadata?.workId === data.metadata?.workId;
|
|
25522
|
+
const sameId = !!data.metadata?.workId && a?.metadata?.workId === data.metadata?.workId;
|
|
25032
25523
|
return sameContent || sameId;
|
|
25033
25524
|
}
|
|
25034
25525
|
);
|
|
@@ -25090,7 +25581,8 @@ function useArtifactPanel({ currentSessionId }) {
|
|
|
25090
25581
|
setActiveArtifact,
|
|
25091
25582
|
removeArtifact,
|
|
25092
25583
|
reorderArtifacts,
|
|
25093
|
-
updateArtifactContent
|
|
25584
|
+
updateArtifactContent,
|
|
25585
|
+
upsertArtifact
|
|
25094
25586
|
};
|
|
25095
25587
|
}
|
|
25096
25588
|
|
|
@@ -25906,7 +26398,8 @@ var AgentChat = React16__default.forwardRef(({
|
|
|
25906
26398
|
setActiveArtifact,
|
|
25907
26399
|
removeArtifact,
|
|
25908
26400
|
reorderArtifacts,
|
|
25909
|
-
updateArtifactContent
|
|
26401
|
+
updateArtifactContent,
|
|
26402
|
+
upsertArtifact
|
|
25910
26403
|
} = useArtifactPanel({ currentSessionId: useAgentStore((state) => state.currentSession?.sessionId) });
|
|
25911
26404
|
const reconnectRef = useRef(null);
|
|
25912
26405
|
const reconnectWrapper = useCallback(async (messageId) => {
|
|
@@ -26380,6 +26873,52 @@ var AgentChat = React16__default.forwardRef(({
|
|
|
26380
26873
|
toast.error("\u5220\u9664\u4EA7\u7269\u5931\u8D25");
|
|
26381
26874
|
}
|
|
26382
26875
|
},
|
|
26876
|
+
onTypeChange: async (artifactId, newType, language) => {
|
|
26877
|
+
try {
|
|
26878
|
+
const content = activeArtifact?.currentContent || "";
|
|
26879
|
+
const res = await artifactService.updateContent(artifactId, content, {
|
|
26880
|
+
type: newType,
|
|
26881
|
+
language
|
|
26882
|
+
});
|
|
26883
|
+
if (res.success && res.data) {
|
|
26884
|
+
upsertArtifact(artifactService.normalizeEntry(res.data));
|
|
26885
|
+
toast.success("\u7C7B\u578B\u5DF2\u66F4\u65B0");
|
|
26886
|
+
} else {
|
|
26887
|
+
toast.error("\u7C7B\u578B\u66F4\u65B0\u5931\u8D25");
|
|
26888
|
+
}
|
|
26889
|
+
} catch (err) {
|
|
26890
|
+
console.error("[AgentChat] Change artifact type failed:", err);
|
|
26891
|
+
toast.error("\u7C7B\u578B\u66F4\u65B0\u5931\u8D25");
|
|
26892
|
+
}
|
|
26893
|
+
},
|
|
26894
|
+
onLanguageChange: async (artifactId, language) => {
|
|
26895
|
+
try {
|
|
26896
|
+
const content = activeArtifact?.currentContent || "";
|
|
26897
|
+
const res = await artifactService.updateContent(artifactId, content, { language });
|
|
26898
|
+
if (res.success && res.data) {
|
|
26899
|
+
upsertArtifact(artifactService.normalizeEntry(res.data));
|
|
26900
|
+
} else {
|
|
26901
|
+
toast.error("\u8BED\u8A00\u66F4\u65B0\u5931\u8D25");
|
|
26902
|
+
}
|
|
26903
|
+
} catch (err) {
|
|
26904
|
+
console.error("[AgentChat] Change artifact language failed:", err);
|
|
26905
|
+
toast.error("\u8BED\u8A00\u66F4\u65B0\u5931\u8D25");
|
|
26906
|
+
}
|
|
26907
|
+
},
|
|
26908
|
+
onTitleChange: async (artifactId, title) => {
|
|
26909
|
+
try {
|
|
26910
|
+
const content = activeArtifact?.currentContent || "";
|
|
26911
|
+
const res = await artifactService.updateContent(artifactId, content, { title });
|
|
26912
|
+
if (res.success && res.data) {
|
|
26913
|
+
upsertArtifact(artifactService.normalizeEntry(res.data));
|
|
26914
|
+
} else {
|
|
26915
|
+
toast.error("\u6807\u9898\u66F4\u65B0\u5931\u8D25");
|
|
26916
|
+
}
|
|
26917
|
+
} catch (err) {
|
|
26918
|
+
console.error("[AgentChat] Change artifact title failed:", err);
|
|
26919
|
+
toast.error("\u6807\u9898\u66F4\u65B0\u5931\u8D25");
|
|
26920
|
+
}
|
|
26921
|
+
},
|
|
26383
26922
|
onVisibilityChange: async (artifactId, isPublic) => {
|
|
26384
26923
|
try {
|
|
26385
26924
|
const res = await artifactService.updateVisibility(artifactId, isPublic);
|
|
@@ -26915,19 +27454,58 @@ function ShareReplayPage({ shareId, onNavigateBack }) {
|
|
|
26915
27454
|
] });
|
|
26916
27455
|
}
|
|
26917
27456
|
var typeConfig = {
|
|
26918
|
-
html: { icon: Globe, label: "HTML", color: "
|
|
26919
|
-
svg: { icon: Globe, label: "SVG", color: "
|
|
26920
|
-
markdown: { icon: FileText, label: "Markdown", color: "
|
|
26921
|
-
json: { icon: FileJson, label: "JSON", color: "
|
|
26922
|
-
code: { icon: FileCode, label: "Code", color: "
|
|
26923
|
-
text: { icon: FileText, label: "Text", color: "
|
|
26924
|
-
image: { icon: FileImage, label: "Image", color: "
|
|
26925
|
-
video: { icon: Video, label: "Video", color: "
|
|
27457
|
+
html: { icon: Globe, label: "HTML", color: "#fb923c" },
|
|
27458
|
+
svg: { icon: Globe, label: "SVG", color: "#fb923c" },
|
|
27459
|
+
markdown: { icon: FileText, label: "Markdown", color: "#60a5fa" },
|
|
27460
|
+
json: { icon: FileJson, label: "JSON", color: "#facc15" },
|
|
27461
|
+
code: { icon: FileCode, label: "Code", color: "#c084fc" },
|
|
27462
|
+
text: { icon: FileText, label: "Text", color: "#a1a1aa" },
|
|
27463
|
+
image: { icon: FileImage, label: "Image", color: "#4ade80" },
|
|
27464
|
+
video: { icon: Video, label: "Video", color: "#f472b6" }
|
|
26926
27465
|
};
|
|
27466
|
+
function FullscreenHtmlPreview({ content }) {
|
|
27467
|
+
const blobUrl = useMemo(() => {
|
|
27468
|
+
const processed = resolveHtmlAssetUrls(content);
|
|
27469
|
+
const styleInjection = `
|
|
27470
|
+
<style>
|
|
27471
|
+
html, body { margin: 0; padding: 0; width: 100%; min-height: 100%; box-sizing: border-box; }
|
|
27472
|
+
* { box-sizing: border-box; }
|
|
27473
|
+
</style>`;
|
|
27474
|
+
let modified = processed;
|
|
27475
|
+
if (processed.includes("<head>")) {
|
|
27476
|
+
modified = processed.replace("<head>", "<head>" + styleInjection);
|
|
27477
|
+
} else if (processed.includes("<html>")) {
|
|
27478
|
+
modified = processed.replace("<html>", "<html><head>" + styleInjection + "</head>");
|
|
27479
|
+
} else if (/<!(DOCTYPE|doctype)/i.test(processed)) {
|
|
27480
|
+
modified = processed.replace(/(<!DOCTYPE[^>]*>|<!doctype[^>]*>)/i, "$1<html><head>" + styleInjection + "</head><body>") + "</body></html>";
|
|
27481
|
+
} else {
|
|
27482
|
+
modified = `<!DOCTYPE html><html><head>${styleInjection}</head><body>${processed}</body></html>`;
|
|
27483
|
+
}
|
|
27484
|
+
const blob = new Blob([modified], { type: "text/html" });
|
|
27485
|
+
return URL.createObjectURL(blob);
|
|
27486
|
+
}, [content]);
|
|
27487
|
+
useEffect(() => {
|
|
27488
|
+
return () => URL.revokeObjectURL(blobUrl);
|
|
27489
|
+
}, [blobUrl]);
|
|
27490
|
+
return /* @__PURE__ */ jsx(
|
|
27491
|
+
"iframe",
|
|
27492
|
+
{
|
|
27493
|
+
src: blobUrl,
|
|
27494
|
+
style: { display: "block", width: "100%", height: "100%", border: "none", background: "white" },
|
|
27495
|
+
sandbox: "allow-scripts allow-same-origin allow-popups allow-forms allow-modals",
|
|
27496
|
+
title: "HTML Preview"
|
|
27497
|
+
}
|
|
27498
|
+
);
|
|
27499
|
+
}
|
|
26927
27500
|
function PublicArtifactPage({ shareToken, onNavigateBack }) {
|
|
26928
27501
|
const [pageState, setPageState] = useState("loading");
|
|
26929
27502
|
const [error, setError] = useState(null);
|
|
26930
27503
|
const [artifact, setArtifact] = useState(null);
|
|
27504
|
+
const [isTheaterMode, setIsTheaterMode] = useState(false);
|
|
27505
|
+
const [isBrowserFullscreen, setIsBrowserFullscreen] = useState(false);
|
|
27506
|
+
const [showTheaterControls, setShowTheaterControls] = useState(true);
|
|
27507
|
+
const theaterTimerRef = useRef(null);
|
|
27508
|
+
const isFullscreenSupported = typeof document !== "undefined" && typeof document.documentElement?.requestFullscreen === "function";
|
|
26931
27509
|
useEffect(() => {
|
|
26932
27510
|
if (!shareToken) {
|
|
26933
27511
|
setPageState("not-found");
|
|
@@ -26951,31 +27529,13 @@ function PublicArtifactPage({ shareToken, onNavigateBack }) {
|
|
|
26951
27529
|
}
|
|
26952
27530
|
load();
|
|
26953
27531
|
}, [shareToken]);
|
|
26954
|
-
const handleShare = useCallback(() => {
|
|
26955
|
-
const url = window.location.href;
|
|
26956
|
-
navigator.clipboard.writeText(url);
|
|
26957
|
-
toast.success("\u94FE\u63A5\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F");
|
|
26958
|
-
}, []);
|
|
26959
27532
|
const handleDownload = useCallback(() => {
|
|
26960
27533
|
if (!artifact) return;
|
|
26961
|
-
const
|
|
26962
|
-
|
|
26963
|
-
|
|
26964
|
-
|
|
26965
|
-
|
|
26966
|
-
code: artifact.language || "txt",
|
|
26967
|
-
text: "txt"
|
|
26968
|
-
};
|
|
26969
|
-
const ext = extMap[artifact.type] || "txt";
|
|
26970
|
-
const mimeMap = {
|
|
26971
|
-
html: "text/html",
|
|
26972
|
-
svg: "image/svg+xml",
|
|
26973
|
-
markdown: "text/markdown",
|
|
26974
|
-
json: "application/json",
|
|
26975
|
-
code: "text/plain",
|
|
26976
|
-
text: "text/plain"
|
|
26977
|
-
};
|
|
26978
|
-
const mime = mimeMap[artifact.type] || "text/plain";
|
|
27534
|
+
const type = artifact.type?.toLowerCase() ?? "text";
|
|
27535
|
+
const extMap = { html: "html", svg: "svg", markdown: "md", json: "json", code: artifact.language || "txt", text: "txt" };
|
|
27536
|
+
const ext = extMap[type] || "txt";
|
|
27537
|
+
const mimeMap = { html: "text/html", svg: "image/svg+xml", markdown: "text/markdown", json: "application/json", code: "text/plain", text: "text/plain" };
|
|
27538
|
+
const mime = mimeMap[type] || "text/plain";
|
|
26979
27539
|
const blob = new Blob([artifact.content], { type: mime });
|
|
26980
27540
|
const url = URL.createObjectURL(blob);
|
|
26981
27541
|
const link2 = document.createElement("a");
|
|
@@ -26986,15 +27546,85 @@ function PublicArtifactPage({ shareToken, onNavigateBack }) {
|
|
|
26986
27546
|
document.body.removeChild(link2);
|
|
26987
27547
|
URL.revokeObjectURL(url);
|
|
26988
27548
|
}, [artifact]);
|
|
27549
|
+
const toggleTheaterMode = useCallback(() => {
|
|
27550
|
+
setIsTheaterMode((prev) => !prev);
|
|
27551
|
+
setShowTheaterControls(true);
|
|
27552
|
+
}, []);
|
|
27553
|
+
const exitTheaterMode = useCallback(() => {
|
|
27554
|
+
setIsTheaterMode(false);
|
|
27555
|
+
setShowTheaterControls(true);
|
|
27556
|
+
}, []);
|
|
27557
|
+
const toggleBrowserFullscreen = useCallback(() => {
|
|
27558
|
+
if (!document.fullscreenElement) {
|
|
27559
|
+
document.documentElement.requestFullscreen().catch(() => {
|
|
27560
|
+
});
|
|
27561
|
+
} else {
|
|
27562
|
+
document.exitFullscreen().catch(() => {
|
|
27563
|
+
});
|
|
27564
|
+
}
|
|
27565
|
+
}, []);
|
|
27566
|
+
useEffect(() => {
|
|
27567
|
+
const handleFullscreenChange = () => {
|
|
27568
|
+
const isFs = !!document.fullscreenElement;
|
|
27569
|
+
setIsBrowserFullscreen(isFs);
|
|
27570
|
+
if (isFs) {
|
|
27571
|
+
setIsTheaterMode(true);
|
|
27572
|
+
setShowTheaterControls(true);
|
|
27573
|
+
} else {
|
|
27574
|
+
setIsTheaterMode(false);
|
|
27575
|
+
}
|
|
27576
|
+
};
|
|
27577
|
+
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
27578
|
+
return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
27579
|
+
}, []);
|
|
27580
|
+
useEffect(() => {
|
|
27581
|
+
if (!isTheaterMode) return;
|
|
27582
|
+
const handleInteraction = () => {
|
|
27583
|
+
setShowTheaterControls(true);
|
|
27584
|
+
if (theaterTimerRef.current) clearTimeout(theaterTimerRef.current);
|
|
27585
|
+
theaterTimerRef.current = setTimeout(() => setShowTheaterControls(false), 3e3);
|
|
27586
|
+
};
|
|
27587
|
+
theaterTimerRef.current = setTimeout(() => setShowTheaterControls(false), 3e3);
|
|
27588
|
+
window.addEventListener("mousemove", handleInteraction);
|
|
27589
|
+
window.addEventListener("touchstart", handleInteraction);
|
|
27590
|
+
return () => {
|
|
27591
|
+
window.removeEventListener("mousemove", handleInteraction);
|
|
27592
|
+
window.removeEventListener("touchstart", handleInteraction);
|
|
27593
|
+
if (theaterTimerRef.current) clearTimeout(theaterTimerRef.current);
|
|
27594
|
+
};
|
|
27595
|
+
}, [isTheaterMode]);
|
|
27596
|
+
useEffect(() => {
|
|
27597
|
+
const handleKeyDown = (e) => {
|
|
27598
|
+
const tag = e.target?.tagName;
|
|
27599
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return;
|
|
27600
|
+
if (e.key === "Escape") {
|
|
27601
|
+
if (document.fullscreenElement) return;
|
|
27602
|
+
if (isTheaterMode) exitTheaterMode();
|
|
27603
|
+
return;
|
|
27604
|
+
}
|
|
27605
|
+
if ((e.key === "f" || e.key === "F") && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
27606
|
+
e.preventDefault();
|
|
27607
|
+
if (isFullscreenSupported) toggleBrowserFullscreen();
|
|
27608
|
+
return;
|
|
27609
|
+
}
|
|
27610
|
+
if ((e.key === "t" || e.key === "T") && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
27611
|
+
e.preventDefault();
|
|
27612
|
+
toggleTheaterMode();
|
|
27613
|
+
}
|
|
27614
|
+
};
|
|
27615
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
27616
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
27617
|
+
}, [isTheaterMode, isFullscreenSupported, exitTheaterMode, toggleBrowserFullscreen, toggleTheaterMode]);
|
|
26989
27618
|
const renderContent = () => {
|
|
26990
27619
|
if (!artifact) return null;
|
|
26991
27620
|
const content = artifact.content;
|
|
26992
|
-
|
|
27621
|
+
const type = artifact.type?.toLowerCase() ?? "text";
|
|
27622
|
+
switch (type) {
|
|
26993
27623
|
case "html":
|
|
26994
27624
|
case "svg":
|
|
26995
|
-
return /* @__PURE__ */ jsx(
|
|
27625
|
+
return /* @__PURE__ */ jsx(FullscreenHtmlPreview, { content });
|
|
26996
27626
|
case "markdown":
|
|
26997
|
-
return /* @__PURE__ */ jsx("div", { className: "p-6 max-w-4xl mx-auto", children: /* @__PURE__ */ jsx(MarkdownPreview, { content }) });
|
|
27627
|
+
return /* @__PURE__ */ jsx("div", { className: "agent-sdk-theme", style: { background: "transparent", height: "100%", overflow: "auto" }, children: /* @__PURE__ */ jsx("div", { className: "p-6 max-w-4xl mx-auto", children: /* @__PURE__ */ jsx(MarkdownPreview, { content }) }) });
|
|
26998
27628
|
case "image":
|
|
26999
27629
|
return /* @__PURE__ */ jsx(ImageArtifactPreview, { content });
|
|
27000
27630
|
case "video":
|
|
@@ -27003,73 +27633,90 @@ function PublicArtifactPage({ shareToken, onNavigateBack }) {
|
|
|
27003
27633
|
case "code":
|
|
27004
27634
|
case "text":
|
|
27005
27635
|
default:
|
|
27006
|
-
return /* @__PURE__ */ jsx(
|
|
27007
|
-
CodeBlock3,
|
|
27008
|
-
{
|
|
27009
|
-
code: content,
|
|
27010
|
-
language: artifact.language || artifact.type
|
|
27011
|
-
}
|
|
27012
|
-
);
|
|
27636
|
+
return /* @__PURE__ */ jsx("div", { className: "agent-sdk-theme", style: { background: "transparent", height: "100%", overflow: "auto" }, children: /* @__PURE__ */ jsx(CodeBlock3, { code: content, language: artifact.language || type }) });
|
|
27013
27637
|
}
|
|
27014
27638
|
};
|
|
27015
27639
|
if (pageState === "loading") {
|
|
27016
|
-
return /* @__PURE__ */ jsx("div", {
|
|
27640
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "100vh", background: "#09090b" }, children: /* @__PURE__ */ jsx(Loader2, { size: 32, style: { color: "#d8ff00" }, className: "animate-spin" }) });
|
|
27017
27641
|
}
|
|
27018
27642
|
if (pageState === "not-found") {
|
|
27019
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
27020
|
-
/* @__PURE__ */ jsx(AlertCircle, { size: 48,
|
|
27021
|
-
/* @__PURE__ */ jsx("p", {
|
|
27022
|
-
/* @__PURE__ */ jsx("p", {
|
|
27643
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100vh", background: "#09090b", gap: 16 }, children: [
|
|
27644
|
+
/* @__PURE__ */ jsx(AlertCircle, { size: 48, style: { color: "#52525b" } }),
|
|
27645
|
+
/* @__PURE__ */ jsx("p", { style: { color: "#a1a1aa", fontSize: 18, margin: 0 }, children: "\u4EA7\u7269\u4E0D\u5B58\u5728\u6216\u5DF2\u8BBE\u4E3A\u79C1\u6709" }),
|
|
27646
|
+
/* @__PURE__ */ jsx("p", { style: { color: "#52525b", fontSize: 14, margin: 0 }, children: "\u8BF7\u68C0\u67E5\u94FE\u63A5\u662F\u5426\u6B63\u786E\uFF0C\u6216\u8054\u7CFB\u4F5C\u8005\u91CD\u65B0\u5206\u4EAB" }),
|
|
27023
27647
|
onNavigateBack && /* @__PURE__ */ jsx(
|
|
27024
27648
|
"button",
|
|
27025
27649
|
{
|
|
27026
27650
|
onClick: onNavigateBack,
|
|
27027
|
-
|
|
27651
|
+
style: { marginTop: 16, padding: "8px 16px", fontSize: 14, background: "#27272a", color: "white", border: "none", borderRadius: 8, cursor: "pointer" },
|
|
27028
27652
|
children: "\u8FD4\u56DE"
|
|
27029
27653
|
}
|
|
27030
27654
|
)
|
|
27031
27655
|
] });
|
|
27032
27656
|
}
|
|
27033
27657
|
if (pageState === "error") {
|
|
27034
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
27035
|
-
/* @__PURE__ */ jsx(AlertCircle, { size: 48,
|
|
27036
|
-
/* @__PURE__ */ jsx("p", {
|
|
27658
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100vh", background: "#09090b", gap: 16 }, children: [
|
|
27659
|
+
/* @__PURE__ */ jsx(AlertCircle, { size: 48, style: { color: "#f87171" } }),
|
|
27660
|
+
/* @__PURE__ */ jsx("p", { style: { color: "#f87171", fontSize: 18, margin: 0 }, children: error || "\u52A0\u8F7D\u5931\u8D25" }),
|
|
27037
27661
|
onNavigateBack && /* @__PURE__ */ jsx(
|
|
27038
27662
|
"button",
|
|
27039
27663
|
{
|
|
27040
27664
|
onClick: onNavigateBack,
|
|
27041
|
-
|
|
27665
|
+
style: { marginTop: 16, padding: "8px 16px", fontSize: 14, background: "#27272a", color: "white", border: "none", borderRadius: 8, cursor: "pointer" },
|
|
27042
27666
|
children: "\u8FD4\u56DE"
|
|
27043
27667
|
}
|
|
27044
27668
|
)
|
|
27045
27669
|
] });
|
|
27046
27670
|
}
|
|
27047
27671
|
if (!artifact) return null;
|
|
27048
|
-
const
|
|
27672
|
+
const normalizedType = artifact.type?.toLowerCase() ?? "text";
|
|
27673
|
+
const config = typeConfig[normalizedType] || typeConfig.text;
|
|
27049
27674
|
const TypeIcon = config.icon;
|
|
27050
|
-
const canDownload = ["html", "svg", "markdown", "json", "code", "text"].includes(
|
|
27051
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
27052
|
-
/* @__PURE__ */ jsxs("div", {
|
|
27053
|
-
|
|
27675
|
+
const canDownload = ["html", "svg", "markdown", "json", "code", "text"].includes(normalizedType);
|
|
27676
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100vh", background: "#09090b" }, children: [
|
|
27677
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
27678
|
+
display: "flex",
|
|
27679
|
+
alignItems: "center",
|
|
27680
|
+
justifyContent: "space-between",
|
|
27681
|
+
padding: isTheaterMode ? "0 16px" : "10px 16px",
|
|
27682
|
+
maxHeight: isTheaterMode ? 0 : 200,
|
|
27683
|
+
overflow: "hidden",
|
|
27684
|
+
opacity: isTheaterMode ? 0 : 1,
|
|
27685
|
+
borderBottom: isTheaterMode ? "none" : "1px solid rgba(39, 39, 42, 0.5)",
|
|
27686
|
+
background: "rgba(9, 9, 11, 0.8)",
|
|
27687
|
+
backdropFilter: "blur(8px)",
|
|
27688
|
+
flexShrink: 0,
|
|
27689
|
+
transition: "max-height 0.3s ease, opacity 0.3s ease, padding 0.3s ease"
|
|
27690
|
+
}, children: [
|
|
27691
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12, minWidth: 0 }, children: [
|
|
27054
27692
|
onNavigateBack && /* @__PURE__ */ jsx(
|
|
27055
27693
|
"button",
|
|
27056
27694
|
{
|
|
27057
27695
|
onClick: onNavigateBack,
|
|
27058
|
-
|
|
27696
|
+
style: { padding: 6, color: "#a1a1aa", background: "none", border: "none", borderRadius: 8, cursor: "pointer", flexShrink: 0 },
|
|
27059
27697
|
children: /* @__PURE__ */ jsx(ArrowLeft, { size: 18 })
|
|
27060
27698
|
}
|
|
27061
27699
|
),
|
|
27062
|
-
/* @__PURE__ */ jsxs("div", {
|
|
27063
|
-
/* @__PURE__ */ jsx("div", {
|
|
27064
|
-
|
|
27065
|
-
|
|
27066
|
-
|
|
27067
|
-
|
|
27068
|
-
|
|
27700
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10, minWidth: 0 }, children: [
|
|
27701
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
27702
|
+
width: 28,
|
|
27703
|
+
height: 28,
|
|
27704
|
+
borderRadius: 8,
|
|
27705
|
+
display: "flex",
|
|
27706
|
+
alignItems: "center",
|
|
27707
|
+
justifyContent: "center",
|
|
27708
|
+
flexShrink: 0,
|
|
27709
|
+
background: `color-mix(in srgb, ${config.color} 15%, transparent)`
|
|
27710
|
+
}, children: /* @__PURE__ */ jsx(TypeIcon, { size: 14, style: { color: config.color } }) }),
|
|
27711
|
+
/* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
|
|
27712
|
+
/* @__PURE__ */ jsx("h1", { style: { fontSize: 14, fontWeight: 500, color: "white", margin: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: artifact.title }),
|
|
27713
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10, fontSize: 11, color: "#71717a", marginTop: 2 }, children: [
|
|
27714
|
+
/* @__PURE__ */ jsx("span", { style: { color: config.color }, children: config.label }),
|
|
27715
|
+
artifact.sharedAt && /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
27069
27716
|
/* @__PURE__ */ jsx(Calendar, { size: 10 }),
|
|
27070
27717
|
new Date(artifact.sharedAt).toLocaleDateString()
|
|
27071
27718
|
] }),
|
|
27072
|
-
artifact.viewCount !== void 0 && artifact.viewCount > 0 && /* @__PURE__ */ jsxs("span", {
|
|
27719
|
+
artifact.viewCount !== void 0 && artifact.viewCount > 0 && /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
27073
27720
|
/* @__PURE__ */ jsx(Eye, { size: 10 }),
|
|
27074
27721
|
artifact.viewCount
|
|
27075
27722
|
] })
|
|
@@ -27077,29 +27724,120 @@ function PublicArtifactPage({ shareToken, onNavigateBack }) {
|
|
|
27077
27724
|
] })
|
|
27078
27725
|
] })
|
|
27079
27726
|
] }),
|
|
27080
|
-
/* @__PURE__ */ jsxs("div", {
|
|
27081
|
-
|
|
27727
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
27728
|
+
/* @__PURE__ */ jsx(
|
|
27082
27729
|
"button",
|
|
27083
27730
|
{
|
|
27084
|
-
onClick:
|
|
27085
|
-
|
|
27086
|
-
title: "\
|
|
27087
|
-
children: /* @__PURE__ */ jsx(
|
|
27731
|
+
onClick: toggleTheaterMode,
|
|
27732
|
+
style: { padding: 8, color: "#a1a1aa", background: "none", border: "none", borderRadius: 8, cursor: "pointer" },
|
|
27733
|
+
title: "\u6C89\u6D78\u6A21\u5F0F (T)",
|
|
27734
|
+
children: /* @__PURE__ */ jsx(MonitorPlay, { size: 16 })
|
|
27088
27735
|
}
|
|
27089
27736
|
),
|
|
27090
|
-
/* @__PURE__ */ jsx(
|
|
27737
|
+
isFullscreenSupported && /* @__PURE__ */ jsx(
|
|
27091
27738
|
"button",
|
|
27092
27739
|
{
|
|
27093
|
-
onClick:
|
|
27094
|
-
|
|
27095
|
-
title: "\
|
|
27096
|
-
children: /* @__PURE__ */ jsx(
|
|
27740
|
+
onClick: toggleBrowserFullscreen,
|
|
27741
|
+
style: { padding: 8, color: "#a1a1aa", background: "none", border: "none", borderRadius: 8, cursor: "pointer" },
|
|
27742
|
+
title: isBrowserFullscreen ? "\u9000\u51FA\u5168\u5C4F (F)" : "\u5168\u5C4F (F)",
|
|
27743
|
+
children: isBrowserFullscreen ? /* @__PURE__ */ jsx(Minimize2, { size: 16 }) : /* @__PURE__ */ jsx(Maximize2, { size: 16 })
|
|
27744
|
+
}
|
|
27745
|
+
),
|
|
27746
|
+
canDownload && /* @__PURE__ */ jsx(
|
|
27747
|
+
"button",
|
|
27748
|
+
{
|
|
27749
|
+
onClick: handleDownload,
|
|
27750
|
+
style: { padding: 8, color: "#a1a1aa", background: "none", border: "none", borderRadius: 8, cursor: "pointer" },
|
|
27751
|
+
title: "\u4E0B\u8F7D",
|
|
27752
|
+
children: /* @__PURE__ */ jsx(Download, { size: 16 })
|
|
27097
27753
|
}
|
|
27098
27754
|
)
|
|
27099
27755
|
] })
|
|
27100
27756
|
] }),
|
|
27101
|
-
/* @__PURE__ */ jsx("div", {
|
|
27102
|
-
/* @__PURE__ */ jsx("div", {
|
|
27757
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, overflow: "hidden" }, children: renderContent() }),
|
|
27758
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
27759
|
+
display: "flex",
|
|
27760
|
+
alignItems: "center",
|
|
27761
|
+
justifyContent: "center",
|
|
27762
|
+
padding: isTheaterMode ? "0" : "8px 0",
|
|
27763
|
+
maxHeight: isTheaterMode ? 0 : 50,
|
|
27764
|
+
overflow: "hidden",
|
|
27765
|
+
opacity: isTheaterMode ? 0 : 1,
|
|
27766
|
+
borderTop: isTheaterMode ? "none" : "1px solid rgba(39, 39, 42, 0.3)",
|
|
27767
|
+
background: "rgba(9, 9, 11, 0.5)",
|
|
27768
|
+
flexShrink: 0,
|
|
27769
|
+
transition: "max-height 0.3s ease, opacity 0.3s ease, padding 0.3s ease"
|
|
27770
|
+
}, children: /* @__PURE__ */ jsx("span", { style: { fontSize: 10, color: "#52525b" }, children: "Powered by BISHAN Agent" }) }),
|
|
27771
|
+
isTheaterMode && /* @__PURE__ */ jsx(
|
|
27772
|
+
"div",
|
|
27773
|
+
{
|
|
27774
|
+
onMouseEnter: () => setShowTheaterControls(true),
|
|
27775
|
+
style: {
|
|
27776
|
+
position: "fixed",
|
|
27777
|
+
top: 0,
|
|
27778
|
+
left: 0,
|
|
27779
|
+
right: 0,
|
|
27780
|
+
height: 40,
|
|
27781
|
+
zIndex: 99
|
|
27782
|
+
}
|
|
27783
|
+
}
|
|
27784
|
+
),
|
|
27785
|
+
isTheaterMode && /* @__PURE__ */ jsxs("div", { style: {
|
|
27786
|
+
position: "fixed",
|
|
27787
|
+
top: 16,
|
|
27788
|
+
right: 16,
|
|
27789
|
+
zIndex: 100,
|
|
27790
|
+
display: "flex",
|
|
27791
|
+
alignItems: "center",
|
|
27792
|
+
gap: 8,
|
|
27793
|
+
opacity: showTheaterControls ? 1 : 0,
|
|
27794
|
+
transform: showTheaterControls ? "translateY(0)" : "translateY(-8px)",
|
|
27795
|
+
transition: "opacity 0.3s ease, transform 0.3s ease",
|
|
27796
|
+
pointerEvents: showTheaterControls ? "auto" : "none"
|
|
27797
|
+
}, children: [
|
|
27798
|
+
/* @__PURE__ */ jsxs(
|
|
27799
|
+
"button",
|
|
27800
|
+
{
|
|
27801
|
+
onClick: exitTheaterMode,
|
|
27802
|
+
style: {
|
|
27803
|
+
display: "flex",
|
|
27804
|
+
alignItems: "center",
|
|
27805
|
+
gap: 6,
|
|
27806
|
+
padding: "8px 12px",
|
|
27807
|
+
background: "rgba(39, 39, 42, 0.9)",
|
|
27808
|
+
backdropFilter: "blur(8px)",
|
|
27809
|
+
border: "1px solid rgba(63, 63, 70, 0.5)",
|
|
27810
|
+
borderRadius: 8,
|
|
27811
|
+
color: "#a1a1aa",
|
|
27812
|
+
fontSize: 12,
|
|
27813
|
+
cursor: "pointer",
|
|
27814
|
+
whiteSpace: "nowrap"
|
|
27815
|
+
},
|
|
27816
|
+
title: "\u9000\u51FA\u6C89\u6D78\u6A21\u5F0F (ESC)",
|
|
27817
|
+
children: [
|
|
27818
|
+
/* @__PURE__ */ jsx(X, { size: 14 }),
|
|
27819
|
+
"\u9000\u51FA\u6C89\u6D78"
|
|
27820
|
+
]
|
|
27821
|
+
}
|
|
27822
|
+
),
|
|
27823
|
+
isFullscreenSupported && /* @__PURE__ */ jsx(
|
|
27824
|
+
"button",
|
|
27825
|
+
{
|
|
27826
|
+
onClick: toggleBrowserFullscreen,
|
|
27827
|
+
style: {
|
|
27828
|
+
padding: 8,
|
|
27829
|
+
background: "rgba(39, 39, 42, 0.9)",
|
|
27830
|
+
backdropFilter: "blur(8px)",
|
|
27831
|
+
border: "1px solid rgba(63, 63, 70, 0.5)",
|
|
27832
|
+
borderRadius: 8,
|
|
27833
|
+
color: "#a1a1aa",
|
|
27834
|
+
cursor: "pointer"
|
|
27835
|
+
},
|
|
27836
|
+
title: isBrowserFullscreen ? "\u9000\u51FA\u5168\u5C4F (F)" : "\u5168\u5C4F (F)",
|
|
27837
|
+
children: isBrowserFullscreen ? /* @__PURE__ */ jsx(Minimize2, { size: 14 }) : /* @__PURE__ */ jsx(Maximize2, { size: 14 })
|
|
27838
|
+
}
|
|
27839
|
+
)
|
|
27840
|
+
] })
|
|
27103
27841
|
] });
|
|
27104
27842
|
}
|
|
27105
27843
|
var AgentSDKProvider = ({
|