@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.d.cts
CHANGED
|
@@ -592,6 +592,7 @@ declare const configUtils: {
|
|
|
592
592
|
|
|
593
593
|
declare function cn(...inputs: ClassValue[]): string;
|
|
594
594
|
declare const formatDate: (timestamp: number, labels?: ChatConfig["labels"]) => string;
|
|
595
|
+
declare const createObjectUrlFromDataUrl: (dataUrl: string) => string | null;
|
|
595
596
|
|
|
596
597
|
declare const chatUtils: {
|
|
597
598
|
generateId: () => string;
|
|
@@ -602,4 +603,4 @@ declare const chatUtils: {
|
|
|
602
603
|
generateThreadTitle: (firstMessage: string) => string;
|
|
603
604
|
};
|
|
604
605
|
|
|
605
|
-
export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
|
|
606
|
+
export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, createObjectUrlFromDataUrl, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -592,6 +592,7 @@ declare const configUtils: {
|
|
|
592
592
|
|
|
593
593
|
declare function cn(...inputs: ClassValue[]): string;
|
|
594
594
|
declare const formatDate: (timestamp: number, labels?: ChatConfig["labels"]) => string;
|
|
595
|
+
declare const createObjectUrlFromDataUrl: (dataUrl: string) => string | null;
|
|
595
596
|
|
|
596
597
|
declare const chatUtils: {
|
|
597
598
|
generateId: () => string;
|
|
@@ -602,4 +603,4 @@ declare const chatUtils: {
|
|
|
602
603
|
generateThreadTitle: (firstMessage: string) => string;
|
|
603
604
|
};
|
|
604
605
|
|
|
605
|
-
export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
|
|
606
|
+
export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, createObjectUrlFromDataUrl, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/chat/ChatUI.tsx
|
|
2
|
-
import { useState as useState8, useEffect as
|
|
2
|
+
import { useState as useState8, useEffect as useEffect10, useRef as useRef6, useCallback as useCallback4, useMemo as useMemo4 } from "react";
|
|
3
3
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
4
4
|
|
|
5
5
|
// src/config/chatConfig.ts
|
|
@@ -245,7 +245,7 @@ var configUtils = {
|
|
|
245
245
|
};
|
|
246
246
|
|
|
247
247
|
// src/components/chat/Message.tsx
|
|
248
|
-
import React, { useState,
|
|
248
|
+
import React, { useState, useMemo, useEffect, memo } from "react";
|
|
249
249
|
import ReactMarkdown from "react-markdown";
|
|
250
250
|
import remarkGfm from "remark-gfm";
|
|
251
251
|
import rehypeHighlight from "rehype-highlight";
|
|
@@ -278,6 +278,24 @@ var formatDate = (timestamp, labels) => {
|
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
};
|
|
281
|
+
var createObjectUrlFromDataUrl = (dataUrl) => {
|
|
282
|
+
const match = dataUrl.match(/^data:(.+?);base64,(.+)$/s);
|
|
283
|
+
if (!match) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
const [, mimeType, base64] = match;
|
|
288
|
+
const binary = atob(base64);
|
|
289
|
+
const bytes = new Uint8Array(binary.length);
|
|
290
|
+
for (let i = 0; i < binary.length; i += 1) {
|
|
291
|
+
bytes[i] = binary.charCodeAt(i);
|
|
292
|
+
}
|
|
293
|
+
const blob = new Blob([bytes], { type: mimeType || "application/octet-stream" });
|
|
294
|
+
return URL.createObjectURL(blob);
|
|
295
|
+
} catch {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
281
299
|
|
|
282
300
|
// src/components/ui/button.tsx
|
|
283
301
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -668,26 +686,22 @@ var StreamingText = memo(function StreamingText2({
|
|
|
668
686
|
] });
|
|
669
687
|
});
|
|
670
688
|
var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
|
|
671
|
-
const [
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
if (isPlaying) {
|
|
677
|
-
audioRef.current.pause();
|
|
678
|
-
} else {
|
|
679
|
-
audioRef.current.play();
|
|
680
|
-
}
|
|
681
|
-
setIsPlaying(!isPlaying);
|
|
682
|
-
} else if (attachment.kind === "video" && videoRef.current) {
|
|
683
|
-
if (isPlaying) {
|
|
684
|
-
videoRef.current.pause();
|
|
685
|
-
} else {
|
|
686
|
-
videoRef.current.play();
|
|
687
|
-
}
|
|
688
|
-
setIsPlaying(!isPlaying);
|
|
689
|
+
const [audioPlaybackSrc, setAudioPlaybackSrc] = useState(attachment.dataUrl);
|
|
690
|
+
useEffect(() => {
|
|
691
|
+
if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
|
|
692
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
693
|
+
return;
|
|
689
694
|
}
|
|
690
|
-
|
|
695
|
+
const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);
|
|
696
|
+
if (!objectUrl) {
|
|
697
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
setAudioPlaybackSrc(objectUrl);
|
|
701
|
+
return () => {
|
|
702
|
+
URL.revokeObjectURL(objectUrl);
|
|
703
|
+
};
|
|
704
|
+
}, [attachment.kind, attachment.dataUrl]);
|
|
691
705
|
const formatDuration = (ms) => {
|
|
692
706
|
if (!ms) return "";
|
|
693
707
|
const seconds = Math.floor(ms / 1e3);
|
|
@@ -712,13 +726,10 @@ var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
|
|
|
712
726
|
return /* @__PURE__ */ jsx7("div", { className: "flex w-full max-w-md py-0 min-w-64 items-center gap-3", children: /* @__PURE__ */ jsx7(
|
|
713
727
|
"audio",
|
|
714
728
|
{
|
|
715
|
-
ref: audioRef,
|
|
716
|
-
src: attachment.dataUrl,
|
|
717
|
-
onPlay: () => setIsPlaying(true),
|
|
718
|
-
onPause: () => setIsPlaying(false),
|
|
719
|
-
onEnded: () => setIsPlaying(false),
|
|
720
729
|
className: "w-full mt-2",
|
|
721
|
-
|
|
730
|
+
preload: "metadata",
|
|
731
|
+
controls: true,
|
|
732
|
+
children: /* @__PURE__ */ jsx7("source", { src: audioPlaybackSrc, type: attachment.mimeType })
|
|
722
733
|
}
|
|
723
734
|
) });
|
|
724
735
|
case "video":
|
|
@@ -726,14 +737,10 @@ var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
|
|
|
726
737
|
/* @__PURE__ */ jsx7(
|
|
727
738
|
"video",
|
|
728
739
|
{
|
|
729
|
-
ref: videoRef,
|
|
730
740
|
src: attachment.dataUrl,
|
|
731
741
|
poster: attachment.poster,
|
|
732
742
|
controls: true,
|
|
733
|
-
className: "w-full h-auto"
|
|
734
|
-
onPlay: () => setIsPlaying(true),
|
|
735
|
-
onPause: () => setIsPlaying(false),
|
|
736
|
-
onEnded: () => setIsPlaying(false)
|
|
743
|
+
className: "w-full h-auto"
|
|
737
744
|
}
|
|
738
745
|
),
|
|
739
746
|
attachment.fileName && /* @__PURE__ */ jsx7("div", { className: "absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-2", children: attachment.fileName })
|
|
@@ -1040,7 +1047,7 @@ var Message = memo(({
|
|
|
1040
1047
|
}, arePropsEqual);
|
|
1041
1048
|
|
|
1042
1049
|
// src/components/chat/Sidebar.tsx
|
|
1043
|
-
import { useState as useState4, useRef as
|
|
1050
|
+
import { useState as useState4, useRef as useRef4, useEffect as useEffect7 } from "react";
|
|
1044
1051
|
|
|
1045
1052
|
// src/components/ui/input.tsx
|
|
1046
1053
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
@@ -2289,9 +2296,9 @@ var Sidebar2 = ({
|
|
|
2289
2296
|
const [deleteThreadId, setDeleteThreadId] = useState4(null);
|
|
2290
2297
|
const [editingThreadId, setEditingThreadId] = useState4(null);
|
|
2291
2298
|
const [editTitle, setEditTitle] = useState4("");
|
|
2292
|
-
const inputRef =
|
|
2299
|
+
const inputRef = useRef4(null);
|
|
2293
2300
|
const { setOpen } = useSidebar();
|
|
2294
|
-
|
|
2301
|
+
useEffect7(() => {
|
|
2295
2302
|
if (editingThreadId && inputRef.current) {
|
|
2296
2303
|
inputRef.current.focus();
|
|
2297
2304
|
inputRef.current.select();
|
|
@@ -2708,10 +2715,10 @@ var ChatHeader = ({
|
|
|
2708
2715
|
};
|
|
2709
2716
|
|
|
2710
2717
|
// src/components/chat/ChatInput.tsx
|
|
2711
|
-
import { useState as useState6, useRef as
|
|
2718
|
+
import { useState as useState6, useRef as useRef5, useCallback as useCallback3, useEffect as useEffect9, memo as memo2 } from "react";
|
|
2712
2719
|
|
|
2713
2720
|
// src/components/chat/UserContext.tsx
|
|
2714
|
-
import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as
|
|
2721
|
+
import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo3, useState as useState5 } from "react";
|
|
2715
2722
|
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2716
2723
|
var Ctx = createContext2(void 0);
|
|
2717
2724
|
var ChatUserContextProvider = ({ children, initial }) => {
|
|
@@ -2719,7 +2726,7 @@ var ChatUserContextProvider = ({ children, initial }) => {
|
|
|
2719
2726
|
updatedAt: Date.now(),
|
|
2720
2727
|
...initial ?? {}
|
|
2721
2728
|
}));
|
|
2722
|
-
|
|
2729
|
+
useEffect8(() => {
|
|
2723
2730
|
if (!initial) return;
|
|
2724
2731
|
setCtx((prev) => ({
|
|
2725
2732
|
...prev,
|
|
@@ -2785,8 +2792,8 @@ import {
|
|
|
2785
2792
|
FileText,
|
|
2786
2793
|
X as X2,
|
|
2787
2794
|
Square,
|
|
2788
|
-
Play
|
|
2789
|
-
Pause
|
|
2795
|
+
Play,
|
|
2796
|
+
Pause,
|
|
2790
2797
|
Loader2
|
|
2791
2798
|
} from "lucide-react";
|
|
2792
2799
|
import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
@@ -2851,7 +2858,23 @@ var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }
|
|
|
2851
2858
|
});
|
|
2852
2859
|
var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove }) {
|
|
2853
2860
|
const [isPlaying, setIsPlaying] = useState6(false);
|
|
2854
|
-
const
|
|
2861
|
+
const [audioPlaybackSrc, setAudioPlaybackSrc] = useState6(attachment.dataUrl);
|
|
2862
|
+
const audioRef = useRef5(null);
|
|
2863
|
+
useEffect9(() => {
|
|
2864
|
+
if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
|
|
2865
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
2866
|
+
return;
|
|
2867
|
+
}
|
|
2868
|
+
const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);
|
|
2869
|
+
if (!objectUrl) {
|
|
2870
|
+
setAudioPlaybackSrc(attachment.dataUrl);
|
|
2871
|
+
return;
|
|
2872
|
+
}
|
|
2873
|
+
setAudioPlaybackSrc(objectUrl);
|
|
2874
|
+
return () => {
|
|
2875
|
+
URL.revokeObjectURL(objectUrl);
|
|
2876
|
+
};
|
|
2877
|
+
}, [attachment.kind, attachment.dataUrl]);
|
|
2855
2878
|
const handlePlayPause = () => {
|
|
2856
2879
|
if (audioRef.current) {
|
|
2857
2880
|
if (isPlaying) {
|
|
@@ -2919,7 +2942,7 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
|
|
|
2919
2942
|
size: "icon",
|
|
2920
2943
|
className: "h-8 w-8",
|
|
2921
2944
|
onClick: handlePlayPause,
|
|
2922
|
-
children: isPlaying ? /* @__PURE__ */ jsx21(
|
|
2945
|
+
children: isPlaying ? /* @__PURE__ */ jsx21(Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx21(Play, { className: "h-3 w-3" })
|
|
2923
2946
|
}
|
|
2924
2947
|
),
|
|
2925
2948
|
/* @__PURE__ */ jsxs11("div", { className: "flex-1", children: [
|
|
@@ -2930,10 +2953,11 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
|
|
|
2930
2953
|
"audio",
|
|
2931
2954
|
{
|
|
2932
2955
|
ref: audioRef,
|
|
2933
|
-
src: attachment.dataUrl,
|
|
2934
2956
|
onPlay: () => setIsPlaying(true),
|
|
2935
2957
|
onPause: () => setIsPlaying(false),
|
|
2936
|
-
onEnded: () => setIsPlaying(false)
|
|
2958
|
+
onEnded: () => setIsPlaying(false),
|
|
2959
|
+
preload: "metadata",
|
|
2960
|
+
children: /* @__PURE__ */ jsx21("source", { src: audioPlaybackSrc, type: attachment.mimeType })
|
|
2937
2961
|
}
|
|
2938
2962
|
),
|
|
2939
2963
|
/* @__PURE__ */ jsx21(
|
|
@@ -3028,13 +3052,13 @@ var ChatInput = memo2(function ChatInput2({
|
|
|
3028
3052
|
const { setContext } = useChatUserContext();
|
|
3029
3053
|
const [recordingDuration, setRecordingDuration] = useState6(0);
|
|
3030
3054
|
const [uploadProgress, setUploadProgress] = useState6(/* @__PURE__ */ new Map());
|
|
3031
|
-
const textareaRef =
|
|
3032
|
-
const fileInputRef =
|
|
3033
|
-
const mediaRecorderRef =
|
|
3034
|
-
const recordingStartTime =
|
|
3035
|
-
const recordingInterval =
|
|
3036
|
-
const mediaStreamRef =
|
|
3037
|
-
|
|
3055
|
+
const textareaRef = useRef5(null);
|
|
3056
|
+
const fileInputRef = useRef5(null);
|
|
3057
|
+
const mediaRecorderRef = useRef5(null);
|
|
3058
|
+
const recordingStartTime = useRef5(0);
|
|
3059
|
+
const recordingInterval = useRef5(null);
|
|
3060
|
+
const mediaStreamRef = useRef5(null);
|
|
3061
|
+
useEffect9(() => {
|
|
3038
3062
|
return () => {
|
|
3039
3063
|
if (mediaStreamRef.current) {
|
|
3040
3064
|
mediaStreamRef.current.getTracks().forEach((track) => track.stop());
|
|
@@ -3892,30 +3916,30 @@ var ChatUI = ({
|
|
|
3892
3916
|
isSidebarCollapsed: false
|
|
3893
3917
|
// No longer used for main sidebar
|
|
3894
3918
|
});
|
|
3895
|
-
|
|
3919
|
+
useEffect10(() => {
|
|
3896
3920
|
if (currentThreadId !== state.selectedThreadId) {
|
|
3897
3921
|
setState((prev) => ({ ...prev, selectedThreadId: currentThreadId }));
|
|
3898
3922
|
}
|
|
3899
3923
|
}, [currentThreadId]);
|
|
3900
|
-
const initialInputApplied =
|
|
3901
|
-
const initialInputConsumedRef =
|
|
3902
|
-
|
|
3924
|
+
const initialInputApplied = useRef6(false);
|
|
3925
|
+
const initialInputConsumedRef = useRef6(false);
|
|
3926
|
+
useEffect10(() => {
|
|
3903
3927
|
if (initialInput && !initialInputApplied.current) {
|
|
3904
3928
|
setInputValue(initialInput);
|
|
3905
3929
|
initialInputApplied.current = true;
|
|
3906
3930
|
}
|
|
3907
3931
|
}, [initialInput]);
|
|
3908
|
-
const scrollAreaRef =
|
|
3909
|
-
const stateRef =
|
|
3910
|
-
const inputValueRef =
|
|
3911
|
-
const attachmentsRef =
|
|
3912
|
-
|
|
3932
|
+
const scrollAreaRef = useRef6(null);
|
|
3933
|
+
const stateRef = useRef6(state);
|
|
3934
|
+
const inputValueRef = useRef6(inputValue);
|
|
3935
|
+
const attachmentsRef = useRef6(attachments);
|
|
3936
|
+
useEffect10(() => {
|
|
3913
3937
|
stateRef.current = state;
|
|
3914
3938
|
}, [state]);
|
|
3915
|
-
|
|
3939
|
+
useEffect10(() => {
|
|
3916
3940
|
inputValueRef.current = inputValue;
|
|
3917
3941
|
}, [inputValue]);
|
|
3918
|
-
|
|
3942
|
+
useEffect10(() => {
|
|
3919
3943
|
attachmentsRef.current = attachments;
|
|
3920
3944
|
}, [attachments]);
|
|
3921
3945
|
const [isCustomMounted, setIsCustomMounted] = useState8(false);
|
|
@@ -3938,7 +3962,7 @@ var ChatUI = ({
|
|
|
3938
3962
|
[]
|
|
3939
3963
|
// No dependencies - uses refs for latest state
|
|
3940
3964
|
);
|
|
3941
|
-
|
|
3965
|
+
useEffect10(() => {
|
|
3942
3966
|
const checkMobile = () => {
|
|
3943
3967
|
setIsMobile(globalThis.innerWidth < 1024);
|
|
3944
3968
|
};
|
|
@@ -3946,7 +3970,7 @@ var ChatUI = ({
|
|
|
3946
3970
|
globalThis.addEventListener("resize", checkMobile);
|
|
3947
3971
|
return () => globalThis.removeEventListener("resize", checkMobile);
|
|
3948
3972
|
}, []);
|
|
3949
|
-
|
|
3973
|
+
useEffect10(() => {
|
|
3950
3974
|
if (!isMobile || !config.customComponent?.component) return;
|
|
3951
3975
|
if (state.showSidebar) {
|
|
3952
3976
|
setIsCustomMounted(true);
|
|
@@ -3957,8 +3981,8 @@ var ChatUI = ({
|
|
|
3957
3981
|
return () => clearTimeout(t);
|
|
3958
3982
|
}
|
|
3959
3983
|
}, [state.showSidebar, isMobile, config.customComponent]);
|
|
3960
|
-
const prevMessageCountRef =
|
|
3961
|
-
|
|
3984
|
+
const prevMessageCountRef = useRef6(0);
|
|
3985
|
+
useEffect10(() => {
|
|
3962
3986
|
if (messages.length === 0) {
|
|
3963
3987
|
prevMessageCountRef.current = 0;
|
|
3964
3988
|
return;
|
|
@@ -3984,10 +4008,10 @@ var ChatUI = ({
|
|
|
3984
4008
|
}
|
|
3985
4009
|
});
|
|
3986
4010
|
}, [messages, state.isAtBottom, virtualizer]);
|
|
3987
|
-
|
|
4011
|
+
useEffect10(() => {
|
|
3988
4012
|
virtualizer.measure();
|
|
3989
4013
|
}, [expandedMessageIds, virtualizer]);
|
|
3990
|
-
|
|
4014
|
+
useEffect10(() => {
|
|
3991
4015
|
const validMessageIds = new Set(messages.map((message) => message.id));
|
|
3992
4016
|
setExpandedMessageIds((prev) => {
|
|
3993
4017
|
const activeIds = Object.keys(prev);
|
|
@@ -4369,7 +4393,7 @@ var ChatUI = ({
|
|
|
4369
4393
|
};
|
|
4370
4394
|
|
|
4371
4395
|
// src/components/chat/ThreadManager.tsx
|
|
4372
|
-
import { useState as useState9, useRef as
|
|
4396
|
+
import { useState as useState9, useRef as useRef7, useEffect as useEffect11 } from "react";
|
|
4373
4397
|
import {
|
|
4374
4398
|
Plus as Plus4,
|
|
4375
4399
|
MessageSquare as MessageSquare2,
|
|
@@ -4388,8 +4412,8 @@ import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-r
|
|
|
4388
4412
|
var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
|
|
4389
4413
|
const [isEditing, setIsEditing] = useState9(false);
|
|
4390
4414
|
const [editTitle, setEditTitle] = useState9(thread.title);
|
|
4391
|
-
const inputRef =
|
|
4392
|
-
|
|
4415
|
+
const inputRef = useRef7(null);
|
|
4416
|
+
useEffect11(() => {
|
|
4393
4417
|
if (isEditing && inputRef.current) {
|
|
4394
4418
|
inputRef.current.focus();
|
|
4395
4419
|
inputRef.current.select();
|
|
@@ -4683,6 +4707,7 @@ export {
|
|
|
4683
4707
|
chatUtils,
|
|
4684
4708
|
cn,
|
|
4685
4709
|
configUtils,
|
|
4710
|
+
createObjectUrlFromDataUrl,
|
|
4686
4711
|
defaultChatConfig,
|
|
4687
4712
|
featureFlags,
|
|
4688
4713
|
formatDate,
|