@copilotz/chat-ui 0.1.0 → 0.1.1
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/README.md +405 -13
- package/dist/index.cjs +369 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +413 -151
- package/dist/index.js.map +1 -1
- package/dist/styles.css +237 -18
- package/package.json +6 -2
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 useRef7, useCallback as useCallback4 } from "react";
|
|
3
3
|
|
|
4
4
|
// src/config/chatConfig.ts
|
|
5
5
|
var defaultChatConfig = {
|
|
@@ -9,6 +9,11 @@ var defaultChatConfig = {
|
|
|
9
9
|
title: "Chat Assistant",
|
|
10
10
|
subtitle: "How can I help you today?"
|
|
11
11
|
},
|
|
12
|
+
agentSelector: {
|
|
13
|
+
enabled: false,
|
|
14
|
+
label: "Select agent",
|
|
15
|
+
hideIfSingle: true
|
|
16
|
+
},
|
|
12
17
|
labels: {
|
|
13
18
|
inputPlaceholder: "Type your message...",
|
|
14
19
|
sendButton: "Send",
|
|
@@ -101,6 +106,10 @@ function mergeConfig(_baseConfig, userConfig) {
|
|
|
101
106
|
...defaultChatConfig.ui,
|
|
102
107
|
...userConfig.ui
|
|
103
108
|
},
|
|
109
|
+
agentSelector: {
|
|
110
|
+
...defaultChatConfig.agentSelector,
|
|
111
|
+
...userConfig.agentSelector
|
|
112
|
+
},
|
|
104
113
|
customComponent: userConfig.customComponent || defaultChatConfig.customComponent,
|
|
105
114
|
headerActions: userConfig.headerActions || defaultChatConfig.headerActions
|
|
106
115
|
};
|
|
@@ -228,7 +237,7 @@ var configUtils = {
|
|
|
228
237
|
};
|
|
229
238
|
|
|
230
239
|
// src/components/chat/Message.tsx
|
|
231
|
-
import { useState, useRef } from "react";
|
|
240
|
+
import { useState, useRef, memo } from "react";
|
|
232
241
|
import ReactMarkdown from "react-markdown";
|
|
233
242
|
import remarkGfm from "remark-gfm";
|
|
234
243
|
import rehypeHighlight from "rehype-highlight";
|
|
@@ -521,7 +530,7 @@ import {
|
|
|
521
530
|
ChevronDown
|
|
522
531
|
} from "lucide-react";
|
|
523
532
|
import { Fragment, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
524
|
-
var ThinkingIndicator = ({ label = "Thinking..." })
|
|
533
|
+
var ThinkingIndicator = memo(function ThinkingIndicator2({ label = "Thinking..." }) {
|
|
525
534
|
return /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 py-2", children: [
|
|
526
535
|
/* @__PURE__ */ jsxs2("div", { className: "flex gap-1", children: [
|
|
527
536
|
/* @__PURE__ */ jsx7(
|
|
@@ -548,26 +557,30 @@ var ThinkingIndicator = ({ label = "Thinking..." }) => {
|
|
|
548
557
|
] }),
|
|
549
558
|
/* @__PURE__ */ jsx7("span", { className: "text-sm text-muted-foreground animate-pulse", children: label })
|
|
550
559
|
] });
|
|
560
|
+
});
|
|
561
|
+
var markdownComponents = {
|
|
562
|
+
code: ({ node, className, children, ...props }) => {
|
|
563
|
+
const inline = props.inline;
|
|
564
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
565
|
+
return !inline && match ? /* @__PURE__ */ jsx7("pre", { className: "relative", children: /* @__PURE__ */ jsx7("code", { className, ...props, children }) }) : /* @__PURE__ */ jsx7("code", { className: "bg-muted px-1 py-0.5 rounded text-sm", ...props, children });
|
|
566
|
+
}
|
|
551
567
|
};
|
|
552
|
-
var
|
|
568
|
+
var remarkPluginsDefault = [remarkGfm];
|
|
569
|
+
var rehypePluginsDefault = [rehypeHighlight];
|
|
570
|
+
var rehypePluginsEmpty = [];
|
|
571
|
+
var StreamingText = memo(function StreamingText2({
|
|
553
572
|
content,
|
|
554
573
|
isStreaming = false,
|
|
555
574
|
thinkingLabel = "Thinking..."
|
|
556
|
-
})
|
|
575
|
+
}) {
|
|
557
576
|
const hasContent = content.trim().length > 0;
|
|
558
577
|
return /* @__PURE__ */ jsxs2("div", { className: "prose prose-sm max-w-none dark:prose-invert", children: [
|
|
559
578
|
hasContent ? /* @__PURE__ */ jsx7(
|
|
560
579
|
ReactMarkdown,
|
|
561
580
|
{
|
|
562
|
-
remarkPlugins:
|
|
563
|
-
rehypePlugins: isStreaming ?
|
|
564
|
-
components:
|
|
565
|
-
code: ({ node, className, children, ...props }) => {
|
|
566
|
-
const inline = props.inline;
|
|
567
|
-
const match = /language-(\w+)/.exec(className || "");
|
|
568
|
-
return !inline && match ? /* @__PURE__ */ jsx7("pre", { className: "relative", children: /* @__PURE__ */ jsx7("code", { className, ...props, children }) }) : /* @__PURE__ */ jsx7("code", { className: "bg-muted px-1 py-0.5 rounded text-sm", ...props, children });
|
|
569
|
-
}
|
|
570
|
-
},
|
|
581
|
+
remarkPlugins: remarkPluginsDefault,
|
|
582
|
+
rehypePlugins: isStreaming ? rehypePluginsEmpty : rehypePluginsDefault,
|
|
583
|
+
components: markdownComponents,
|
|
571
584
|
children: content
|
|
572
585
|
}
|
|
573
586
|
) : isStreaming ? (
|
|
@@ -576,8 +589,8 @@ var StreamingText = ({
|
|
|
576
589
|
) : null,
|
|
577
590
|
isStreaming && hasContent && /* @__PURE__ */ jsx7("span", { className: "inline-block w-2 h-4 bg-primary animate-pulse ml-1" })
|
|
578
591
|
] });
|
|
579
|
-
};
|
|
580
|
-
var MediaRenderer = ({ attachment })
|
|
592
|
+
});
|
|
593
|
+
var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
|
|
581
594
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
582
595
|
const audioRef = useRef(null);
|
|
583
596
|
const videoRef = useRef(null);
|
|
@@ -651,8 +664,8 @@ var MediaRenderer = ({ attachment }) => {
|
|
|
651
664
|
default:
|
|
652
665
|
return null;
|
|
653
666
|
}
|
|
654
|
-
};
|
|
655
|
-
var ToolCallsDisplay = ({ toolCalls, label })
|
|
667
|
+
});
|
|
668
|
+
var ToolCallsDisplay = memo(function ToolCallsDisplay2({ toolCalls, label }) {
|
|
656
669
|
const [expandedCall, setExpandedCall] = useState(null);
|
|
657
670
|
const getStatusIcon = (status) => {
|
|
658
671
|
switch (status) {
|
|
@@ -721,8 +734,48 @@ var ToolCallsDisplay = ({ toolCalls, label }) => {
|
|
|
721
734
|
] }, call.id);
|
|
722
735
|
})
|
|
723
736
|
] });
|
|
737
|
+
});
|
|
738
|
+
var arePropsEqual = (prevProps, nextProps) => {
|
|
739
|
+
if (prevProps.message.id !== nextProps.message.id) return false;
|
|
740
|
+
if (prevProps.message.content !== nextProps.message.content) return false;
|
|
741
|
+
if (prevProps.message.isStreaming !== nextProps.message.isStreaming) return false;
|
|
742
|
+
if (prevProps.message.isComplete !== nextProps.message.isComplete) return false;
|
|
743
|
+
if (prevProps.message.isEdited !== nextProps.message.isEdited) return false;
|
|
744
|
+
if (prevProps.message.timestamp !== nextProps.message.timestamp) return false;
|
|
745
|
+
if (prevProps.message.toolCalls !== nextProps.message.toolCalls) {
|
|
746
|
+
const prevCalls = prevProps.message.toolCalls;
|
|
747
|
+
const nextCalls = nextProps.message.toolCalls;
|
|
748
|
+
if (!prevCalls || !nextCalls || prevCalls.length !== nextCalls.length) return false;
|
|
749
|
+
for (let i = 0; i < prevCalls.length; i++) {
|
|
750
|
+
if (prevCalls[i].id !== nextCalls[i].id || prevCalls[i].status !== nextCalls[i].status || prevCalls[i].result !== nextCalls[i].result) {
|
|
751
|
+
return false;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
if (prevProps.message.attachments !== nextProps.message.attachments) {
|
|
756
|
+
const prevAtt = prevProps.message.attachments;
|
|
757
|
+
const nextAtt = nextProps.message.attachments;
|
|
758
|
+
if (!prevAtt || !nextAtt || prevAtt.length !== nextAtt.length) return false;
|
|
759
|
+
}
|
|
760
|
+
if (prevProps.isUser !== nextProps.isUser) return false;
|
|
761
|
+
if (prevProps.userAvatar !== nextProps.userAvatar) return false;
|
|
762
|
+
if (prevProps.userName !== nextProps.userName) return false;
|
|
763
|
+
if (prevProps.assistantName !== nextProps.assistantName) return false;
|
|
764
|
+
if (prevProps.showTimestamp !== nextProps.showTimestamp) return false;
|
|
765
|
+
if (prevProps.showAvatar !== nextProps.showAvatar) return false;
|
|
766
|
+
if (prevProps.enableCopy !== nextProps.enableCopy) return false;
|
|
767
|
+
if (prevProps.enableEdit !== nextProps.enableEdit) return false;
|
|
768
|
+
if (prevProps.enableRegenerate !== nextProps.enableRegenerate) return false;
|
|
769
|
+
if (prevProps.enableToolCallsDisplay !== nextProps.enableToolCallsDisplay) return false;
|
|
770
|
+
if (prevProps.compactMode !== nextProps.compactMode) return false;
|
|
771
|
+
if (prevProps.className !== nextProps.className) return false;
|
|
772
|
+
if (prevProps.toolUsedLabel !== nextProps.toolUsedLabel) return false;
|
|
773
|
+
if (prevProps.thinkingLabel !== nextProps.thinkingLabel) return false;
|
|
774
|
+
if (prevProps.isGrouped !== nextProps.isGrouped) return false;
|
|
775
|
+
if (prevProps.assistantAvatar !== nextProps.assistantAvatar) return false;
|
|
776
|
+
return true;
|
|
724
777
|
};
|
|
725
|
-
var Message = ({
|
|
778
|
+
var Message = memo(({
|
|
726
779
|
message,
|
|
727
780
|
isUser,
|
|
728
781
|
userAvatar,
|
|
@@ -739,7 +792,8 @@ var Message = ({
|
|
|
739
792
|
onAction,
|
|
740
793
|
className = "",
|
|
741
794
|
toolUsedLabel,
|
|
742
|
-
thinkingLabel = "Thinking..."
|
|
795
|
+
thinkingLabel = "Thinking...",
|
|
796
|
+
isGrouped = false
|
|
743
797
|
}) => {
|
|
744
798
|
const [isEditing, setIsEditing] = useState(false);
|
|
745
799
|
const [editContent, setEditContent] = useState(message.content);
|
|
@@ -789,7 +843,7 @@ var Message = ({
|
|
|
789
843
|
onMouseEnter: () => setShowActions(true),
|
|
790
844
|
onMouseLeave: () => setShowActions(false),
|
|
791
845
|
children: [
|
|
792
|
-
/* @__PURE__ */ jsxs2("div", { className: `flex gap-3 ${messageIsUser ? "flex-row-reverse" : "flex-row"} w-full mb-1`, children: [
|
|
846
|
+
!isGrouped && /* @__PURE__ */ jsxs2("div", { className: `flex gap-3 ${messageIsUser ? "flex-row-reverse" : "flex-row"} w-full mb-1`, children: [
|
|
793
847
|
showAvatar && /* @__PURE__ */ jsx7("div", { className: `flex-shrink-0 ${compactMode ? "mt-1" : "mt-0"}`, children: /* @__PURE__ */ jsx7(Avatar, { className: compactMode ? "h-6 w-6" : "h-8 w-8", children: messageIsUser ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
794
848
|
/* @__PURE__ */ jsx7(AvatarImage, { src: userAvatar, alt: userName }),
|
|
795
849
|
/* @__PURE__ */ jsx7(AvatarFallback, { className: "bg-primary text-primary-foreground", children: userName.charAt(0).toUpperCase() })
|
|
@@ -800,7 +854,7 @@ var Message = ({
|
|
|
800
854
|
message.isEdited && /* @__PURE__ */ jsx7(Badge, { variant: "outline", className: "text-xs", children: "editado" })
|
|
801
855
|
] })
|
|
802
856
|
] }),
|
|
803
|
-
/* @__PURE__ */ jsx7("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"}`, children: /* @__PURE__ */ jsxs2("div", { className: `relative inline-flex flex-col ${messageIsUser ? "rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]" : "max-w-[85%]"}`, children: [
|
|
857
|
+
/* @__PURE__ */ jsx7("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${isGrouped && showAvatar && !messageIsUser ? compactMode ? "ml-9" : "ml-11" : ""} ${isGrouped && showAvatar && messageIsUser ? compactMode ? "mr-9" : "mr-11" : ""}`, children: /* @__PURE__ */ jsxs2("div", { className: `relative inline-flex flex-col ${messageIsUser ? "rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]" : "max-w-[85%]"}`, children: [
|
|
804
858
|
isEditing ? /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
805
859
|
/* @__PURE__ */ jsx7(
|
|
806
860
|
Textarea,
|
|
@@ -878,10 +932,10 @@ var Message = ({
|
|
|
878
932
|
]
|
|
879
933
|
}
|
|
880
934
|
) });
|
|
881
|
-
};
|
|
935
|
+
}, arePropsEqual);
|
|
882
936
|
|
|
883
937
|
// src/components/chat/Sidebar.tsx
|
|
884
|
-
import { useState as useState4, useRef as
|
|
938
|
+
import { useState as useState4, useRef as useRef5, useEffect as useEffect7 } from "react";
|
|
885
939
|
|
|
886
940
|
// src/components/ui/input.tsx
|
|
887
941
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
@@ -903,7 +957,7 @@ function Input({ className, type, ...props }) {
|
|
|
903
957
|
}
|
|
904
958
|
|
|
905
959
|
// src/components/ui/sidebar.tsx
|
|
906
|
-
import * as
|
|
960
|
+
import * as React4 from "react";
|
|
907
961
|
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
908
962
|
import { cva as cva3 } from "class-variance-authority";
|
|
909
963
|
import { PanelLeftIcon } from "lucide-react";
|
|
@@ -950,11 +1004,30 @@ function Separator({
|
|
|
950
1004
|
}
|
|
951
1005
|
|
|
952
1006
|
// src/components/ui/sheet.tsx
|
|
1007
|
+
import * as React3 from "react";
|
|
953
1008
|
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
|
954
1009
|
import { XIcon } from "lucide-react";
|
|
955
1010
|
import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
956
|
-
function
|
|
957
|
-
|
|
1011
|
+
function cleanupBodyStyles() {
|
|
1012
|
+
if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
|
|
1013
|
+
document.body.style.pointerEvents = "";
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
function Sheet({ open, onOpenChange, ...props }) {
|
|
1017
|
+
const prevOpenRef = React3.useRef(open);
|
|
1018
|
+
React3.useEffect(() => {
|
|
1019
|
+
if (prevOpenRef.current === true && open === false) {
|
|
1020
|
+
const timeout = setTimeout(cleanupBodyStyles, 350);
|
|
1021
|
+
return () => clearTimeout(timeout);
|
|
1022
|
+
}
|
|
1023
|
+
prevOpenRef.current = open;
|
|
1024
|
+
}, [open]);
|
|
1025
|
+
React3.useEffect(() => {
|
|
1026
|
+
return () => {
|
|
1027
|
+
cleanupBodyStyles();
|
|
1028
|
+
};
|
|
1029
|
+
}, []);
|
|
1030
|
+
return /* @__PURE__ */ jsx10(SheetPrimitive.Root, { "data-slot": "sheet", open, onOpenChange, ...props });
|
|
958
1031
|
}
|
|
959
1032
|
function SheetPortal({
|
|
960
1033
|
...props
|
|
@@ -970,7 +1043,10 @@ function SheetOverlay({
|
|
|
970
1043
|
{
|
|
971
1044
|
"data-slot": "sheet-overlay",
|
|
972
1045
|
className: cn(
|
|
973
|
-
"
|
|
1046
|
+
"fixed inset-0 z-50 bg-black/50",
|
|
1047
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
1048
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1049
|
+
"data-[state=closed]:pointer-events-none",
|
|
974
1050
|
className
|
|
975
1051
|
),
|
|
976
1052
|
...props
|
|
@@ -989,6 +1065,7 @@ function SheetContent({
|
|
|
989
1065
|
SheetPrimitive.Content,
|
|
990
1066
|
{
|
|
991
1067
|
"data-slot": "sheet-content",
|
|
1068
|
+
"aria-describedby": void 0,
|
|
992
1069
|
className: cn(
|
|
993
1070
|
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
|
|
994
1071
|
side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
|
|
@@ -1054,9 +1131,9 @@ var SIDEBAR_WIDTH = "16rem";
|
|
|
1054
1131
|
var SIDEBAR_WIDTH_MOBILE = "18rem";
|
|
1055
1132
|
var SIDEBAR_WIDTH_ICON = "3rem";
|
|
1056
1133
|
var SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
1057
|
-
var SidebarContext =
|
|
1134
|
+
var SidebarContext = React4.createContext(null);
|
|
1058
1135
|
function useSidebar() {
|
|
1059
|
-
const context =
|
|
1136
|
+
const context = React4.useContext(SidebarContext);
|
|
1060
1137
|
if (!context) {
|
|
1061
1138
|
throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
1062
1139
|
}
|
|
@@ -1072,10 +1149,10 @@ function SidebarProvider({
|
|
|
1072
1149
|
...props
|
|
1073
1150
|
}) {
|
|
1074
1151
|
const isMobile = useIsMobile();
|
|
1075
|
-
const [openMobile, setOpenMobile] =
|
|
1076
|
-
const [_open, _setOpen] =
|
|
1152
|
+
const [openMobile, setOpenMobile] = React4.useState(false);
|
|
1153
|
+
const [_open, _setOpen] = React4.useState(defaultOpen);
|
|
1077
1154
|
const open = openProp ?? _open;
|
|
1078
|
-
const setOpen =
|
|
1155
|
+
const setOpen = React4.useCallback(
|
|
1079
1156
|
(value) => {
|
|
1080
1157
|
const openState = typeof value === "function" ? value(open) : value;
|
|
1081
1158
|
if (setOpenProp) {
|
|
@@ -1087,10 +1164,10 @@ function SidebarProvider({
|
|
|
1087
1164
|
},
|
|
1088
1165
|
[setOpenProp, open]
|
|
1089
1166
|
);
|
|
1090
|
-
const toggleSidebar =
|
|
1167
|
+
const toggleSidebar = React4.useCallback(() => {
|
|
1091
1168
|
return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
|
|
1092
1169
|
}, [isMobile, setOpen, setOpenMobile]);
|
|
1093
|
-
|
|
1170
|
+
React4.useEffect(() => {
|
|
1094
1171
|
const handleKeyDown = (event) => {
|
|
1095
1172
|
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
1096
1173
|
event.preventDefault();
|
|
@@ -1101,7 +1178,7 @@ function SidebarProvider({
|
|
|
1101
1178
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1102
1179
|
}, [toggleSidebar]);
|
|
1103
1180
|
const state = open ? "expanded" : "collapsed";
|
|
1104
|
-
const contextValue =
|
|
1181
|
+
const contextValue = React4.useMemo(
|
|
1105
1182
|
() => ({
|
|
1106
1183
|
state,
|
|
1107
1184
|
open,
|
|
@@ -1484,13 +1561,34 @@ function SidebarMenuAction({
|
|
|
1484
1561
|
}
|
|
1485
1562
|
|
|
1486
1563
|
// src/components/ui/dialog.tsx
|
|
1564
|
+
import * as React5 from "react";
|
|
1487
1565
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
1488
1566
|
import { XIcon as XIcon2 } from "lucide-react";
|
|
1489
1567
|
import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1568
|
+
function cleanupBodyStyles2() {
|
|
1569
|
+
if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
|
|
1570
|
+
document.body.style.pointerEvents = "";
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1490
1573
|
function Dialog({
|
|
1574
|
+
open,
|
|
1575
|
+
onOpenChange,
|
|
1491
1576
|
...props
|
|
1492
1577
|
}) {
|
|
1493
|
-
|
|
1578
|
+
const prevOpenRef = React5.useRef(open);
|
|
1579
|
+
React5.useEffect(() => {
|
|
1580
|
+
if (prevOpenRef.current === true && open === false) {
|
|
1581
|
+
const timeout = setTimeout(cleanupBodyStyles2, 250);
|
|
1582
|
+
return () => clearTimeout(timeout);
|
|
1583
|
+
}
|
|
1584
|
+
prevOpenRef.current = open;
|
|
1585
|
+
}, [open]);
|
|
1586
|
+
React5.useEffect(() => {
|
|
1587
|
+
return () => {
|
|
1588
|
+
cleanupBodyStyles2();
|
|
1589
|
+
};
|
|
1590
|
+
}, []);
|
|
1591
|
+
return /* @__PURE__ */ jsx12(DialogPrimitive.Root, { "data-slot": "dialog", open, onOpenChange, ...props });
|
|
1494
1592
|
}
|
|
1495
1593
|
function DialogTrigger({
|
|
1496
1594
|
...props
|
|
@@ -1511,7 +1609,10 @@ function DialogOverlay({
|
|
|
1511
1609
|
{
|
|
1512
1610
|
"data-slot": "dialog-overlay",
|
|
1513
1611
|
className: cn(
|
|
1514
|
-
"
|
|
1612
|
+
"fixed inset-0 z-50 bg-black/50",
|
|
1613
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
1614
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1615
|
+
"data-[state=closed]:pointer-events-none",
|
|
1515
1616
|
className
|
|
1516
1617
|
),
|
|
1517
1618
|
...props
|
|
@@ -1530,6 +1631,7 @@ function DialogContent({
|
|
|
1530
1631
|
DialogPrimitive.Content,
|
|
1531
1632
|
{
|
|
1532
1633
|
"data-slot": "dialog-content",
|
|
1634
|
+
"aria-describedby": void 0,
|
|
1533
1635
|
className: cn(
|
|
1534
1636
|
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
1535
1637
|
className
|
|
@@ -1604,12 +1706,33 @@ function DialogDescription({
|
|
|
1604
1706
|
}
|
|
1605
1707
|
|
|
1606
1708
|
// src/components/ui/alert-dialog.tsx
|
|
1709
|
+
import * as React6 from "react";
|
|
1607
1710
|
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
1608
1711
|
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1712
|
+
function cleanupBodyStyles3() {
|
|
1713
|
+
if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
|
|
1714
|
+
document.body.style.pointerEvents = "";
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1609
1717
|
function AlertDialog({
|
|
1718
|
+
open,
|
|
1719
|
+
onOpenChange,
|
|
1610
1720
|
...props
|
|
1611
1721
|
}) {
|
|
1612
|
-
|
|
1722
|
+
const prevOpenRef = React6.useRef(open);
|
|
1723
|
+
React6.useEffect(() => {
|
|
1724
|
+
if (prevOpenRef.current === true && open === false) {
|
|
1725
|
+
const timeout = setTimeout(cleanupBodyStyles3, 250);
|
|
1726
|
+
return () => clearTimeout(timeout);
|
|
1727
|
+
}
|
|
1728
|
+
prevOpenRef.current = open;
|
|
1729
|
+
}, [open]);
|
|
1730
|
+
React6.useEffect(() => {
|
|
1731
|
+
return () => {
|
|
1732
|
+
cleanupBodyStyles3();
|
|
1733
|
+
};
|
|
1734
|
+
}, []);
|
|
1735
|
+
return /* @__PURE__ */ jsx13(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", open, onOpenChange, ...props });
|
|
1613
1736
|
}
|
|
1614
1737
|
function AlertDialogPortal({
|
|
1615
1738
|
...props
|
|
@@ -1625,7 +1748,10 @@ function AlertDialogOverlay({
|
|
|
1625
1748
|
{
|
|
1626
1749
|
"data-slot": "alert-dialog-overlay",
|
|
1627
1750
|
className: cn(
|
|
1628
|
-
"
|
|
1751
|
+
"fixed inset-0 z-50 bg-black/50",
|
|
1752
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
1753
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1754
|
+
"data-[state=closed]:pointer-events-none",
|
|
1629
1755
|
className
|
|
1630
1756
|
),
|
|
1631
1757
|
...props
|
|
@@ -1829,7 +1955,8 @@ import {
|
|
|
1829
1955
|
Trash2,
|
|
1830
1956
|
Archive,
|
|
1831
1957
|
Search,
|
|
1832
|
-
Filter
|
|
1958
|
+
Filter,
|
|
1959
|
+
Bot
|
|
1833
1960
|
} from "lucide-react";
|
|
1834
1961
|
|
|
1835
1962
|
// src/components/chat/UserMenu.tsx
|
|
@@ -2044,9 +2171,9 @@ var Sidebar2 = ({
|
|
|
2044
2171
|
const [deleteThreadId, setDeleteThreadId] = useState4(null);
|
|
2045
2172
|
const [editingThreadId, setEditingThreadId] = useState4(null);
|
|
2046
2173
|
const [editTitle, setEditTitle] = useState4("");
|
|
2047
|
-
const inputRef =
|
|
2174
|
+
const inputRef = useRef5(null);
|
|
2048
2175
|
const { setOpen } = useSidebar();
|
|
2049
|
-
|
|
2176
|
+
useEffect7(() => {
|
|
2050
2177
|
if (editingThreadId && inputRef.current) {
|
|
2051
2178
|
inputRef.current.focus();
|
|
2052
2179
|
inputRef.current.select();
|
|
@@ -2099,6 +2226,13 @@ var Sidebar2 = ({
|
|
|
2099
2226
|
};
|
|
2100
2227
|
return /* @__PURE__ */ jsxs9(Sidebar, { collapsible: "icon", ...props, children: [
|
|
2101
2228
|
/* @__PURE__ */ jsxs9(SidebarHeader, { children: [
|
|
2229
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 px-2 py-3", children: [
|
|
2230
|
+
/* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center shrink-0", children: config.branding?.logo || /* @__PURE__ */ jsx16(Avatar, { className: "h-8 w-8", children: /* @__PURE__ */ jsx16(AvatarFallback, { className: "bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx16(Bot, { className: "h-4 w-4" }) }) }) }),
|
|
2231
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col min-w-0 group-data-[collapsible=icon]:hidden", children: [
|
|
2232
|
+
/* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold truncate", children: config.branding?.title || "Chat" }),
|
|
2233
|
+
config.branding?.subtitle && /* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground truncate", children: config.branding.subtitle })
|
|
2234
|
+
] })
|
|
2235
|
+
] }),
|
|
2102
2236
|
onCreateThread && /* @__PURE__ */ jsx16(
|
|
2103
2237
|
CreateThreadDialog,
|
|
2104
2238
|
{
|
|
@@ -2118,7 +2252,7 @@ var Sidebar2 = ({
|
|
|
2118
2252
|
) }) })
|
|
2119
2253
|
}
|
|
2120
2254
|
),
|
|
2121
|
-
/* @__PURE__ */ jsxs9("div", { className: "px-2 py-1 mt-
|
|
2255
|
+
/* @__PURE__ */ jsxs9("div", { className: "px-2 py-1 mt-4", children: [
|
|
2122
2256
|
/* @__PURE__ */ jsxs9("div", { className: "relative group-data-[collapsible=icon]:hidden", children: [
|
|
2123
2257
|
/* @__PURE__ */ jsx16(Search, { className: "pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50" }),
|
|
2124
2258
|
/* @__PURE__ */ jsx16(
|
|
@@ -2233,7 +2367,7 @@ var Sidebar2 = ({
|
|
|
2233
2367
|
}
|
|
2234
2368
|
) }),
|
|
2235
2369
|
/* @__PURE__ */ jsx16(SidebarRail, {}),
|
|
2236
|
-
/* @__PURE__ */ jsx16(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs9(AlertDialogContent, { children: [
|
|
2370
|
+
deleteThreadId && /* @__PURE__ */ jsx16(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs9(AlertDialogContent, { children: [
|
|
2237
2371
|
/* @__PURE__ */ jsxs9(AlertDialogHeader, { children: [
|
|
2238
2372
|
/* @__PURE__ */ jsx16(AlertDialogTitle, { children: config.labels?.deleteConfirmTitle || "Delete Conversation" }),
|
|
2239
2373
|
/* @__PURE__ */ jsx16(AlertDialogDescription, { children: config.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
|
|
@@ -2254,9 +2388,9 @@ var Sidebar2 = ({
|
|
|
2254
2388
|
};
|
|
2255
2389
|
|
|
2256
2390
|
// src/components/chat/ChatHeader.tsx
|
|
2257
|
-
import
|
|
2391
|
+
import React8 from "react";
|
|
2258
2392
|
import {
|
|
2259
|
-
Bot,
|
|
2393
|
+
Bot as Bot2,
|
|
2260
2394
|
MoreVertical,
|
|
2261
2395
|
Download,
|
|
2262
2396
|
Upload,
|
|
@@ -2264,7 +2398,9 @@ import {
|
|
|
2264
2398
|
Plus as Plus2,
|
|
2265
2399
|
Menu,
|
|
2266
2400
|
Moon as Moon2,
|
|
2267
|
-
Sun as Sun2
|
|
2401
|
+
Sun as Sun2,
|
|
2402
|
+
ChevronDown as ChevronDown2,
|
|
2403
|
+
Check as Check2
|
|
2268
2404
|
} from "lucide-react";
|
|
2269
2405
|
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2270
2406
|
var ChatHeader = ({
|
|
@@ -2278,13 +2414,17 @@ var ChatHeader = ({
|
|
|
2278
2414
|
onClearAll,
|
|
2279
2415
|
showCustomComponentButton,
|
|
2280
2416
|
isMobile,
|
|
2417
|
+
showAgentSelector = false,
|
|
2418
|
+
agentOptions = [],
|
|
2419
|
+
selectedAgentId = null,
|
|
2420
|
+
onSelectAgent,
|
|
2281
2421
|
className = ""
|
|
2282
2422
|
}) => {
|
|
2283
|
-
const [isDarkMode, setIsDarkMode] =
|
|
2423
|
+
const [isDarkMode, setIsDarkMode] = React8.useState(() => {
|
|
2284
2424
|
if (typeof window === "undefined") return false;
|
|
2285
2425
|
return document.documentElement.classList.contains("dark");
|
|
2286
2426
|
});
|
|
2287
|
-
|
|
2427
|
+
React8.useEffect(() => {
|
|
2288
2428
|
const observer = new MutationObserver(() => {
|
|
2289
2429
|
setIsDarkMode(document.documentElement.classList.contains("dark"));
|
|
2290
2430
|
});
|
|
@@ -2328,22 +2468,64 @@ var ChatHeader = ({
|
|
|
2328
2468
|
};
|
|
2329
2469
|
input.click();
|
|
2330
2470
|
};
|
|
2471
|
+
const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;
|
|
2472
|
+
const agentPlaceholder = config.agentSelector?.label || "Select agent";
|
|
2331
2473
|
return /* @__PURE__ */ jsx17(
|
|
2332
2474
|
Card,
|
|
2333
2475
|
{
|
|
2334
2476
|
"data-chat-header": true,
|
|
2335
2477
|
className: `py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 ${className}`,
|
|
2336
2478
|
style: isMobile ? { paddingTop: "env(safe-area-inset-top)" } : void 0,
|
|
2337
|
-
children: /* @__PURE__ */ jsx17(CardHeader, { className: "p-2", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between", children: [
|
|
2338
|
-
/* @__PURE__ */
|
|
2339
|
-
/* @__PURE__ */
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2479
|
+
children: /* @__PURE__ */ jsx17(CardHeader, { className: "p-2", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2480
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
|
|
2481
|
+
/* @__PURE__ */ jsxs10(Tooltip, { children: [
|
|
2482
|
+
/* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx17(SidebarTrigger, { className: "-ml-1" }) }),
|
|
2483
|
+
/* @__PURE__ */ jsx17(TooltipContent, { children: config.labels?.sidebarToggle || "Toggle Sidebar" })
|
|
2484
|
+
] }),
|
|
2485
|
+
showAgentSelector && /* @__PURE__ */ jsxs10(DropdownMenu, { children: [
|
|
2486
|
+
/* @__PURE__ */ jsx17(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
|
|
2487
|
+
Button,
|
|
2488
|
+
{
|
|
2489
|
+
variant: "ghost",
|
|
2490
|
+
className: "h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50",
|
|
2491
|
+
children: [
|
|
2492
|
+
selectedAgent?.avatarUrl ? /* @__PURE__ */ jsxs10(Avatar, { className: "h-5 w-5", children: [
|
|
2493
|
+
/* @__PURE__ */ jsx17(AvatarImage, { src: selectedAgent.avatarUrl, alt: selectedAgent.name }),
|
|
2494
|
+
/* @__PURE__ */ jsx17(AvatarFallback, { className: "text-[10px]", children: selectedAgent.name.charAt(0).toUpperCase() })
|
|
2495
|
+
] }) : null,
|
|
2496
|
+
/* @__PURE__ */ jsx17("span", { className: "max-w-[200px] truncate", children: selectedAgent?.name || agentPlaceholder }),
|
|
2497
|
+
/* @__PURE__ */ jsx17(ChevronDown2, { className: "h-4 w-4 opacity-50" })
|
|
2498
|
+
]
|
|
2499
|
+
}
|
|
2500
|
+
) }),
|
|
2501
|
+
/* @__PURE__ */ jsx17(DropdownMenuContent, { align: "start", className: "w-[280px]", children: agentOptions.map((agent) => {
|
|
2502
|
+
const isSelected = agent.id === selectedAgentId;
|
|
2503
|
+
return /* @__PURE__ */ jsxs10(
|
|
2504
|
+
DropdownMenuItem,
|
|
2505
|
+
{
|
|
2506
|
+
onClick: () => onSelectAgent?.(agent.id),
|
|
2507
|
+
className: "flex items-start gap-3 p-3 cursor-pointer",
|
|
2508
|
+
children: [
|
|
2509
|
+
agent.avatarUrl ? /* @__PURE__ */ jsxs10(Avatar, { className: "h-6 w-6 mt-0.5 shrink-0", children: [
|
|
2510
|
+
/* @__PURE__ */ jsx17(AvatarImage, { src: agent.avatarUrl, alt: agent.name }),
|
|
2511
|
+
/* @__PURE__ */ jsx17(AvatarFallback, { className: "text-[10px]", children: agent.name.charAt(0).toUpperCase() })
|
|
2512
|
+
] }) : /* @__PURE__ */ jsx17("div", { className: "h-6 w-6 mt-0.5 shrink-0 flex items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx17(Bot2, { className: "h-3.5 w-3.5 text-primary" }) }),
|
|
2513
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
|
|
2514
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
2515
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-sm", children: agent.name }),
|
|
2516
|
+
isSelected && /* @__PURE__ */ jsx17(Check2, { className: "h-4 w-4 text-primary shrink-0" })
|
|
2517
|
+
] }),
|
|
2518
|
+
agent.description && /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: agent.description })
|
|
2519
|
+
] })
|
|
2520
|
+
]
|
|
2521
|
+
},
|
|
2522
|
+
agent.id
|
|
2523
|
+
);
|
|
2524
|
+
}) })
|
|
2525
|
+
] }),
|
|
2526
|
+
!showAgentSelector && isMobile && /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium truncate max-w-[150px] ml-2", children: currentThreadTitle || config.branding?.title || "Chat" })
|
|
2346
2527
|
] }),
|
|
2528
|
+
/* @__PURE__ */ jsx17("div", { className: "flex-1" }),
|
|
2347
2529
|
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
|
|
2348
2530
|
showCustomComponentButton && config.customComponent && /* @__PURE__ */ jsxs10(Tooltip, { children: [
|
|
2349
2531
|
/* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx17(
|
|
@@ -2408,10 +2590,10 @@ var ChatHeader = ({
|
|
|
2408
2590
|
};
|
|
2409
2591
|
|
|
2410
2592
|
// src/components/chat/ChatInput.tsx
|
|
2411
|
-
import { useState as useState6, useRef as
|
|
2593
|
+
import { useState as useState6, useRef as useRef6, useCallback as useCallback3, useEffect as useEffect9, memo as memo2 } from "react";
|
|
2412
2594
|
|
|
2413
2595
|
// src/components/chat/UserContext.tsx
|
|
2414
|
-
import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as
|
|
2596
|
+
import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo2, useState as useState5 } from "react";
|
|
2415
2597
|
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2416
2598
|
var Ctx = createContext2(void 0);
|
|
2417
2599
|
var ChatUserContextProvider = ({ children, initial }) => {
|
|
@@ -2419,7 +2601,7 @@ var ChatUserContextProvider = ({ children, initial }) => {
|
|
|
2419
2601
|
updatedAt: Date.now(),
|
|
2420
2602
|
...initial ?? {}
|
|
2421
2603
|
}));
|
|
2422
|
-
|
|
2604
|
+
useEffect8(() => {
|
|
2423
2605
|
if (!initial) return;
|
|
2424
2606
|
setCtx((prev) => ({
|
|
2425
2607
|
...prev,
|
|
@@ -2490,7 +2672,7 @@ import {
|
|
|
2490
2672
|
Loader2
|
|
2491
2673
|
} from "lucide-react";
|
|
2492
2674
|
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2493
|
-
var FileUploadItem = ({ file, progress, onCancel })
|
|
2675
|
+
var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }) {
|
|
2494
2676
|
const guessTypeFromName = (name) => {
|
|
2495
2677
|
const ext = (name || "").split(".").pop()?.toLowerCase();
|
|
2496
2678
|
switch (ext) {
|
|
@@ -2548,10 +2730,10 @@ var FileUploadItem = ({ file, progress, onCancel }) => {
|
|
|
2548
2730
|
}
|
|
2549
2731
|
)
|
|
2550
2732
|
] }) }) });
|
|
2551
|
-
};
|
|
2552
|
-
var AttachmentPreview = ({ attachment, onRemove })
|
|
2733
|
+
});
|
|
2734
|
+
var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove }) {
|
|
2553
2735
|
const [isPlaying, setIsPlaying] = useState6(false);
|
|
2554
|
-
const audioRef =
|
|
2736
|
+
const audioRef = useRef6(null);
|
|
2555
2737
|
const handlePlayPause = () => {
|
|
2556
2738
|
if (audioRef.current) {
|
|
2557
2739
|
if (isPlaying) {
|
|
@@ -2649,8 +2831,8 @@ var AttachmentPreview = ({ attachment, onRemove }) => {
|
|
|
2649
2831
|
] }),
|
|
2650
2832
|
attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ jsx20("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ jsx20("p", { className: "truncate", children: attachment.fileName }) })
|
|
2651
2833
|
] }) });
|
|
2652
|
-
};
|
|
2653
|
-
var AudioRecorder = ({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config })
|
|
2834
|
+
});
|
|
2835
|
+
var AudioRecorder = memo2(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
|
|
2654
2836
|
const formatTime = (seconds) => {
|
|
2655
2837
|
const mins = Math.floor(seconds / 60);
|
|
2656
2838
|
const secs = seconds % 60;
|
|
@@ -2704,8 +2886,8 @@ var AudioRecorder = ({ isRecording, onStartRecording, onStopRecording, onCancel,
|
|
|
2704
2886
|
)
|
|
2705
2887
|
] })
|
|
2706
2888
|
] }) }) });
|
|
2707
|
-
};
|
|
2708
|
-
var ChatInput = ({
|
|
2889
|
+
});
|
|
2890
|
+
var ChatInput = memo2(function ChatInput2({
|
|
2709
2891
|
value,
|
|
2710
2892
|
onChange,
|
|
2711
2893
|
onSubmit,
|
|
@@ -2723,18 +2905,18 @@ var ChatInput = ({
|
|
|
2723
2905
|
acceptedFileTypes = ["image/*", "video/*", "audio/*"],
|
|
2724
2906
|
className = "",
|
|
2725
2907
|
config
|
|
2726
|
-
})
|
|
2908
|
+
}) {
|
|
2727
2909
|
const [isRecording, setIsRecording] = useState6(false);
|
|
2728
2910
|
const { setContext } = useChatUserContext();
|
|
2729
2911
|
const [recordingDuration, setRecordingDuration] = useState6(0);
|
|
2730
2912
|
const [uploadProgress, setUploadProgress] = useState6(/* @__PURE__ */ new Map());
|
|
2731
|
-
const textareaRef =
|
|
2732
|
-
const fileInputRef =
|
|
2733
|
-
const mediaRecorderRef =
|
|
2734
|
-
const recordingStartTime =
|
|
2735
|
-
const recordingInterval =
|
|
2736
|
-
const mediaStreamRef =
|
|
2737
|
-
|
|
2913
|
+
const textareaRef = useRef6(null);
|
|
2914
|
+
const fileInputRef = useRef6(null);
|
|
2915
|
+
const mediaRecorderRef = useRef6(null);
|
|
2916
|
+
const recordingStartTime = useRef6(0);
|
|
2917
|
+
const recordingInterval = useRef6(null);
|
|
2918
|
+
const mediaStreamRef = useRef6(null);
|
|
2919
|
+
useEffect9(() => {
|
|
2738
2920
|
return () => {
|
|
2739
2921
|
if (mediaStreamRef.current) {
|
|
2740
2922
|
mediaStreamRef.current.getTracks().forEach((track) => track.stop());
|
|
@@ -3065,16 +3247,16 @@ var ChatInput = ({
|
|
|
3065
3247
|
] })
|
|
3066
3248
|
] })
|
|
3067
3249
|
] }) }) });
|
|
3068
|
-
};
|
|
3250
|
+
});
|
|
3069
3251
|
|
|
3070
3252
|
// src/components/chat/UserProfile.tsx
|
|
3071
3253
|
import { useState as useState7 } from "react";
|
|
3072
3254
|
|
|
3073
3255
|
// src/components/ui/scroll-area.tsx
|
|
3074
|
-
import * as
|
|
3256
|
+
import * as React11 from "react";
|
|
3075
3257
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
3076
3258
|
import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3077
|
-
var ScrollArea =
|
|
3259
|
+
var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
|
|
3078
3260
|
return /* @__PURE__ */ jsxs12(
|
|
3079
3261
|
ScrollAreaPrimitive.Root,
|
|
3080
3262
|
{
|
|
@@ -3154,9 +3336,9 @@ import {
|
|
|
3154
3336
|
Lightbulb,
|
|
3155
3337
|
Info,
|
|
3156
3338
|
Heart,
|
|
3157
|
-
Bot as
|
|
3339
|
+
Bot as Bot3,
|
|
3158
3340
|
Pencil,
|
|
3159
|
-
Check as
|
|
3341
|
+
Check as Check3,
|
|
3160
3342
|
X as X3
|
|
3161
3343
|
} from "lucide-react";
|
|
3162
3344
|
import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
@@ -3423,7 +3605,7 @@ var UserProfile = ({
|
|
|
3423
3605
|
{
|
|
3424
3606
|
className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50 group",
|
|
3425
3607
|
children: [
|
|
3426
|
-
/* @__PURE__ */ jsx22("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ jsx22(
|
|
3608
|
+
/* @__PURE__ */ jsx22("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ jsx22(Bot3, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
|
|
3427
3609
|
/* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
|
|
3428
3610
|
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 mb-0.5", children: [
|
|
3429
3611
|
/* @__PURE__ */ jsx22("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
|
|
@@ -3470,7 +3652,7 @@ var UserProfile = ({
|
|
|
3470
3652
|
onClick: handleSaveEdit,
|
|
3471
3653
|
disabled: !editingMemoryContent.trim(),
|
|
3472
3654
|
children: [
|
|
3473
|
-
/* @__PURE__ */ jsx22(
|
|
3655
|
+
/* @__PURE__ */ jsx22(Check3, { className: "h-3.5 w-3.5 mr-1" }),
|
|
3474
3656
|
"Salvar"
|
|
3475
3657
|
]
|
|
3476
3658
|
}
|
|
@@ -3533,7 +3715,7 @@ var UserProfile = ({
|
|
|
3533
3715
|
};
|
|
3534
3716
|
|
|
3535
3717
|
// src/components/chat/ChatUI.tsx
|
|
3536
|
-
import { Sparkles } from "lucide-react";
|
|
3718
|
+
import { Sparkles, ArrowRight, MessageSquare, Lightbulb as Lightbulb2, Zap, HelpCircle } from "lucide-react";
|
|
3537
3719
|
import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3538
3720
|
var ChatUI = ({
|
|
3539
3721
|
messages = [],
|
|
@@ -3546,10 +3728,16 @@ var ChatUI = ({
|
|
|
3546
3728
|
user,
|
|
3547
3729
|
assistant,
|
|
3548
3730
|
suggestions = [],
|
|
3731
|
+
messageSuggestions = {},
|
|
3732
|
+
agentOptions = [],
|
|
3733
|
+
selectedAgentId = null,
|
|
3734
|
+
onSelectAgent,
|
|
3549
3735
|
className = "",
|
|
3550
3736
|
onAddMemory,
|
|
3551
3737
|
onUpdateMemory,
|
|
3552
|
-
onDeleteMemory
|
|
3738
|
+
onDeleteMemory,
|
|
3739
|
+
initialInput,
|
|
3740
|
+
onInitialInputConsumed
|
|
3553
3741
|
}) => {
|
|
3554
3742
|
const config = mergeConfig(defaultChatConfig, userConfig);
|
|
3555
3743
|
const [isMobile, setIsMobile] = useState8(false);
|
|
@@ -3567,9 +3755,9 @@ var ChatUI = ({
|
|
|
3567
3755
|
}
|
|
3568
3756
|
return false;
|
|
3569
3757
|
};
|
|
3758
|
+
const [inputValue, setInputValue] = useState8("");
|
|
3759
|
+
const [attachments, setAttachments] = useState8([]);
|
|
3570
3760
|
const [state, setState] = useState8({
|
|
3571
|
-
input: "",
|
|
3572
|
-
attachments: [],
|
|
3573
3761
|
isRecording: false,
|
|
3574
3762
|
selectedThreadId: currentThreadId,
|
|
3575
3763
|
isAtBottom: true,
|
|
@@ -3581,23 +3769,48 @@ var ChatUI = ({
|
|
|
3581
3769
|
isSidebarCollapsed: false
|
|
3582
3770
|
// No longer used for main sidebar
|
|
3583
3771
|
});
|
|
3584
|
-
|
|
3772
|
+
useEffect10(() => {
|
|
3585
3773
|
if (currentThreadId !== state.selectedThreadId) {
|
|
3586
3774
|
setState((prev) => ({ ...prev, selectedThreadId: currentThreadId }));
|
|
3587
3775
|
}
|
|
3588
3776
|
}, [currentThreadId]);
|
|
3589
|
-
const
|
|
3590
|
-
const
|
|
3777
|
+
const initialInputApplied = useRef7(false);
|
|
3778
|
+
const initialInputConsumedRef = useRef7(false);
|
|
3779
|
+
useEffect10(() => {
|
|
3780
|
+
if (initialInput && !initialInputApplied.current) {
|
|
3781
|
+
setInputValue(initialInput);
|
|
3782
|
+
initialInputApplied.current = true;
|
|
3783
|
+
}
|
|
3784
|
+
}, [initialInput]);
|
|
3785
|
+
const messagesEndRef = useRef7(null);
|
|
3786
|
+
const scrollAreaRef = useRef7(null);
|
|
3787
|
+
const stateRef = useRef7(state);
|
|
3788
|
+
const inputValueRef = useRef7(inputValue);
|
|
3789
|
+
const attachmentsRef = useRef7(attachments);
|
|
3790
|
+
useEffect10(() => {
|
|
3791
|
+
stateRef.current = state;
|
|
3792
|
+
}, [state]);
|
|
3793
|
+
useEffect10(() => {
|
|
3794
|
+
inputValueRef.current = inputValue;
|
|
3795
|
+
}, [inputValue]);
|
|
3796
|
+
useEffect10(() => {
|
|
3797
|
+
attachmentsRef.current = attachments;
|
|
3798
|
+
}, [attachments]);
|
|
3591
3799
|
const [isCustomMounted, setIsCustomMounted] = useState8(false);
|
|
3592
3800
|
const [isCustomVisible, setIsCustomVisible] = useState8(false);
|
|
3593
3801
|
const createStateCallback = useCallback4(
|
|
3594
3802
|
(setter) => ({
|
|
3595
3803
|
setState: (newState) => setter?.(newState),
|
|
3596
|
-
getState: () =>
|
|
3804
|
+
getState: () => ({
|
|
3805
|
+
...stateRef.current,
|
|
3806
|
+
input: inputValueRef.current,
|
|
3807
|
+
attachments: attachmentsRef.current
|
|
3808
|
+
})
|
|
3597
3809
|
}),
|
|
3598
|
-
[
|
|
3810
|
+
[]
|
|
3811
|
+
// No dependencies - uses refs for latest state
|
|
3599
3812
|
);
|
|
3600
|
-
|
|
3813
|
+
useEffect10(() => {
|
|
3601
3814
|
const checkMobile = () => {
|
|
3602
3815
|
setIsMobile(globalThis.innerWidth < 1024);
|
|
3603
3816
|
};
|
|
@@ -3605,7 +3818,7 @@ var ChatUI = ({
|
|
|
3605
3818
|
globalThis.addEventListener("resize", checkMobile);
|
|
3606
3819
|
return () => globalThis.removeEventListener("resize", checkMobile);
|
|
3607
3820
|
}, []);
|
|
3608
|
-
|
|
3821
|
+
useEffect10(() => {
|
|
3609
3822
|
if (!isMobile || !config.customComponent?.component) return;
|
|
3610
3823
|
if (state.showSidebar) {
|
|
3611
3824
|
setIsCustomMounted(true);
|
|
@@ -3616,7 +3829,7 @@ var ChatUI = ({
|
|
|
3616
3829
|
return () => clearTimeout(t);
|
|
3617
3830
|
}
|
|
3618
3831
|
}, [state.showSidebar, isMobile, config.customComponent]);
|
|
3619
|
-
|
|
3832
|
+
useEffect10(() => {
|
|
3620
3833
|
if (!state.isAtBottom) return;
|
|
3621
3834
|
const viewport = scrollAreaRef.current;
|
|
3622
3835
|
if (!viewport) return;
|
|
@@ -3632,15 +3845,16 @@ var ChatUI = ({
|
|
|
3632
3845
|
const isAtBottom = scrollHeight - scrollTop - clientHeight < 50;
|
|
3633
3846
|
setState((prev) => ({ ...prev, isAtBottom }));
|
|
3634
3847
|
}, []);
|
|
3635
|
-
const handleSendMessage = useCallback4((content,
|
|
3636
|
-
if (!content.trim() &&
|
|
3637
|
-
callbacks.onSendMessage?.(content,
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3848
|
+
const handleSendMessage = useCallback4((content, messageAttachments = []) => {
|
|
3849
|
+
if (!content.trim() && messageAttachments.length === 0) return;
|
|
3850
|
+
callbacks.onSendMessage?.(content, messageAttachments, createStateCallback());
|
|
3851
|
+
if (initialInputApplied.current && !initialInputConsumedRef.current) {
|
|
3852
|
+
initialInputConsumedRef.current = true;
|
|
3853
|
+
onInitialInputConsumed?.();
|
|
3854
|
+
}
|
|
3855
|
+
setInputValue("");
|
|
3856
|
+
setAttachments([]);
|
|
3857
|
+
}, [callbacks, createStateCallback, onInitialInputConsumed]);
|
|
3644
3858
|
const handleMessageAction = useCallback4((event) => {
|
|
3645
3859
|
const { action, messageId, content } = event;
|
|
3646
3860
|
switch (action) {
|
|
@@ -3661,7 +3875,7 @@ var ChatUI = ({
|
|
|
3661
3875
|
}
|
|
3662
3876
|
}, [callbacks, createStateCallback]);
|
|
3663
3877
|
const handleCreateThread = useCallback4((title) => {
|
|
3664
|
-
callbacks.onCreateThread?.(title, createStateCallback(
|
|
3878
|
+
callbacks.onCreateThread?.(title, createStateCallback());
|
|
3665
3879
|
}, [callbacks, createStateCallback]);
|
|
3666
3880
|
const handleSelectThread = useCallback4((threadId) => {
|
|
3667
3881
|
callbacks.onSelectThread?.(threadId, createStateCallback());
|
|
@@ -3686,23 +3900,54 @@ var ChatUI = ({
|
|
|
3686
3900
|
}
|
|
3687
3901
|
return component;
|
|
3688
3902
|
}, [config?.customComponent?.component, closeSidebar, isMobile]);
|
|
3903
|
+
const SuggestionIconComponents = [MessageSquare, Lightbulb2, Zap, HelpCircle];
|
|
3689
3904
|
const renderSuggestions = () => {
|
|
3690
3905
|
if (messages.length > 0 || !suggestions.length) return null;
|
|
3691
|
-
return /* @__PURE__ */ jsxs14("div", { className: "
|
|
3692
|
-
/* @__PURE__ */
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3906
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
|
|
3907
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-center mb-8", children: [
|
|
3908
|
+
/* @__PURE__ */ jsx23("div", { className: "inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-br from-primary/20 to-primary/5 mb-4 shadow-sm", children: /* @__PURE__ */ jsx23(Sparkles, { className: "w-7 h-7 text-primary" }) }),
|
|
3909
|
+
/* @__PURE__ */ jsx23("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
|
|
3910
|
+
/* @__PURE__ */ jsx23("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
|
|
3911
|
+
] }),
|
|
3912
|
+
/* @__PURE__ */ jsx23("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl", children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs14(
|
|
3913
|
+
"button",
|
|
3697
3914
|
{
|
|
3698
|
-
|
|
3915
|
+
type: "button",
|
|
3699
3916
|
onClick: () => handleSendMessage(suggestion),
|
|
3700
|
-
|
|
3917
|
+
className: "group relative flex items-start gap-3 p-4 text-left rounded-xl border bg-card hover:bg-accent/50 hover:border-accent transition-all duration-200 hover:shadow-sm",
|
|
3918
|
+
children: [
|
|
3919
|
+
(() => {
|
|
3920
|
+
const IconComponent = SuggestionIconComponents[index % SuggestionIconComponents.length];
|
|
3921
|
+
return /* @__PURE__ */ jsx23("div", { className: "flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 text-primary shrink-0 group-hover:bg-primary/15 transition-colors", children: /* @__PURE__ */ jsx23(IconComponent, { className: "h-4 w-4" }) });
|
|
3922
|
+
})(),
|
|
3923
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 min-w-0 pr-6", children: /* @__PURE__ */ jsx23("p", { className: "text-sm font-medium leading-snug line-clamp-2", children: suggestion }) }),
|
|
3924
|
+
/* @__PURE__ */ jsx23(ArrowRight, { className: "absolute right-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
|
|
3925
|
+
]
|
|
3701
3926
|
},
|
|
3702
3927
|
index
|
|
3703
3928
|
)) })
|
|
3704
3929
|
] });
|
|
3705
3930
|
};
|
|
3931
|
+
const renderInlineSuggestions = (messageId) => {
|
|
3932
|
+
const items = messageSuggestions?.[messageId];
|
|
3933
|
+
if (!items || items.length === 0) return null;
|
|
3934
|
+
return /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-2 mt-2 ml-11", children: items.map((suggestion, index) => /* @__PURE__ */ jsxs14(
|
|
3935
|
+
"button",
|
|
3936
|
+
{
|
|
3937
|
+
type: "button",
|
|
3938
|
+
onClick: () => handleSendMessage(suggestion),
|
|
3939
|
+
className: "group inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border border-border bg-background hover:bg-accent hover:border-accent-foreground/20 transition-all duration-150 text-foreground/80 hover:text-foreground",
|
|
3940
|
+
children: [
|
|
3941
|
+
/* @__PURE__ */ jsx23(Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
|
|
3942
|
+
/* @__PURE__ */ jsx23("span", { className: "max-w-[200px] truncate", children: suggestion })
|
|
3943
|
+
]
|
|
3944
|
+
},
|
|
3945
|
+
`${messageId}-suggestion-${index}`
|
|
3946
|
+
)) });
|
|
3947
|
+
};
|
|
3948
|
+
const shouldShowAgentSelector = Boolean(
|
|
3949
|
+
config.agentSelector?.enabled && onSelectAgent && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1)
|
|
3950
|
+
);
|
|
3706
3951
|
return /* @__PURE__ */ jsx23(TooltipProvider, { children: /* @__PURE__ */ jsx23(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ jsxs14("div", { className: `flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`, children: [
|
|
3707
3952
|
/* @__PURE__ */ jsx23(
|
|
3708
3953
|
Sidebar2,
|
|
@@ -3743,7 +3988,11 @@ var ChatUI = ({
|
|
|
3743
3988
|
isMobile,
|
|
3744
3989
|
onCustomComponentToggle: () => setState((prev) => ({ ...prev, showSidebar: !prev.showSidebar })),
|
|
3745
3990
|
onNewThread: handleCreateThread,
|
|
3746
|
-
showCustomComponentButton: !!config?.customComponent?.component
|
|
3991
|
+
showCustomComponentButton: !!config?.customComponent?.component,
|
|
3992
|
+
showAgentSelector: shouldShowAgentSelector,
|
|
3993
|
+
agentOptions,
|
|
3994
|
+
selectedAgentId,
|
|
3995
|
+
onSelectAgent
|
|
3747
3996
|
}
|
|
3748
3997
|
),
|
|
3749
3998
|
/* @__PURE__ */ jsxs14("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
|
|
@@ -3757,27 +4006,34 @@ var ChatUI = ({
|
|
|
3757
4006
|
onScrollCapture: handleScroll,
|
|
3758
4007
|
children: /* @__PURE__ */ jsxs14("div", { className: "max-w-4xl mx-auto space-y-4 pb-4", children: [
|
|
3759
4008
|
renderSuggestions(),
|
|
3760
|
-
messages.map((message) =>
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
4009
|
+
messages.map((message, index) => {
|
|
4010
|
+
const prevMessage = index > 0 ? messages[index - 1] : null;
|
|
4011
|
+
const isGrouped = prevMessage !== null && prevMessage.role === message.role;
|
|
4012
|
+
return /* @__PURE__ */ jsxs14("div", { className: isGrouped ? "space-y-1 -mt-2" : "space-y-2", children: [
|
|
4013
|
+
/* @__PURE__ */ jsx23(
|
|
4014
|
+
Message,
|
|
4015
|
+
{
|
|
4016
|
+
message,
|
|
4017
|
+
userAvatar: user?.avatar,
|
|
4018
|
+
userName: user?.name,
|
|
4019
|
+
assistantAvatar: assistant?.avatar,
|
|
4020
|
+
assistantName: assistant?.name,
|
|
4021
|
+
showTimestamp: config.ui.showTimestamps,
|
|
4022
|
+
showAvatar: config.ui.showAvatars,
|
|
4023
|
+
enableCopy: config.features.enableMessageCopy,
|
|
4024
|
+
enableEdit: config.features.enableMessageEditing,
|
|
4025
|
+
enableRegenerate: config.features.enableRegeneration,
|
|
4026
|
+
enableToolCallsDisplay: config.features.enableToolCallsDisplay,
|
|
4027
|
+
compactMode: config.ui.compactMode,
|
|
4028
|
+
onAction: handleMessageAction,
|
|
4029
|
+
toolUsedLabel: config.labels.toolUsed,
|
|
4030
|
+
thinkingLabel: config.labels.thinking,
|
|
4031
|
+
isGrouped
|
|
4032
|
+
}
|
|
4033
|
+
),
|
|
4034
|
+
message.role === "assistant" && renderInlineSuggestions(message.id)
|
|
4035
|
+
] }, message.id);
|
|
4036
|
+
}),
|
|
3781
4037
|
/* @__PURE__ */ jsx23("div", { ref: messagesEndRef })
|
|
3782
4038
|
] })
|
|
3783
4039
|
}
|
|
@@ -3785,11 +4041,17 @@ var ChatUI = ({
|
|
|
3785
4041
|
/* @__PURE__ */ jsx23("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ jsx23(
|
|
3786
4042
|
ChatInput,
|
|
3787
4043
|
{
|
|
3788
|
-
value:
|
|
3789
|
-
onChange: (value) =>
|
|
4044
|
+
value: inputValue,
|
|
4045
|
+
onChange: (value) => {
|
|
4046
|
+
setInputValue(value);
|
|
4047
|
+
if (initialInputApplied.current && !initialInputConsumedRef.current) {
|
|
4048
|
+
initialInputConsumedRef.current = true;
|
|
4049
|
+
onInitialInputConsumed?.();
|
|
4050
|
+
}
|
|
4051
|
+
},
|
|
3790
4052
|
onSubmit: handleSendMessage,
|
|
3791
|
-
attachments
|
|
3792
|
-
onAttachmentsChange:
|
|
4053
|
+
attachments,
|
|
4054
|
+
onAttachmentsChange: setAttachments,
|
|
3793
4055
|
placeholder: config.labels.inputPlaceholder,
|
|
3794
4056
|
disabled: false,
|
|
3795
4057
|
isGenerating,
|
|
@@ -3829,7 +4091,7 @@ var ChatUI = ({
|
|
|
3829
4091
|
}
|
|
3830
4092
|
)
|
|
3831
4093
|
] }),
|
|
3832
|
-
/* @__PURE__ */ jsx23(
|
|
4094
|
+
isUserProfileOpen && /* @__PURE__ */ jsx23(
|
|
3833
4095
|
UserProfile,
|
|
3834
4096
|
{
|
|
3835
4097
|
isOpen: isUserProfileOpen,
|
|
@@ -3852,10 +4114,10 @@ var ChatUI = ({
|
|
|
3852
4114
|
};
|
|
3853
4115
|
|
|
3854
4116
|
// src/components/chat/ThreadManager.tsx
|
|
3855
|
-
import { useState as useState9, useRef as
|
|
4117
|
+
import { useState as useState9, useRef as useRef8, useEffect as useEffect11 } from "react";
|
|
3856
4118
|
import {
|
|
3857
4119
|
Plus as Plus4,
|
|
3858
|
-
MessageSquare,
|
|
4120
|
+
MessageSquare as MessageSquare2,
|
|
3859
4121
|
MoreVertical as MoreVertical2,
|
|
3860
4122
|
Edit2 as Edit22,
|
|
3861
4123
|
Trash2 as Trash24,
|
|
@@ -3865,14 +4127,14 @@ import {
|
|
|
3865
4127
|
Calendar as Calendar2,
|
|
3866
4128
|
Hash,
|
|
3867
4129
|
X as X4,
|
|
3868
|
-
Check as
|
|
4130
|
+
Check as Check4
|
|
3869
4131
|
} from "lucide-react";
|
|
3870
4132
|
import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3871
4133
|
var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
|
|
3872
4134
|
const [isEditing, setIsEditing] = useState9(false);
|
|
3873
4135
|
const [editTitle, setEditTitle] = useState9(thread.title);
|
|
3874
|
-
const inputRef =
|
|
3875
|
-
|
|
4136
|
+
const inputRef = useRef8(null);
|
|
4137
|
+
useEffect11(() => {
|
|
3876
4138
|
if (isEditing && inputRef.current) {
|
|
3877
4139
|
inputRef.current.focus();
|
|
3878
4140
|
inputRef.current.select();
|
|
@@ -3910,7 +4172,7 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
|
|
|
3910
4172
|
placeholder: config?.labels?.threadNamePlaceholder || "Conversation name"
|
|
3911
4173
|
}
|
|
3912
4174
|
),
|
|
3913
|
-
/* @__PURE__ */ jsx24(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ jsx24(
|
|
4175
|
+
/* @__PURE__ */ jsx24(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ jsx24(Check4, { className: "h-3 w-3" }) }),
|
|
3914
4176
|
/* @__PURE__ */ jsx24(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ jsx24(X4, { className: "h-3 w-3" }) })
|
|
3915
4177
|
] }) : /* @__PURE__ */ jsxs15(Fragment6, { children: [
|
|
3916
4178
|
/* @__PURE__ */ jsx24("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
|
|
@@ -4043,7 +4305,7 @@ var ThreadManager = ({
|
|
|
4043
4305
|
/* @__PURE__ */ jsxs15(CardHeader, { className: "border-b", children: [
|
|
4044
4306
|
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
4045
4307
|
/* @__PURE__ */ jsxs15(CardTitle, { className: "flex items-center gap-2", children: [
|
|
4046
|
-
/* @__PURE__ */ jsx24(
|
|
4308
|
+
/* @__PURE__ */ jsx24(MessageSquare2, { className: "h-5 w-5" }),
|
|
4047
4309
|
config?.labels?.newChat || "Conversations"
|
|
4048
4310
|
] }),
|
|
4049
4311
|
/* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx24(X4, { className: "h-4 w-4" }) })
|
|
@@ -4086,7 +4348,7 @@ var ThreadManager = ({
|
|
|
4086
4348
|
/* @__PURE__ */ jsxs15(CardContent, { className: "p-0 flex-1", children: [
|
|
4087
4349
|
/* @__PURE__ */ jsx24("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ jsx24(CreateThreadDialog2, { onCreateThread, config }) }),
|
|
4088
4350
|
/* @__PURE__ */ jsx24(ScrollArea, { className: "h-[calc(100vh-280px)]", children: /* @__PURE__ */ jsx24("div", { className: "px-4 pb-4 space-y-4", children: Object.keys(groupedThreads).length === 0 ? /* @__PURE__ */ jsxs15("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
4089
|
-
/* @__PURE__ */ jsx24(
|
|
4351
|
+
/* @__PURE__ */ jsx24(MessageSquare2, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
|
|
4090
4352
|
/* @__PURE__ */ jsx24("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
|
|
4091
4353
|
] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ jsxs15("div", { children: [
|
|
4092
4354
|
/* @__PURE__ */ jsx24("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
|
|
@@ -4106,7 +4368,7 @@ var ThreadManager = ({
|
|
|
4106
4368
|
] }, group)) }) })
|
|
4107
4369
|
] })
|
|
4108
4370
|
] }) }),
|
|
4109
|
-
/* @__PURE__ */ jsx24(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs15(AlertDialogContent, { children: [
|
|
4371
|
+
deleteThreadId && /* @__PURE__ */ jsx24(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs15(AlertDialogContent, { children: [
|
|
4110
4372
|
/* @__PURE__ */ jsxs15(AlertDialogHeader, { children: [
|
|
4111
4373
|
/* @__PURE__ */ jsx24(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
|
|
4112
4374
|
/* @__PURE__ */ jsx24(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
|