@arbidocs/react 0.3.171 → 0.3.173
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/chunk-Q6XAXIT3.js +43 -0
- package/dist/chunk-Q6XAXIT3.js.map +1 -0
- package/dist/{chunk-ZMTLGO3K.cjs → chunk-RWCMW36I.cjs} +20 -2
- package/dist/chunk-RWCMW36I.cjs.map +1 -0
- package/dist/index.cjs +433 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -1
- package/dist/index.d.ts +118 -1
- package/dist/index.js +399 -4
- package/dist/index.js.map +1 -1
- package/dist/viewers/index.cjs +7 -21
- package/dist/viewers/index.cjs.map +1 -1
- package/dist/viewers/index.js +3 -19
- package/dist/viewers/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-J4MX2W4H.js +0 -26
- package/dist/chunk-J4MX2W4H.js.map +0 -1
- package/dist/chunk-ZMTLGO3K.cjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useArbi, ArbiProvider } from './chunk-
|
|
2
|
-
export { ArbiProvider, useArbi } from './chunk-
|
|
1
|
+
import { useArbi, ArbiProvider, AudioViewer } from './chunk-Q6XAXIT3.js';
|
|
2
|
+
export { ArbiProvider, useArbi } from './chunk-Q6XAXIT3.js';
|
|
3
3
|
import { cn, Avatar, AvatarFallback, AvatarImage, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverContent, AiMarkdown, Card, Button, Badge, MarkdownRenderer, Input, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, ScrollArea, DropdownMenuItem, Textarea, Slider, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DropdownMenuLabel, DropdownMenuSeparator, Checkbox } from './chunk-PAJGQHFM.js';
|
|
4
4
|
export { AiMarkdown, Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, HoverCard, HoverCardContent, HoverCardTrigger, Input, Label, MarkdownRenderer, MarkdownStreamingContext, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Slider, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cardVariants, cn, markdownBaseComponents, splitMarkdownBlocks, toggleVariants } from './chunk-PAJGQHFM.js';
|
|
5
5
|
import React2, { memo, useState, createContext, forwardRef, useMemo, useCallback, useId, useRef, useContext, useEffect, Fragment as Fragment$1 } from 'react';
|
|
@@ -7,7 +7,7 @@ import { useQuery, useMutation, useQueries, QueryClient, QueryClientProvider, us
|
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { connectWithReconnect, resolveCitations, summarizeCitations } from '@arbidocs/sdk/browser';
|
|
9
9
|
export { Arbi, ArbiError } from '@arbidocs/sdk/browser';
|
|
10
|
-
import { Link, Trash2, CheckCheck, Check, MessageCircleMore, MoreVertical, MessageSquareLock, Info, FileQuestion, BookOpen, Upload, LogOut, LayoutGrid, Bell, MessageSquare, CircleUserRound, Wrench, CreditCard, ClipboardList, UserPlus, UserStar, Settings2, Users, User, NotebookPen, NotebookText, StickyNote, FolderPlus, Hash, EyeOff, Eye, CaptionsOff, FolderOpen, MessageSquareMore, MessageSquarePlus, MessageSquareText, MessageSquareOff, MessagesSquare, Columns3Cog, SquarePlus, SquareM, ChevronsDown, Bot, Calendar, Search, Folder, List, SquareCheckBig, Loader2, AlertTriangle, ShieldCheck, Copy, Sparkles, FileText, GitCompareArrows, Download, Image as Image$1, CornerDownLeft, X, ArrowLeft, Send, Tags, Crown, Activity, Gauge, Gift, PartyPopper, UserCheck, FileX2, FileCheck2, Pencil, SquareArrowOutUpRight, BellOff, XCircle, CheckCircle2, ArrowRight, ChevronDown, MoreHorizontal, SquarePen, FileX, SkipForward, CheckCircle } from 'lucide-react';
|
|
10
|
+
import { Link, Trash2, CheckCheck, Check, MessageCircleMore, MoreVertical, MessageSquareLock, Info, FileQuestion, BookOpen, Upload, LogOut, LayoutGrid, Bell, MessageSquare, CircleUserRound, Wrench, CreditCard, ClipboardList, UserPlus, UserStar, Settings2, Users, User, NotebookPen, NotebookText, StickyNote, FolderPlus, Hash, EyeOff, Eye, CaptionsOff, FolderOpen, MessageSquareMore, MessageSquarePlus, MessageSquareText, MessageSquareOff, MessagesSquare, Columns3Cog, SquarePlus, SquareM, ChevronsDown, Bot, Calendar, Search, Folder, List, SquareCheckBig, Loader2, AlertTriangle, ShieldCheck, Copy, Sparkles, FileText, GitCompareArrows, Download, Image as Image$1, CornerDownLeft, X, ArrowLeft, Send, Tags, Crown, Activity, Gauge, Gift, PartyPopper, UserCheck, FileX2, FileCheck2, Pencil, SquareArrowOutUpRight, BellOff, XCircle, CheckCircle2, ArrowRight, ChevronDown, MoreHorizontal, SquarePen, Mic, Pause, Play, Square, RotateCcw, FileX, SkipForward, CheckCircle } from 'lucide-react';
|
|
11
11
|
import { isMessageType } from '@arbidocs/client';
|
|
12
12
|
export { isMessageType } from '@arbidocs/client';
|
|
13
13
|
import { create } from 'zustand';
|
|
@@ -7160,7 +7160,402 @@ function DocumentGallery({
|
|
|
7160
7160
|
}
|
|
7161
7161
|
);
|
|
7162
7162
|
}
|
|
7163
|
+
var LEVEL_UPDATE_INTERVAL_MS = 50;
|
|
7164
|
+
function classifyMicError(err) {
|
|
7165
|
+
const name = err instanceof DOMException ? err.name : void 0;
|
|
7166
|
+
if (name === "NotAllowedError" || name === "SecurityError") {
|
|
7167
|
+
return "Microphone access is blocked. Allow microphone permission in your browser settings to use voice input.";
|
|
7168
|
+
}
|
|
7169
|
+
if (name === "NotFoundError" || name === "DevicesNotFoundError") {
|
|
7170
|
+
return "No microphone found on this device.";
|
|
7171
|
+
}
|
|
7172
|
+
if (!navigator.mediaDevices?.getUserMedia) {
|
|
7173
|
+
return "Voice input is not supported in this browser.";
|
|
7174
|
+
}
|
|
7175
|
+
return "Could not start recording. Please try again.";
|
|
7176
|
+
}
|
|
7177
|
+
function useAudioRecorder() {
|
|
7178
|
+
const [state, setState] = useState("idle");
|
|
7179
|
+
const [level, setLevel] = useState(0);
|
|
7180
|
+
const [elapsedMs, setElapsedMs] = useState(0);
|
|
7181
|
+
const [blob, setBlob] = useState(null);
|
|
7182
|
+
const [mimeType, setMimeType] = useState(null);
|
|
7183
|
+
const [error, setError] = useState(null);
|
|
7184
|
+
const mediaRecorderRef = useRef(null);
|
|
7185
|
+
const chunksRef = useRef([]);
|
|
7186
|
+
const streamRef = useRef(null);
|
|
7187
|
+
const stateRef = useRef("idle");
|
|
7188
|
+
stateRef.current = state;
|
|
7189
|
+
const segmentStartRef = useRef(0);
|
|
7190
|
+
const accumulatedMsRef = useRef(0);
|
|
7191
|
+
const audioContextRef = useRef(null);
|
|
7192
|
+
const analyserRef = useRef(null);
|
|
7193
|
+
const levelRafRef = useRef(null);
|
|
7194
|
+
const stopMeter = useCallback(() => {
|
|
7195
|
+
if (levelRafRef.current !== null) cancelAnimationFrame(levelRafRef.current);
|
|
7196
|
+
levelRafRef.current = null;
|
|
7197
|
+
analyserRef.current = null;
|
|
7198
|
+
void audioContextRef.current?.close().catch(() => {
|
|
7199
|
+
});
|
|
7200
|
+
audioContextRef.current = null;
|
|
7201
|
+
}, []);
|
|
7202
|
+
const startMeter = useCallback((stream) => {
|
|
7203
|
+
const audioContext = new AudioContext();
|
|
7204
|
+
const source = audioContext.createMediaStreamSource(stream);
|
|
7205
|
+
const analyser = audioContext.createAnalyser();
|
|
7206
|
+
analyser.fftSize = 256;
|
|
7207
|
+
source.connect(analyser);
|
|
7208
|
+
audioContextRef.current = audioContext;
|
|
7209
|
+
analyserRef.current = analyser;
|
|
7210
|
+
const data = new Uint8Array(analyser.frequencyBinCount);
|
|
7211
|
+
let lastUpdate = 0;
|
|
7212
|
+
const tick = (t) => {
|
|
7213
|
+
const active = analyserRef.current;
|
|
7214
|
+
if (!active) return;
|
|
7215
|
+
if (t - lastUpdate >= LEVEL_UPDATE_INTERVAL_MS) {
|
|
7216
|
+
lastUpdate = t;
|
|
7217
|
+
active.getByteTimeDomainData(data);
|
|
7218
|
+
let sumSquares = 0;
|
|
7219
|
+
for (let i = 0; i < data.length; i++) {
|
|
7220
|
+
const centered = (data[i] - 128) / 128;
|
|
7221
|
+
sumSquares += centered * centered;
|
|
7222
|
+
}
|
|
7223
|
+
const rms = Math.sqrt(sumSquares / data.length);
|
|
7224
|
+
setLevel(Math.sqrt(Math.min(1, rms * 8)));
|
|
7225
|
+
setElapsedMs(accumulatedMsRef.current + (t - segmentStartRef.current));
|
|
7226
|
+
}
|
|
7227
|
+
levelRafRef.current = requestAnimationFrame(tick);
|
|
7228
|
+
};
|
|
7229
|
+
levelRafRef.current = requestAnimationFrame(tick);
|
|
7230
|
+
}, []);
|
|
7231
|
+
const stopTracks = useCallback(() => {
|
|
7232
|
+
streamRef.current?.getTracks().forEach((t) => t.stop());
|
|
7233
|
+
streamRef.current = null;
|
|
7234
|
+
}, []);
|
|
7235
|
+
useEffect(
|
|
7236
|
+
() => () => {
|
|
7237
|
+
stopTracks();
|
|
7238
|
+
stopMeter();
|
|
7239
|
+
},
|
|
7240
|
+
[stopTracks, stopMeter]
|
|
7241
|
+
);
|
|
7242
|
+
const start = useCallback(async () => {
|
|
7243
|
+
if (stateRef.current === "recording" || stateRef.current === "paused") return;
|
|
7244
|
+
setError(null);
|
|
7245
|
+
try {
|
|
7246
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
7247
|
+
streamRef.current = stream;
|
|
7248
|
+
const mt = MediaRecorder.isTypeSupported("audio/webm") ? "audio/webm" : "audio/mp4";
|
|
7249
|
+
const recorder = new MediaRecorder(stream, { mimeType: mt });
|
|
7250
|
+
chunksRef.current = [];
|
|
7251
|
+
recorder.ondataavailable = (e) => {
|
|
7252
|
+
if (e.data.size > 0) chunksRef.current.push(e.data);
|
|
7253
|
+
};
|
|
7254
|
+
mediaRecorderRef.current = recorder;
|
|
7255
|
+
setMimeType(mt);
|
|
7256
|
+
setBlob(null);
|
|
7257
|
+
accumulatedMsRef.current = 0;
|
|
7258
|
+
segmentStartRef.current = performance.now();
|
|
7259
|
+
recorder.start();
|
|
7260
|
+
setState("recording");
|
|
7261
|
+
startMeter(stream);
|
|
7262
|
+
} catch (err) {
|
|
7263
|
+
stopTracks();
|
|
7264
|
+
setError(classifyMicError(err));
|
|
7265
|
+
}
|
|
7266
|
+
}, [startMeter, stopTracks]);
|
|
7267
|
+
const pause = useCallback(() => {
|
|
7268
|
+
const recorder = mediaRecorderRef.current;
|
|
7269
|
+
if (!recorder || recorder.state !== "recording") return;
|
|
7270
|
+
recorder.pause();
|
|
7271
|
+
accumulatedMsRef.current += performance.now() - segmentStartRef.current;
|
|
7272
|
+
stopMeter();
|
|
7273
|
+
setLevel(0);
|
|
7274
|
+
setState("paused");
|
|
7275
|
+
}, [stopMeter]);
|
|
7276
|
+
const resume = useCallback(() => {
|
|
7277
|
+
const recorder = mediaRecorderRef.current;
|
|
7278
|
+
if (!recorder || recorder.state !== "paused") return;
|
|
7279
|
+
recorder.resume();
|
|
7280
|
+
segmentStartRef.current = performance.now();
|
|
7281
|
+
setState("recording");
|
|
7282
|
+
if (streamRef.current) startMeter(streamRef.current);
|
|
7283
|
+
}, [startMeter]);
|
|
7284
|
+
const stop = useCallback(() => {
|
|
7285
|
+
const recorder = mediaRecorderRef.current;
|
|
7286
|
+
if (!recorder || recorder.state === "inactive") return;
|
|
7287
|
+
const finalElapsed = recorder.state === "paused" ? accumulatedMsRef.current : accumulatedMsRef.current + (performance.now() - segmentStartRef.current);
|
|
7288
|
+
stopMeter();
|
|
7289
|
+
recorder.onstop = () => {
|
|
7290
|
+
stopTracks();
|
|
7291
|
+
const finalBlob = chunksRef.current.length ? new Blob(chunksRef.current, { type: recorder.mimeType }) : null;
|
|
7292
|
+
setBlob(finalBlob);
|
|
7293
|
+
setElapsedMs(finalElapsed);
|
|
7294
|
+
setLevel(0);
|
|
7295
|
+
setState("stopped");
|
|
7296
|
+
};
|
|
7297
|
+
recorder.stop();
|
|
7298
|
+
}, [stopMeter, stopTracks]);
|
|
7299
|
+
const reset = useCallback(() => {
|
|
7300
|
+
setState("idle");
|
|
7301
|
+
setBlob(null);
|
|
7302
|
+
setElapsedMs(0);
|
|
7303
|
+
setLevel(0);
|
|
7304
|
+
setMimeType(null);
|
|
7305
|
+
setError(null);
|
|
7306
|
+
}, []);
|
|
7307
|
+
return { state, level, elapsedMs, blob, mimeType, error, start, pause, resume, stop, reset };
|
|
7308
|
+
}
|
|
7309
|
+
|
|
7310
|
+
// src/documents/format-elapsed.ts
|
|
7311
|
+
function formatElapsed(ms) {
|
|
7312
|
+
const totalSeconds = Math.max(0, Math.floor(ms / 1e3));
|
|
7313
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
7314
|
+
const seconds = totalSeconds % 60;
|
|
7315
|
+
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
|
7316
|
+
}
|
|
7317
|
+
var BAR_WEIGHTS = [
|
|
7318
|
+
0.25,
|
|
7319
|
+
0.32,
|
|
7320
|
+
0.48,
|
|
7321
|
+
0.62,
|
|
7322
|
+
0.82,
|
|
7323
|
+
0.56,
|
|
7324
|
+
0.92,
|
|
7325
|
+
0.72,
|
|
7326
|
+
1,
|
|
7327
|
+
0.86,
|
|
7328
|
+
0.62,
|
|
7329
|
+
0.96,
|
|
7330
|
+
0.76,
|
|
7331
|
+
0.5,
|
|
7332
|
+
0.84,
|
|
7333
|
+
0.66,
|
|
7334
|
+
0.42,
|
|
7335
|
+
0.56,
|
|
7336
|
+
0.36,
|
|
7337
|
+
0.28,
|
|
7338
|
+
0.22
|
|
7339
|
+
];
|
|
7340
|
+
var MIN_BAR_PX = 3;
|
|
7341
|
+
var MAX_BAR_PX = 40;
|
|
7342
|
+
function MicWaveformIndicator({
|
|
7343
|
+
level,
|
|
7344
|
+
elapsedMs,
|
|
7345
|
+
paused = false
|
|
7346
|
+
}) {
|
|
7347
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3", "data-testid": "mic-waveform-indicator", children: [
|
|
7348
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7349
|
+
/* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2", children: [
|
|
7350
|
+
!paused && /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75" }),
|
|
7351
|
+
/* @__PURE__ */ jsx(
|
|
7352
|
+
"span",
|
|
7353
|
+
{
|
|
7354
|
+
className: `relative inline-flex h-2 w-2 rounded-full ${paused ? "bg-muted-foreground" : "bg-red-500"}`
|
|
7355
|
+
}
|
|
7356
|
+
)
|
|
7357
|
+
] }),
|
|
7358
|
+
/* @__PURE__ */ jsx(
|
|
7359
|
+
"span",
|
|
7360
|
+
{
|
|
7361
|
+
className: `text-xs font-semibold uppercase tracking-wide ${paused ? "text-muted-foreground" : "text-red-500"}`,
|
|
7362
|
+
children: paused ? "Paused" : "Rec"
|
|
7363
|
+
}
|
|
7364
|
+
),
|
|
7365
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-xs tabular-nums text-muted-foreground", children: formatElapsed(elapsedMs) })
|
|
7366
|
+
] }),
|
|
7367
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-10 items-end gap-[3px]", "data-testid": "mic-waveform-indicator-bars", children: BAR_WEIGHTS.map((weight, i) => /* @__PURE__ */ jsx(
|
|
7368
|
+
"span",
|
|
7369
|
+
{
|
|
7370
|
+
className: "w-1 rounded-full bg-secondary transition-[height] duration-75 ease-out",
|
|
7371
|
+
style: {
|
|
7372
|
+
height: Math.min(MAX_BAR_PX, Math.max(MIN_BAR_PX, level * weight * MAX_BAR_PX))
|
|
7373
|
+
}
|
|
7374
|
+
},
|
|
7375
|
+
i
|
|
7376
|
+
)) })
|
|
7377
|
+
] });
|
|
7378
|
+
}
|
|
7379
|
+
function VoiceNoteRecorder({
|
|
7380
|
+
onSave,
|
|
7381
|
+
onDiscard,
|
|
7382
|
+
onError,
|
|
7383
|
+
title = "Voice note",
|
|
7384
|
+
isSaving = false,
|
|
7385
|
+
transcribe
|
|
7386
|
+
}) {
|
|
7387
|
+
const recorder = useAudioRecorder();
|
|
7388
|
+
const [transcript, setTranscript] = useState(null);
|
|
7389
|
+
const [isTranscribing, setIsTranscribing] = useState(false);
|
|
7390
|
+
useEffect(() => {
|
|
7391
|
+
if (recorder.error) onError?.(recorder.error);
|
|
7392
|
+
}, [recorder.error]);
|
|
7393
|
+
useEffect(() => {
|
|
7394
|
+
if (recorder.state !== "stopped" || !recorder.blob) {
|
|
7395
|
+
setTranscript(null);
|
|
7396
|
+
setIsTranscribing(false);
|
|
7397
|
+
return;
|
|
7398
|
+
}
|
|
7399
|
+
if (!transcribe) return;
|
|
7400
|
+
let cancelled = false;
|
|
7401
|
+
setIsTranscribing(true);
|
|
7402
|
+
transcribe(recorder.blob).then((text) => {
|
|
7403
|
+
if (!cancelled) setTranscript(text);
|
|
7404
|
+
}).catch(() => {
|
|
7405
|
+
}).finally(() => {
|
|
7406
|
+
if (!cancelled) setIsTranscribing(false);
|
|
7407
|
+
});
|
|
7408
|
+
return () => {
|
|
7409
|
+
cancelled = true;
|
|
7410
|
+
};
|
|
7411
|
+
}, [recorder.state, recorder.blob]);
|
|
7412
|
+
const handleSave = () => {
|
|
7413
|
+
if (!recorder.blob) return;
|
|
7414
|
+
void onSave(recorder.blob, recorder.mimeType);
|
|
7415
|
+
};
|
|
7416
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-6 p-8", children: [
|
|
7417
|
+
recorder.state === "idle" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7418
|
+
/* @__PURE__ */ jsx(
|
|
7419
|
+
Button,
|
|
7420
|
+
{
|
|
7421
|
+
type: "button",
|
|
7422
|
+
size: "lg",
|
|
7423
|
+
className: "h-16 w-16 rounded-full p-0",
|
|
7424
|
+
onClick: () => void recorder.start(),
|
|
7425
|
+
"data-testid": "voice-note-record-button",
|
|
7426
|
+
children: /* @__PURE__ */ jsx(Mic, { className: "h-6 w-6" })
|
|
7427
|
+
}
|
|
7428
|
+
),
|
|
7429
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Press to start recording" })
|
|
7430
|
+
] }),
|
|
7431
|
+
(recorder.state === "recording" || recorder.state === "paused") && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7432
|
+
/* @__PURE__ */ jsx(
|
|
7433
|
+
MicWaveformIndicator,
|
|
7434
|
+
{
|
|
7435
|
+
level: recorder.level,
|
|
7436
|
+
elapsedMs: recorder.elapsedMs,
|
|
7437
|
+
paused: recorder.state === "paused"
|
|
7438
|
+
}
|
|
7439
|
+
),
|
|
7440
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7441
|
+
recorder.state === "recording" ? /* @__PURE__ */ jsxs(
|
|
7442
|
+
Button,
|
|
7443
|
+
{
|
|
7444
|
+
type: "button",
|
|
7445
|
+
variant: "outline",
|
|
7446
|
+
onClick: recorder.pause,
|
|
7447
|
+
"data-testid": "voice-note-pause-button",
|
|
7448
|
+
children: [
|
|
7449
|
+
/* @__PURE__ */ jsx(Pause, { className: "mr-1.5 h-4 w-4" }),
|
|
7450
|
+
"Pause"
|
|
7451
|
+
]
|
|
7452
|
+
}
|
|
7453
|
+
) : /* @__PURE__ */ jsxs(
|
|
7454
|
+
Button,
|
|
7455
|
+
{
|
|
7456
|
+
type: "button",
|
|
7457
|
+
variant: "outline",
|
|
7458
|
+
onClick: recorder.resume,
|
|
7459
|
+
"data-testid": "voice-note-resume-button",
|
|
7460
|
+
children: [
|
|
7461
|
+
/* @__PURE__ */ jsx(Play, { className: "mr-1.5 h-4 w-4" }),
|
|
7462
|
+
"Resume"
|
|
7463
|
+
]
|
|
7464
|
+
}
|
|
7465
|
+
),
|
|
7466
|
+
/* @__PURE__ */ jsxs(Button, { type: "button", onClick: recorder.stop, "data-testid": "voice-note-stop-button", children: [
|
|
7467
|
+
/* @__PURE__ */ jsx(Square, { className: "mr-1.5 h-3.5 w-3.5 fill-current" }),
|
|
7468
|
+
"Stop"
|
|
7469
|
+
] })
|
|
7470
|
+
] })
|
|
7471
|
+
] }),
|
|
7472
|
+
recorder.state === "stopped" && recorder.blob && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7473
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsx(AudioViewer, { blob: recorder.blob, title }) }),
|
|
7474
|
+
(isTranscribing || transcript) && /* @__PURE__ */ jsx(
|
|
7475
|
+
"div",
|
|
7476
|
+
{
|
|
7477
|
+
className: "w-full max-w-md rounded-md border border-border bg-muted/30 p-3 text-sm text-muted-foreground",
|
|
7478
|
+
"data-testid": "voice-note-rough-transcript",
|
|
7479
|
+
children: isTranscribing ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
7480
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
7481
|
+
"Transcribing\u2026"
|
|
7482
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7483
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide", children: "Rough transcript" }),
|
|
7484
|
+
/* @__PURE__ */ jsx("p", { children: transcript })
|
|
7485
|
+
] })
|
|
7486
|
+
}
|
|
7487
|
+
),
|
|
7488
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7489
|
+
/* @__PURE__ */ jsxs(
|
|
7490
|
+
Button,
|
|
7491
|
+
{
|
|
7492
|
+
type: "button",
|
|
7493
|
+
variant: "outline",
|
|
7494
|
+
onClick: onDiscard,
|
|
7495
|
+
disabled: isSaving,
|
|
7496
|
+
"data-testid": "voice-note-discard-button",
|
|
7497
|
+
children: [
|
|
7498
|
+
/* @__PURE__ */ jsx(Trash2, { className: "mr-1.5 h-4 w-4" }),
|
|
7499
|
+
"Discard"
|
|
7500
|
+
]
|
|
7501
|
+
}
|
|
7502
|
+
),
|
|
7503
|
+
/* @__PURE__ */ jsxs(
|
|
7504
|
+
Button,
|
|
7505
|
+
{
|
|
7506
|
+
type: "button",
|
|
7507
|
+
variant: "outline",
|
|
7508
|
+
onClick: recorder.reset,
|
|
7509
|
+
disabled: isSaving,
|
|
7510
|
+
"data-testid": "voice-note-record-again-button",
|
|
7511
|
+
children: [
|
|
7512
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "mr-1.5 h-4 w-4" }),
|
|
7513
|
+
"Record again"
|
|
7514
|
+
]
|
|
7515
|
+
}
|
|
7516
|
+
),
|
|
7517
|
+
/* @__PURE__ */ jsxs(
|
|
7518
|
+
Button,
|
|
7519
|
+
{
|
|
7520
|
+
type: "button",
|
|
7521
|
+
onClick: handleSave,
|
|
7522
|
+
disabled: isSaving,
|
|
7523
|
+
"data-testid": "voice-note-save-button",
|
|
7524
|
+
children: [
|
|
7525
|
+
isSaving ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1.5 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Check, { className: "mr-1.5 h-4 w-4" }),
|
|
7526
|
+
isSaving ? "Saving\u2026" : "Save"
|
|
7527
|
+
]
|
|
7528
|
+
}
|
|
7529
|
+
)
|
|
7530
|
+
] })
|
|
7531
|
+
] })
|
|
7532
|
+
] });
|
|
7533
|
+
}
|
|
7534
|
+
|
|
7535
|
+
// src/documents/has-video-track.ts
|
|
7536
|
+
function hasVideoTrack(blob) {
|
|
7537
|
+
return new Promise((resolve) => {
|
|
7538
|
+
const url = URL.createObjectURL(blob);
|
|
7539
|
+
const video = document.createElement("video");
|
|
7540
|
+
video.preload = "metadata";
|
|
7541
|
+
video.muted = true;
|
|
7542
|
+
const cleanup = () => {
|
|
7543
|
+
video.removeAttribute("src");
|
|
7544
|
+
video.load();
|
|
7545
|
+
URL.revokeObjectURL(url);
|
|
7546
|
+
};
|
|
7547
|
+
video.onloadedmetadata = () => {
|
|
7548
|
+
resolve(video.videoWidth > 0 && video.videoHeight > 0);
|
|
7549
|
+
cleanup();
|
|
7550
|
+
};
|
|
7551
|
+
video.onerror = () => {
|
|
7552
|
+
resolve(false);
|
|
7553
|
+
cleanup();
|
|
7554
|
+
};
|
|
7555
|
+
video.src = url;
|
|
7556
|
+
});
|
|
7557
|
+
}
|
|
7163
7558
|
|
|
7164
|
-
export { ActivityFeed, AgentBadge, AiActionCard, AiAnswer, AppleIcon, ArbiBotHeadIcon, ArbiBotIcon, ArbiChat, ArbiChatPanel, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, AudIcon, BASE_COLORS2 as BASE_COLORS, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DEFAULT_NOTIFY_TONE, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCard, DocumentCardMenu, DocumentEntity, DocumentGallery, DocumentReview, DocumentTable, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, ImgIcon, LinkedInIcon, MessageArtifactCard, MessageBubble2 as MessageBubble, MessageThread, NEUTRAL_GRAY2 as NEUTRAL_GRAY, NotificationBell, OpenAIIcon, PLACEHOLDER_COLOR, PassageCard, PdfIcon, PresenceLabel, ProjectEntity, ProviderIcon, RUN_WINDOW_MS, RagDot, RelevanceDot, SemanticSearch, StatusPill, TAG_TYPE_ICONS, TAG_TYPE_LABELS, TagEntity, Toaster, TxtIcon, TypingIndicator, UserEntity, UserMenu, VISIBILITY_ICONS, VidIcon, VisibilityIcon, XlsIcon, annotateThread, arbiQueryKeys, configureEntityRegistry, configureRagLabels, configureStatusRegistry, cropImage, dayKey, describeActivity, formatRelativeTime, getDocIcon, getEntityColor2 as getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getNotificationTypeMeta, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceActionText, getWorkspaceColor, getWorkspaceSentPhrase, isWorkspaceNotificationType, notify, parseActivityContent, redlineStats, seedNotifications, selectUnread, textToArtifact, toRedlineMarkdown, useActivity, useAgents, useAiTask, useArbiConnected, useArbiDocumentSync, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useNotify, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
|
|
7559
|
+
export { ActivityFeed, AgentBadge, AiActionCard, AiAnswer, AppleIcon, ArbiBotHeadIcon, ArbiBotIcon, ArbiChat, ArbiChatPanel, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, AudIcon, BASE_COLORS2 as BASE_COLORS, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DEFAULT_NOTIFY_TONE, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCard, DocumentCardMenu, DocumentEntity, DocumentGallery, DocumentReview, DocumentTable, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, ImgIcon, LinkedInIcon, MessageArtifactCard, MessageBubble2 as MessageBubble, MessageThread, MicWaveformIndicator, NEUTRAL_GRAY2 as NEUTRAL_GRAY, NotificationBell, OpenAIIcon, PLACEHOLDER_COLOR, PassageCard, PdfIcon, PresenceLabel, ProjectEntity, ProviderIcon, RUN_WINDOW_MS, RagDot, RelevanceDot, SemanticSearch, StatusPill, TAG_TYPE_ICONS, TAG_TYPE_LABELS, TagEntity, Toaster, TxtIcon, TypingIndicator, UserEntity, UserMenu, VISIBILITY_ICONS, VidIcon, VisibilityIcon, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, configureEntityRegistry, configureRagLabels, configureStatusRegistry, cropImage, dayKey, describeActivity, formatElapsed, formatRelativeTime, getDocIcon, getEntityColor2 as getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getNotificationTypeMeta, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceActionText, getWorkspaceColor, getWorkspaceSentPhrase, hasVideoTrack, isWorkspaceNotificationType, notify, parseActivityContent, redlineStats, seedNotifications, selectUnread, textToArtifact, toRedlineMarkdown, useActivity, useAgents, useAiTask, useArbiConnected, useArbiDocumentSync, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useAudioRecorder, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useNotify, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
|
|
7165
7560
|
//# sourceMappingURL=index.js.map
|
|
7166
7561
|
//# sourceMappingURL=index.js.map
|