callix-dialer-widget 2.8.4 → 2.8.5
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.
|
@@ -43754,6 +43754,7 @@ const INITIAL_TRANSCRIPT = { segments: [], status: null, insight: null, interims
|
|
|
43754
43754
|
const MAX_SEGMENTS = 300;
|
|
43755
43755
|
const RECONNECT_MIN_MS = 500;
|
|
43756
43756
|
const RECONNECT_MAX_MS = 5e3;
|
|
43757
|
+
const ENGINE_VIEW_TIMEOUT_MS = 15e3;
|
|
43757
43758
|
const PENDING_COMMANDS_MAX = 10;
|
|
43758
43759
|
const PENDING_COMMANDS_TTL_MS = 15e3;
|
|
43759
43760
|
function engineWsUrl(baseUrl) {
|
|
@@ -43775,6 +43776,9 @@ class EngineClient {
|
|
|
43775
43776
|
this.reconnectDelay = RECONNECT_MIN_MS;
|
|
43776
43777
|
this.pendingCommands = [];
|
|
43777
43778
|
this.reconnectTimer = null;
|
|
43779
|
+
this.viewTimer = null;
|
|
43780
|
+
this.lastSnapshotAt = null;
|
|
43781
|
+
this.connectionError = null;
|
|
43778
43782
|
this.closed = false;
|
|
43779
43783
|
this.iceServers = [{ urls: "stun:stun.l.google.com:19302" }];
|
|
43780
43784
|
this.pc = null;
|
|
@@ -43828,9 +43832,10 @@ class EngineClient {
|
|
|
43828
43832
|
if (this.closed) this.closed = false;
|
|
43829
43833
|
if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) return;
|
|
43830
43834
|
const Impl = this.options.WebSocketImpl ?? WebSocket;
|
|
43831
|
-
this.setState({ wsState: "connecting" });
|
|
43835
|
+
this.setState({ wsState: "connecting", tabId: null, view: null });
|
|
43832
43836
|
const ws = new Impl(engineWsUrl(this.options.url));
|
|
43833
43837
|
this.ws = ws;
|
|
43838
|
+
this.watchForView(ws);
|
|
43834
43839
|
ws.onopen = () => {
|
|
43835
43840
|
var _a2, _b;
|
|
43836
43841
|
if (this.ws !== ws) return;
|
|
@@ -43840,6 +43845,7 @@ class EngineClient {
|
|
|
43840
43845
|
}
|
|
43841
43846
|
this.reconnectDelay = RECONNECT_MIN_MS;
|
|
43842
43847
|
this.setState({ wsState: "open" });
|
|
43848
|
+
this.watchForView(ws);
|
|
43843
43849
|
const sessionToken = !this.session && this.options.sessionToken ? this.options.sessionToken() : null;
|
|
43844
43850
|
const hello = {
|
|
43845
43851
|
type: "hello",
|
|
@@ -43865,24 +43871,14 @@ class EngineClient {
|
|
|
43865
43871
|
this.handle(message);
|
|
43866
43872
|
};
|
|
43867
43873
|
ws.onclose = () => {
|
|
43868
|
-
|
|
43869
|
-
this.ws = null;
|
|
43870
|
-
const wasEngaged = this.state.engaged;
|
|
43871
|
-
this.setState({ wsState: "closed", tabId: null, engaged: false });
|
|
43872
|
-
if (wasEngaged) this.stopAudio();
|
|
43873
|
-
if (this.closed) return;
|
|
43874
|
-
this.log(`conexão com o motor caiu; nova tentativa em ${this.reconnectDelay} ms`);
|
|
43875
|
-
this.reconnectTimer = setTimeout(() => {
|
|
43876
|
-
this.reconnectTimer = null;
|
|
43877
|
-
this.connect();
|
|
43878
|
-
}, this.reconnectDelay);
|
|
43879
|
-
this.reconnectDelay = Math.min(this.reconnectDelay * 2, RECONNECT_MAX_MS);
|
|
43874
|
+
this.disconnected(ws, "Conexão com o motor interrompida. Reconectando...");
|
|
43880
43875
|
};
|
|
43881
43876
|
ws.onerror = () => void 0;
|
|
43882
43877
|
}
|
|
43883
43878
|
/** fecha de vez (sem reconectar) e solta o áudio */
|
|
43884
43879
|
close() {
|
|
43885
43880
|
this.closed = true;
|
|
43881
|
+
this.clearViewTimer();
|
|
43886
43882
|
if (this.reconnectTimer) {
|
|
43887
43883
|
clearTimeout(this.reconnectTimer);
|
|
43888
43884
|
this.reconnectTimer = null;
|
|
@@ -43896,7 +43892,39 @@ class EngineClient {
|
|
|
43896
43892
|
}
|
|
43897
43893
|
this.pendingCommands = [];
|
|
43898
43894
|
this.rejectWaiters(new Error("a conexão com o motor foi encerrada"));
|
|
43899
|
-
this.
|
|
43895
|
+
this.userSignal.set(void 0);
|
|
43896
|
+
this.setState({ wsState: "closed", tabId: null, view: null, engaged: false });
|
|
43897
|
+
}
|
|
43898
|
+
clearViewTimer() {
|
|
43899
|
+
if (this.viewTimer) clearTimeout(this.viewTimer);
|
|
43900
|
+
this.viewTimer = null;
|
|
43901
|
+
}
|
|
43902
|
+
watchForView(ws) {
|
|
43903
|
+
var _a2, _b;
|
|
43904
|
+
this.clearViewTimer();
|
|
43905
|
+
this.viewTimer = setTimeout(() => {
|
|
43906
|
+
if (this.ws !== ws) return;
|
|
43907
|
+
this.disconnected(ws, "O motor parou de atualizar o estado. Reconectando...");
|
|
43908
|
+
ws.close();
|
|
43909
|
+
}, ENGINE_VIEW_TIMEOUT_MS);
|
|
43910
|
+
(_b = (_a2 = this.viewTimer).unref) == null ? void 0 : _b.call(_a2);
|
|
43911
|
+
}
|
|
43912
|
+
disconnected(ws, message) {
|
|
43913
|
+
if (this.ws !== ws) return;
|
|
43914
|
+
this.ws = null;
|
|
43915
|
+
this.clearViewTimer();
|
|
43916
|
+
this.userSignal.set(void 0);
|
|
43917
|
+
this.connectionError = message;
|
|
43918
|
+
this.setState({ wsState: "closed", tabId: null, view: null, engaged: false, lastError: message });
|
|
43919
|
+
this.stopAudio();
|
|
43920
|
+
if (this.closed) return;
|
|
43921
|
+
this.log(`conexão com o motor caiu; nova tentativa em ${this.reconnectDelay} ms`);
|
|
43922
|
+
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
|
|
43923
|
+
this.reconnectTimer = setTimeout(() => {
|
|
43924
|
+
this.reconnectTimer = null;
|
|
43925
|
+
this.connect();
|
|
43926
|
+
}, this.reconnectDelay);
|
|
43927
|
+
this.reconnectDelay = Math.min(this.reconnectDelay * 2, RECONNECT_MAX_MS);
|
|
43900
43928
|
}
|
|
43901
43929
|
/**
|
|
43902
43930
|
* A view atual, ou a próxima que o host mandar (welcome/view). Com `accept`, espera uma
|
|
@@ -43906,7 +43934,7 @@ class EngineClient {
|
|
|
43906
43934
|
waitForView(timeoutMs = 15e3, accept, options) {
|
|
43907
43935
|
const rejected = this.state.rejected;
|
|
43908
43936
|
if (rejected) return Promise.reject(new EngineAccessError(rejected.code, rejected.message));
|
|
43909
|
-
if (!(options == null ? void 0 : options.fresh) && this.state.view && this.state.tabId && (!accept || accept(this.state.view))) return Promise.resolve(this.state.view);
|
|
43937
|
+
if (!(options == null ? void 0 : options.fresh) && this.state.wsState === "open" && this.state.view && this.state.tabId && (!accept || accept(this.state.view))) return Promise.resolve(this.state.view);
|
|
43910
43938
|
return new Promise((resolve, reject) => {
|
|
43911
43939
|
const timer = setTimeout(() => {
|
|
43912
43940
|
const index = this.viewWaiters.findIndex((w) => w.timer === timer);
|
|
@@ -43930,6 +43958,7 @@ class EngineClient {
|
|
|
43930
43958
|
case "welcome": {
|
|
43931
43959
|
if (Array.isArray(message.iceServers) && message.iceServers.length > 0) this.iceServers = message.iceServers;
|
|
43932
43960
|
this.setState({ tabId: message.tabId, rejected: null });
|
|
43961
|
+
if (this.ws) this.watchForView(this.ws);
|
|
43933
43962
|
this.flushPendingCommands();
|
|
43934
43963
|
this.applyView(message.view);
|
|
43935
43964
|
this.log(`sou a aba ${message.tabId}`);
|
|
@@ -43987,21 +44016,34 @@ class EngineClient {
|
|
|
43987
44016
|
}
|
|
43988
44017
|
}
|
|
43989
44018
|
applyView(view) {
|
|
43990
|
-
var _a2, _b;
|
|
44019
|
+
var _a2, _b, _c;
|
|
43991
44020
|
const previous = this.state.view;
|
|
44021
|
+
const snapshotAt = (_a2 = view.snapshot) == null ? void 0 : _a2.at;
|
|
44022
|
+
if (view.engine === "stopped" || view.engine === "crashed") {
|
|
44023
|
+
this.clearViewTimer();
|
|
44024
|
+
} else if (this.ws && (snapshotAt !== void 0 && snapshotAt !== this.lastSnapshotAt || (previous == null ? void 0 : previous.engine) === "stopped" || (previous == null ? void 0 : previous.engine) === "crashed")) {
|
|
44025
|
+
this.watchForView(this.ws);
|
|
44026
|
+
}
|
|
44027
|
+
if (snapshotAt !== void 0) this.lastSnapshotAt = snapshotAt;
|
|
43992
44028
|
const lost = view.sessionLost ?? null;
|
|
43993
44029
|
const newlyLost = Boolean(lost) && !(previous == null ? void 0 : previous.sessionLost);
|
|
43994
44030
|
if (newlyLost) {
|
|
43995
44031
|
this.session = null;
|
|
43996
44032
|
this.log(`o Callix derrubou a sessão: ${(lost == null ? void 0 : lost.message) ?? ""}`);
|
|
43997
44033
|
}
|
|
43998
|
-
const user = (
|
|
44034
|
+
const user = (_b = view.snapshot) == null ? void 0 : _b.leg.user;
|
|
43999
44035
|
this.userSignal.set(user ? { ...user, sessionId: 0 } : void 0);
|
|
44000
|
-
const call = (
|
|
44036
|
+
const call = (_c = view.snapshot) == null ? void 0 : _c.leg.call;
|
|
44001
44037
|
const patch = { view, sessionLost: lost ? { originator: lost.originator, message: lost.message } : null };
|
|
44038
|
+
if (this.connectionError && this.state.lastError === this.connectionError) patch.lastError = null;
|
|
44039
|
+
this.connectionError = null;
|
|
44002
44040
|
if (call && typeof call.muted === "boolean" && call.muted !== this.state.inputMuted && call.state !== "ended") patch.inputMuted = call.muted;
|
|
44003
44041
|
this.setState(patch);
|
|
44004
44042
|
for (const waiter of this.viewWaiters.splice(0)) {
|
|
44043
|
+
if (this.state.wsState !== "open" || !this.state.tabId) {
|
|
44044
|
+
this.viewWaiters.push(waiter);
|
|
44045
|
+
continue;
|
|
44046
|
+
}
|
|
44005
44047
|
if (waiter.accept && !waiter.accept(view)) {
|
|
44006
44048
|
this.viewWaiters.push(waiter);
|
|
44007
44049
|
continue;
|
|
@@ -44087,6 +44129,7 @@ class EngineClient {
|
|
|
44087
44129
|
}
|
|
44088
44130
|
command(command) {
|
|
44089
44131
|
if (this.ws && this.ws.readyState === WebSocket.OPEN && this.state.tabId) {
|
|
44132
|
+
this.setState({ lastError: null });
|
|
44090
44133
|
this.send({ type: "command", command });
|
|
44091
44134
|
this.log(`comando: ${command.name}${command.phone ? ` ${command.phone}` : ""}`);
|
|
44092
44135
|
return;
|
|
@@ -44094,7 +44137,8 @@ class EngineClient {
|
|
|
44094
44137
|
this.pendingCommands.push({ command, at: Date.now() });
|
|
44095
44138
|
if (this.pendingCommands.length > PENDING_COMMANDS_MAX) this.pendingCommands.shift();
|
|
44096
44139
|
this.log(`comando: ${command.name} guardado até a conexão com o motor voltar`);
|
|
44097
|
-
this.
|
|
44140
|
+
this.connectionError = "Sem conexão com o motor neste momento; o comando será enviado assim que ela voltar.";
|
|
44141
|
+
this.setState({ lastError: this.connectionError });
|
|
44098
44142
|
this.connect();
|
|
44099
44143
|
}
|
|
44100
44144
|
/** manda os comandos guardados que ainda fazem sentido (os velhos poderiam atingir outra chamada) */
|
|
@@ -44356,13 +44400,13 @@ class EngineCall {
|
|
|
44356
44400
|
return Math.max(0, Math.floor((Date.now() - from) / 1e3));
|
|
44357
44401
|
}
|
|
44358
44402
|
answer() {
|
|
44359
|
-
this.client
|
|
44403
|
+
engineCommand(this.client, { name: "answer" });
|
|
44360
44404
|
}
|
|
44361
44405
|
reject() {
|
|
44362
|
-
this.client
|
|
44406
|
+
engineCommand(this.client, { name: "reject" });
|
|
44363
44407
|
}
|
|
44364
44408
|
hangup() {
|
|
44365
|
-
this.client
|
|
44409
|
+
engineCommand(this.client, { name: "hangup" });
|
|
44366
44410
|
}
|
|
44367
44411
|
isOnHold() {
|
|
44368
44412
|
return { local: false, remote: false };
|
|
@@ -44381,7 +44425,7 @@ class EngineCall {
|
|
|
44381
44425
|
this.client.setInputMuted(false);
|
|
44382
44426
|
}
|
|
44383
44427
|
sendDtmf(tones) {
|
|
44384
|
-
this.client
|
|
44428
|
+
engineCommand(this.client, { name: "dtmf", tones });
|
|
44385
44429
|
}
|
|
44386
44430
|
on(event, listener) {
|
|
44387
44431
|
let set = this.listeners.get(event);
|
|
@@ -44417,10 +44461,12 @@ class EngineCall {
|
|
|
44417
44461
|
}
|
|
44418
44462
|
}
|
|
44419
44463
|
function operatorStateFromView(view, call) {
|
|
44420
|
-
var _a2, _b, _c;
|
|
44464
|
+
var _a2, _b, _c, _d, _e;
|
|
44421
44465
|
if (!view) return void 0;
|
|
44422
|
-
if (((_a2 = view.
|
|
44423
|
-
|
|
44466
|
+
if (view.logoffError || ((_a2 = view.snapshot) == null ? void 0 : _a2.leg.logoffError)) return { state: "startupError", error: "unknownError" };
|
|
44467
|
+
if (view.loggingOff || ((_b = view.snapshot) == null ? void 0 : _b.leg.loggingOff)) return { state: "starting" };
|
|
44468
|
+
if (((_c = view.sessionLost) == null ? void 0 : _c.originator) === "anotherDevice") return { state: "startupError", error: "userIsAlreadyConnectedOnAnotherDevice" };
|
|
44469
|
+
const leg = (_d = view.snapshot) == null ? void 0 : _d.leg;
|
|
44424
44470
|
if (!leg) {
|
|
44425
44471
|
if (view.engine === "starting") return { state: "starting" };
|
|
44426
44472
|
if (view.engine === "running") return { state: "starting" };
|
|
@@ -44435,7 +44481,7 @@ function operatorStateFromView(view, call) {
|
|
|
44435
44481
|
case "ringing":
|
|
44436
44482
|
return { state: "callRinging", call: asCall };
|
|
44437
44483
|
case "dialing":
|
|
44438
|
-
return ((
|
|
44484
|
+
return ((_e = leg.call) == null ? void 0 : _e.state) === "ringing" ? { state: "manualCallRinging", call: asCall } : { state: "manualCallSetup", call: asCall };
|
|
44439
44485
|
case "inCall":
|
|
44440
44486
|
return { state: "callInProgress", call: asCall };
|
|
44441
44487
|
case "afterCall":
|
|
@@ -44448,6 +44494,30 @@ function operatorStateFromView(view, call) {
|
|
|
44448
44494
|
return { state: "startupError", error: "unknownError" };
|
|
44449
44495
|
}
|
|
44450
44496
|
}
|
|
44497
|
+
function operatorStateFromClientState(state, call) {
|
|
44498
|
+
if (state.wsState !== "open" || !state.tabId || !state.view) return { state: "starting" };
|
|
44499
|
+
if (state.rejected) return { state: "startupError", error: "unknownError" };
|
|
44500
|
+
return operatorStateFromView(state.view, call);
|
|
44501
|
+
}
|
|
44502
|
+
function assertEngineCommand(client2, allowDisconnected = false) {
|
|
44503
|
+
var _a2, _b, _c, _d;
|
|
44504
|
+
const state = client2.getState();
|
|
44505
|
+
const view = state.view;
|
|
44506
|
+
const error2 = ((_a2 = state.rejected) == null ? void 0 : _a2.message) ?? ((_b = state.sessionLost) == null ? void 0 : _b.message) ?? (view == null ? void 0 : view.logoffError) ?? ((_c = view == null ? void 0 : view.snapshot) == null ? void 0 : _c.leg.logoffError);
|
|
44507
|
+
if (error2) throw new Error(error2);
|
|
44508
|
+
if ((view == null ? void 0 : view.loggingOff) || ((_d = view == null ? void 0 : view.snapshot) == null ? void 0 : _d.leg.loggingOff)) throw new Error("Aguarde o encerramento da sessão antes de usar o discador.");
|
|
44509
|
+
if (state.wsState !== "open" || !state.tabId || !view) {
|
|
44510
|
+
if (allowDisconnected) return;
|
|
44511
|
+
throw new Error("Sem conexão com o motor. Aguarde a reconexão antes de usar o discador.");
|
|
44512
|
+
}
|
|
44513
|
+
if (view.engine !== "running" || !view.snapshot || view.snapshot.leg.status === "offline" || view.snapshot.leg.status === "error" || view.snapshot.leg.status === "starting") {
|
|
44514
|
+
throw new Error("O atendimento ainda não está conectado ao Callix. Aguarde antes de usar o discador.");
|
|
44515
|
+
}
|
|
44516
|
+
}
|
|
44517
|
+
function engineCommand(client2, command) {
|
|
44518
|
+
assertEngineCommand(client2, command.name === "hangup");
|
|
44519
|
+
client2.command(command);
|
|
44520
|
+
}
|
|
44451
44521
|
function callInfoFromView(view) {
|
|
44452
44522
|
var _a2;
|
|
44453
44523
|
const leg = (_a2 = view == null ? void 0 : view.snapshot) == null ? void 0 : _a2.leg;
|
|
@@ -44479,9 +44549,9 @@ function callInfoFromView(view) {
|
|
|
44479
44549
|
return { type: "manual", info: { successQualifications, discardQualifications } };
|
|
44480
44550
|
}
|
|
44481
44551
|
function useEngineCall(client2) {
|
|
44482
|
-
var _a2, _b;
|
|
44552
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
44483
44553
|
const state = useEngineState(client2);
|
|
44484
|
-
const snapshot = ((_b = (
|
|
44554
|
+
const snapshot = state.wsState === "open" && state.tabId && !((_a2 = state.view) == null ? void 0 : _a2.logoffError) && !((_b = state.view) == null ? void 0 : _b.loggingOff) && !((_d = (_c = state.view) == null ? void 0 : _c.snapshot) == null ? void 0 : _d.leg.logoffError) && !((_f = (_e = state.view) == null ? void 0 : _e.snapshot) == null ? void 0 : _f.leg.loggingOff) ? ((_h = (_g = state.view) == null ? void 0 : _g.snapshot) == null ? void 0 : _h.leg.call) ?? null : null;
|
|
44485
44555
|
const ref = useRef(null);
|
|
44486
44556
|
if (!snapshot || snapshot.state === "ended") {
|
|
44487
44557
|
ref.current = null;
|
|
@@ -44495,7 +44565,7 @@ function useEngineCall(client2) {
|
|
|
44495
44565
|
function useEngineOperatorState(client2) {
|
|
44496
44566
|
const state = useEngineState(client2);
|
|
44497
44567
|
const call = useEngineCall(client2);
|
|
44498
|
-
return useMemo(() =>
|
|
44568
|
+
return useMemo(() => operatorStateFromClientState(state, call), [state, call]);
|
|
44499
44569
|
}
|
|
44500
44570
|
function useEngineCurrentCall(client2) {
|
|
44501
44571
|
const call = useEngineCall(client2);
|
|
@@ -44520,15 +44590,16 @@ function useEngineControls(client2) {
|
|
|
44520
44590
|
() => ({
|
|
44521
44591
|
becomeAvailable: () => {
|
|
44522
44592
|
var _a2, _b;
|
|
44593
|
+
assertEngineCommand(client2);
|
|
44523
44594
|
const status = (_b = (_a2 = client2.getState().view) == null ? void 0 : _a2.snapshot) == null ? void 0 : _b.leg.status;
|
|
44524
|
-
if (status === "onBreak") client2
|
|
44595
|
+
if (status === "onBreak") engineCommand(client2, { name: "resume" });
|
|
44525
44596
|
},
|
|
44526
44597
|
goOffline: () => void 0,
|
|
44527
|
-
enterOnBreak: (breakId) => client2
|
|
44528
|
-
makeManualCall: (phoneNumber) => client2
|
|
44598
|
+
enterOnBreak: (breakId) => engineCommand(client2, pauseCommand(breakId)),
|
|
44599
|
+
makeManualCall: (phoneNumber) => engineCommand(client2, { name: "dial", phone: phoneNumber }),
|
|
44529
44600
|
finishAfterCall: (data) => {
|
|
44530
|
-
if (typeof data.qualificationId === "number") client2
|
|
44531
|
-
else client2
|
|
44601
|
+
if (typeof data.qualificationId === "number") engineCommand(client2, { name: "qualify", qualificationId: data.qualificationId, result: data.result === "failure" ? "discard" : "success" });
|
|
44602
|
+
else engineCommand(client2, { name: "finish" });
|
|
44532
44603
|
}
|
|
44533
44604
|
}),
|
|
44534
44605
|
[client2]
|
|
@@ -44537,9 +44608,9 @@ function useEngineControls(client2) {
|
|
|
44537
44608
|
function useEngineCurrentCallControls(client2) {
|
|
44538
44609
|
return useMemo(
|
|
44539
44610
|
() => ({
|
|
44540
|
-
answer: () => client2
|
|
44541
|
-
reject: () => client2
|
|
44542
|
-
hangup: () => client2
|
|
44611
|
+
answer: () => engineCommand(client2, { name: "answer" }),
|
|
44612
|
+
reject: () => engineCommand(client2, { name: "reject" }),
|
|
44613
|
+
hangup: () => engineCommand(client2, { name: "hangup" }),
|
|
44543
44614
|
isOnHold: () => ({ local: false, remote: false }),
|
|
44544
44615
|
hold: async () => void 0,
|
|
44545
44616
|
unhold: async () => void 0,
|
|
@@ -44592,13 +44663,14 @@ function engineOperator(client2) {
|
|
|
44592
44663
|
goOffline: () => void 0,
|
|
44593
44664
|
becomeAvailable: () => {
|
|
44594
44665
|
var _a2, _b;
|
|
44595
|
-
|
|
44666
|
+
assertEngineCommand(client2);
|
|
44667
|
+
if (((_b = (_a2 = client2.getState().view) == null ? void 0 : _a2.snapshot) == null ? void 0 : _b.leg.status) === "onBreak") engineCommand(client2, { name: "resume" });
|
|
44596
44668
|
},
|
|
44597
|
-
enterOnBreak: (breakId) => client2
|
|
44598
|
-
makeManualCall: (phoneNumber) => client2
|
|
44669
|
+
enterOnBreak: (breakId) => engineCommand(client2, pauseCommand(breakId)),
|
|
44670
|
+
makeManualCall: (phoneNumber) => engineCommand(client2, { name: "dial", phone: phoneNumber }),
|
|
44599
44671
|
finishAfterCall: (data) => {
|
|
44600
|
-
if (typeof data.qualificationId === "number") client2
|
|
44601
|
-
else client2
|
|
44672
|
+
if (typeof data.qualificationId === "number") engineCommand(client2, { name: "qualify", qualificationId: data.qualificationId, result: data.result === "failure" ? "discard" : "success" });
|
|
44673
|
+
else engineCommand(client2, { name: "finish" });
|
|
44602
44674
|
}
|
|
44603
44675
|
};
|
|
44604
44676
|
operators.set(client2, operator);
|
|
@@ -57872,8 +57944,14 @@ function LiveCaptionPanelInner({ client: client2, maxLines }) {
|
|
|
57872
57944
|
] });
|
|
57873
57945
|
}
|
|
57874
57946
|
function useDialerNotices(options = {}) {
|
|
57947
|
+
var _a2, _b, _c;
|
|
57875
57948
|
const operatorState = useCallOperatorState();
|
|
57876
57949
|
const currentCall = useCallOperatorCurrentCall();
|
|
57950
|
+
const engine = useEngineClient();
|
|
57951
|
+
const subscribeEngine = useCallback((listener) => engine ? engine.subscribe(listener) : () => {
|
|
57952
|
+
}, [engine]);
|
|
57953
|
+
const readEngine = useCallback(() => (engine == null ? void 0 : engine.getState()) ?? null, [engine]);
|
|
57954
|
+
const engineState = useSyncExternalStore(subscribeEngine, readEngine, readEngine);
|
|
57877
57955
|
const [deviceIssue, setDeviceIssue] = useState(null);
|
|
57878
57956
|
const [sessionDrop, setSessionDrop] = useState(null);
|
|
57879
57957
|
const [callFailure, setCallFailure] = useState(null);
|
|
@@ -57886,7 +57964,7 @@ function useDialerNotices(options = {}) {
|
|
|
57886
57964
|
setDeviceIssue(issue);
|
|
57887
57965
|
}, [options.checkDevices]);
|
|
57888
57966
|
useEffect(() => {
|
|
57889
|
-
var
|
|
57967
|
+
var _a3;
|
|
57890
57968
|
if (options.checkDevices === false) return;
|
|
57891
57969
|
let cancelled = false;
|
|
57892
57970
|
const run = async () => {
|
|
@@ -57896,11 +57974,11 @@ function useDialerNotices(options = {}) {
|
|
|
57896
57974
|
void run();
|
|
57897
57975
|
const mediaDevices = typeof navigator !== "undefined" ? navigator.mediaDevices : void 0;
|
|
57898
57976
|
const handler = () => void run();
|
|
57899
|
-
(
|
|
57977
|
+
(_a3 = mediaDevices == null ? void 0 : mediaDevices.addEventListener) == null ? void 0 : _a3.call(mediaDevices, "devicechange", handler);
|
|
57900
57978
|
return () => {
|
|
57901
|
-
var
|
|
57979
|
+
var _a4;
|
|
57902
57980
|
cancelled = true;
|
|
57903
|
-
(
|
|
57981
|
+
(_a4 = mediaDevices == null ? void 0 : mediaDevices.removeEventListener) == null ? void 0 : _a4.call(mediaDevices, "devicechange", handler);
|
|
57904
57982
|
};
|
|
57905
57983
|
}, [options.checkDevices]);
|
|
57906
57984
|
useCallOperatorEventListener("userSessionDropped", (data) => {
|
|
@@ -57909,8 +57987,8 @@ function useDialerNotices(options = {}) {
|
|
|
57909
57987
|
useEffect(() => {
|
|
57910
57988
|
if (!(currentCall == null ? void 0 : currentCall.on)) return;
|
|
57911
57989
|
const handleFailed = (event) => {
|
|
57912
|
-
var
|
|
57913
|
-
const failure = (event == null ? void 0 : event.failure) ?? ((
|
|
57990
|
+
var _a3;
|
|
57991
|
+
const failure = (event == null ? void 0 : event.failure) ?? ((_a3 = currentCall.toCallData) == null ? void 0 : _a3.call(currentCall).failure) ?? null;
|
|
57914
57992
|
setCallFailure(failure ?? { cause: null });
|
|
57915
57993
|
setDismissedCode(null);
|
|
57916
57994
|
if (failureTimer.current) clearTimeout(failureTimer.current);
|
|
@@ -57918,14 +57996,14 @@ function useDialerNotices(options = {}) {
|
|
|
57918
57996
|
};
|
|
57919
57997
|
currentCall.on("failed", handleFailed);
|
|
57920
57998
|
return () => {
|
|
57921
|
-
var
|
|
57922
|
-
(
|
|
57999
|
+
var _a3;
|
|
58000
|
+
(_a3 = currentCall.off) == null ? void 0 : _a3.call(currentCall, "failed", handleFailed);
|
|
57923
58001
|
};
|
|
57924
58002
|
}, [currentCall, ttl]);
|
|
57925
58003
|
useEffect(() => {
|
|
57926
|
-
var
|
|
58004
|
+
var _a3, _b2;
|
|
57927
58005
|
if ((operatorState == null ? void 0 : operatorState.state) !== "manualCallFailed") return;
|
|
57928
|
-
const failure = ((
|
|
58006
|
+
const failure = ((_b2 = (_a3 = operatorState.call) == null ? void 0 : _a3.toCallData) == null ? void 0 : _b2.call(_a3).failure) ?? null;
|
|
57929
58007
|
setCallFailure((current) => current ?? failure ?? { cause: null });
|
|
57930
58008
|
setDismissedCode(null);
|
|
57931
58009
|
}, [operatorState]);
|
|
@@ -57938,13 +58016,26 @@ function useDialerNotices(options = {}) {
|
|
|
57938
58016
|
useEffect(() => () => {
|
|
57939
58017
|
if (failureTimer.current) clearTimeout(failureTimer.current);
|
|
57940
58018
|
}, []);
|
|
57941
|
-
|
|
58019
|
+
let notice = pickNotice({
|
|
57942
58020
|
deviceIssue,
|
|
57943
58021
|
operatorState: (operatorState == null ? void 0 : operatorState.state) ?? null,
|
|
57944
58022
|
startupError: (operatorState == null ? void 0 : operatorState.state) === "startupError" ? operatorState.error ?? null : null,
|
|
57945
58023
|
sessionDrop,
|
|
57946
58024
|
callFailure
|
|
57947
58025
|
});
|
|
58026
|
+
const logoffError = ((_a2 = engineState == null ? void 0 : engineState.view) == null ? void 0 : _a2.logoffError) ?? ((_c = (_b = engineState == null ? void 0 : engineState.view) == null ? void 0 : _b.snapshot) == null ? void 0 : _c.leg.logoffError);
|
|
58027
|
+
const reconnecting = Boolean(engineState && (engineState.wsState !== "open" || !engineState.tabId));
|
|
58028
|
+
const engineError = logoffError ?? (engineState == null ? void 0 : engineState.lastError);
|
|
58029
|
+
if (engineState && !sessionDrop && (engineError || reconnecting)) {
|
|
58030
|
+
notice = {
|
|
58031
|
+
level: "error",
|
|
58032
|
+
source: "offline",
|
|
58033
|
+
title: logoffError ? "Saída não concluída" : reconnecting ? "Reconectando ao discador" : "Comando não concluído",
|
|
58034
|
+
detail: engineError || "Aguardando a conexão e o estado atual do motor.",
|
|
58035
|
+
action: logoffError ? "Clique em Sair novamente para concluir o encerramento da sessão." : reconnecting ? "Aguarde a conexão voltar antes de ligar." : "Confira o estado do discador e tente novamente.",
|
|
58036
|
+
code: logoffError ? "engine:logoff" : reconnecting ? "engine:reconnecting" : "engine:command"
|
|
58037
|
+
};
|
|
58038
|
+
}
|
|
57948
58039
|
const visible = notice && notice.code !== dismissedCode ? notice : null;
|
|
57949
58040
|
const dismiss = useCallback(() => {
|
|
57950
58041
|
if (!notice) return;
|
|
@@ -58778,7 +58869,7 @@ function AuthenticatedMobileDialer({
|
|
|
58778
58869
|
showClientInfoModal = false,
|
|
58779
58870
|
density
|
|
58780
58871
|
}) {
|
|
58781
|
-
var _a2, _b, _c, _d, _e
|
|
58872
|
+
var _a2, _b, _c, _d, _e;
|
|
58782
58873
|
const { skipManualQualification } = useDialerConfig();
|
|
58783
58874
|
const [dialValue, setDialValue] = useState("");
|
|
58784
58875
|
const [activeScreen, setActiveScreen] = useState("dialer");
|
|
@@ -58792,7 +58883,6 @@ function AuthenticatedMobileDialer({
|
|
|
58792
58883
|
const [isClientInfoModalOpen, setIsClientInfoModalOpen] = useState(false);
|
|
58793
58884
|
const [isDebugPanelOpen, setIsDebugPanelOpen] = useState(false);
|
|
58794
58885
|
useDebugLogger();
|
|
58795
|
-
const [currentBreakName, setCurrentBreakName] = useState(null);
|
|
58796
58886
|
const [pauseStartTime, setPauseStartTime] = useState(null);
|
|
58797
58887
|
const [pauseDurationSeconds, setPauseDurationSeconds] = useState(0);
|
|
58798
58888
|
const [contactData, setContactData] = useState({
|
|
@@ -58828,6 +58918,10 @@ function AuthenticatedMobileDialer({
|
|
|
58828
58918
|
const breaks = useSignal(operator == null ? void 0 : operator.breaks) || [];
|
|
58829
58919
|
const userData = useSignal(operator == null ? void 0 : operator.user);
|
|
58830
58920
|
const isOnBreak = (operatorState == null ? void 0 : operatorState.state) === "onBreak";
|
|
58921
|
+
const activeBreak = (operatorState == null ? void 0 : operatorState.state) === "onBreak" ? operatorState.break : void 0;
|
|
58922
|
+
const activeBreakId = activeBreak == null ? void 0 : activeBreak.id;
|
|
58923
|
+
const hasConfirmedPauseState = isOnBreak || ["idle", "manualCallSetup", "manualCallRinging", "manualCallFailed", "callRinging", "callInProgress", "afterCall"].includes((operatorState == null ? void 0 : operatorState.state) ?? "");
|
|
58924
|
+
const previousBreakRef = useRef({ isOnBreak, id: activeBreakId, confirmed: hasConfirmedPauseState });
|
|
58831
58925
|
const [inputMuted, setInputMuted] = useCallOperatorAudioInputMuted();
|
|
58832
58926
|
const haptic = useHaptic();
|
|
58833
58927
|
const dtmf = useDTMF({ enabled: true });
|
|
@@ -58927,8 +59021,12 @@ function AuthenticatedMobileDialer({
|
|
|
58927
59021
|
const INITIAL_BREAK_ID = 5;
|
|
58928
59022
|
const INITIAL_BREAK_NAME = "Reunião";
|
|
58929
59023
|
const callState = operatorState == null ? void 0 : operatorState.state;
|
|
58930
|
-
const hasEnteredInitialBreakRef = useRef(
|
|
59024
|
+
const hasEnteredInitialBreakRef = useRef(isOnBreak);
|
|
58931
59025
|
useEffect(() => {
|
|
59026
|
+
if (isOnBreak) {
|
|
59027
|
+
hasEnteredInitialBreakRef.current = true;
|
|
59028
|
+
return;
|
|
59029
|
+
}
|
|
58932
59030
|
if (breaks.length === 0 || callState !== "idle" || hasEnteredInitialBreakRef.current || isOnBreak) {
|
|
58933
59031
|
return;
|
|
58934
59032
|
}
|
|
@@ -58941,10 +59039,8 @@ function AuthenticatedMobileDialer({
|
|
|
58941
59039
|
);
|
|
58942
59040
|
if (reuniaoBreak) {
|
|
58943
59041
|
console.log("[MobileDialer] Operador conectado (idle), entrando em pausa inicial:", reuniaoBreak.name);
|
|
58944
|
-
Promise.resolve(goOnBreak(reuniaoBreak.id)).then(() => {
|
|
58945
|
-
console.log("[MobileDialer] Pausa inicial
|
|
58946
|
-
setCurrentBreakName(reuniaoBreak.name);
|
|
58947
|
-
setPauseStartTime(Date.now());
|
|
59042
|
+
Promise.resolve().then(() => goOnBreak(reuniaoBreak.id)).then(() => {
|
|
59043
|
+
console.log("[MobileDialer] Pausa inicial solicitada:", reuniaoBreak.name);
|
|
58948
59044
|
}).catch((err) => {
|
|
58949
59045
|
console.error("[MobileDialer] Falha ao entrar em pausa:", err);
|
|
58950
59046
|
hasEnteredInitialBreakRef.current = false;
|
|
@@ -58952,10 +59048,8 @@ function AuthenticatedMobileDialer({
|
|
|
58952
59048
|
} else {
|
|
58953
59049
|
const firstBreak = breaks[0];
|
|
58954
59050
|
console.log('[MobileDialer] Pausa "Reunião" não encontrada, usando:', firstBreak.name);
|
|
58955
|
-
Promise.resolve(goOnBreak(firstBreak.id)).then(() => {
|
|
58956
|
-
console.log("[MobileDialer] Pausa inicial
|
|
58957
|
-
setCurrentBreakName(firstBreak.name);
|
|
58958
|
-
setPauseStartTime(Date.now());
|
|
59051
|
+
Promise.resolve().then(() => goOnBreak(firstBreak.id)).then(() => {
|
|
59052
|
+
console.log("[MobileDialer] Pausa inicial solicitada:", firstBreak.name);
|
|
58959
59053
|
}).catch((err) => {
|
|
58960
59054
|
console.error("[MobileDialer] Falha ao entrar em pausa:", err);
|
|
58961
59055
|
hasEnteredInitialBreakRef.current = false;
|
|
@@ -59037,7 +59131,8 @@ function AuthenticatedMobileDialer({
|
|
|
59037
59131
|
const { notice: dialerNotice, dismiss: dismissDialerNotice, recheckDevices } = useDialerNotices();
|
|
59038
59132
|
const [noticeHeight, setNoticeHeight] = useState(0);
|
|
59039
59133
|
const isError = callStateStr === "startupError" || callStateStr === "offline" || (dialerNotice == null ? void 0 : dialerNotice.source) === "device" || (dialerNotice == null ? void 0 : dialerNotice.source) === "session";
|
|
59040
|
-
const
|
|
59134
|
+
const isReconnecting = !callStateStr || callStateStr === "starting";
|
|
59135
|
+
const isIdle = callStateStr === "idle" || callStateStr === "onBreak";
|
|
59041
59136
|
const isConnecting = callState === "manualCallSetup" || callState === "manualCallRinging" || callState === "callRinging";
|
|
59042
59137
|
const isInCall = callState === "callInProgress";
|
|
59043
59138
|
const isAfterCall = callState === "afterCall";
|
|
@@ -59070,22 +59165,32 @@ function AuthenticatedMobileDialer({
|
|
|
59070
59165
|
return () => clearInterval(interval);
|
|
59071
59166
|
}, [isInCall]);
|
|
59072
59167
|
useEffect(() => {
|
|
59073
|
-
|
|
59168
|
+
const previous = previousBreakRef.current;
|
|
59169
|
+
if (!hasConfirmedPauseState) {
|
|
59170
|
+
previousBreakRef.current = { ...previous, confirmed: false };
|
|
59074
59171
|
return;
|
|
59075
59172
|
}
|
|
59076
|
-
|
|
59077
|
-
|
|
59078
|
-
setPauseDurationSeconds(elapsed);
|
|
59079
|
-
}, 1e3);
|
|
59080
|
-
return () => clearInterval(interval);
|
|
59081
|
-
}, [isOnBreak, pauseStartTime]);
|
|
59082
|
-
useEffect(() => {
|
|
59083
|
-
if (!isOnBreak && currentBreakName) {
|
|
59084
|
-
setCurrentBreakName(null);
|
|
59173
|
+
previousBreakRef.current = { isOnBreak, id: activeBreakId, confirmed: true };
|
|
59174
|
+
if (!isOnBreak) {
|
|
59085
59175
|
setPauseStartTime(null);
|
|
59086
59176
|
setPauseDurationSeconds(0);
|
|
59177
|
+
} else if (previous.confirmed && !previous.isOnBreak || previous.isOnBreak && previous.id !== activeBreakId) {
|
|
59178
|
+
setPauseStartTime(Date.now());
|
|
59179
|
+
setPauseDurationSeconds(0);
|
|
59087
59180
|
}
|
|
59088
|
-
}, [isOnBreak,
|
|
59181
|
+
}, [isOnBreak, activeBreakId, hasConfirmedPauseState]);
|
|
59182
|
+
useEffect(() => {
|
|
59183
|
+
if (!isOnBreak || pauseStartTime === null) {
|
|
59184
|
+
return;
|
|
59185
|
+
}
|
|
59186
|
+
const update2 = () => {
|
|
59187
|
+
const elapsed = Math.max(0, Math.floor((Date.now() - pauseStartTime) / 1e3));
|
|
59188
|
+
setPauseDurationSeconds(elapsed);
|
|
59189
|
+
};
|
|
59190
|
+
update2();
|
|
59191
|
+
const interval = setInterval(update2, 1e3);
|
|
59192
|
+
return () => clearInterval(interval);
|
|
59193
|
+
}, [isOnBreak, pauseStartTime]);
|
|
59089
59194
|
useEffect(() => {
|
|
59090
59195
|
const onClickToCall = (event) => {
|
|
59091
59196
|
const task = event.detail;
|
|
@@ -59211,6 +59316,7 @@ function AuthenticatedMobileDialer({
|
|
|
59211
59316
|
setDialValue((prev) => prev.slice(0, -1));
|
|
59212
59317
|
}, [haptic]);
|
|
59213
59318
|
const handleCall = useCallback(async () => {
|
|
59319
|
+
if (!isIdle) return;
|
|
59214
59320
|
console.log("[MobileDialer] handleCall triggered, dialValue:", dialValue);
|
|
59215
59321
|
addLog("event", "Call", "📞 Iniciando chamada manual", { dialValue });
|
|
59216
59322
|
const sanitized = sanitizeInput(dialValue);
|
|
@@ -59243,7 +59349,7 @@ function AuthenticatedMobileDialer({
|
|
|
59243
59349
|
setCallError("Erro ao iniciar chamada.");
|
|
59244
59350
|
haptic.notificationError();
|
|
59245
59351
|
}
|
|
59246
|
-
}, [dialValue, makeManualCall, sanitizeInput, haptic]);
|
|
59352
|
+
}, [dialValue, makeManualCall, sanitizeInput, haptic, isIdle]);
|
|
59247
59353
|
const handleHangup = useCallback(async () => {
|
|
59248
59354
|
if (!hangup) return;
|
|
59249
59355
|
addLog("event", "Call", "📴 Encerrando chamada");
|
|
@@ -59415,28 +59521,21 @@ function AuthenticatedMobileDialer({
|
|
|
59415
59521
|
async (breakId) => {
|
|
59416
59522
|
if (!goOnBreak) return;
|
|
59417
59523
|
try {
|
|
59418
|
-
const selectedBreak = breaks.find((b) => b.id === breakId);
|
|
59419
59524
|
await goOnBreak(breakId);
|
|
59420
59525
|
haptic.notificationSuccess();
|
|
59421
|
-
setCurrentBreakName((selectedBreak == null ? void 0 : selectedBreak.name) ?? "Em pausa");
|
|
59422
|
-
setPauseStartTime(Date.now());
|
|
59423
|
-
setPauseDurationSeconds(0);
|
|
59424
59526
|
setIsPauseModalOpen(false);
|
|
59425
59527
|
} catch (error2) {
|
|
59426
59528
|
console.error("Erro ao entrar em pausa", error2);
|
|
59427
59529
|
haptic.notificationError();
|
|
59428
59530
|
}
|
|
59429
59531
|
},
|
|
59430
|
-
[goOnBreak,
|
|
59532
|
+
[goOnBreak, haptic]
|
|
59431
59533
|
);
|
|
59432
59534
|
const handleGoOffBreak = useCallback(async () => {
|
|
59433
59535
|
if (!goOffBreak) return;
|
|
59434
59536
|
try {
|
|
59435
59537
|
await goOffBreak();
|
|
59436
59538
|
haptic.notificationSuccess();
|
|
59437
|
-
setCurrentBreakName(null);
|
|
59438
|
-
setPauseStartTime(null);
|
|
59439
|
-
setPauseDurationSeconds(0);
|
|
59440
59539
|
setIsPauseModalOpen(false);
|
|
59441
59540
|
} catch (error2) {
|
|
59442
59541
|
console.error("Erro ao sair de pausa", error2);
|
|
@@ -59482,6 +59581,7 @@ function AuthenticatedMobileDialer({
|
|
|
59482
59581
|
return activeCallNumber ? formatPhoneForDisplay(activeCallNumber) : "(--) ----- ----";
|
|
59483
59582
|
}, [callInfo, formattedDial, activeCallNumber]);
|
|
59484
59583
|
const callStatusLabel = useMemo(() => {
|
|
59584
|
+
if (isReconnecting) return "Conectando...";
|
|
59485
59585
|
if (isConnecting) return "Ligando...";
|
|
59486
59586
|
if (isInCall) return "Em chamada";
|
|
59487
59587
|
if (isAfterCall) return "Encerrando...";
|
|
@@ -59489,19 +59589,22 @@ function AuthenticatedMobileDialer({
|
|
|
59489
59589
|
if (isError) return (dialerNotice == null ? void 0 : dialerNotice.title) ?? "Erro de conexão";
|
|
59490
59590
|
if (isOnBreak) return "Em pausa";
|
|
59491
59591
|
return "Disponível";
|
|
59492
|
-
}, [callStateStr, dialerNotice, isAfterCall, isConnecting, isError, isInCall, isOnBreak]);
|
|
59592
|
+
}, [callStateStr, dialerNotice, isAfterCall, isConnecting, isError, isInCall, isOnBreak, isReconnecting]);
|
|
59493
59593
|
const statusBadgeClass = useMemo(() => {
|
|
59594
|
+
if (isReconnecting) return "connecting";
|
|
59494
59595
|
if (isError) return "error";
|
|
59495
59596
|
if (isOnBreak) return "paused";
|
|
59496
59597
|
return "available";
|
|
59497
|
-
}, [isError, isOnBreak]);
|
|
59498
|
-
const activeBreakName =
|
|
59598
|
+
}, [isError, isOnBreak, isReconnecting]);
|
|
59599
|
+
const activeBreakName = activeBreak == null ? void 0 : activeBreak.name;
|
|
59499
59600
|
const statusBadgeText = useMemo(() => {
|
|
59601
|
+
if (isReconnecting) return "Conectando";
|
|
59500
59602
|
if (isError) return (dialerNotice == null ? void 0 : dialerNotice.source) === "device" ? dialerNotice.title : "Erro";
|
|
59501
|
-
if (isOnBreak) return
|
|
59603
|
+
if (isOnBreak) return activeBreakName || "Em pausa";
|
|
59502
59604
|
return "Disponível";
|
|
59503
|
-
}, [dialerNotice, isError, isOnBreak,
|
|
59605
|
+
}, [dialerNotice, isError, isOnBreak, activeBreakName, isReconnecting]);
|
|
59504
59606
|
const pauseDurationLabel = useMemo(() => {
|
|
59607
|
+
if (pauseStartTime === null) return "--:--";
|
|
59505
59608
|
const hours = Math.floor(pauseDurationSeconds / 3600);
|
|
59506
59609
|
const minutes = Math.floor(pauseDurationSeconds % 3600 / 60).toString().padStart(2, "0");
|
|
59507
59610
|
const seconds = (pauseDurationSeconds % 60).toString().padStart(2, "0");
|
|
@@ -59509,7 +59612,7 @@ function AuthenticatedMobileDialer({
|
|
|
59509
59612
|
return `${hours}:${minutes}:${seconds}`;
|
|
59510
59613
|
}
|
|
59511
59614
|
return `${minutes}:${seconds}`;
|
|
59512
|
-
}, [pauseDurationSeconds]);
|
|
59615
|
+
}, [pauseDurationSeconds, pauseStartTime]);
|
|
59513
59616
|
const callDurationLabel = useMemo(() => {
|
|
59514
59617
|
const m = Math.floor(callDurationSeconds / 60).toString().padStart(2, "0");
|
|
59515
59618
|
const s = (callDurationSeconds % 60).toString().padStart(2, "0");
|
|
@@ -59550,7 +59653,7 @@ function AuthenticatedMobileDialer({
|
|
|
59550
59653
|
isOnBreak ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "resume-btn", id: "resumeBtn", onClick: handleGoOffBreak, children: [
|
|
59551
59654
|
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-play" }),
|
|
59552
59655
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Voltar" })
|
|
59553
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "pause-btn", id: "pauseBtn", onClick: () => setIsPauseModalOpen(true), children: [
|
|
59656
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "pause-btn", id: "pauseBtn", disabled: isReconnecting || callStateStr === "offline" || callStateStr === "startupError", onClick: () => setIsPauseModalOpen(true), children: [
|
|
59554
59657
|
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-pause" }),
|
|
59555
59658
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Pausa" })
|
|
59556
59659
|
] }),
|
|
@@ -59638,15 +59741,15 @@ function AuthenticatedMobileDialer({
|
|
|
59638
59741
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-card-header", children: [
|
|
59639
59742
|
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-user-circle client-avatar" }),
|
|
59640
59743
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-main-info", children: [
|
|
59641
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-name", id: "clientName", children: findValue(contactData.finalData, ["DECISOR", "NOME", "CLIENTE", "PROSPECT"]) ?? ((
|
|
59642
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-company", id: "clientCompany", children: findValue(contactData.finalData, ["EMPRESA", "RAZAO SOCIAL", "RAZÃO SOCIAL", "RAZAO_SOCIAL"]) ?? ((
|
|
59744
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-name", id: "clientName", children: findValue(contactData.finalData, ["DECISOR", "NOME", "CLIENTE", "PROSPECT"]) ?? ((_b = callInfo.info.campaignContact) == null ? void 0 : _b.label) ?? "--" }),
|
|
59745
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-company", id: "clientCompany", children: findValue(contactData.finalData, ["EMPRESA", "RAZAO SOCIAL", "RAZÃO SOCIAL", "RAZAO_SOCIAL"]) ?? ((_c = callInfo.info.campaign) == null ? void 0 : _c.name) ?? "--" })
|
|
59643
59746
|
] })
|
|
59644
59747
|
] }),
|
|
59645
59748
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "client-card-divider" }),
|
|
59646
59749
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-info-list", children: [
|
|
59647
59750
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-info-row", children: [
|
|
59648
59751
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-label", children: "Socio" }),
|
|
59649
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-value", children: findValue(contactData.finalData, ["SOCIO", "PROSPECT", "DECISOR", "NOME", "CLIENTE"]) ?? ((
|
|
59752
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-value", children: findValue(contactData.finalData, ["SOCIO", "PROSPECT", "DECISOR", "NOME", "CLIENTE"]) ?? ((_d = callInfo.info.campaignContact) == null ? void 0 : _d.label) ?? "--" })
|
|
59650
59753
|
] }),
|
|
59651
59754
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-info-row", children: [
|
|
59652
59755
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-label", children: "Empresa" }),
|
|
@@ -59843,7 +59946,7 @@ function AuthenticatedMobileDialer({
|
|
|
59843
59946
|
{
|
|
59844
59947
|
isOpen: isClientInfoModalOpen,
|
|
59845
59948
|
campaignCallInfo,
|
|
59846
|
-
campaignContactPhoneId: ((
|
|
59949
|
+
campaignContactPhoneId: ((_e = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _e.campaignContactPhoneId) ?? null,
|
|
59847
59950
|
callDuration: callDurationSeconds,
|
|
59848
59951
|
isCallActive: isInCall || isConnecting,
|
|
59849
59952
|
onClose: () => setIsClientInfoModalOpen(false)
|
|
@@ -60878,7 +60981,7 @@ function ClickToCallAgent({ enabled = true, pollIntervalMs, sessionToken, onTask
|
|
|
60878
60981
|
}, [enabled, pollIntervalMs, sessionToken]);
|
|
60879
60982
|
return null;
|
|
60880
60983
|
}
|
|
60881
|
-
const WIDGET_VERSION = "2.8.
|
|
60984
|
+
const WIDGET_VERSION = "2.8.5";
|
|
60882
60985
|
let currentSipWebSocket = null;
|
|
60883
60986
|
function sendSipUnregisterIfPossible(ws) {
|
|
60884
60987
|
if (ws.readyState !== WebSocket.OPEN) return;
|
|
@@ -61236,6 +61339,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
61236
61339
|
const [tabDecided, setTabDecided] = useState(false);
|
|
61237
61340
|
const [tabNote, setTabNote] = useState(null);
|
|
61238
61341
|
const [engineWaiting, setEngineWaiting] = useState(false);
|
|
61342
|
+
const [engineError, setEngineError] = useState(null);
|
|
61239
61343
|
const busRef = useRef(null);
|
|
61240
61344
|
const takeoverTimerRef = useRef(null);
|
|
61241
61345
|
const isAuthenticatedRef = useRef(false);
|
|
@@ -61388,6 +61492,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
61388
61492
|
[options.domain, options.apiUrl]
|
|
61389
61493
|
);
|
|
61390
61494
|
const enterEngine = useCallback(async (user, domain, token) => {
|
|
61495
|
+
var _a2, _b, _c, _d;
|
|
61391
61496
|
if (token) {
|
|
61392
61497
|
const skip = await fetchSkipQualification(domain, token);
|
|
61393
61498
|
if (skip !== null) {
|
|
@@ -61398,6 +61503,16 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
61398
61503
|
}
|
|
61399
61504
|
}
|
|
61400
61505
|
}
|
|
61506
|
+
const engineState = (_a2 = engineRef.current) == null ? void 0 : _a2.getState();
|
|
61507
|
+
if (!engineState || engineState.wsState !== "open" || !engineState.tabId || !engineState.view || engineState.rejected) {
|
|
61508
|
+
throw new Error("A conexão com o motor caiu. Aguarde a reconexão antes de entrar.");
|
|
61509
|
+
}
|
|
61510
|
+
if (engineState.view.engine !== "running" && engineState.view.engine !== "starting" || engineState.sessionLost || engineState.view.sessionLost) {
|
|
61511
|
+
throw new Error("A sessão do motor foi encerrada durante a entrada. Entre novamente.");
|
|
61512
|
+
}
|
|
61513
|
+
if (engineState.view.logoffError || engineState.view.loggingOff || ((_b = engineState.view.snapshot) == null ? void 0 : _b.leg.logoffError) || ((_c = engineState.view.snapshot) == null ? void 0 : _c.leg.loggingOff)) {
|
|
61514
|
+
throw new Error(engineState.view.logoffError || ((_d = engineState.view.snapshot) == null ? void 0 : _d.leg.logoffError) || "A sessão anterior ainda está sendo encerrada.");
|
|
61515
|
+
}
|
|
61401
61516
|
try {
|
|
61402
61517
|
localStorage.setItem(LAST_USERNAME_KEY, user);
|
|
61403
61518
|
if (token) {
|
|
@@ -61438,12 +61553,15 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
61438
61553
|
if (!engineMode || !username || isRestoringSession) return;
|
|
61439
61554
|
const user = username;
|
|
61440
61555
|
const client2 = ensureEngine(user);
|
|
61441
|
-
|
|
61556
|
+
const initial = client2.getState();
|
|
61557
|
+
setEngineWaiting(initial.wsState !== "open" || !initial.tabId || !initial.view);
|
|
61442
61558
|
const fallback = setTimeout(() => setEngineWaiting(false), 15e3);
|
|
61443
61559
|
let joining = false;
|
|
61444
61560
|
let rejectedNote = false;
|
|
61445
61561
|
const sync = () => {
|
|
61446
|
-
|
|
61562
|
+
var _a2;
|
|
61563
|
+
const { view, sessionLost, rejected, wsState, tabId, lastError } = client2.getState();
|
|
61564
|
+
setEngineError((view == null ? void 0 : view.logoffError) ?? ((_a2 = view == null ? void 0 : view.snapshot) == null ? void 0 : _a2.leg.logoffError) ?? lastError ?? null);
|
|
61447
61565
|
if (!rejected && rejectedNote) {
|
|
61448
61566
|
rejectedNote = false;
|
|
61449
61567
|
setTabNote(null);
|
|
@@ -61461,7 +61579,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
61461
61579
|
setTabNote(rejected.message);
|
|
61462
61580
|
return;
|
|
61463
61581
|
}
|
|
61464
|
-
if (!view) return;
|
|
61582
|
+
if (wsState !== "open" || !tabId || !view) return;
|
|
61465
61583
|
setEngineWaiting(false);
|
|
61466
61584
|
const hasSession = (view.engine === "running" || view.engine === "starting") && !sessionLost;
|
|
61467
61585
|
if (hasSession && !view.loggingOff && !view.logoffError && !logoffPendingRef.current && !isAuthenticatedRef.current && !isLoadingRef.current && !joining) {
|
|
@@ -62071,7 +62189,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
62071
62189
|
onLogin: handleLogin,
|
|
62072
62190
|
onLogout: handleLogout,
|
|
62073
62191
|
isLoadingSession: isLoading || isRestoringSession || deciding,
|
|
62074
|
-
sessionError: error2,
|
|
62192
|
+
sessionError: error2 || engineError,
|
|
62075
62193
|
sessionStatus: loginStatus,
|
|
62076
62194
|
loginConfirmation,
|
|
62077
62195
|
onCancelLoginConfirmation: handleCancelLoginConfirmation,
|
|
@@ -62094,7 +62212,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
62094
62212
|
onLogin: handleLogin,
|
|
62095
62213
|
onLogout: handleLogout,
|
|
62096
62214
|
isLoadingSession: isLoading,
|
|
62097
|
-
sessionError: error2,
|
|
62215
|
+
sessionError: error2 || engineError,
|
|
62098
62216
|
sessionStatus: loginStatus,
|
|
62099
62217
|
variant: uiVariant,
|
|
62100
62218
|
portalTarget,
|