@copilotz/chat-ui 0.3.2 → 0.3.3
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 +5 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -3
- package/dist/index.d.ts +0 -3
- package/dist/index.js +5 -164
- package/dist/index.js.map +1 -1
- package/dist/styles.css +0 -12
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -85,8 +85,6 @@ var defaultChatConfig = {
|
|
|
85
85
|
stopGenerationTooltip: "Stop generation",
|
|
86
86
|
attachFiles: "Attach Files",
|
|
87
87
|
attachFileTooltip: "Attach file",
|
|
88
|
-
recordAudio: "Record Audio",
|
|
89
|
-
recordAudioTooltip: "Record audio",
|
|
90
88
|
voiceEnter: "Voice input",
|
|
91
89
|
voiceExit: "Use keyboard",
|
|
92
90
|
voiceTitle: "Voice",
|
|
@@ -177,7 +175,6 @@ var defaultChatConfig = {
|
|
|
177
175
|
components: {}
|
|
178
176
|
},
|
|
179
177
|
voiceCompose: {
|
|
180
|
-
enabled: false,
|
|
181
178
|
defaultMode: "text",
|
|
182
179
|
reviewMode: "manual",
|
|
183
180
|
autoSendDelayMs: 5e3,
|
|
@@ -3850,61 +3847,6 @@ var AttachmentPreview = (0, import_react6.memo)(function AttachmentPreview2({ at
|
|
|
3850
3847
|
attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "truncate", children: attachment.fileName }) })
|
|
3851
3848
|
] }) });
|
|
3852
3849
|
});
|
|
3853
|
-
var AudioRecorder = (0, import_react6.memo)(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
|
|
3854
|
-
const formatTime = (seconds) => {
|
|
3855
|
-
const mins = Math.floor(seconds / 60);
|
|
3856
|
-
const secs = seconds % 60;
|
|
3857
|
-
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
3858
|
-
};
|
|
3859
|
-
if (!isRecording) {
|
|
3860
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
3861
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3862
|
-
Button,
|
|
3863
|
-
{
|
|
3864
|
-
variant: "outline",
|
|
3865
|
-
size: "icon",
|
|
3866
|
-
onClick: onStartRecording,
|
|
3867
|
-
className: "h-10 w-10",
|
|
3868
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Mic, { className: "h-4 w-4" })
|
|
3869
|
-
}
|
|
3870
|
-
) }),
|
|
3871
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.recordAudioTooltip })
|
|
3872
|
-
] });
|
|
3873
|
-
}
|
|
3874
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Card, { className: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardContent, { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
3875
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3876
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
|
|
3877
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: config?.labels?.voiceListening || "Recording" })
|
|
3878
|
-
] }),
|
|
3879
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
|
|
3880
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-1 ml-auto", children: [
|
|
3881
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3882
|
-
Button,
|
|
3883
|
-
{
|
|
3884
|
-
variant: "outline",
|
|
3885
|
-
size: "sm",
|
|
3886
|
-
onClick: onCancel,
|
|
3887
|
-
children: [
|
|
3888
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { className: "h-3 w-3 mr-1" }),
|
|
3889
|
-
config?.labels?.cancel || "Cancel"
|
|
3890
|
-
]
|
|
3891
|
-
}
|
|
3892
|
-
),
|
|
3893
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3894
|
-
Button,
|
|
3895
|
-
{
|
|
3896
|
-
variant: "default",
|
|
3897
|
-
size: "sm",
|
|
3898
|
-
onClick: onStopRecording,
|
|
3899
|
-
children: [
|
|
3900
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Square, { className: "h-3 w-3 mr-1" }),
|
|
3901
|
-
config?.labels?.voiceStop || "Stop"
|
|
3902
|
-
]
|
|
3903
|
-
}
|
|
3904
|
-
)
|
|
3905
|
-
] })
|
|
3906
|
-
] }) }) });
|
|
3907
|
-
});
|
|
3908
3850
|
var resolveVoiceErrorMessage = (error, config) => {
|
|
3909
3851
|
if (error instanceof DOMException && error.name === "NotAllowedError") {
|
|
3910
3852
|
return config?.labels?.voicePermissionDenied || "Microphone access was denied.";
|
|
@@ -3937,7 +3879,6 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
3937
3879
|
mentionAgents = [],
|
|
3938
3880
|
onTargetAgentChange
|
|
3939
3881
|
}) {
|
|
3940
|
-
const voiceComposeEnabled = config?.voiceCompose?.enabled === true;
|
|
3941
3882
|
const voiceDefaultMode = config?.voiceCompose?.defaultMode ?? "text";
|
|
3942
3883
|
const voiceReviewMode = config?.voiceCompose?.reviewMode ?? "manual";
|
|
3943
3884
|
const voiceAutoSendDelayMs = config?.voiceCompose?.autoSendDelayMs ?? 5e3;
|
|
@@ -3945,12 +3886,10 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
3945
3886
|
const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;
|
|
3946
3887
|
const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? "final-only";
|
|
3947
3888
|
const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;
|
|
3948
|
-
const [isRecording, setIsRecording] = (0, import_react6.useState)(false);
|
|
3949
3889
|
const { setContext } = useChatUserContext();
|
|
3950
|
-
const [recordingDuration, setRecordingDuration] = (0, import_react6.useState)(0);
|
|
3951
3890
|
const [uploadProgress, setUploadProgress] = (0, import_react6.useState)(/* @__PURE__ */ new Map());
|
|
3952
3891
|
const [isVoiceComposerOpen, setIsVoiceComposerOpen] = (0, import_react6.useState)(
|
|
3953
|
-
() =>
|
|
3892
|
+
() => enableAudioRecording && voiceDefaultMode === "voice"
|
|
3954
3893
|
);
|
|
3955
3894
|
const [voiceState, setVoiceState] = (0, import_react6.useState)("idle");
|
|
3956
3895
|
const [voiceDraft, setVoiceDraft] = (0, import_react6.useState)(null);
|
|
@@ -3964,10 +3903,6 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
3964
3903
|
const [activeMentionIndex, setActiveMentionIndex] = (0, import_react6.useState)(0);
|
|
3965
3904
|
const textareaRef = (0, import_react6.useRef)(null);
|
|
3966
3905
|
const fileInputRef = (0, import_react6.useRef)(null);
|
|
3967
|
-
const mediaRecorderRef = (0, import_react6.useRef)(null);
|
|
3968
|
-
const recordingStartTime = (0, import_react6.useRef)(0);
|
|
3969
|
-
const recordingInterval = (0, import_react6.useRef)(null);
|
|
3970
|
-
const mediaStreamRef = (0, import_react6.useRef)(null);
|
|
3971
3906
|
const voiceProviderRef = (0, import_react6.useRef)(null);
|
|
3972
3907
|
const voiceDraftRef = (0, import_react6.useRef)(null);
|
|
3973
3908
|
const voiceAppendBaseRef = (0, import_react6.useRef)(null);
|
|
@@ -4003,12 +3938,6 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
4003
3938
|
}, []);
|
|
4004
3939
|
(0, import_react6.useEffect)(() => {
|
|
4005
3940
|
return () => {
|
|
4006
|
-
if (mediaStreamRef.current) {
|
|
4007
|
-
mediaStreamRef.current.getTracks().forEach((track) => track.stop());
|
|
4008
|
-
}
|
|
4009
|
-
if (recordingInterval.current) {
|
|
4010
|
-
clearInterval(recordingInterval.current);
|
|
4011
|
-
}
|
|
4012
3941
|
if (voiceProviderRef.current) {
|
|
4013
3942
|
void voiceProviderRef.current.destroy();
|
|
4014
3943
|
voiceProviderRef.current = null;
|
|
@@ -4181,73 +4110,6 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
4181
4110
|
const handleDragOver = (0, import_react6.useCallback)((e) => {
|
|
4182
4111
|
e.preventDefault();
|
|
4183
4112
|
}, []);
|
|
4184
|
-
const startRecording = async () => {
|
|
4185
|
-
try {
|
|
4186
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
4187
|
-
mediaStreamRef.current = stream;
|
|
4188
|
-
const mediaRecorder = new MediaRecorder(stream);
|
|
4189
|
-
mediaRecorderRef.current = mediaRecorder;
|
|
4190
|
-
const chunks = [];
|
|
4191
|
-
mediaRecorder.ondataavailable = (e) => {
|
|
4192
|
-
chunks.push(e.data);
|
|
4193
|
-
};
|
|
4194
|
-
mediaRecorder.onstop = async () => {
|
|
4195
|
-
const blob = new Blob(chunks, { type: "audio/webm" });
|
|
4196
|
-
const dataUrl = await new Promise((resolve, reject) => {
|
|
4197
|
-
const reader = new FileReader();
|
|
4198
|
-
reader.onload = () => resolve(reader.result);
|
|
4199
|
-
reader.onerror = reject;
|
|
4200
|
-
reader.readAsDataURL(blob);
|
|
4201
|
-
});
|
|
4202
|
-
const attachment = {
|
|
4203
|
-
kind: "audio",
|
|
4204
|
-
dataUrl,
|
|
4205
|
-
mimeType: blob.type,
|
|
4206
|
-
durationMs: recordingDuration * 1e3,
|
|
4207
|
-
fileName: `audio_${(/* @__PURE__ */ new Date()).toISOString().slice(0, 19)}.webm`,
|
|
4208
|
-
size: blob.size
|
|
4209
|
-
};
|
|
4210
|
-
onAttachmentsChange([...attachments, attachment]);
|
|
4211
|
-
if (mediaStreamRef.current) {
|
|
4212
|
-
mediaStreamRef.current.getTracks().forEach((track) => track.stop());
|
|
4213
|
-
mediaStreamRef.current = null;
|
|
4214
|
-
}
|
|
4215
|
-
};
|
|
4216
|
-
recordingStartTime.current = Date.now();
|
|
4217
|
-
setRecordingDuration(0);
|
|
4218
|
-
setIsRecording(true);
|
|
4219
|
-
mediaRecorder.start();
|
|
4220
|
-
recordingInterval.current = setInterval(() => {
|
|
4221
|
-
const duration = Math.floor((Date.now() - recordingStartTime.current) / 1e3);
|
|
4222
|
-
setRecordingDuration(duration);
|
|
4223
|
-
}, 1e3);
|
|
4224
|
-
} catch (error) {
|
|
4225
|
-
console.error("Error starting recording:", error);
|
|
4226
|
-
alert(config?.labels?.voicePermissionDenied || "Microphone access was denied.");
|
|
4227
|
-
}
|
|
4228
|
-
};
|
|
4229
|
-
const stopRecording = () => {
|
|
4230
|
-
if (mediaRecorderRef.current && isRecording) {
|
|
4231
|
-
mediaRecorderRef.current.stop();
|
|
4232
|
-
setIsRecording(false);
|
|
4233
|
-
if (recordingInterval.current) {
|
|
4234
|
-
clearInterval(recordingInterval.current);
|
|
4235
|
-
}
|
|
4236
|
-
}
|
|
4237
|
-
};
|
|
4238
|
-
const cancelRecording = () => {
|
|
4239
|
-
if (mediaRecorderRef.current && isRecording) {
|
|
4240
|
-
mediaRecorderRef.current.stop();
|
|
4241
|
-
setIsRecording(false);
|
|
4242
|
-
if (recordingInterval.current) {
|
|
4243
|
-
clearInterval(recordingInterval.current);
|
|
4244
|
-
}
|
|
4245
|
-
if (mediaStreamRef.current) {
|
|
4246
|
-
mediaStreamRef.current.getTracks().forEach((track) => track.stop());
|
|
4247
|
-
mediaStreamRef.current = null;
|
|
4248
|
-
}
|
|
4249
|
-
}
|
|
4250
|
-
};
|
|
4251
4113
|
const resetVoiceComposerState = (0, import_react6.useCallback)((nextState = "idle") => {
|
|
4252
4114
|
setVoiceState(nextState);
|
|
4253
4115
|
setVoiceDraft(null);
|
|
@@ -4532,7 +4394,7 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
4532
4394
|
onAttachmentsChange(newAttachments);
|
|
4533
4395
|
};
|
|
4534
4396
|
const canAddMoreAttachments = attachments.length < maxAttachments;
|
|
4535
|
-
const showVoiceComposer =
|
|
4397
|
+
const showVoiceComposer = enableAudioRecording && isVoiceComposerOpen;
|
|
4536
4398
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: `border-t py-0 bg-transparent ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "px-0 md:p-2 pb-1 space-y-4 bg-transparent", children: [
|
|
4537
4399
|
uploadProgress.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4538
4400
|
FileUploadItem,
|
|
@@ -4549,17 +4411,6 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
4549
4411
|
},
|
|
4550
4412
|
id
|
|
4551
4413
|
)) }),
|
|
4552
|
-
isRecording && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4553
|
-
AudioRecorder,
|
|
4554
|
-
{
|
|
4555
|
-
isRecording,
|
|
4556
|
-
onStartRecording: startRecording,
|
|
4557
|
-
onStopRecording: stopRecording,
|
|
4558
|
-
onCancel: cancelRecording,
|
|
4559
|
-
recordingDuration,
|
|
4560
|
-
config
|
|
4561
|
-
}
|
|
4562
|
-
),
|
|
4563
4414
|
attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4564
4415
|
AttachmentPreview,
|
|
4565
4416
|
{
|
|
@@ -4689,7 +4540,7 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
4689
4540
|
agent.id
|
|
4690
4541
|
)) }) })
|
|
4691
4542
|
] }),
|
|
4692
|
-
enableAudioRecording &&
|
|
4543
|
+
enableAudioRecording && canAddMoreAttachments && !value.trim() && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
4693
4544
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4694
4545
|
Button,
|
|
4695
4546
|
{
|
|
@@ -4704,18 +4555,8 @@ var ChatInput = (0, import_react6.memo)(function ChatInput2({
|
|
|
4704
4555
|
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Mic, { className: "h-4 w-4" })
|
|
4705
4556
|
}
|
|
4706
4557
|
) }),
|
|
4707
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.voiceEnter
|
|
4708
|
-
] })
|
|
4709
|
-
AudioRecorder,
|
|
4710
|
-
{
|
|
4711
|
-
isRecording,
|
|
4712
|
-
onStartRecording: startRecording,
|
|
4713
|
-
onStopRecording: stopRecording,
|
|
4714
|
-
onCancel: cancelRecording,
|
|
4715
|
-
recordingDuration,
|
|
4716
|
-
config
|
|
4717
|
-
}
|
|
4718
|
-
)),
|
|
4558
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { children: config?.labels?.voiceEnter })
|
|
4559
|
+
] }),
|
|
4719
4560
|
isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
4720
4561
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4721
4562
|
Button,
|