@copilotz/chat-ui 0.1.10 → 0.1.11
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 +58 -32
- 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 +96 -71
- 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 })
|
|
@@ -2855,7 +2863,23 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
|
|
|
2855
2863
|
});
|
|
2856
2864
|
var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ attachment, onRemove }) {
|
|
2857
2865
|
const [isPlaying, setIsPlaying] = (0, import_react5.useState)(false);
|
|
2866
|
+
const [audioPlaybackSrc, setAudioPlaybackSrc] = (0, import_react5.useState)(attachment.dataUrl);
|
|
2858
2867
|
const audioRef = (0, import_react5.useRef)(null);
|
|
2868
|
+
(0, import_react5.useEffect)(() => {
|
|
2869
|
+
if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
|
|
2870
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
2871
|
+
return;
|
|
2872
|
+
}
|
|
2873
|
+
const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);
|
|
2874
|
+
if (!objectUrl) {
|
|
2875
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
setAudioPlaybackSrc(objectUrl);
|
|
2879
|
+
return () => {
|
|
2880
|
+
URL.revokeObjectURL(objectUrl);
|
|
2881
|
+
};
|
|
2882
|
+
}, [attachment.kind, attachment.dataUrl]);
|
|
2859
2883
|
const handlePlayPause = () => {
|
|
2860
2884
|
if (audioRef.current) {
|
|
2861
2885
|
if (isPlaying) {
|
|
@@ -2934,10 +2958,11 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
|
|
|
2934
2958
|
"audio",
|
|
2935
2959
|
{
|
|
2936
2960
|
ref: audioRef,
|
|
2937
|
-
src: attachment.dataUrl,
|
|
2938
2961
|
onPlay: () => setIsPlaying(true),
|
|
2939
2962
|
onPause: () => setIsPlaying(false),
|
|
2940
|
-
onEnded: () => setIsPlaying(false)
|
|
2963
|
+
onEnded: () => setIsPlaying(false),
|
|
2964
|
+
preload: "metadata",
|
|
2965
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
|
|
2941
2966
|
}
|
|
2942
2967
|
),
|
|
2943
2968
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
@@ -4649,6 +4674,7 @@ var chatUtils = {
|
|
|
4649
4674
|
chatUtils,
|
|
4650
4675
|
cn,
|
|
4651
4676
|
configUtils,
|
|
4677
|
+
createObjectUrlFromDataUrl,
|
|
4652
4678
|
defaultChatConfig,
|
|
4653
4679
|
featureFlags,
|
|
4654
4680
|
formatDate,
|