@gendive/chatllm 0.6.7 → 0.6.9
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.js +132 -121
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +132 -121
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -2016,97 +2016,80 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
|
|
|
2016
2016
|
const [isHovered, setIsHovered] = React4.useState(false);
|
|
2017
2017
|
const [copyState, setCopyState] = React4.useState("idle");
|
|
2018
2018
|
const imgRef = React4.useRef(null);
|
|
2019
|
-
const
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
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...");
|
|
2019
|
+
const getImageBlob = async () => {
|
|
2020
|
+
const img = imgRef.current;
|
|
2021
|
+
if (img && img.complete && img.naturalWidth > 0) {
|
|
2022
|
+
try {
|
|
2023
|
+
const canvas = document.createElement("canvas");
|
|
2024
|
+
canvas.width = img.naturalWidth;
|
|
2025
|
+
canvas.height = img.naturalHeight;
|
|
2026
|
+
const ctx = canvas.getContext("2d");
|
|
2027
|
+
if (ctx) {
|
|
2028
|
+
ctx.drawImage(img, 0, 0);
|
|
2029
|
+
const blob = await new Promise((resolve) => {
|
|
2030
|
+
canvas.toBlob(resolve, "image/png");
|
|
2031
|
+
});
|
|
2032
|
+
if (blob) return blob;
|
|
2051
2033
|
}
|
|
2034
|
+
} catch {
|
|
2035
|
+
console.log("Canvas method failed (CORS), trying fetch...");
|
|
2052
2036
|
}
|
|
2037
|
+
}
|
|
2038
|
+
if (!src.startsWith("data:")) {
|
|
2053
2039
|
try {
|
|
2054
2040
|
const response = await fetch(src, { mode: "cors" });
|
|
2055
2041
|
if (response.ok) {
|
|
2056
2042
|
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
|
-
}
|
|
2043
|
+
if (blob.type === "image/png") return blob;
|
|
2065
2044
|
const tempImg = new Image();
|
|
2066
2045
|
const blobUrl = URL.createObjectURL(blob);
|
|
2067
|
-
|
|
2068
|
-
tempImg.onload =
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
if (!ctx) {
|
|
2075
|
-
reject(new Error("Failed to get canvas context"));
|
|
2076
|
-
return;
|
|
2077
|
-
}
|
|
2046
|
+
return new Promise((resolve) => {
|
|
2047
|
+
tempImg.onload = () => {
|
|
2048
|
+
const canvas = document.createElement("canvas");
|
|
2049
|
+
canvas.width = tempImg.naturalWidth;
|
|
2050
|
+
canvas.height = tempImg.naturalHeight;
|
|
2051
|
+
const ctx = canvas.getContext("2d");
|
|
2052
|
+
if (ctx) {
|
|
2078
2053
|
ctx.drawImage(tempImg, 0, 0);
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2054
|
+
canvas.toBlob((pngBlob) => {
|
|
2055
|
+
URL.revokeObjectURL(blobUrl);
|
|
2056
|
+
resolve(pngBlob);
|
|
2057
|
+
}, "image/png");
|
|
2058
|
+
} else {
|
|
2082
2059
|
URL.revokeObjectURL(blobUrl);
|
|
2083
|
-
|
|
2084
|
-
await navigator.clipboard.write([
|
|
2085
|
-
new ClipboardItem({ "image/png": pngBlob })
|
|
2086
|
-
]);
|
|
2087
|
-
setCopyState("copied");
|
|
2088
|
-
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2089
|
-
resolve();
|
|
2090
|
-
} else {
|
|
2091
|
-
reject(new Error("Failed to create PNG blob"));
|
|
2092
|
-
}
|
|
2093
|
-
} catch (err) {
|
|
2094
|
-
reject(err);
|
|
2060
|
+
resolve(null);
|
|
2095
2061
|
}
|
|
2096
2062
|
};
|
|
2097
2063
|
tempImg.onerror = () => {
|
|
2098
2064
|
URL.revokeObjectURL(blobUrl);
|
|
2099
|
-
|
|
2065
|
+
resolve(null);
|
|
2100
2066
|
};
|
|
2101
2067
|
tempImg.src = blobUrl;
|
|
2102
2068
|
});
|
|
2103
|
-
return;
|
|
2104
2069
|
}
|
|
2105
2070
|
} catch {
|
|
2106
|
-
console.log("Fetch method failed
|
|
2071
|
+
console.log("Fetch method failed");
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
return null;
|
|
2075
|
+
};
|
|
2076
|
+
const handleCopy = async () => {
|
|
2077
|
+
setCopyState("copying");
|
|
2078
|
+
try {
|
|
2079
|
+
if (!navigator.clipboard?.write) {
|
|
2080
|
+
await navigator.clipboard.writeText(src);
|
|
2081
|
+
setCopyState("copied");
|
|
2082
|
+
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
const blob = await getImageBlob();
|
|
2086
|
+
if (blob) {
|
|
2087
|
+
await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
|
|
2088
|
+
setCopyState("copied");
|
|
2089
|
+
} else {
|
|
2090
|
+
await navigator.clipboard.writeText(src);
|
|
2091
|
+
setCopyState("copied");
|
|
2107
2092
|
}
|
|
2108
|
-
await navigator.clipboard.writeText(src);
|
|
2109
|
-
setCopyState("copied");
|
|
2110
2093
|
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2111
2094
|
} catch (error) {
|
|
2112
2095
|
console.error("Failed to copy image:", error);
|
|
@@ -2114,27 +2097,34 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
|
|
|
2114
2097
|
setTimeout(() => setCopyState("idle"), 2e3);
|
|
2115
2098
|
}
|
|
2116
2099
|
};
|
|
2117
|
-
const
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2100
|
+
const handleDownload = async () => {
|
|
2101
|
+
try {
|
|
2102
|
+
const blob = await getImageBlob();
|
|
2103
|
+
const url = blob ? URL.createObjectURL(blob) : src;
|
|
2104
|
+
const link = document.createElement("a");
|
|
2105
|
+
link.href = url;
|
|
2106
|
+
link.download = alt || `image-${Date.now()}.png`;
|
|
2107
|
+
document.body.appendChild(link);
|
|
2108
|
+
link.click();
|
|
2109
|
+
document.body.removeChild(link);
|
|
2110
|
+
if (blob) URL.revokeObjectURL(url);
|
|
2111
|
+
} catch (error) {
|
|
2112
|
+
console.error("Failed to download image:", error);
|
|
2113
|
+
window.open(src, "_blank");
|
|
2127
2114
|
}
|
|
2128
2115
|
};
|
|
2129
|
-
const
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2116
|
+
const toolbarButtonStyle = {
|
|
2117
|
+
display: "flex",
|
|
2118
|
+
alignItems: "center",
|
|
2119
|
+
justifyContent: "center",
|
|
2120
|
+
width: "36px",
|
|
2121
|
+
height: "36px",
|
|
2122
|
+
backgroundColor: "transparent",
|
|
2123
|
+
border: "none",
|
|
2124
|
+
borderRadius: "8px",
|
|
2125
|
+
cursor: "pointer",
|
|
2126
|
+
color: "var(--chatllm-text-muted, #9ca3af)",
|
|
2127
|
+
transition: "background-color 0.2s, color 0.2s"
|
|
2138
2128
|
};
|
|
2139
2129
|
return /* @__PURE__ */ jsxs5(
|
|
2140
2130
|
"div",
|
|
@@ -2154,7 +2144,7 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
|
|
|
2154
2144
|
src,
|
|
2155
2145
|
alt,
|
|
2156
2146
|
className: "chatllm-image",
|
|
2157
|
-
crossOrigin: "anonymous",
|
|
2147
|
+
crossOrigin: src.startsWith("data:") ? void 0 : "anonymous",
|
|
2158
2148
|
style: {
|
|
2159
2149
|
maxWidth: "100%",
|
|
2160
2150
|
borderRadius: "8px",
|
|
@@ -2164,50 +2154,71 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
|
|
|
2164
2154
|
}
|
|
2165
2155
|
),
|
|
2166
2156
|
/* @__PURE__ */ jsxs5(
|
|
2167
|
-
"
|
|
2157
|
+
"div",
|
|
2168
2158
|
{
|
|
2169
|
-
onClick: handleCopyImage,
|
|
2170
|
-
disabled: copyState === "copying",
|
|
2171
2159
|
style: {
|
|
2172
2160
|
position: "absolute",
|
|
2173
|
-
|
|
2174
|
-
|
|
2161
|
+
bottom: "0",
|
|
2162
|
+
left: "0",
|
|
2163
|
+
right: "0",
|
|
2175
2164
|
display: "flex",
|
|
2176
2165
|
alignItems: "center",
|
|
2177
|
-
gap: "
|
|
2178
|
-
padding: "
|
|
2179
|
-
backgroundColor: "
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
fontWeight: 500,
|
|
2185
|
-
cursor: copyState === "copying" ? "wait" : "pointer",
|
|
2186
|
-
opacity: isHovered || copyState !== "idle" ? 1 : 0,
|
|
2187
|
-
transform: isHovered || copyState !== "idle" ? "translateY(0)" : "translateY(-4px)",
|
|
2166
|
+
gap: "4px",
|
|
2167
|
+
padding: "8px 12px",
|
|
2168
|
+
backgroundColor: "var(--chatllm-bg, #ffffff)",
|
|
2169
|
+
borderTop: "1px solid var(--chatllm-border-light, #e5e7eb)",
|
|
2170
|
+
borderRadius: "0 0 8px 8px",
|
|
2171
|
+
opacity: isHovered ? 1 : 0,
|
|
2172
|
+
transform: isHovered ? "translateY(0)" : "translateY(8px)",
|
|
2188
2173
|
transition: "opacity 0.2s ease, transform 0.2s ease",
|
|
2189
|
-
|
|
2190
|
-
boxShadow: "0 2px 8px rgba(0, 0, 0, 0.2)"
|
|
2174
|
+
pointerEvents: isHovered ? "auto" : "none"
|
|
2191
2175
|
},
|
|
2192
2176
|
children: [
|
|
2193
2177
|
/* @__PURE__ */ jsx6(
|
|
2194
|
-
"
|
|
2178
|
+
"button",
|
|
2195
2179
|
{
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2180
|
+
onClick: handleCopy,
|
|
2181
|
+
disabled: copyState === "copying",
|
|
2182
|
+
style: {
|
|
2183
|
+
...toolbarButtonStyle,
|
|
2184
|
+
color: copyState === "copied" ? "var(--chatllm-success, #22c55e)" : copyState === "error" ? "var(--chatllm-error, #ef4444)" : "var(--chatllm-text-muted, #9ca3af)"
|
|
2185
|
+
},
|
|
2186
|
+
title: copyState === "copied" ? "\uBCF5\uC0AC\uB428!" : copyState === "error" ? "\uBCF5\uC0AC \uC2E4\uD328" : "\uBCF5\uC0AC\uD558\uAE30",
|
|
2187
|
+
onMouseOver: (e) => {
|
|
2188
|
+
e.currentTarget.style.backgroundColor = "var(--chatllm-bg-hover, #f3f4f6)";
|
|
2189
|
+
e.currentTarget.style.color = "var(--chatllm-text, #1f2937)";
|
|
2190
|
+
},
|
|
2191
|
+
onMouseOut: (e) => {
|
|
2192
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
2193
|
+
e.currentTarget.style.color = copyState === "copied" ? "var(--chatllm-success, #22c55e)" : "var(--chatllm-text-muted, #9ca3af)";
|
|
2194
|
+
},
|
|
2195
|
+
children: /* @__PURE__ */ jsx6("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: copyState === "copied" ? /* @__PURE__ */ jsx6("polyline", { points: "20 6 9 17 4 12" }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2205
2196
|
/* @__PURE__ */ jsx6("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
|
|
2206
2197
|
/* @__PURE__ */ jsx6("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
2207
|
-
] })
|
|
2198
|
+
] }) })
|
|
2208
2199
|
}
|
|
2209
2200
|
),
|
|
2210
|
-
|
|
2201
|
+
/* @__PURE__ */ jsx6(
|
|
2202
|
+
"button",
|
|
2203
|
+
{
|
|
2204
|
+
onClick: handleDownload,
|
|
2205
|
+
style: toolbarButtonStyle,
|
|
2206
|
+
title: "\uB2E4\uC6B4\uB85C\uB4DC",
|
|
2207
|
+
onMouseOver: (e) => {
|
|
2208
|
+
e.currentTarget.style.backgroundColor = "var(--chatllm-bg-hover, #f3f4f6)";
|
|
2209
|
+
e.currentTarget.style.color = "var(--chatllm-text, #1f2937)";
|
|
2210
|
+
},
|
|
2211
|
+
onMouseOut: (e) => {
|
|
2212
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
2213
|
+
e.currentTarget.style.color = "var(--chatllm-text-muted, #9ca3af)";
|
|
2214
|
+
},
|
|
2215
|
+
children: /* @__PURE__ */ jsxs5("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2216
|
+
/* @__PURE__ */ jsx6("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
2217
|
+
/* @__PURE__ */ jsx6("polyline", { points: "7 10 12 15 17 10" }),
|
|
2218
|
+
/* @__PURE__ */ jsx6("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
|
|
2219
|
+
] })
|
|
2220
|
+
}
|
|
2221
|
+
)
|
|
2211
2222
|
]
|
|
2212
2223
|
}
|
|
2213
2224
|
)
|