@skippr/live-agent-sdk 0.91.0 → 0.92.0
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/esm/lib-exports.js
CHANGED
|
@@ -8,7 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
8
8
|
|
|
9
9
|
// src/components/LiveAgent.tsx
|
|
10
10
|
import { LiveKitRoom, RoomAudioRenderer } from "@livekit/components-react";
|
|
11
|
-
import { useCallback as
|
|
11
|
+
import { useCallback as useCallback32, useEffect as useEffect49, useMemo as useMemo7, useRef as useRef42, useState as useState39 } from "react";
|
|
12
12
|
// ../../node_modules/.bun/lucide-react@1.8.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/createLucideIcon.js
|
|
13
13
|
import { forwardRef as forwardRef2, createElement as createElement3 } from "react";
|
|
14
14
|
|
|
@@ -5526,6 +5526,39 @@ function DomCapture({ pushOrTapMicMode = false }) {
|
|
|
5526
5526
|
// src/components/HighlightOverlay.tsx
|
|
5527
5527
|
import { useDataChannel } from "@livekit/components-react/hooks";
|
|
5528
5528
|
import { useCallback as useCallback15, useEffect as useEffect22, useRef as useRef17 } from "react";
|
|
5529
|
+
|
|
5530
|
+
// src/capture/highlightSignal.ts
|
|
5531
|
+
var highlightActive = false;
|
|
5532
|
+
var activeSubscribers = new Set;
|
|
5533
|
+
function setHighlightActive(active) {
|
|
5534
|
+
if (highlightActive === active)
|
|
5535
|
+
return;
|
|
5536
|
+
highlightActive = active;
|
|
5537
|
+
for (const subscriber of activeSubscribers)
|
|
5538
|
+
subscriber(active);
|
|
5539
|
+
}
|
|
5540
|
+
function isHighlightActive() {
|
|
5541
|
+
return highlightActive;
|
|
5542
|
+
}
|
|
5543
|
+
function subscribeHighlightActive(subscriber) {
|
|
5544
|
+
activeSubscribers.add(subscriber);
|
|
5545
|
+
return () => {
|
|
5546
|
+
activeSubscribers.delete(subscriber);
|
|
5547
|
+
};
|
|
5548
|
+
}
|
|
5549
|
+
var clearSubscribers = new Set;
|
|
5550
|
+
function clearHighlight() {
|
|
5551
|
+
for (const subscriber of clearSubscribers)
|
|
5552
|
+
subscriber();
|
|
5553
|
+
}
|
|
5554
|
+
function onHighlightCleared(subscriber) {
|
|
5555
|
+
clearSubscribers.add(subscriber);
|
|
5556
|
+
return () => {
|
|
5557
|
+
clearSubscribers.delete(subscriber);
|
|
5558
|
+
};
|
|
5559
|
+
}
|
|
5560
|
+
|
|
5561
|
+
// src/components/HighlightOverlay.tsx
|
|
5529
5562
|
var HIGHLIGHT_AUTO_CLEAR_MS = 25000;
|
|
5530
5563
|
var textDecoder = new TextDecoder;
|
|
5531
5564
|
function parseHighlightMessage(payload) {
|
|
@@ -5556,6 +5589,7 @@ function HighlightOverlay() {
|
|
|
5556
5589
|
autoClearRef.current = null;
|
|
5557
5590
|
targetRef.current = null;
|
|
5558
5591
|
clearCursorTarget("guide");
|
|
5592
|
+
setHighlightActive(false);
|
|
5559
5593
|
}, []);
|
|
5560
5594
|
const onHighlightMessage = useCallback15((msg) => {
|
|
5561
5595
|
const parsed = parseHighlightMessage(msg.payload);
|
|
@@ -5578,9 +5612,11 @@ function HighlightOverlay() {
|
|
|
5578
5612
|
label: parsed.message || "Click here",
|
|
5579
5613
|
mode: "guide"
|
|
5580
5614
|
});
|
|
5615
|
+
setHighlightActive(true);
|
|
5581
5616
|
autoClearRef.current = setTimeout(clear, HIGHLIGHT_AUTO_CLEAR_MS);
|
|
5582
5617
|
}, [clear]);
|
|
5583
5618
|
useDataChannel(HIGHLIGHT_TOPIC, onHighlightMessage);
|
|
5619
|
+
useEffect22(() => onHighlightCleared(clear), [clear]);
|
|
5584
5620
|
useEffect22(() => {
|
|
5585
5621
|
const onClick = (event) => {
|
|
5586
5622
|
const target = targetRef.current;
|
|
@@ -8876,7 +8912,7 @@ function SidebarTrigger() {
|
|
|
8876
8912
|
}
|
|
8877
8913
|
|
|
8878
8914
|
// src/components/VoiceBar.tsx
|
|
8879
|
-
import { useCallback as
|
|
8915
|
+
import { useCallback as useCallback31, useContext as useContext22, useState as useState38 } from "react";
|
|
8880
8916
|
|
|
8881
8917
|
// src/hooks/useBarNotifications.ts
|
|
8882
8918
|
import { useContext as useContext19 } from "react";
|
|
@@ -8948,15 +8984,37 @@ function useBarNotifications() {
|
|
|
8948
8984
|
}
|
|
8949
8985
|
|
|
8950
8986
|
// src/components/VoiceBarFrame.tsx
|
|
8951
|
-
import { useIsSpeaking, useLocalParticipant as
|
|
8952
|
-
import { useCallback as
|
|
8987
|
+
import { useIsSpeaking, useLocalParticipant as useLocalParticipant13 } from "@livekit/components-react/hooks";
|
|
8988
|
+
import { useCallback as useCallback29, useContext as useContext21, useEffect as useEffect46, useRef as useRef39, useState as useState35 } from "react";
|
|
8989
|
+
|
|
8990
|
+
// src/hooks/useHighlightControl.ts
|
|
8991
|
+
import { useLocalParticipant as useLocalParticipant12 } from "@livekit/components-react/hooks";
|
|
8992
|
+
import { useCallback as useCallback26, useEffect as useEffect37, useState as useState28 } from "react";
|
|
8993
|
+
var textEncoder7 = new TextEncoder;
|
|
8994
|
+
function useHighlightControl() {
|
|
8995
|
+
const { localParticipant } = useLocalParticipant12();
|
|
8996
|
+
const [active, setActive] = useState28(isHighlightActive);
|
|
8997
|
+
useEffect37(() => subscribeHighlightActive(setActive), []);
|
|
8998
|
+
const requestClear = useCallback26(async () => {
|
|
8999
|
+
clearHighlight();
|
|
9000
|
+
try {
|
|
9001
|
+
await localParticipant.publishData(textEncoder7.encode(JSON.stringify({ type: "dismiss" })), {
|
|
9002
|
+
reliable: true,
|
|
9003
|
+
topic: HIGHLIGHT_TOPIC
|
|
9004
|
+
});
|
|
9005
|
+
} catch (error) {
|
|
9006
|
+
console.error("Failed to send highlight dismiss:", error);
|
|
9007
|
+
}
|
|
9008
|
+
}, [localParticipant]);
|
|
9009
|
+
return { highlightActive: active, clearHighlight: requestClear };
|
|
9010
|
+
}
|
|
8953
9011
|
|
|
8954
9012
|
// src/hooks/useKeyboardStop.ts
|
|
8955
|
-
import { useEffect as
|
|
9013
|
+
import { useEffect as useEffect38, useRef as useRef33 } from "react";
|
|
8956
9014
|
function useKeyboardStop({ enabled, onStop }) {
|
|
8957
9015
|
const handler = useRef33(onStop);
|
|
8958
9016
|
handler.current = onStop;
|
|
8959
|
-
|
|
9017
|
+
useEffect38(() => {
|
|
8960
9018
|
if (!enabled)
|
|
8961
9019
|
return;
|
|
8962
9020
|
const onKeyDown = (event) => {
|
|
@@ -8973,18 +9031,18 @@ function useKeyboardStop({ enabled, onStop }) {
|
|
|
8973
9031
|
}
|
|
8974
9032
|
|
|
8975
9033
|
// src/hooks/useSessionTimer.ts
|
|
8976
|
-
import { useEffect as
|
|
9034
|
+
import { useEffect as useEffect40, useState as useState30 } from "react";
|
|
8977
9035
|
|
|
8978
9036
|
// src/hooks/useElapsedSeconds.ts
|
|
8979
|
-
import { useEffect as
|
|
9037
|
+
import { useEffect as useEffect39, useRef as useRef34, useState as useState29 } from "react";
|
|
8980
9038
|
function useElapsedSeconds(isRunning, resetSignal) {
|
|
8981
|
-
const [elapsed, setElapsed] =
|
|
9039
|
+
const [elapsed, setElapsed] = useState29(0);
|
|
8982
9040
|
const accumulatedSecondsRef = useRef34(0);
|
|
8983
|
-
|
|
9041
|
+
useEffect39(() => {
|
|
8984
9042
|
accumulatedSecondsRef.current = 0;
|
|
8985
9043
|
setElapsed(0);
|
|
8986
9044
|
}, [resetSignal]);
|
|
8987
|
-
|
|
9045
|
+
useEffect39(() => {
|
|
8988
9046
|
if (!isRunning)
|
|
8989
9047
|
return;
|
|
8990
9048
|
const resumedAt = Date.now();
|
|
@@ -9009,8 +9067,8 @@ function useSessionTimer(isRunning, resetSignal) {
|
|
|
9009
9067
|
const active = isRunning && remaining !== null;
|
|
9010
9068
|
const warning = active && remaining !== null && remaining <= SESSION_TIMER_WARNING_S;
|
|
9011
9069
|
const revealCycle = !active ? null : warning ? "warning" : "normal";
|
|
9012
|
-
const [revealed, setRevealed] =
|
|
9013
|
-
|
|
9070
|
+
const [revealed, setRevealed] = useState30(false);
|
|
9071
|
+
useEffect40(() => {
|
|
9014
9072
|
if (!revealCycle) {
|
|
9015
9073
|
setRevealed(false);
|
|
9016
9074
|
return;
|
|
@@ -9038,7 +9096,7 @@ function useSessionTimer(isRunning, resetSignal) {
|
|
|
9038
9096
|
}
|
|
9039
9097
|
|
|
9040
9098
|
// src/hooks/useVoiceBarDrag.ts
|
|
9041
|
-
import { useEffect as
|
|
9099
|
+
import { useEffect as useEffect41, useRef as useRef35 } from "react";
|
|
9042
9100
|
import { flushSync as flushSync2 } from "react-dom";
|
|
9043
9101
|
var DRAG_THRESHOLD_PX2 = 5;
|
|
9044
9102
|
function useVoiceBarDrag(containerRef, onDrop, followRefs, reportDragging) {
|
|
@@ -9049,7 +9107,7 @@ function useVoiceBarDrag(containerRef, onDrop, followRefs, reportDragging) {
|
|
|
9049
9107
|
followTargetsRef.current = followRefs;
|
|
9050
9108
|
const reportDraggingRef = useRef35(reportDragging);
|
|
9051
9109
|
reportDraggingRef.current = reportDragging;
|
|
9052
|
-
|
|
9110
|
+
useEffect41(() => {
|
|
9053
9111
|
const el = containerRef.current;
|
|
9054
9112
|
if (!el)
|
|
9055
9113
|
return;
|
|
@@ -9201,7 +9259,7 @@ function useVoiceBarDrag(containerRef, onDrop, followRefs, reportDragging) {
|
|
|
9201
9259
|
}
|
|
9202
9260
|
|
|
9203
9261
|
// src/components/VoiceBarChatLine.tsx
|
|
9204
|
-
import { useCallback as
|
|
9262
|
+
import { useCallback as useCallback27, useContext as useContext20, useEffect as useEffect42, useRef as useRef36, useState as useState31 } from "react";
|
|
9205
9263
|
import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
9206
9264
|
var IDLE_HIDE_MS = 6000;
|
|
9207
9265
|
function VoiceBarChatLine({
|
|
@@ -9213,19 +9271,19 @@ function VoiceBarChatLine({
|
|
|
9213
9271
|
const { sendChatMessage, isSendingChat } = useChatMessages();
|
|
9214
9272
|
const ctx = useContext20(LiveAgentContext);
|
|
9215
9273
|
const reportChatActivity = ctx?.reportChatActivity;
|
|
9216
|
-
const [localDraft, setLocalDraft] =
|
|
9274
|
+
const [localDraft, setLocalDraft] = useState31("");
|
|
9217
9275
|
const text = ctx?.chatDraft ?? localDraft;
|
|
9218
9276
|
const setText = ctx?.setChatDraft ?? setLocalDraft;
|
|
9219
9277
|
const inputRef = useRef36(null);
|
|
9220
9278
|
const idleTimerRef = useRef36(null);
|
|
9221
9279
|
const onCloseRef = useRef36(onClose);
|
|
9222
9280
|
onCloseRef.current = onClose;
|
|
9223
|
-
const armIdle =
|
|
9281
|
+
const armIdle = useCallback27(() => {
|
|
9224
9282
|
if (idleTimerRef.current)
|
|
9225
9283
|
clearTimeout(idleTimerRef.current);
|
|
9226
9284
|
idleTimerRef.current = setTimeout(() => onCloseRef.current(), IDLE_HIDE_MS);
|
|
9227
9285
|
}, []);
|
|
9228
|
-
|
|
9286
|
+
useEffect42(() => {
|
|
9229
9287
|
inputRef.current?.focus();
|
|
9230
9288
|
armIdle();
|
|
9231
9289
|
return () => {
|
|
@@ -9294,26 +9352,26 @@ function VoiceBarChatLine({
|
|
|
9294
9352
|
}
|
|
9295
9353
|
|
|
9296
9354
|
// src/components/VoiceBarLinkCard.tsx
|
|
9297
|
-
import { useCallback as
|
|
9355
|
+
import { useCallback as useCallback28, useEffect as useEffect43, useRef as useRef37, useState as useState32 } from "react";
|
|
9298
9356
|
import { jsx as jsx39, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
9299
9357
|
var COPIED_RESET_MS2 = 2000;
|
|
9300
9358
|
var DISMISS_AFTER_COPY_MS2 = 3000;
|
|
9301
9359
|
function VoiceBarLinkCard({ card, onDismiss }) {
|
|
9302
|
-
const [copied, setCopied] =
|
|
9360
|
+
const [copied, setCopied] = useState32(false);
|
|
9303
9361
|
const dismissTimerRef = useRef37(null);
|
|
9304
|
-
|
|
9362
|
+
useEffect43(() => {
|
|
9305
9363
|
if (!copied)
|
|
9306
9364
|
return;
|
|
9307
9365
|
const timer = setTimeout(() => setCopied(false), COPIED_RESET_MS2);
|
|
9308
9366
|
return () => clearTimeout(timer);
|
|
9309
9367
|
}, [copied]);
|
|
9310
|
-
|
|
9368
|
+
useEffect43(() => {
|
|
9311
9369
|
return () => {
|
|
9312
9370
|
if (dismissTimerRef.current)
|
|
9313
9371
|
clearTimeout(dismissTimerRef.current);
|
|
9314
9372
|
};
|
|
9315
9373
|
}, []);
|
|
9316
|
-
const handleCopy =
|
|
9374
|
+
const handleCopy = useCallback28(async () => {
|
|
9317
9375
|
const ok = await copyToClipboard(card.url);
|
|
9318
9376
|
if (!ok)
|
|
9319
9377
|
return;
|
|
@@ -9381,17 +9439,17 @@ function VoiceBarLinkCard({ card, onDismiss }) {
|
|
|
9381
9439
|
}
|
|
9382
9440
|
|
|
9383
9441
|
// src/components/VoiceBarNotification.tsx
|
|
9384
|
-
import { useEffect as
|
|
9442
|
+
import { useEffect as useEffect44, useRef as useRef38, useState as useState33 } from "react";
|
|
9385
9443
|
import { jsx as jsx40, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
9386
9444
|
function VoiceBarNotification({
|
|
9387
9445
|
notifications,
|
|
9388
9446
|
dock,
|
|
9389
9447
|
onDismiss
|
|
9390
9448
|
}) {
|
|
9391
|
-
const [index2, setIndex] =
|
|
9392
|
-
const [paused, setPaused] =
|
|
9449
|
+
const [index2, setIndex] = useState33(0);
|
|
9450
|
+
const [paused, setPaused] = useState33(false);
|
|
9393
9451
|
const cardRef = useRef38(null);
|
|
9394
|
-
|
|
9452
|
+
useEffect44(() => {
|
|
9395
9453
|
const el = cardRef.current;
|
|
9396
9454
|
if (!el)
|
|
9397
9455
|
return;
|
|
@@ -9404,7 +9462,7 @@ function VoiceBarNotification({
|
|
|
9404
9462
|
el.removeEventListener("mouseleave", leave);
|
|
9405
9463
|
};
|
|
9406
9464
|
}, []);
|
|
9407
|
-
|
|
9465
|
+
useEffect44(() => {
|
|
9408
9466
|
if (paused)
|
|
9409
9467
|
return;
|
|
9410
9468
|
const rotate = setInterval(() => setIndex((current) => (current + 1) % notifications.length), TIP_ROTATE_MS);
|
|
@@ -9483,7 +9541,7 @@ function VoiceBarNotification({
|
|
|
9483
9541
|
}
|
|
9484
9542
|
|
|
9485
9543
|
// src/components/VoiceBarPlanCard.tsx
|
|
9486
|
-
import { useEffect as
|
|
9544
|
+
import { useEffect as useEffect45, useState as useState34 } from "react";
|
|
9487
9545
|
import { jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
9488
9546
|
var APPROVING_RESET_MS2 = 8000;
|
|
9489
9547
|
function StepIndicator({ step }) {
|
|
@@ -9518,8 +9576,8 @@ function VoiceBarPlanCard({
|
|
|
9518
9576
|
embedded = false
|
|
9519
9577
|
}) {
|
|
9520
9578
|
const awaitingApproval = plan.state === "proposed";
|
|
9521
|
-
const [isApproving, setIsApproving] =
|
|
9522
|
-
const [lastPlanId, setLastPlanId] =
|
|
9579
|
+
const [isApproving, setIsApproving] = useState34(false);
|
|
9580
|
+
const [lastPlanId, setLastPlanId] = useState34(plan.planId);
|
|
9523
9581
|
if (plan.planId !== lastPlanId) {
|
|
9524
9582
|
setLastPlanId(plan.planId);
|
|
9525
9583
|
setIsApproving(false);
|
|
@@ -9534,13 +9592,13 @@ function VoiceBarPlanCard({
|
|
|
9534
9592
|
const cancel = () => {
|
|
9535
9593
|
sendChatMessage(CANCEL_MESSAGE).catch((e) => console.warn("[Skippr] plan reply failed", e));
|
|
9536
9594
|
};
|
|
9537
|
-
|
|
9595
|
+
useEffect45(() => {
|
|
9538
9596
|
if (!isApproving)
|
|
9539
9597
|
return;
|
|
9540
9598
|
const timer = setTimeout(() => setIsApproving(false), APPROVING_RESET_MS2);
|
|
9541
9599
|
return () => clearTimeout(timer);
|
|
9542
9600
|
}, [isApproving]);
|
|
9543
|
-
|
|
9601
|
+
useEffect45(() => {
|
|
9544
9602
|
if (plan.state !== "completed")
|
|
9545
9603
|
return;
|
|
9546
9604
|
const timer = setTimeout(onDismiss, COMPLETED_CARD_VISIBLE_MS);
|
|
@@ -9678,6 +9736,24 @@ function BusyRing({ tone }) {
|
|
|
9678
9736
|
className: cn("skippr:pointer-events-none skippr:absolute skippr:-inset-[3px] skippr:rounded-full skippr:border-2 skippr:animate-spin", tone === "white" ? "skippr:border-white/30 skippr:border-t-white" : "skippr:border-[var(--skippr-brand-ring)] skippr:border-t-brand")
|
|
9679
9737
|
});
|
|
9680
9738
|
}
|
|
9739
|
+
function useTransientHint(timeoutMs) {
|
|
9740
|
+
const [visible, setVisible] = useState35(false);
|
|
9741
|
+
const hideTimer = useRef39(null);
|
|
9742
|
+
useEffect46(() => () => clearTimeout(hideTimer.current ?? undefined), []);
|
|
9743
|
+
const show = () => {
|
|
9744
|
+
setVisible(true);
|
|
9745
|
+
clearTimeout(hideTimer.current ?? undefined);
|
|
9746
|
+
hideTimer.current = setTimeout(() => setVisible(false), timeoutMs);
|
|
9747
|
+
};
|
|
9748
|
+
const hide = () => {
|
|
9749
|
+
clearTimeout(hideTimer.current ?? undefined);
|
|
9750
|
+
setVisible(false);
|
|
9751
|
+
};
|
|
9752
|
+
return {
|
|
9753
|
+
visible,
|
|
9754
|
+
hintProps: { onMouseEnter: show, onMouseLeave: hide, onFocus: show, onBlur: hide }
|
|
9755
|
+
};
|
|
9756
|
+
}
|
|
9681
9757
|
function AgentDots() {
|
|
9682
9758
|
return /* @__PURE__ */ jsxs35("span", {
|
|
9683
9759
|
className: "skippr:flex skippr:items-center skippr:gap-[4px]",
|
|
@@ -9711,7 +9787,7 @@ var MIC_HALO_IDLE_PX = 30;
|
|
|
9711
9787
|
var MIC_HALO_GROWTH_PX = 12;
|
|
9712
9788
|
var MIC_HALO_NOISE_GATE = 0.15;
|
|
9713
9789
|
function MicLevelHalo({ enabled }) {
|
|
9714
|
-
const { microphoneTrack } =
|
|
9790
|
+
const { microphoneTrack } = useLocalParticipant13();
|
|
9715
9791
|
const { barRefs } = useAudioLevelBars(enabled ? microphoneTrack?.track?.mediaStreamTrack : undefined, {
|
|
9716
9792
|
barCount: 1,
|
|
9717
9793
|
idleHeightPx: MIC_HALO_IDLE_PX,
|
|
@@ -9739,8 +9815,8 @@ function ShortcutHint({
|
|
|
9739
9815
|
children
|
|
9740
9816
|
}) {
|
|
9741
9817
|
const ref = useRef39(null);
|
|
9742
|
-
const [visible, setVisible] =
|
|
9743
|
-
|
|
9818
|
+
const [visible, setVisible] = useState35(false);
|
|
9819
|
+
useEffect46(() => {
|
|
9744
9820
|
if (!enabled)
|
|
9745
9821
|
return;
|
|
9746
9822
|
const el = ref.current;
|
|
@@ -9853,15 +9929,15 @@ function VoiceBarFrame({
|
|
|
9853
9929
|
captureMode,
|
|
9854
9930
|
chatActivityAt
|
|
9855
9931
|
} = ctx;
|
|
9856
|
-
const [bannerOpen, setBannerOpen] =
|
|
9932
|
+
const [bannerOpen, setBannerOpen] = useState35(false);
|
|
9857
9933
|
const hasNotifications = notifications.length > 0;
|
|
9858
9934
|
const notifAccent = notifications[0]?.accentColor;
|
|
9859
|
-
const closeBanner =
|
|
9935
|
+
const closeBanner = useCallback29(() => setBannerOpen(false), []);
|
|
9860
9936
|
const containerRef = useRef39(null);
|
|
9861
9937
|
const dragFollowers = isPanelOpen ? [panelRef] : null;
|
|
9862
9938
|
const { wasDraggedRef } = useVoiceBarDrag(containerRef, onDrop, dragFollowers, setDragging);
|
|
9863
9939
|
const { isMuted, toggleMute } = useMediaControls();
|
|
9864
|
-
const { localParticipant } =
|
|
9940
|
+
const { localParticipant } = useLocalParticipant13();
|
|
9865
9941
|
const isUserSpeaking = useIsSpeaking(localParticipant);
|
|
9866
9942
|
const { state } = useAgentVoiceState();
|
|
9867
9943
|
const { isCapturingSpeech, toggle: toggleTapToTalk, start, commit } = useVoiceTurnContext();
|
|
@@ -9870,20 +9946,22 @@ function VoiceBarFrame({
|
|
|
9870
9946
|
const plan = usePlanUpdates();
|
|
9871
9947
|
const linkCard = useLinkCard();
|
|
9872
9948
|
const { sendChatMessage } = useChatMessages();
|
|
9873
|
-
const [dismissedFloatingPlanId, setDismissedFloatingPlanId] =
|
|
9874
|
-
const [dismissedBlockPlanId, setDismissedBlockPlanId] =
|
|
9875
|
-
const [dismissedLinkCardId, setDismissedLinkCardId] =
|
|
9949
|
+
const [dismissedFloatingPlanId, setDismissedFloatingPlanId] = useState35(null);
|
|
9950
|
+
const [dismissedBlockPlanId, setDismissedBlockPlanId] = useState35(null);
|
|
9951
|
+
const [dismissedLinkCardId, setDismissedLinkCardId] = useState35(null);
|
|
9876
9952
|
const micMode = agentControls?.micMode;
|
|
9877
9953
|
const pushOrTap = isRequestResponseMicMode(micMode);
|
|
9878
9954
|
const isPushToTalk = micMode === MIC_MODE.PushToTalk;
|
|
9879
9955
|
const agentActive = state === "speaking" || state === "thinking";
|
|
9880
|
-
const { actionsActive } = useActionControl();
|
|
9956
|
+
const { actionsActive, stopActions: stopActions2 } = useActionControl();
|
|
9957
|
+
const { highlightActive: highlightActive2, clearHighlight: clearHighlight2 } = useHighlightControl();
|
|
9958
|
+
const { visible: stopHintVisible, hintProps: stopHintProps } = useTransientHint(1000);
|
|
9881
9959
|
const showActionControl = isConnected && captureMode === CAPTURE_MODE.Auto && actionsActive;
|
|
9882
9960
|
const chatSurface = agentControls?.chat ?? DEFAULT_CHAT_SURFACE;
|
|
9883
9961
|
const isRoomChat = chatSurface === CHAT_SURFACE.Room;
|
|
9884
|
-
const [chatLineOpen, setChatLineOpen] =
|
|
9885
|
-
const [chatLineMounted, setChatLineMounted] =
|
|
9886
|
-
const [chatLineClosing, setChatLineClosing] =
|
|
9962
|
+
const [chatLineOpen, setChatLineOpen] = useState35(false);
|
|
9963
|
+
const [chatLineMounted, setChatLineMounted] = useState35(false);
|
|
9964
|
+
const [chatLineClosing, setChatLineClosing] = useState35(false);
|
|
9887
9965
|
const chatOpen = isRoomChat ? isPanelOpen : chatLineOpen;
|
|
9888
9966
|
const lineBlockOpen = !isRoomChat && chatLineMounted;
|
|
9889
9967
|
const toggleChat = () => {
|
|
@@ -9893,7 +9971,7 @@ function VoiceBarFrame({
|
|
|
9893
9971
|
setChatLineOpen((open) => !open);
|
|
9894
9972
|
}
|
|
9895
9973
|
};
|
|
9896
|
-
|
|
9974
|
+
useEffect46(() => {
|
|
9897
9975
|
if (chatLineOpen) {
|
|
9898
9976
|
setChatLineMounted(true);
|
|
9899
9977
|
setChatLineClosing(false);
|
|
@@ -9924,16 +10002,14 @@ function VoiceBarFrame({
|
|
|
9924
10002
|
return;
|
|
9925
10003
|
action();
|
|
9926
10004
|
};
|
|
9927
|
-
const
|
|
9928
|
-
const closeBar = (source) => {
|
|
10005
|
+
const closeBar = () => {
|
|
9929
10006
|
if (sessionLive) {
|
|
9930
|
-
setPauseSource(source);
|
|
9931
10007
|
pauseSession();
|
|
9932
10008
|
} else {
|
|
9933
10009
|
minimizePanel();
|
|
9934
10010
|
}
|
|
9935
10011
|
};
|
|
9936
|
-
useKeyboardStop({ enabled: sessionLive, onStop:
|
|
10012
|
+
useKeyboardStop({ enabled: sessionLive, onStop: closeBar });
|
|
9937
10013
|
const hintSeenRef = useRef39(false);
|
|
9938
10014
|
const requestPillBg = isCapturingSpeech ? "var(--skippr-brand-active)" : "var(--skippr-brand, #2bc0ae)";
|
|
9939
10015
|
const agentStateLabel = state === "thinking" ? "thinking…" : state === "speaking" ? "talking…" : null;
|
|
@@ -9941,17 +10017,17 @@ function VoiceBarFrame({
|
|
|
9941
10017
|
const requestLabel = agentStateLabel ?? (isCapturingSpeech ? "listening…" : idleRequestLabel);
|
|
9942
10018
|
const livePillBg = agentActive && !isHeld ? "var(--skippr-brand-active)" : "var(--skippr-brand, #2bc0ae)";
|
|
9943
10019
|
const glow = isConnected && !isHeld && agentActive;
|
|
9944
|
-
const [autoOffClosing, setAutoOffClosing] =
|
|
10020
|
+
const [autoOffClosing, setAutoOffClosing] = useState35(false);
|
|
9945
10021
|
const { reportActivity } = useIdleAutoOff({
|
|
9946
10022
|
enabled: isConnected && !autoOffClosing,
|
|
9947
10023
|
active: agentActive || isCapturingSpeech || isUserSpeaking,
|
|
9948
10024
|
onExpire: () => setAutoOffClosing(true)
|
|
9949
10025
|
});
|
|
9950
|
-
|
|
10026
|
+
useEffect46(() => {
|
|
9951
10027
|
if (chatActivityAt)
|
|
9952
10028
|
reportActivity();
|
|
9953
10029
|
}, [chatActivityAt, reportActivity]);
|
|
9954
|
-
|
|
10030
|
+
useEffect46(() => {
|
|
9955
10031
|
if (!autoOffClosing)
|
|
9956
10032
|
return;
|
|
9957
10033
|
if (!isConnected) {
|
|
@@ -9967,12 +10043,12 @@ function VoiceBarFrame({
|
|
|
9967
10043
|
const floatingPlanActive = planEnabled && !isRoomChat && !lineBlockOpen && activePlan.planId !== dismissedFloatingPlanId;
|
|
9968
10044
|
const planInLineBlock = planEnabled && lineBlockOpen && activePlan.planId !== dismissedBlockPlanId;
|
|
9969
10045
|
const planCardActive = floatingPlanActive || planInLineBlock;
|
|
9970
|
-
|
|
10046
|
+
useEffect46(() => {
|
|
9971
10047
|
if (lineBlockOpen)
|
|
9972
10048
|
setDismissedBlockPlanId(null);
|
|
9973
10049
|
}, [lineBlockOpen]);
|
|
9974
|
-
const [autoOpenedPlanId, setAutoOpenedPlanId] =
|
|
9975
|
-
|
|
10050
|
+
const [autoOpenedPlanId, setAutoOpenedPlanId] = useState35(null);
|
|
10051
|
+
useEffect46(() => {
|
|
9976
10052
|
if (!isRoomChat || !planEnabled || !activePlan)
|
|
9977
10053
|
return;
|
|
9978
10054
|
if (activePlan.planId === autoOpenedPlanId)
|
|
@@ -10162,12 +10238,12 @@ function VoiceBarFrame({
|
|
|
10162
10238
|
children: [
|
|
10163
10239
|
showClose && /* @__PURE__ */ jsxs35("button", {
|
|
10164
10240
|
type: "button",
|
|
10165
|
-
onClick: ifNotDragged(
|
|
10241
|
+
onClick: ifNotDragged(closeBar),
|
|
10166
10242
|
disabled: isPausing || isStarting,
|
|
10167
10243
|
"aria-label": sessionLive ? "End session" : "Close",
|
|
10168
10244
|
className: cn(EDGE_BUTTON, "skippr:relative skippr:size-[26px]", isStarting && "skippr:cursor-not-allowed skippr:opacity-40 skippr:hover:bg-transparent skippr:hover:text-[#b8b4ac]"),
|
|
10169
10245
|
children: [
|
|
10170
|
-
isPausing &&
|
|
10246
|
+
isPausing && /* @__PURE__ */ jsx42(BusyRing, {
|
|
10171
10247
|
tone: "brand"
|
|
10172
10248
|
}),
|
|
10173
10249
|
/* @__PURE__ */ jsx42(X, {
|
|
@@ -10276,20 +10352,29 @@ function VoiceBarFrame({
|
|
|
10276
10352
|
})
|
|
10277
10353
|
]
|
|
10278
10354
|
}),
|
|
10279
|
-
/* @__PURE__ */ jsxs35("
|
|
10280
|
-
|
|
10281
|
-
onClick: ifNotDragged(() => closeBar("stop")),
|
|
10282
|
-
disabled: isPausing,
|
|
10283
|
-
"aria-label": "End session",
|
|
10284
|
-
className: "skippr:relative skippr:flex skippr:size-[26px] skippr:shrink-0 skippr:items-center skippr:justify-center skippr:rounded-full skippr:bg-transparent skippr:cursor-pointer skippr:transition-colors skippr:hover:bg-white/20 skippr:disabled:cursor-not-allowed",
|
|
10355
|
+
/* @__PURE__ */ jsxs35("span", {
|
|
10356
|
+
className: "skippr:relative skippr:inline-flex",
|
|
10285
10357
|
children: [
|
|
10286
|
-
|
|
10287
|
-
|
|
10358
|
+
/* @__PURE__ */ jsx42("button", {
|
|
10359
|
+
type: "button",
|
|
10360
|
+
onClick: ifNotDragged(() => {
|
|
10361
|
+
stopActions2();
|
|
10362
|
+
if (highlightActive2)
|
|
10363
|
+
clearHighlight2();
|
|
10364
|
+
}),
|
|
10365
|
+
...stopHintProps,
|
|
10366
|
+
"aria-label": "Stop live action",
|
|
10367
|
+
className: "skippr:flex skippr:size-[26px] skippr:shrink-0 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:rounded-full skippr:bg-transparent skippr:transition-colors skippr:hover:bg-white/20",
|
|
10368
|
+
children: /* @__PURE__ */ jsx42(Square, {
|
|
10369
|
+
className: "skippr:size-[11px]",
|
|
10370
|
+
fill: "currentColor",
|
|
10371
|
+
strokeWidth: 0
|
|
10372
|
+
})
|
|
10288
10373
|
}),
|
|
10289
|
-
/* @__PURE__ */ jsx42(
|
|
10290
|
-
className: "skippr:
|
|
10291
|
-
|
|
10292
|
-
|
|
10374
|
+
stopHintVisible && /* @__PURE__ */ jsx42("span", {
|
|
10375
|
+
className: "skippr:pointer-events-none skippr:absolute skippr:bottom-full skippr:left-1/2 skippr:z-10 skippr:mb-1.5 skippr:-translate-x-1/2 skippr:whitespace-nowrap skippr:rounded skippr:bg-foreground skippr:px-1.5 skippr:py-0.5 skippr:text-[10px] skippr:font-medium skippr:text-background",
|
|
10376
|
+
"aria-hidden": "true",
|
|
10377
|
+
children: "Stop live action"
|
|
10293
10378
|
})
|
|
10294
10379
|
]
|
|
10295
10380
|
})
|
|
@@ -10372,10 +10457,10 @@ function VoiceBarFrame({
|
|
|
10372
10457
|
}
|
|
10373
10458
|
|
|
10374
10459
|
// src/components/VoiceBarLauncher.tsx
|
|
10375
|
-
import { useCallback as
|
|
10460
|
+
import { useCallback as useCallback30, useEffect as useEffect48, useRef as useRef41, useState as useState37 } from "react";
|
|
10376
10461
|
|
|
10377
10462
|
// src/components/LauncherNotification.tsx
|
|
10378
|
-
import { useEffect as
|
|
10463
|
+
import { useEffect as useEffect47, useRef as useRef40, useState as useState36 } from "react";
|
|
10379
10464
|
import { jsx as jsx43, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
10380
10465
|
function LauncherNotification({
|
|
10381
10466
|
notifications,
|
|
@@ -10383,10 +10468,10 @@ function LauncherNotification({
|
|
|
10383
10468
|
mode,
|
|
10384
10469
|
onDismiss
|
|
10385
10470
|
}) {
|
|
10386
|
-
const [index2, setIndex] =
|
|
10387
|
-
const [paused, setPaused] =
|
|
10471
|
+
const [index2, setIndex] = useState36(0);
|
|
10472
|
+
const [paused, setPaused] = useState36(false);
|
|
10388
10473
|
const cardRef = useRef40(null);
|
|
10389
|
-
|
|
10474
|
+
useEffect47(() => {
|
|
10390
10475
|
const el = cardRef.current;
|
|
10391
10476
|
if (!el)
|
|
10392
10477
|
return;
|
|
@@ -10399,7 +10484,7 @@ function LauncherNotification({
|
|
|
10399
10484
|
el.removeEventListener("mouseleave", leave);
|
|
10400
10485
|
};
|
|
10401
10486
|
}, []);
|
|
10402
|
-
|
|
10487
|
+
useEffect47(() => {
|
|
10403
10488
|
if (paused)
|
|
10404
10489
|
return;
|
|
10405
10490
|
const rotate = setInterval(() => setIndex((current) => (current + 1) % notifications.length), TIP_ROTATE_MS);
|
|
@@ -10597,11 +10682,11 @@ function VoiceBarLauncher({
|
|
|
10597
10682
|
const containerRef = useRef41(null);
|
|
10598
10683
|
const { wasDraggedRef } = useVoiceBarDrag(containerRef, onDrop, null, setDragging);
|
|
10599
10684
|
const horizontal = isHorizontalEdge(dock.edge);
|
|
10600
|
-
const [cardOpen, setCardOpen] =
|
|
10601
|
-
const [hovered, setHovered] =
|
|
10685
|
+
const [cardOpen, setCardOpen] = useState37(false);
|
|
10686
|
+
const [hovered, setHovered] = useState37(false);
|
|
10602
10687
|
const hasNotif = notifications.length > 0;
|
|
10603
10688
|
const dotColor = notifications.find((item) => item.kind === NOTIFICATION_KIND.Module)?.accentColor ?? notifications[0]?.accentColor ?? NOTIF_ACCENT_COLOR;
|
|
10604
|
-
|
|
10689
|
+
useEffect48(() => {
|
|
10605
10690
|
const el = containerRef.current;
|
|
10606
10691
|
if (!el)
|
|
10607
10692
|
return;
|
|
@@ -10631,7 +10716,7 @@ function VoiceBarLauncher({
|
|
|
10631
10716
|
return;
|
|
10632
10717
|
setCardOpen((open2) => !open2);
|
|
10633
10718
|
};
|
|
10634
|
-
const closeCard =
|
|
10719
|
+
const closeCard = useCallback30(() => setCardOpen(false), []);
|
|
10635
10720
|
if (mode === "strip") {
|
|
10636
10721
|
const expanded = hovered && !!onChat;
|
|
10637
10722
|
const length = expanded ? 84 : 40;
|
|
@@ -10779,8 +10864,8 @@ function VoiceBar({ revealed }) {
|
|
|
10779
10864
|
barDock,
|
|
10780
10865
|
setBarDock
|
|
10781
10866
|
} = ctx;
|
|
10782
|
-
const [launcherDock, setLauncherDock] =
|
|
10783
|
-
const onLauncherDrop =
|
|
10867
|
+
const [launcherDock, setLauncherDock] = useState38(() => readSavedDock("launcher"));
|
|
10868
|
+
const onLauncherDrop = useCallback31((next) => {
|
|
10784
10869
|
setLauncherDock(next);
|
|
10785
10870
|
persistDock("launcher", next);
|
|
10786
10871
|
}, []);
|
|
@@ -10850,7 +10935,7 @@ function PlanPanelOpener() {
|
|
|
10850
10935
|
const plan = usePlanUpdates();
|
|
10851
10936
|
const { expandPanel } = useLiveAgent();
|
|
10852
10937
|
const surfacedPlanIdRef = useRef42(null);
|
|
10853
|
-
|
|
10938
|
+
useEffect49(() => {
|
|
10854
10939
|
if (plan?.state !== "proposed" || surfacedPlanIdRef.current === plan.planId)
|
|
10855
10940
|
return;
|
|
10856
10941
|
surfacedPlanIdRef.current = plan.planId;
|
|
@@ -10890,19 +10975,19 @@ function LiveAgent(props) {
|
|
|
10890
10975
|
const auth = useAuth({ appKey });
|
|
10891
10976
|
const usesHostAuth = !!getUserToken || !!userToken || !!authTokenProp;
|
|
10892
10977
|
const effectiveAuthToken = usesHostAuth ? authTokenProp : auth.authToken ?? undefined;
|
|
10893
|
-
const [activeModule, setActiveModule] =
|
|
10894
|
-
const [sessionAgentMode, setSessionAgentMode] =
|
|
10895
|
-
const minimizeOnSessionStart =
|
|
10978
|
+
const [activeModule, setActiveModule] = useState39(null);
|
|
10979
|
+
const [sessionAgentMode, setSessionAgentMode] = useState39(null);
|
|
10980
|
+
const minimizeOnSessionStart = useCallback32(() => {
|
|
10896
10981
|
if (minimizable) {
|
|
10897
10982
|
setIsMinimized(true);
|
|
10898
10983
|
setIsPanelOpen(false);
|
|
10899
10984
|
}
|
|
10900
10985
|
}, [minimizable]);
|
|
10901
|
-
const expandOnSessionStartError =
|
|
10986
|
+
const expandOnSessionStartError = useCallback32(() => {
|
|
10902
10987
|
setIsMinimized(false);
|
|
10903
10988
|
setIsPanelOpen(true);
|
|
10904
10989
|
}, []);
|
|
10905
|
-
const minimizeOnSessionDisconnect =
|
|
10990
|
+
const minimizeOnSessionDisconnect = useCallback32(() => {
|
|
10906
10991
|
setActiveModule(null);
|
|
10907
10992
|
setSessionAgentMode(null);
|
|
10908
10993
|
if (minimizable) {
|
|
@@ -10941,28 +11026,28 @@ function LiveAgent(props) {
|
|
|
10941
11026
|
});
|
|
10942
11027
|
const teardownInFlightRef = useRef42(false);
|
|
10943
11028
|
teardownInFlightRef.current = isPaused || isPausing || isDisconnecting;
|
|
10944
|
-
const handleRoomDisconnected =
|
|
11029
|
+
const handleRoomDisconnected = useCallback32(() => {
|
|
10945
11030
|
if (teardownInFlightRef.current)
|
|
10946
11031
|
return;
|
|
10947
11032
|
disconnect();
|
|
10948
11033
|
}, [disconnect]);
|
|
10949
11034
|
const isSessionLive = connection !== null || isStarting || isPausing || isDisconnecting;
|
|
10950
|
-
const [isPanelOpen, setIsPanelOpen] =
|
|
10951
|
-
const [isMinimized, setIsMinimized] =
|
|
10952
|
-
const [sidebarTab, setSidebarTab] =
|
|
10953
|
-
const [phasesSnapshot, setPhasesSnapshot] =
|
|
10954
|
-
const [textMode, setTextMode] =
|
|
10955
|
-
const [panelExpanded, setPanelExpanded] =
|
|
10956
|
-
const togglePanelExpanded =
|
|
11035
|
+
const [isPanelOpen, setIsPanelOpen] = useState39(defaultOpen);
|
|
11036
|
+
const [isMinimized, setIsMinimized] = useState39(minimizable && !defaultOpen);
|
|
11037
|
+
const [sidebarTab, setSidebarTab] = useState39("agenda");
|
|
11038
|
+
const [phasesSnapshot, setPhasesSnapshot] = useState39([]);
|
|
11039
|
+
const [textMode, setTextMode] = useState39(false);
|
|
11040
|
+
const [panelExpanded, setPanelExpanded] = useState39(false);
|
|
11041
|
+
const togglePanelExpanded = useCallback32(() => setPanelExpanded((prev) => !prev), []);
|
|
10957
11042
|
const panelRef = useRef42(null);
|
|
10958
11043
|
const controlBarRef = useRef42(null);
|
|
10959
|
-
const [isDragging, setIsDragging] =
|
|
10960
|
-
const setTextModeState =
|
|
11044
|
+
const [isDragging, setIsDragging] = useState39(false);
|
|
11045
|
+
const setTextModeState = useCallback32((enabled) => {
|
|
10961
11046
|
setTextMode(enabled);
|
|
10962
11047
|
}, []);
|
|
10963
11048
|
const isConnected = connection !== null;
|
|
10964
11049
|
const showControlBar = isConnected || isStarting || isPausing;
|
|
10965
|
-
|
|
11050
|
+
useEffect49(() => {
|
|
10966
11051
|
if (!isConnected)
|
|
10967
11052
|
setTextModeState(false);
|
|
10968
11053
|
}, [isConnected, setTextModeState]);
|
|
@@ -10993,7 +11078,7 @@ function LiveAgent(props) {
|
|
|
10993
11078
|
const buddyActive = isBuddyActive(appearance) && variant !== "sidebar" && !hostAgentId;
|
|
10994
11079
|
const buddyShape = appearance?.buddy?.shape ?? DEFAULT_BUDDY_SHAPE;
|
|
10995
11080
|
const effectiveHostAgentId = buddyActive ? undefined : hostAgentId;
|
|
10996
|
-
const startSession =
|
|
11081
|
+
const startSession = useCallback32((opts) => startSessionRaw(buddyActive ? { ...opts, agentControls: buddyEffectiveControls(opts.agentControls) } : opts), [startSessionRaw, buddyActive]);
|
|
10997
11082
|
const defaultAgentId = buddyActive ? defaultSelection.agentId : hostAgentId ?? defaultSelection.agentId;
|
|
10998
11083
|
const defaultModule = availableModules.find((m) => m.id === defaultAgentId) ?? null;
|
|
10999
11084
|
const operatingModule = buddyActive ? defaultModule : activeModule ?? (effectiveHostAgentId ? availableModules[0] ?? null : null);
|
|
@@ -11004,7 +11089,7 @@ function LiveAgent(props) {
|
|
|
11004
11089
|
const shouldAnimateCursor = operatingModule?.uiPreferences?.animateCursor ?? animateAgentCursor;
|
|
11005
11090
|
const buddyDefaultMissing = buddyActive && hasResolvedModules && !modulesError && !defaultModule && !isSessionLive;
|
|
11006
11091
|
const resumableSession = useMemo7(() => getResumableSession(operatingModule), [operatingModule]);
|
|
11007
|
-
const resumeSession =
|
|
11092
|
+
const resumeSession = useCallback32(async () => {
|
|
11008
11093
|
if (!resumableSession)
|
|
11009
11094
|
return;
|
|
11010
11095
|
if (operatingModule) {
|
|
@@ -11017,7 +11102,7 @@ function LiveAgent(props) {
|
|
|
11017
11102
|
existingSessionId: resumableSession.id
|
|
11018
11103
|
});
|
|
11019
11104
|
}, [resumableSession, operatingModule, startSession, baseAgentControls]);
|
|
11020
|
-
const selectModule =
|
|
11105
|
+
const selectModule = useCallback32((moduleId, opts) => {
|
|
11021
11106
|
const found = availableModules.find((m) => m.id === moduleId);
|
|
11022
11107
|
if (!found)
|
|
11023
11108
|
return;
|
|
@@ -11030,7 +11115,7 @@ function LiveAgent(props) {
|
|
|
11030
11115
|
autoStarted: opts?.autoStarted
|
|
11031
11116
|
});
|
|
11032
11117
|
}, [availableModules, startSession]);
|
|
11033
|
-
const startAdoptionSession =
|
|
11118
|
+
const startAdoptionSession = useCallback32((goal) => {
|
|
11034
11119
|
attendGoal(goal.goalId);
|
|
11035
11120
|
const found = availableModules.find((m) => m.id === goal.agentId);
|
|
11036
11121
|
if (found)
|
|
@@ -11042,12 +11127,12 @@ function LiveAgent(props) {
|
|
|
11042
11127
|
adoptionGoalId: goal.goalId
|
|
11043
11128
|
});
|
|
11044
11129
|
}, [attendGoal, availableModules, startSession]);
|
|
11045
|
-
const [welcomeDismissed, setWelcomeDismissed] =
|
|
11046
|
-
const dismissWelcome =
|
|
11047
|
-
const [savedPosition] =
|
|
11048
|
-
const [currentPosition, setCurrentPosition] =
|
|
11130
|
+
const [welcomeDismissed, setWelcomeDismissed] = useState39(false);
|
|
11131
|
+
const dismissWelcome = useCallback32(() => setWelcomeDismissed(true), []);
|
|
11132
|
+
const [savedPosition] = useState39(readSavedPosition);
|
|
11133
|
+
const [currentPosition, setCurrentPosition] = useState39(savedPosition ?? "right");
|
|
11049
11134
|
const positionLockedRef = useRef42(savedPosition !== null);
|
|
11050
|
-
const setPositionWithPersist =
|
|
11135
|
+
const setPositionWithPersist = useCallback32((pos) => {
|
|
11051
11136
|
positionLockedRef.current = true;
|
|
11052
11137
|
setCurrentPosition(pos);
|
|
11053
11138
|
try {
|
|
@@ -11055,18 +11140,18 @@ function LiveAgent(props) {
|
|
|
11055
11140
|
} catch {}
|
|
11056
11141
|
}, []);
|
|
11057
11142
|
const serverPosition = appearance?.position ?? null;
|
|
11058
|
-
|
|
11143
|
+
useEffect49(() => {
|
|
11059
11144
|
if (!serverPosition || positionLockedRef.current)
|
|
11060
11145
|
return;
|
|
11061
11146
|
setCurrentPosition(serverPosition);
|
|
11062
11147
|
}, [serverPosition]);
|
|
11063
|
-
const [savedLauncherBottom] =
|
|
11148
|
+
const [savedLauncherBottom] = useState39(readSavedLauncherBottom);
|
|
11064
11149
|
const hasDraggedRef = useRef42(savedLauncherBottom !== null);
|
|
11065
11150
|
const verticalAlignRef = useRef42(hostVerticalAlign ?? "bottom");
|
|
11066
|
-
const [launcherBottomPx, setLauncherBottomPxState] =
|
|
11067
|
-
const [popsDown, setPopsDown] =
|
|
11151
|
+
const [launcherBottomPx, setLauncherBottomPxState] = useState39(() => savedLauncherBottom !== null ? clampLauncherBottom(savedLauncherBottom) : verticalAlignToBottomPx(verticalAlignRef.current));
|
|
11152
|
+
const [popsDown, setPopsDown] = useState39(() => launcherPopsDown(launcherBottomPx));
|
|
11068
11153
|
const serverVerticalAlign = appearance?.verticalAlign ?? null;
|
|
11069
|
-
|
|
11154
|
+
useEffect49(() => {
|
|
11070
11155
|
if (!serverVerticalAlign || hostVerticalAlign !== undefined || hasDraggedRef.current)
|
|
11071
11156
|
return;
|
|
11072
11157
|
verticalAlignRef.current = serverVerticalAlign;
|
|
@@ -11074,7 +11159,7 @@ function LiveAgent(props) {
|
|
|
11074
11159
|
setLauncherBottomPxState(next);
|
|
11075
11160
|
setPopsDown(launcherPopsDown(next));
|
|
11076
11161
|
}, [serverVerticalAlign, hostVerticalAlign]);
|
|
11077
|
-
const setLauncherBottomPx =
|
|
11162
|
+
const setLauncherBottomPx = useCallback32((px) => {
|
|
11078
11163
|
hasDraggedRef.current = true;
|
|
11079
11164
|
setLauncherBottomPxState(px);
|
|
11080
11165
|
setPopsDown(launcherPopsDown(px));
|
|
@@ -11084,22 +11169,22 @@ function LiveAgent(props) {
|
|
|
11084
11169
|
}, []);
|
|
11085
11170
|
const launcherBottomPxRef = useRef42(launcherBottomPx);
|
|
11086
11171
|
launcherBottomPxRef.current = launcherBottomPx;
|
|
11087
|
-
const [chatActivityAt, setChatActivityAt] =
|
|
11088
|
-
const reportChatActivity =
|
|
11172
|
+
const [chatActivityAt, setChatActivityAt] = useState39(0);
|
|
11173
|
+
const reportChatActivity = useCallback32(() => {
|
|
11089
11174
|
const now = Date.now();
|
|
11090
11175
|
setChatActivityAt((last) => now - last < CHAT_ACTIVITY_THROTTLE_MS ? last : now);
|
|
11091
11176
|
}, []);
|
|
11092
|
-
const [chatDraft, setChatDraft] =
|
|
11093
|
-
const commitLauncherDrop =
|
|
11177
|
+
const [chatDraft, setChatDraft] = useState39("");
|
|
11178
|
+
const commitLauncherDrop = useCallback32(({ side, bottomPx }) => {
|
|
11094
11179
|
setPositionWithPersist(side);
|
|
11095
11180
|
setLauncherBottomPx(bottomPx);
|
|
11096
11181
|
}, [setPositionWithPersist, setLauncherBottomPx]);
|
|
11097
|
-
const [barDock, setBarDockState] =
|
|
11098
|
-
const setBarDock =
|
|
11182
|
+
const [barDock, setBarDockState] = useState39(() => readSavedDock("bar"));
|
|
11183
|
+
const setBarDock = useCallback32((next) => {
|
|
11099
11184
|
setBarDockState(next);
|
|
11100
11185
|
persistDock("bar", next);
|
|
11101
11186
|
}, []);
|
|
11102
|
-
|
|
11187
|
+
useEffect49(() => {
|
|
11103
11188
|
const syncToViewport = () => {
|
|
11104
11189
|
const next = hasDraggedRef.current ? clampLauncherBottom(launcherBottomPxRef.current) : verticalAlignToBottomPx(verticalAlignRef.current);
|
|
11105
11190
|
setLauncherBottomPxState(next);
|
|
@@ -11109,24 +11194,24 @@ function LiveAgent(props) {
|
|
|
11109
11194
|
window.addEventListener("resize", syncToViewport);
|
|
11110
11195
|
return () => window.removeEventListener("resize", syncToViewport);
|
|
11111
11196
|
}, []);
|
|
11112
|
-
const openPanel =
|
|
11113
|
-
const closePanel =
|
|
11114
|
-
const togglePanel =
|
|
11115
|
-
const expandPanel =
|
|
11197
|
+
const openPanel = useCallback32(() => setIsPanelOpen(true), []);
|
|
11198
|
+
const closePanel = useCallback32(() => setIsPanelOpen(false), []);
|
|
11199
|
+
const togglePanel = useCallback32(() => setIsPanelOpen((prev) => !prev), []);
|
|
11200
|
+
const expandPanel = useCallback32(() => {
|
|
11116
11201
|
setIsMinimized(false);
|
|
11117
11202
|
setIsPanelOpen(true);
|
|
11118
11203
|
}, []);
|
|
11119
|
-
const minimizePanel =
|
|
11204
|
+
const minimizePanel = useCallback32(() => {
|
|
11120
11205
|
if (!minimizable)
|
|
11121
11206
|
return;
|
|
11122
11207
|
setIsMinimized(true);
|
|
11123
11208
|
setIsPanelOpen(false);
|
|
11124
11209
|
}, [minimizable]);
|
|
11125
|
-
const pauseSessionAndMinimize =
|
|
11210
|
+
const pauseSessionAndMinimize = useCallback32(async () => {
|
|
11126
11211
|
await pauseSession();
|
|
11127
11212
|
minimizePanel();
|
|
11128
11213
|
}, [pauseSession, minimizePanel]);
|
|
11129
|
-
const startDefaultSession =
|
|
11214
|
+
const startDefaultSession = useCallback32(() => {
|
|
11130
11215
|
const target = availableModules.find((m) => m.id === defaultAgentId);
|
|
11131
11216
|
if (!target)
|
|
11132
11217
|
return;
|
|
@@ -11394,9 +11479,9 @@ function LiveAgent(props) {
|
|
|
11394
11479
|
});
|
|
11395
11480
|
}
|
|
11396
11481
|
// src/hooks/useIsLocalSpeaking.ts
|
|
11397
|
-
import { useIsSpeaking as useIsSpeaking2, useLocalParticipant as
|
|
11482
|
+
import { useIsSpeaking as useIsSpeaking2, useLocalParticipant as useLocalParticipant14 } from "@livekit/components-react/hooks";
|
|
11398
11483
|
function useIsLocalSpeaking() {
|
|
11399
|
-
const { localParticipant } =
|
|
11484
|
+
const { localParticipant } = useLocalParticipant14();
|
|
11400
11485
|
return useIsSpeaking2(localParticipant);
|
|
11401
11486
|
}
|
|
11402
11487
|
// src/hooks/useIsSessionHeld.ts
|