@arbidocs/react 0.3.174 → 0.3.176
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-7IOCMCC5.cjs +99 -0
- package/dist/chunk-7IOCMCC5.cjs.map +1 -0
- package/dist/{chunk-ZYHVJM4V.cjs → chunk-FIPS3VPH.cjs} +15 -9
- package/dist/chunk-FIPS3VPH.cjs.map +1 -0
- package/dist/{chunk-QZAXTBVW.js → chunk-I256BUCX.js} +15 -10
- package/dist/chunk-I256BUCX.js.map +1 -0
- package/dist/chunk-JKO3NR5L.js +93 -0
- package/dist/chunk-JKO3NR5L.js.map +1 -0
- package/dist/index.cjs +686 -331
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -1
- package/dist/index.d.ts +135 -1
- package/dist/index.js +357 -7
- package/dist/index.js.map +1 -1
- package/dist/ui/index.cjs +109 -109
- package/dist/ui/index.js +1 -1
- package/dist/viewers/index.cjs +14 -58
- package/dist/viewers/index.cjs.map +1 -1
- package/dist/viewers/index.js +3 -53
- package/dist/viewers/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-Q6XAXIT3.js +0 -43
- package/dist/chunk-Q6XAXIT3.js.map +0 -1
- package/dist/chunk-QZAXTBVW.js.map +0 -1
- package/dist/chunk-RWCMW36I.cjs +0 -47
- package/dist/chunk-RWCMW36I.cjs.map +0 -1
- package/dist/chunk-ZYHVJM4V.cjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
1
|
+
import { cn, Avatar, AvatarFallback, AvatarImage, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverContent, AiMarkdown, Card, Button, Badge, MarkdownRenderer, Input, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, ScrollArea, Textarea, Slider, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DropdownMenuLabel, DropdownMenuSeparator, Checkbox, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed } from './chunk-I256BUCX.js';
|
|
2
|
+
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, DictateProvider, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, HoverCard, HoverCardContent, HoverCardTrigger, IconToggle, InlineMicButton, Input, Label, MarkdownRenderer, MarkdownStreamingContext, MicRecordingOverlay, MicWaveformIndicator, 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, formatElapsed, markdownBaseComponents, splitMarkdownBlocks, toggleVariants, useAudioRecorder } from './chunk-I256BUCX.js';
|
|
3
|
+
import { useArbi, ArbiProvider, AudioViewer, ImageViewer, VideoViewer } from './chunk-JKO3NR5L.js';
|
|
4
|
+
export { ArbiProvider, useArbi } from './chunk-JKO3NR5L.js';
|
|
5
5
|
import React2, { memo, useState, createContext, forwardRef, useMemo, useCallback, useId, useRef, useContext, useEffect, Fragment as Fragment$1 } from 'react';
|
|
6
6
|
import { useQuery, useMutation, useQueries, QueryClient, QueryClientProvider, useQueryClient } from '@tanstack/react-query';
|
|
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, Mic, Pause, Play, Square, RotateCcw, 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, Camera, Circle, 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';
|
|
@@ -5394,6 +5394,15 @@ function NotificationBell({
|
|
|
5394
5394
|
"data-testid": `${testId}-mute`,
|
|
5395
5395
|
children: /* @__PURE__ */ jsx(BellOff, { className: "size-3.5" })
|
|
5396
5396
|
}
|
|
5397
|
+
),
|
|
5398
|
+
/* @__PURE__ */ jsx(
|
|
5399
|
+
DropdownMenuItem,
|
|
5400
|
+
{
|
|
5401
|
+
className: "flex size-6 items-center justify-center rounded-md p-0 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus:bg-accent",
|
|
5402
|
+
"aria-label": "Close notifications",
|
|
5403
|
+
"data-testid": `${testId}-close`,
|
|
5404
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
|
|
5405
|
+
}
|
|
5397
5406
|
)
|
|
5398
5407
|
] })
|
|
5399
5408
|
] }),
|
|
@@ -6469,8 +6478,18 @@ function UserMenu({
|
|
|
6469
6478
|
sideOffset: 8,
|
|
6470
6479
|
collisionPadding: 12,
|
|
6471
6480
|
className: "w-56 rounded-lg border-border/60 shadow-lg",
|
|
6481
|
+
"data-testid": "user-menu-panel",
|
|
6472
6482
|
children: [
|
|
6473
|
-
/* @__PURE__ */ jsxs(DropdownMenuLabel, { children: [
|
|
6483
|
+
/* @__PURE__ */ jsxs(DropdownMenuLabel, { className: "relative pr-8", children: [
|
|
6484
|
+
/* @__PURE__ */ jsx(
|
|
6485
|
+
DropdownMenuItem,
|
|
6486
|
+
{
|
|
6487
|
+
className: "absolute right-1 top-1 flex size-6 items-center justify-center rounded-md p-0 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus:bg-accent",
|
|
6488
|
+
"aria-label": "Close account menu",
|
|
6489
|
+
"data-testid": "user-menu-close",
|
|
6490
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
|
|
6491
|
+
}
|
|
6492
|
+
),
|
|
6474
6493
|
/* @__PURE__ */ jsx("div", { className: "font-medium text-foreground", children: user.name }),
|
|
6475
6494
|
user.email && /* @__PURE__ */ jsx("div", { className: "text-xs font-normal text-muted-foreground", children: user.email }),
|
|
6476
6495
|
status && /* @__PURE__ */ jsxs(
|
|
@@ -7349,6 +7368,337 @@ function DraftTitleControls({
|
|
|
7349
7368
|
)
|
|
7350
7369
|
] });
|
|
7351
7370
|
}
|
|
7371
|
+
function useCameraStream(constraints = { video: true, audio: false }) {
|
|
7372
|
+
const [stream, setStream] = useState(null);
|
|
7373
|
+
const [isStarting, setIsStarting] = useState(false);
|
|
7374
|
+
const [error, setError] = useState(null);
|
|
7375
|
+
const streamRef = useRef(null);
|
|
7376
|
+
const stop = useCallback(() => {
|
|
7377
|
+
streamRef.current?.getTracks().forEach((t) => t.stop());
|
|
7378
|
+
streamRef.current = null;
|
|
7379
|
+
setStream(null);
|
|
7380
|
+
}, []);
|
|
7381
|
+
const constraintsRef = useRef(constraints);
|
|
7382
|
+
constraintsRef.current = constraints;
|
|
7383
|
+
const start = useCallback(async () => {
|
|
7384
|
+
if (streamRef.current) return;
|
|
7385
|
+
setError(null);
|
|
7386
|
+
setIsStarting(true);
|
|
7387
|
+
try {
|
|
7388
|
+
const media = await navigator.mediaDevices.getUserMedia(constraintsRef.current);
|
|
7389
|
+
streamRef.current = media;
|
|
7390
|
+
setStream(media);
|
|
7391
|
+
} catch (err) {
|
|
7392
|
+
setError(classifyMediaError(err, "camera"));
|
|
7393
|
+
} finally {
|
|
7394
|
+
setIsStarting(false);
|
|
7395
|
+
}
|
|
7396
|
+
}, []);
|
|
7397
|
+
useEffect(() => () => stop(), [stop]);
|
|
7398
|
+
return { stream, isStarting, error, start, stop };
|
|
7399
|
+
}
|
|
7400
|
+
var ELAPSED_TICK_MS = 200;
|
|
7401
|
+
function useVideoRecorder(stream) {
|
|
7402
|
+
const [state, setState] = useState("idle");
|
|
7403
|
+
const [elapsedMs, setElapsedMs] = useState(0);
|
|
7404
|
+
const [blob, setBlob] = useState(null);
|
|
7405
|
+
const [mimeType, setMimeType] = useState(null);
|
|
7406
|
+
const mediaRecorderRef = useRef(null);
|
|
7407
|
+
const chunksRef = useRef([]);
|
|
7408
|
+
const startedAtRef = useRef(0);
|
|
7409
|
+
const tickRef = useRef(null);
|
|
7410
|
+
const stateRef = useRef("idle");
|
|
7411
|
+
stateRef.current = state;
|
|
7412
|
+
const stopTicking = useCallback(() => {
|
|
7413
|
+
if (tickRef.current !== null) clearInterval(tickRef.current);
|
|
7414
|
+
tickRef.current = null;
|
|
7415
|
+
}, []);
|
|
7416
|
+
useEffect(() => stopTicking, [stopTicking]);
|
|
7417
|
+
const start = useCallback(() => {
|
|
7418
|
+
if (!stream || stateRef.current === "recording") return;
|
|
7419
|
+
const mt = MediaRecorder.isTypeSupported("video/webm") ? "video/webm" : "video/mp4";
|
|
7420
|
+
const recorder = new MediaRecorder(stream, { mimeType: mt });
|
|
7421
|
+
chunksRef.current = [];
|
|
7422
|
+
recorder.ondataavailable = (e) => {
|
|
7423
|
+
if (e.data.size > 0) chunksRef.current.push(e.data);
|
|
7424
|
+
};
|
|
7425
|
+
mediaRecorderRef.current = recorder;
|
|
7426
|
+
setMimeType(mt);
|
|
7427
|
+
setBlob(null);
|
|
7428
|
+
startedAtRef.current = performance.now();
|
|
7429
|
+
setElapsedMs(0);
|
|
7430
|
+
recorder.start();
|
|
7431
|
+
setState("recording");
|
|
7432
|
+
tickRef.current = setInterval(() => {
|
|
7433
|
+
setElapsedMs(performance.now() - startedAtRef.current);
|
|
7434
|
+
}, ELAPSED_TICK_MS);
|
|
7435
|
+
}, [stream]);
|
|
7436
|
+
const stop = useCallback(() => {
|
|
7437
|
+
const recorder = mediaRecorderRef.current;
|
|
7438
|
+
if (!recorder || recorder.state === "inactive") return;
|
|
7439
|
+
const finalElapsed = performance.now() - startedAtRef.current;
|
|
7440
|
+
stopTicking();
|
|
7441
|
+
recorder.onstop = () => {
|
|
7442
|
+
const finalBlob = chunksRef.current.length ? new Blob(chunksRef.current, { type: recorder.mimeType }) : null;
|
|
7443
|
+
setBlob(finalBlob);
|
|
7444
|
+
setElapsedMs(finalElapsed);
|
|
7445
|
+
setState("stopped");
|
|
7446
|
+
};
|
|
7447
|
+
recorder.stop();
|
|
7448
|
+
}, [stopTicking]);
|
|
7449
|
+
const reset = useCallback(() => {
|
|
7450
|
+
setState("idle");
|
|
7451
|
+
setBlob(null);
|
|
7452
|
+
setElapsedMs(0);
|
|
7453
|
+
setMimeType(null);
|
|
7454
|
+
}, []);
|
|
7455
|
+
return { state, elapsedMs, blob, mimeType, start, stop, reset };
|
|
7456
|
+
}
|
|
7457
|
+
|
|
7458
|
+
// src/documents/capture-frame.ts
|
|
7459
|
+
function captureFrameAsBlob(video, mimeType = "image/png") {
|
|
7460
|
+
return new Promise((resolve, reject) => {
|
|
7461
|
+
const canvas = document.createElement("canvas");
|
|
7462
|
+
canvas.width = video.videoWidth;
|
|
7463
|
+
canvas.height = video.videoHeight;
|
|
7464
|
+
const ctx = canvas.getContext("2d");
|
|
7465
|
+
if (!ctx) {
|
|
7466
|
+
reject(new Error("Canvas 2D context is not available"));
|
|
7467
|
+
return;
|
|
7468
|
+
}
|
|
7469
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
7470
|
+
canvas.toBlob((blob) => {
|
|
7471
|
+
if (blob) resolve(blob);
|
|
7472
|
+
else reject(new Error("Failed to capture the photo"));
|
|
7473
|
+
}, mimeType);
|
|
7474
|
+
});
|
|
7475
|
+
}
|
|
7476
|
+
function PhotoCapture({ onSave, onDiscard, onError, isSaving = false }) {
|
|
7477
|
+
const camera = useCameraStream({ video: true, audio: false });
|
|
7478
|
+
const videoRef = useRef(null);
|
|
7479
|
+
const [capturedBlob, setCapturedBlob] = useState(null);
|
|
7480
|
+
const [captureError, setCaptureError] = useState(null);
|
|
7481
|
+
useEffect(() => {
|
|
7482
|
+
void camera.start();
|
|
7483
|
+
}, []);
|
|
7484
|
+
useEffect(() => {
|
|
7485
|
+
if (camera.error) onError?.(camera.error);
|
|
7486
|
+
}, [camera.error]);
|
|
7487
|
+
useEffect(() => {
|
|
7488
|
+
const video = videoRef.current;
|
|
7489
|
+
if (!video) return;
|
|
7490
|
+
video.srcObject = camera.stream;
|
|
7491
|
+
if (camera.stream) void video.play().catch(() => {
|
|
7492
|
+
});
|
|
7493
|
+
}, [camera.stream]);
|
|
7494
|
+
const handleShutter = () => {
|
|
7495
|
+
const video = videoRef.current;
|
|
7496
|
+
if (!video) return;
|
|
7497
|
+
setCaptureError(null);
|
|
7498
|
+
captureFrameAsBlob(video).then(setCapturedBlob).catch((err) => {
|
|
7499
|
+
const message = err instanceof Error ? err.message : "Failed to capture the photo";
|
|
7500
|
+
setCaptureError(message);
|
|
7501
|
+
onError?.(message);
|
|
7502
|
+
});
|
|
7503
|
+
};
|
|
7504
|
+
const handleRetake = () => setCapturedBlob(null);
|
|
7505
|
+
const handleSave = () => {
|
|
7506
|
+
if (!capturedBlob) return;
|
|
7507
|
+
void onSave(capturedBlob, "image/png");
|
|
7508
|
+
};
|
|
7509
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-6 p-8", children: [
|
|
7510
|
+
!capturedBlob && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7511
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md overflow-hidden rounded-lg bg-muted/30", children: /* @__PURE__ */ jsx(
|
|
7512
|
+
"video",
|
|
7513
|
+
{
|
|
7514
|
+
ref: videoRef,
|
|
7515
|
+
autoPlay: true,
|
|
7516
|
+
muted: true,
|
|
7517
|
+
playsInline: true,
|
|
7518
|
+
className: "w-full max-h-[60vh] object-contain",
|
|
7519
|
+
"data-testid": "photo-capture-preview"
|
|
7520
|
+
}
|
|
7521
|
+
) }),
|
|
7522
|
+
/* @__PURE__ */ jsx(
|
|
7523
|
+
Button,
|
|
7524
|
+
{
|
|
7525
|
+
type: "button",
|
|
7526
|
+
size: "lg",
|
|
7527
|
+
className: "h-16 w-16 rounded-full p-0",
|
|
7528
|
+
onClick: handleShutter,
|
|
7529
|
+
disabled: !camera.stream,
|
|
7530
|
+
"data-testid": "photo-capture-shutter-button",
|
|
7531
|
+
children: /* @__PURE__ */ jsx(Camera, { className: "h-6 w-6" })
|
|
7532
|
+
}
|
|
7533
|
+
),
|
|
7534
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: camera.isStarting ? "Starting camera\u2026" : camera.stream ? "Press to take a photo" : "Waiting for camera access\u2026" }),
|
|
7535
|
+
captureError && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-text", children: captureError })
|
|
7536
|
+
] }),
|
|
7537
|
+
capturedBlob && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7538
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsx(ImageViewer, { blob: capturedBlob, alt: "Captured photo" }) }),
|
|
7539
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7540
|
+
/* @__PURE__ */ jsxs(
|
|
7541
|
+
Button,
|
|
7542
|
+
{
|
|
7543
|
+
type: "button",
|
|
7544
|
+
variant: "outline",
|
|
7545
|
+
onClick: onDiscard,
|
|
7546
|
+
disabled: isSaving,
|
|
7547
|
+
"data-testid": "photo-capture-discard-button",
|
|
7548
|
+
children: [
|
|
7549
|
+
/* @__PURE__ */ jsx(Trash2, { className: "mr-1.5 h-4 w-4" }),
|
|
7550
|
+
"Discard"
|
|
7551
|
+
]
|
|
7552
|
+
}
|
|
7553
|
+
),
|
|
7554
|
+
/* @__PURE__ */ jsxs(
|
|
7555
|
+
Button,
|
|
7556
|
+
{
|
|
7557
|
+
type: "button",
|
|
7558
|
+
variant: "outline",
|
|
7559
|
+
onClick: handleRetake,
|
|
7560
|
+
disabled: isSaving,
|
|
7561
|
+
"data-testid": "photo-capture-retake-button",
|
|
7562
|
+
children: [
|
|
7563
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "mr-1.5 h-4 w-4" }),
|
|
7564
|
+
"Retake"
|
|
7565
|
+
]
|
|
7566
|
+
}
|
|
7567
|
+
),
|
|
7568
|
+
/* @__PURE__ */ jsxs(
|
|
7569
|
+
Button,
|
|
7570
|
+
{
|
|
7571
|
+
type: "button",
|
|
7572
|
+
onClick: handleSave,
|
|
7573
|
+
disabled: isSaving,
|
|
7574
|
+
"data-testid": "photo-capture-save-button",
|
|
7575
|
+
children: [
|
|
7576
|
+
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" }),
|
|
7577
|
+
isSaving ? "Saving\u2026" : "Save"
|
|
7578
|
+
]
|
|
7579
|
+
}
|
|
7580
|
+
)
|
|
7581
|
+
] })
|
|
7582
|
+
] })
|
|
7583
|
+
] });
|
|
7584
|
+
}
|
|
7585
|
+
function VideoCapture({ onSave, onDiscard, onError, isSaving = false }) {
|
|
7586
|
+
const camera = useCameraStream({ video: true, audio: true });
|
|
7587
|
+
const recorder = useVideoRecorder(camera.stream);
|
|
7588
|
+
const videoRef = useRef(null);
|
|
7589
|
+
useEffect(() => {
|
|
7590
|
+
void camera.start();
|
|
7591
|
+
}, []);
|
|
7592
|
+
useEffect(() => {
|
|
7593
|
+
if (camera.error) onError?.(camera.error);
|
|
7594
|
+
}, [camera.error]);
|
|
7595
|
+
useEffect(() => {
|
|
7596
|
+
const video = videoRef.current;
|
|
7597
|
+
if (!video || recorder.state === "stopped") return;
|
|
7598
|
+
video.srcObject = camera.stream;
|
|
7599
|
+
if (camera.stream) void video.play().catch(() => {
|
|
7600
|
+
});
|
|
7601
|
+
}, [camera.stream, recorder.state]);
|
|
7602
|
+
const handleRetake = () => {
|
|
7603
|
+
recorder.reset();
|
|
7604
|
+
};
|
|
7605
|
+
const handleSave = () => {
|
|
7606
|
+
if (!recorder.blob) return;
|
|
7607
|
+
void onSave(recorder.blob, recorder.mimeType);
|
|
7608
|
+
};
|
|
7609
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-6 p-8", children: [
|
|
7610
|
+
recorder.state !== "stopped" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7611
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md overflow-hidden rounded-lg bg-muted/30", children: /* @__PURE__ */ jsx(
|
|
7612
|
+
"video",
|
|
7613
|
+
{
|
|
7614
|
+
ref: videoRef,
|
|
7615
|
+
autoPlay: true,
|
|
7616
|
+
muted: true,
|
|
7617
|
+
playsInline: true,
|
|
7618
|
+
className: "w-full max-h-[60vh] object-contain",
|
|
7619
|
+
"data-testid": "video-capture-preview"
|
|
7620
|
+
}
|
|
7621
|
+
) }),
|
|
7622
|
+
recorder.state === "recording" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", "data-testid": "video-capture-rec-indicator", children: [
|
|
7623
|
+
/* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2", children: [
|
|
7624
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75" }),
|
|
7625
|
+
/* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-red-500" })
|
|
7626
|
+
] }),
|
|
7627
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wide text-red-500", children: "Rec" }),
|
|
7628
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-xs tabular-nums text-muted-foreground", children: formatElapsed(recorder.elapsedMs) })
|
|
7629
|
+
] }),
|
|
7630
|
+
recorder.state === "recording" ? /* @__PURE__ */ jsx(
|
|
7631
|
+
Button,
|
|
7632
|
+
{
|
|
7633
|
+
type: "button",
|
|
7634
|
+
size: "lg",
|
|
7635
|
+
className: "h-16 w-16 rounded-full p-0",
|
|
7636
|
+
onClick: recorder.stop,
|
|
7637
|
+
"data-testid": "video-capture-stop-button",
|
|
7638
|
+
children: /* @__PURE__ */ jsx(Square, { className: "h-5 w-5 fill-current" })
|
|
7639
|
+
}
|
|
7640
|
+
) : /* @__PURE__ */ jsx(
|
|
7641
|
+
Button,
|
|
7642
|
+
{
|
|
7643
|
+
type: "button",
|
|
7644
|
+
size: "lg",
|
|
7645
|
+
className: "h-16 w-16 rounded-full p-0",
|
|
7646
|
+
onClick: recorder.start,
|
|
7647
|
+
disabled: !camera.stream,
|
|
7648
|
+
"data-testid": "video-capture-record-button",
|
|
7649
|
+
children: /* @__PURE__ */ jsx(Circle, { className: "h-6 w-6 fill-current" })
|
|
7650
|
+
}
|
|
7651
|
+
),
|
|
7652
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: recorder.state === "recording" ? "Tap to stop recording" : camera.isStarting ? "Starting camera\u2026" : camera.stream ? "Tap to start recording" : "Waiting for camera access\u2026" })
|
|
7653
|
+
] }),
|
|
7654
|
+
recorder.state === "stopped" && recorder.blob && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7655
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsx(VideoViewer, { blob: recorder.blob, title: "Captured video" }) }),
|
|
7656
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7657
|
+
/* @__PURE__ */ jsxs(
|
|
7658
|
+
Button,
|
|
7659
|
+
{
|
|
7660
|
+
type: "button",
|
|
7661
|
+
variant: "outline",
|
|
7662
|
+
onClick: onDiscard,
|
|
7663
|
+
disabled: isSaving,
|
|
7664
|
+
"data-testid": "video-capture-discard-button",
|
|
7665
|
+
children: [
|
|
7666
|
+
/* @__PURE__ */ jsx(Trash2, { className: "mr-1.5 h-4 w-4" }),
|
|
7667
|
+
"Discard"
|
|
7668
|
+
]
|
|
7669
|
+
}
|
|
7670
|
+
),
|
|
7671
|
+
/* @__PURE__ */ jsxs(
|
|
7672
|
+
Button,
|
|
7673
|
+
{
|
|
7674
|
+
type: "button",
|
|
7675
|
+
variant: "outline",
|
|
7676
|
+
onClick: handleRetake,
|
|
7677
|
+
disabled: isSaving,
|
|
7678
|
+
"data-testid": "video-capture-retake-button",
|
|
7679
|
+
children: [
|
|
7680
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "mr-1.5 h-4 w-4" }),
|
|
7681
|
+
"Record again"
|
|
7682
|
+
]
|
|
7683
|
+
}
|
|
7684
|
+
),
|
|
7685
|
+
/* @__PURE__ */ jsxs(
|
|
7686
|
+
Button,
|
|
7687
|
+
{
|
|
7688
|
+
type: "button",
|
|
7689
|
+
onClick: handleSave,
|
|
7690
|
+
disabled: isSaving,
|
|
7691
|
+
"data-testid": "video-capture-save-button",
|
|
7692
|
+
children: [
|
|
7693
|
+
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" }),
|
|
7694
|
+
isSaving ? "Saving\u2026" : "Save"
|
|
7695
|
+
]
|
|
7696
|
+
}
|
|
7697
|
+
)
|
|
7698
|
+
] })
|
|
7699
|
+
] })
|
|
7700
|
+
] });
|
|
7701
|
+
}
|
|
7352
7702
|
|
|
7353
7703
|
// src/documents/has-video-track.ts
|
|
7354
7704
|
function hasVideoTrack(blob) {
|
|
@@ -7374,6 +7724,6 @@ function hasVideoTrack(blob) {
|
|
|
7374
7724
|
});
|
|
7375
7725
|
}
|
|
7376
7726
|
|
|
7377
|
-
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, DraftTitleControls, 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, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, configureEntityRegistry, configureRagLabels, configureStatusRegistry, cropImage, dayKey, describeActivity, 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, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useNotify, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
|
|
7727
|
+
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, DraftTitleControls, 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, PhotoCapture, 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, VideoCapture, VisibilityIcon, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, configureEntityRegistry, configureRagLabels, configureStatusRegistry, cropImage, dayKey, describeActivity, 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, useCameraStream, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useNotify, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
|
|
7378
7728
|
//# sourceMappingURL=index.js.map
|
|
7379
7729
|
//# sourceMappingURL=index.js.map
|