@gendive/chatllm 0.6.6 → 0.6.7
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/react/index.d.mts +4 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.js +91 -39
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +91 -39
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -1024,7 +1024,9 @@ var ChatHeader = ({
|
|
|
1024
1024
|
onModelChange,
|
|
1025
1025
|
onSettingsOpen,
|
|
1026
1026
|
onSidebarToggle,
|
|
1027
|
-
sidebarOpen
|
|
1027
|
+
sidebarOpen,
|
|
1028
|
+
showModelSelector = true,
|
|
1029
|
+
showSettings = true
|
|
1028
1030
|
}) => {
|
|
1029
1031
|
const [modelDropdownOpen, setModelDropdownOpen] = useState2(false);
|
|
1030
1032
|
const currentModel = models.find((m) => m.id === model);
|
|
@@ -1081,7 +1083,7 @@ var ChatHeader = ({
|
|
|
1081
1083
|
)
|
|
1082
1084
|
] }),
|
|
1083
1085
|
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
1084
|
-
/* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
1086
|
+
showModelSelector && /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
1085
1087
|
/* @__PURE__ */ jsxs2(
|
|
1086
1088
|
"button",
|
|
1087
1089
|
{
|
|
@@ -1248,7 +1250,7 @@ var ChatHeader = ({
|
|
|
1248
1250
|
)
|
|
1249
1251
|
] })
|
|
1250
1252
|
] }),
|
|
1251
|
-
/* @__PURE__ */ jsx3(
|
|
1253
|
+
showSettings && /* @__PURE__ */ jsx3(
|
|
1252
1254
|
"button",
|
|
1253
1255
|
{
|
|
1254
1256
|
onClick: onSettingsOpen,
|
|
@@ -2013,53 +2015,99 @@ var CodeBlock = ({ language, code }) => {
|
|
|
2013
2015
|
var ImageWithCopyButton = ({ src, alt, imageKey }) => {
|
|
2014
2016
|
const [isHovered, setIsHovered] = React4.useState(false);
|
|
2015
2017
|
const [copyState, setCopyState] = React4.useState("idle");
|
|
2018
|
+
const imgRef = React4.useRef(null);
|
|
2016
2019
|
const handleCopyImage = async () => {
|
|
2017
2020
|
setCopyState("copying");
|
|
2018
2021
|
try {
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2022
|
+
if (!navigator.clipboard || !navigator.clipboard.write) {
|
|
2023
|
+
await navigator.clipboard.writeText(src);
|
|
2024
|
+
setCopyState("copied");
|
|
2025
|
+
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2028
|
+
const img = imgRef.current;
|
|
2029
|
+
if (img && img.complete && img.naturalWidth > 0) {
|
|
2030
|
+
try {
|
|
2031
|
+
const canvas = document.createElement("canvas");
|
|
2032
|
+
canvas.width = img.naturalWidth;
|
|
2033
|
+
canvas.height = img.naturalHeight;
|
|
2034
|
+
const ctx = canvas.getContext("2d");
|
|
2035
|
+
if (ctx) {
|
|
2036
|
+
ctx.drawImage(img, 0, 0);
|
|
2037
|
+
const blob = await new Promise((resolve) => {
|
|
2038
|
+
canvas.toBlob(resolve, "image/png");
|
|
2039
|
+
});
|
|
2040
|
+
if (blob) {
|
|
2041
|
+
await navigator.clipboard.write([
|
|
2042
|
+
new ClipboardItem({ "image/png": blob })
|
|
2043
|
+
]);
|
|
2044
|
+
setCopyState("copied");
|
|
2045
|
+
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
} catch {
|
|
2050
|
+
console.log("Canvas method failed (CORS), trying fetch...");
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
try {
|
|
2054
|
+
const response = await fetch(src, { mode: "cors" });
|
|
2055
|
+
if (response.ok) {
|
|
2056
|
+
const blob = await response.blob();
|
|
2057
|
+
if (blob.type === "image/png") {
|
|
2058
|
+
await navigator.clipboard.write([
|
|
2059
|
+
new ClipboardItem({ "image/png": blob })
|
|
2060
|
+
]);
|
|
2061
|
+
setCopyState("copied");
|
|
2062
|
+
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
const tempImg = new Image();
|
|
2066
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
2027
2067
|
await new Promise((resolve, reject) => {
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2068
|
+
tempImg.onload = async () => {
|
|
2069
|
+
try {
|
|
2070
|
+
const canvas = document.createElement("canvas");
|
|
2071
|
+
canvas.width = tempImg.naturalWidth;
|
|
2072
|
+
canvas.height = tempImg.naturalHeight;
|
|
2073
|
+
const ctx = canvas.getContext("2d");
|
|
2074
|
+
if (!ctx) {
|
|
2075
|
+
reject(new Error("Failed to get canvas context"));
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
ctx.drawImage(tempImg, 0, 0);
|
|
2079
|
+
const pngBlob = await new Promise((res) => {
|
|
2080
|
+
canvas.toBlob(res, "image/png");
|
|
2081
|
+
});
|
|
2082
|
+
URL.revokeObjectURL(blobUrl);
|
|
2039
2083
|
if (pngBlob) {
|
|
2040
|
-
|
|
2084
|
+
await navigator.clipboard.write([
|
|
2085
|
+
new ClipboardItem({ "image/png": pngBlob })
|
|
2086
|
+
]);
|
|
2087
|
+
setCopyState("copied");
|
|
2088
|
+
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2041
2089
|
resolve();
|
|
2042
2090
|
} else {
|
|
2043
|
-
reject(new Error("Failed to
|
|
2091
|
+
reject(new Error("Failed to create PNG blob"));
|
|
2044
2092
|
}
|
|
2045
|
-
}
|
|
2093
|
+
} catch (err) {
|
|
2094
|
+
reject(err);
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
2097
|
+
tempImg.onerror = () => {
|
|
2098
|
+
URL.revokeObjectURL(blobUrl);
|
|
2099
|
+
reject(new Error("Failed to load image"));
|
|
2046
2100
|
};
|
|
2047
|
-
|
|
2048
|
-
img.src = URL.createObjectURL(blob);
|
|
2101
|
+
tempImg.src = blobUrl;
|
|
2049
2102
|
});
|
|
2103
|
+
return;
|
|
2050
2104
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
[imageBlob.type]: imageBlob
|
|
2054
|
-
})
|
|
2055
|
-
]);
|
|
2056
|
-
setCopyState("copied");
|
|
2057
|
-
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2058
|
-
} else {
|
|
2059
|
-
await navigator.clipboard.writeText(src);
|
|
2060
|
-
setCopyState("copied");
|
|
2061
|
-
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2105
|
+
} catch {
|
|
2106
|
+
console.log("Fetch method failed, using URL fallback");
|
|
2062
2107
|
}
|
|
2108
|
+
await navigator.clipboard.writeText(src);
|
|
2109
|
+
setCopyState("copied");
|
|
2110
|
+
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2063
2111
|
} catch (error) {
|
|
2064
2112
|
console.error("Failed to copy image:", error);
|
|
2065
2113
|
setCopyState("error");
|
|
@@ -2102,9 +2150,11 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
|
|
|
2102
2150
|
/* @__PURE__ */ jsx6(
|
|
2103
2151
|
"img",
|
|
2104
2152
|
{
|
|
2153
|
+
ref: imgRef,
|
|
2105
2154
|
src,
|
|
2106
2155
|
alt,
|
|
2107
2156
|
className: "chatllm-image",
|
|
2157
|
+
crossOrigin: "anonymous",
|
|
2108
2158
|
style: {
|
|
2109
2159
|
maxWidth: "100%",
|
|
2110
2160
|
borderRadius: "8px",
|
|
@@ -4472,7 +4522,9 @@ var ChatUI = ({
|
|
|
4472
4522
|
onModelChange: setModel,
|
|
4473
4523
|
onSettingsOpen: openSettings,
|
|
4474
4524
|
onSidebarToggle: toggleSidebar,
|
|
4475
|
-
sidebarOpen
|
|
4525
|
+
sidebarOpen,
|
|
4526
|
+
showModelSelector,
|
|
4527
|
+
showSettings
|
|
4476
4528
|
}
|
|
4477
4529
|
),
|
|
4478
4530
|
messages.length === 0 ? /* @__PURE__ */ jsx12(
|