@copilotz/chat-ui 0.1.10 → 0.1.12
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.cjs +62 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +100 -73
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
chatUtils: () => chatUtils,
|
|
44
44
|
cn: () => cn,
|
|
45
45
|
configUtils: () => configUtils,
|
|
46
|
+
createObjectUrlFromDataUrl: () => createObjectUrlFromDataUrl,
|
|
46
47
|
defaultChatConfig: () => defaultChatConfig,
|
|
47
48
|
featureFlags: () => featureFlags,
|
|
48
49
|
formatDate: () => formatDate,
|
|
@@ -333,6 +334,24 @@ var formatDate = (timestamp, labels) => {
|
|
|
333
334
|
});
|
|
334
335
|
}
|
|
335
336
|
};
|
|
337
|
+
var createObjectUrlFromDataUrl = (dataUrl) => {
|
|
338
|
+
const match = dataUrl.match(/^data:(.+?);base64,(.+)$/s);
|
|
339
|
+
if (!match) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
const [, mimeType, base64] = match;
|
|
344
|
+
const binary = atob(base64);
|
|
345
|
+
const bytes = new Uint8Array(binary.length);
|
|
346
|
+
for (let i = 0; i < binary.length; i += 1) {
|
|
347
|
+
bytes[i] = binary.charCodeAt(i);
|
|
348
|
+
}
|
|
349
|
+
const blob = new Blob([bytes], { type: mimeType || "application/octet-stream" });
|
|
350
|
+
return URL.createObjectURL(blob);
|
|
351
|
+
} catch {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
};
|
|
336
355
|
|
|
337
356
|
// src/components/ui/button.tsx
|
|
338
357
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -713,26 +732,22 @@ var StreamingText = (0, import_react.memo)(function StreamingText2({
|
|
|
713
732
|
] });
|
|
714
733
|
});
|
|
715
734
|
var MediaRenderer = (0, import_react.memo)(function MediaRenderer2({ attachment }) {
|
|
716
|
-
const [
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
if (isPlaying) {
|
|
722
|
-
audioRef.current.pause();
|
|
723
|
-
} else {
|
|
724
|
-
audioRef.current.play();
|
|
725
|
-
}
|
|
726
|
-
setIsPlaying(!isPlaying);
|
|
727
|
-
} else if (attachment.kind === "video" && videoRef.current) {
|
|
728
|
-
if (isPlaying) {
|
|
729
|
-
videoRef.current.pause();
|
|
730
|
-
} else {
|
|
731
|
-
videoRef.current.play();
|
|
732
|
-
}
|
|
733
|
-
setIsPlaying(!isPlaying);
|
|
735
|
+
const [audioPlaybackSrc, setAudioPlaybackSrc] = (0, import_react.useState)(attachment.dataUrl);
|
|
736
|
+
(0, import_react.useEffect)(() => {
|
|
737
|
+
if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
|
|
738
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
739
|
+
return;
|
|
734
740
|
}
|
|
735
|
-
|
|
741
|
+
const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);
|
|
742
|
+
if (!objectUrl) {
|
|
743
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
setAudioPlaybackSrc(objectUrl);
|
|
747
|
+
return () => {
|
|
748
|
+
URL.revokeObjectURL(objectUrl);
|
|
749
|
+
};
|
|
750
|
+
}, [attachment.kind, attachment.dataUrl]);
|
|
736
751
|
const formatDuration = (ms) => {
|
|
737
752
|
if (!ms) return "";
|
|
738
753
|
const seconds = Math.floor(ms / 1e3);
|
|
@@ -757,13 +772,10 @@ var MediaRenderer = (0, import_react.memo)(function MediaRenderer2({ attachment
|
|
|
757
772
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex w-full max-w-md py-0 min-w-64 items-center gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
758
773
|
"audio",
|
|
759
774
|
{
|
|
760
|
-
ref: audioRef,
|
|
761
|
-
src: attachment.dataUrl,
|
|
762
|
-
onPlay: () => setIsPlaying(true),
|
|
763
|
-
onPause: () => setIsPlaying(false),
|
|
764
|
-
onEnded: () => setIsPlaying(false),
|
|
765
775
|
className: "w-full mt-2",
|
|
766
|
-
|
|
776
|
+
preload: "metadata",
|
|
777
|
+
controls: true,
|
|
778
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
|
|
767
779
|
}
|
|
768
780
|
) });
|
|
769
781
|
case "video":
|
|
@@ -771,14 +783,10 @@ var MediaRenderer = (0, import_react.memo)(function MediaRenderer2({ attachment
|
|
|
771
783
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
772
784
|
"video",
|
|
773
785
|
{
|
|
774
|
-
ref: videoRef,
|
|
775
786
|
src: attachment.dataUrl,
|
|
776
787
|
poster: attachment.poster,
|
|
777
788
|
controls: true,
|
|
778
|
-
className: "w-full h-auto"
|
|
779
|
-
onPlay: () => setIsPlaying(true),
|
|
780
|
-
onPause: () => setIsPlaying(false),
|
|
781
|
-
onEnded: () => setIsPlaying(false)
|
|
789
|
+
className: "w-full h-auto"
|
|
782
790
|
}
|
|
783
791
|
),
|
|
784
792
|
attachment.fileName && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-2", children: attachment.fileName })
|
|
@@ -934,6 +942,7 @@ var Message = (0, import_react.memo)(({
|
|
|
934
942
|
contentVisibility: "auto",
|
|
935
943
|
containIntrinsicSize: "1px 400px"
|
|
936
944
|
} : void 0;
|
|
945
|
+
const horizontalOffsetClass = showAvatar ? messageIsUser ? compactMode ? "mr-9" : "mr-11" : compactMode ? "ml-9" : "ml-11" : "";
|
|
937
946
|
const handleCopy = async () => {
|
|
938
947
|
try {
|
|
939
948
|
await navigator.clipboard.writeText(message.content);
|
|
@@ -989,7 +998,7 @@ var Message = (0, import_react.memo)(({
|
|
|
989
998
|
message.isEdited && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Badge, { variant: "outline", className: "text-xs", children: "editado" })
|
|
990
999
|
] })
|
|
991
1000
|
] }),
|
|
992
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${
|
|
1001
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${horizontalOffsetClass}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `relative inline-flex flex-col overflow-hidden text-left ${messageIsUser ? "rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]" : "max-w-full"}`, children: [
|
|
993
1002
|
isEditing ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-2", children: [
|
|
994
1003
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
995
1004
|
Textarea,
|
|
@@ -2855,7 +2864,23 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
|
|
|
2855
2864
|
});
|
|
2856
2865
|
var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ attachment, onRemove }) {
|
|
2857
2866
|
const [isPlaying, setIsPlaying] = (0, import_react5.useState)(false);
|
|
2867
|
+
const [audioPlaybackSrc, setAudioPlaybackSrc] = (0, import_react5.useState)(attachment.dataUrl);
|
|
2858
2868
|
const audioRef = (0, import_react5.useRef)(null);
|
|
2869
|
+
(0, import_react5.useEffect)(() => {
|
|
2870
|
+
if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
|
|
2871
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
2872
|
+
return;
|
|
2873
|
+
}
|
|
2874
|
+
const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);
|
|
2875
|
+
if (!objectUrl) {
|
|
2876
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
2877
|
+
return;
|
|
2878
|
+
}
|
|
2879
|
+
setAudioPlaybackSrc(objectUrl);
|
|
2880
|
+
return () => {
|
|
2881
|
+
URL.revokeObjectURL(objectUrl);
|
|
2882
|
+
};
|
|
2883
|
+
}, [attachment.kind, attachment.dataUrl]);
|
|
2859
2884
|
const handlePlayPause = () => {
|
|
2860
2885
|
if (audioRef.current) {
|
|
2861
2886
|
if (isPlaying) {
|
|
@@ -2934,10 +2959,11 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
|
|
|
2934
2959
|
"audio",
|
|
2935
2960
|
{
|
|
2936
2961
|
ref: audioRef,
|
|
2937
|
-
src: attachment.dataUrl,
|
|
2938
2962
|
onPlay: () => setIsPlaying(true),
|
|
2939
2963
|
onPause: () => setIsPlaying(false),
|
|
2940
|
-
onEnded: () => setIsPlaying(false)
|
|
2964
|
+
onEnded: () => setIsPlaying(false),
|
|
2965
|
+
preload: "metadata",
|
|
2966
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
|
|
2941
2967
|
}
|
|
2942
2968
|
),
|
|
2943
2969
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
@@ -4087,7 +4113,8 @@ var ChatUI = ({
|
|
|
4087
4113
|
const renderInlineSuggestions = (messageId) => {
|
|
4088
4114
|
const items = messageSuggestions?.[messageId];
|
|
4089
4115
|
if (!items || items.length === 0) return null;
|
|
4090
|
-
|
|
4116
|
+
const inlineSuggestionOffsetClass = config.ui.showAvatars ? config.ui.compactMode ? "ml-9" : "ml-11" : "";
|
|
4117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
4091
4118
|
"button",
|
|
4092
4119
|
{
|
|
4093
4120
|
type: "button",
|
|
@@ -4649,6 +4676,7 @@ var chatUtils = {
|
|
|
4649
4676
|
chatUtils,
|
|
4650
4677
|
cn,
|
|
4651
4678
|
configUtils,
|
|
4679
|
+
createObjectUrlFromDataUrl,
|
|
4652
4680
|
defaultChatConfig,
|
|
4653
4681
|
featureFlags,
|
|
4654
4682
|
formatDate,
|