@bravophone/webphone 0.2.0 → 0.2.1
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/README.md +15 -2
- package/dist/bravophone.mjs +320 -274
- package/dist/bravophone.umd.js +33 -10
- package/host/popup.js +1 -1
- package/host/styles/theme-fixes.css +10 -4
- package/package.json +1 -1
- package/types/index.d.ts +9 -1
package/dist/bravophone.mjs
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"',
|
|
1
|
+
const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"', fe = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
|
|
2
2
|
<path class="bp-i-body" d="M15.6 12.8a11 11 0 0 1-4.4-4.4l1-1a1.6 1.6 0 0 0 .3-1.7c-.2-.7-.4-1.4-.5-2.2A1.6 1.6 0 0 0 10.4 2H7.9a1.6 1.6 0 0 0-1.6 1.8 15.8 15.8 0 0 0 2.4 6.9 15.6 15.6 0 0 0 4.8 4.8 15.8 15.8 0 0 0 6.9 2.4 1.6 1.6 0 0 0 1.7-1.6v-2.5a1.6 1.6 0 0 0-1.4-1.6c-.8-.1-1.5-.3-2.2-.5a1.6 1.6 0 0 0-1.7.4z"/>
|
|
3
3
|
<path class="bp-i-wave bp-i-wave-1" d="M14.5 6.2a4 4 0 0 1 3.3 3.3"/>
|
|
4
4
|
<path class="bp-i-wave bp-i-wave-2" d="M14.1 2.6a7.6 7.6 0 0 1 7.3 7.3"/>
|
|
5
|
-
</svg>`,
|
|
5
|
+
</svg>`, xe = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
|
|
6
6
|
<path class="bp-i-bar bp-i-bar-1" d="M4 10v4"/>
|
|
7
7
|
<path class="bp-i-bar bp-i-bar-2" d="M8.7 6.5v11"/>
|
|
8
8
|
<path class="bp-i-bar bp-i-bar-3" d="M12 3.5v17"/>
|
|
9
9
|
<path class="bp-i-bar bp-i-bar-4" d="M15.3 6.5v11"/>
|
|
10
10
|
<path class="bp-i-bar bp-i-bar-5" d="M20 10v4"/>
|
|
11
|
-
</svg>`,
|
|
11
|
+
</svg>`, we = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
|
|
12
12
|
<path class="bp-i-body" d="M4 13v-1a8 8 0 0 1 16 0v1"/>
|
|
13
13
|
<path class="bp-i-body" d="M20 14.5v2a3.5 3.5 0 0 1-3.5 3.5H13"/>
|
|
14
14
|
<rect class="bp-i-cup" x="1.6" y="12.6" width="4.4" height="6.4" rx="1.8"/>
|
|
15
15
|
<rect class="bp-i-cup" x="18" y="12.6" width="4.4" height="6.4" rx="1.8"/>
|
|
16
|
-
</svg>`,
|
|
16
|
+
</svg>`, ye = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
|
|
17
17
|
<path class="bp-i-body" d="M21 11.5a8.4 8.4 0 0 1-9 8.4 9 9 0 0 1-2.9-.5L3 21.5l1.5-4.6A8.4 8.4 0 0 1 12 3.1a8.4 8.4 0 0 1 9 8.4z"/>
|
|
18
18
|
<path class="bp-i-hand" d="M14.6 14.4a6.5 6.5 0 0 1-3.2-3.2l.7-.7a1 1 0 0 0 .2-1.1 6 6 0 0 1-.3-1.2 1 1 0 0 0-1-.8H9.6a1 1 0 0 0-1 1.1 9.6 9.6 0 0 0 4.8 7.2 1 1 0 0 0 1.4-.9v-1.2a1 1 0 0 0-.8-1z"/>
|
|
19
|
-
</svg>`,
|
|
19
|
+
</svg>`, ve = `<svg viewBox="0 0 10 16" width="10" height="16" fill="currentColor" aria-hidden="true">
|
|
20
20
|
<circle cx="2.6" cy="2.6" r="1.35"/><circle cx="7.4" cy="2.6" r="1.35"/>
|
|
21
21
|
<circle cx="2.6" cy="8" r="1.35"/><circle cx="7.4" cy="8" r="1.35"/>
|
|
22
22
|
<circle cx="2.6" cy="13.4" r="1.35"/><circle cx="7.4" cy="13.4" r="1.35"/>
|
|
23
23
|
</svg>`, J = {
|
|
24
|
-
"phone-waves":
|
|
25
|
-
waveform:
|
|
26
|
-
headset:
|
|
27
|
-
"chat-phone":
|
|
28
|
-
},
|
|
24
|
+
"phone-waves": fe,
|
|
25
|
+
waveform: xe,
|
|
26
|
+
headset: we,
|
|
27
|
+
"chat-phone": ye
|
|
28
|
+
}, ae = "phone-waves", ke = `
|
|
29
29
|
.bp-launcher-icon svg { width: 100%; height: 100%; display: block; overflow: visible; }
|
|
30
30
|
|
|
31
31
|
/* Ponto de status no canto do ícone — verde registrado, cinza sem linha. */
|
|
@@ -95,7 +95,7 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
|
|
|
95
95
|
.bp-i-wave, .bp-i-body, .bp-i-hand, .bp-i-bar { animation: none !important; }
|
|
96
96
|
.bp-launcher-icon { transition: none; }
|
|
97
97
|
}
|
|
98
|
-
`,
|
|
98
|
+
`, Me = `
|
|
99
99
|
:host { all: initial; }
|
|
100
100
|
* { box-sizing: border-box; }
|
|
101
101
|
|
|
@@ -227,6 +227,21 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
|
|
|
227
227
|
/* Uma janela docada nao se redimensiona pelas bordas coladas na viewport. */
|
|
228
228
|
.bp-root.bp-docked { border-radius: 0; }
|
|
229
229
|
|
|
230
|
+
/* ---- destaque: "a janela esta aqui" ----
|
|
231
|
+
Disparado ao clicar na aba com o webphone ja aberto. Um halo que cresce e
|
|
232
|
+
some, no lugar de um shake: em interface, tremer significa erro ou acao
|
|
233
|
+
negada (senha errada), e aqui nada deu errado. */
|
|
234
|
+
@keyframes bp-attention {
|
|
235
|
+
0% { box-shadow: 0 12px 40px rgba(0,0,0,.45), 0 0 0 0 rgba(124,108,245,.55); }
|
|
236
|
+
55% { box-shadow: 0 12px 40px rgba(0,0,0,.45), 0 0 0 12px rgba(124,108,245,0); }
|
|
237
|
+
100% { box-shadow: 0 12px 40px rgba(0,0,0,.45), 0 0 0 0 rgba(124,108,245,0); }
|
|
238
|
+
}
|
|
239
|
+
.bp-root.bp-attention { animation: bp-attention .85s ease-out 2; }
|
|
240
|
+
|
|
241
|
+
@media (prefers-reduced-motion: reduce) {
|
|
242
|
+
.bp-root.bp-attention { animation: none; outline: 2px solid #7c6cf5; outline-offset: 2px; }
|
|
243
|
+
}
|
|
244
|
+
|
|
230
245
|
/* ---- previa de encaixe (docking) ----
|
|
231
246
|
Fantasma que mostra onde a janela vai parar antes de soltar. */
|
|
232
247
|
.bp-preview {
|
|
@@ -244,7 +259,9 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
|
|
|
244
259
|
.bp-launcher {
|
|
245
260
|
position: fixed;
|
|
246
261
|
top: 50%;
|
|
247
|
-
|
|
262
|
+
/* Acima da janela (2147483000): a aba nunca some, e uma janela docada na
|
|
263
|
+
mesma borda a esconderia. */
|
|
264
|
+
z-index: 2147483001;
|
|
248
265
|
display: flex;
|
|
249
266
|
align-items: center;
|
|
250
267
|
gap: 0;
|
|
@@ -341,11 +358,11 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
|
|
|
341
358
|
.bp-launcher[data-badge]:not([data-badge=""]) { animation: none; }
|
|
342
359
|
}
|
|
343
360
|
|
|
344
|
-
${
|
|
345
|
-
`,
|
|
346
|
-
function
|
|
361
|
+
${ke}
|
|
362
|
+
`, ge = "bravophone:widget:geometry", V = 28, X = 32;
|
|
363
|
+
function Le(e) {
|
|
347
364
|
try {
|
|
348
|
-
const a = localStorage.getItem(
|
|
365
|
+
const a = localStorage.getItem(ge);
|
|
349
366
|
if (!a) return { ...e };
|
|
350
367
|
const n = JSON.parse(a);
|
|
351
368
|
return n.dock ? { ...e, ...n, ...U(n.dock, n) } : { ...e, ...n };
|
|
@@ -355,7 +372,7 @@ function Me(e) {
|
|
|
355
372
|
}
|
|
356
373
|
function K(e) {
|
|
357
374
|
try {
|
|
358
|
-
localStorage.setItem(
|
|
375
|
+
localStorage.setItem(ge, JSON.stringify(e));
|
|
359
376
|
} catch (a) {
|
|
360
377
|
}
|
|
361
378
|
}
|
|
@@ -378,7 +395,7 @@ function R(e) {
|
|
|
378
395
|
};
|
|
379
396
|
}
|
|
380
397
|
function U(e, a) {
|
|
381
|
-
const n = window.innerWidth, o = window.innerHeight, i = Math.round(n / 2),
|
|
398
|
+
const n = window.innerWidth, o = window.innerHeight, i = Math.round(n / 2), d = Math.round(o / 2), u = Math.min(a.width, n);
|
|
382
399
|
switch (e) {
|
|
383
400
|
case "left":
|
|
384
401
|
return { x: 0, y: 0, width: u, height: o };
|
|
@@ -389,13 +406,13 @@ function U(e, a) {
|
|
|
389
406
|
case "right-half":
|
|
390
407
|
return { x: n - i, y: 0, width: i, height: o };
|
|
391
408
|
case "top":
|
|
392
|
-
return { x: a.x, y: 0, width: u, height:
|
|
409
|
+
return { x: a.x, y: 0, width: u, height: d };
|
|
393
410
|
case "bottom":
|
|
394
|
-
return { x: a.x, y: o -
|
|
411
|
+
return { x: a.x, y: o - d, width: u, height: d };
|
|
395
412
|
case "top-half":
|
|
396
|
-
return { x: 0, y: 0, width: n, height:
|
|
413
|
+
return { x: 0, y: 0, width: n, height: d };
|
|
397
414
|
case "bottom-half":
|
|
398
|
-
return { x: 0, y: o -
|
|
415
|
+
return { x: 0, y: o - d, width: n, height: d };
|
|
399
416
|
case "max":
|
|
400
417
|
return { x: 0, y: 0, width: n, height: o };
|
|
401
418
|
default:
|
|
@@ -403,14 +420,14 @@ function U(e, a) {
|
|
|
403
420
|
}
|
|
404
421
|
}
|
|
405
422
|
function ze(e, a, n) {
|
|
406
|
-
const o = window.innerWidth, i = window.innerHeight,
|
|
407
|
-
return (
|
|
408
|
-
}
|
|
409
|
-
function
|
|
410
|
-
let t = { ...i }, g = null, p = "",
|
|
411
|
-
const
|
|
412
|
-
e.style.left = `${t.x}px`, e.style.top = `${t.y}px`, e.style.width = `${t.width}px`, e.style.height = `${t.height}px`, e.classList.toggle("bp-docked", !!t.dock),
|
|
413
|
-
},
|
|
423
|
+
const o = window.innerWidth, i = window.innerHeight, d = e <= V, u = e >= o - V, f = a <= V, t = a >= i - V;
|
|
424
|
+
return (f || t) && d ? "left-half" : (f || t) && u ? "right-half" : f ? n || "max" : t ? "bottom-half" : d ? "left" : u ? "right" : null;
|
|
425
|
+
}
|
|
426
|
+
function Se({ root: e, handle: a, handles: n, preview: o, geometry: i, limits: d, topDock: u, onChange: f }) {
|
|
427
|
+
let t = { ...i }, g = null, p = "", c = null, h = null, x = null, w = null;
|
|
428
|
+
const z = () => {
|
|
429
|
+
e.style.left = `${t.x}px`, e.style.top = `${t.y}px`, e.style.width = `${t.width}px`, e.style.height = `${t.height}px`, e.classList.toggle("bp-docked", !!t.dock), f == null || f(t);
|
|
430
|
+
}, C = (r) => {
|
|
414
431
|
if (o) {
|
|
415
432
|
if (!r) {
|
|
416
433
|
o.hidden = !0;
|
|
@@ -419,32 +436,32 @@ function Le({ root: e, handle: a, handles: n, preview: o, geometry: i, limits: s
|
|
|
419
436
|
o.hidden = !1, o.style.left = `${r.x}px`, o.style.top = `${r.y}px`, o.style.width = `${r.width}px`, o.style.height = `${r.height}px`;
|
|
420
437
|
}
|
|
421
438
|
}, $ = (r, b) => {
|
|
422
|
-
const
|
|
423
|
-
let { x: v, y:
|
|
424
|
-
p.includes("e") && (
|
|
425
|
-
}, j = (r, b,
|
|
439
|
+
const l = he(d);
|
|
440
|
+
let { x: v, y: S, width: E, height: H } = c;
|
|
441
|
+
p.includes("e") && (E = c.width + r), p.includes("w") && (E = c.width - r), p.includes("s") && (H = c.height + b), p.includes("n") && (H = c.height - b), E = Math.min(l.maxWidth, Math.max(l.minWidth, E)), H = Math.min(l.maxHeight, Math.max(l.minHeight, H)), p.includes("w") && (v = c.x + (c.width - E)), p.includes("n") && (S = c.y + (c.height - H)), p.includes("e") && Math.abs(v + E - window.innerWidth) <= X && (E = window.innerWidth - v), p.includes("w") && Math.abs(v) <= X && (E += v, v = 0), p.includes("s") && Math.abs(S + H - window.innerHeight) <= X && (H = window.innerHeight - S), p.includes("n") && Math.abs(S) <= X && (H += S, S = 0), t = { ...t, x: v, y: S, width: E, height: H, dock: null }, z();
|
|
442
|
+
}, j = (r, b, l, v) => {
|
|
426
443
|
if (t.dock) {
|
|
427
|
-
const
|
|
428
|
-
t = { ...t, ...
|
|
429
|
-
...
|
|
430
|
-
x:
|
|
431
|
-
y: v -
|
|
432
|
-
px:
|
|
433
|
-
py:
|
|
444
|
+
const S = w || { width: d.width, height: d.height }, E = h.x / Math.max(1, t.width);
|
|
445
|
+
t = { ...t, ...S, dock: null }, h = { x: Math.round(S.width * E), y: Math.min(h.y, 32) }, c = {
|
|
446
|
+
...c,
|
|
447
|
+
x: l - h.x,
|
|
448
|
+
y: v - h.y,
|
|
449
|
+
px: c.px + r,
|
|
450
|
+
py: c.py + b
|
|
434
451
|
}, r = 0, b = 0;
|
|
435
452
|
}
|
|
436
|
-
t = R({ ...t, x:
|
|
453
|
+
t = R({ ...t, x: c.x + r, y: c.y + b }), z(), x = ze(l, v, u), C(x ? U(x, t) : null);
|
|
437
454
|
}, _ = () => {
|
|
438
|
-
x && (
|
|
439
|
-
},
|
|
440
|
-
|
|
455
|
+
x && (w = w || { width: t.width, height: t.height }, t = { ...t, ...U(x, t), dock: x }, z());
|
|
456
|
+
}, F = (r, b) => (l) => {
|
|
457
|
+
l.button === 0 && (r === "drag" && l.target.closest(".bp-btn") || (g = r, p = b || "", c = { px: l.clientX, py: l.clientY, ...t }, h = { x: l.clientX - t.x, y: l.clientY - t.y }, t.dock || (w = { width: t.width, height: t.height }), e.classList.add(r === "drag" ? "bp-dragging" : "bp-resizing"), l.currentTarget.setPointerCapture(l.pointerId), l.preventDefault()));
|
|
441
458
|
}, D = (r) => {
|
|
442
|
-
if (!g || !
|
|
443
|
-
const b = r.clientX -
|
|
444
|
-
g === "drag" ? j(b,
|
|
445
|
-
},
|
|
459
|
+
if (!g || !c) return;
|
|
460
|
+
const b = r.clientX - c.px, l = r.clientY - c.py;
|
|
461
|
+
g === "drag" ? j(b, l, r.clientX, r.clientY) : $(b, l);
|
|
462
|
+
}, A = (r) => {
|
|
446
463
|
if (g) {
|
|
447
|
-
e.classList.remove("bp-dragging", "bp-resizing"),
|
|
464
|
+
e.classList.remove("bp-dragging", "bp-resizing"), C(null), g === "drag" && _(), g = null, p = "", c = null, x = null;
|
|
448
465
|
try {
|
|
449
466
|
r.currentTarget.releasePointerCapture(r.pointerId);
|
|
450
467
|
} catch (b) {
|
|
@@ -452,173 +469,179 @@ function Le({ root: e, handle: a, handles: n, preview: o, geometry: i, limits: s
|
|
|
452
469
|
K(t);
|
|
453
470
|
}
|
|
454
471
|
};
|
|
455
|
-
a.addEventListener("pointerdown",
|
|
456
|
-
r.addEventListener("pointerdown",
|
|
472
|
+
a.addEventListener("pointerdown", F("drag")), a.addEventListener("pointermove", D), a.addEventListener("pointerup", A), a.addEventListener("pointercancel", A), (n || []).forEach(({ el: r, dir: b }) => {
|
|
473
|
+
r.addEventListener("pointerdown", F("resize", b)), r.addEventListener("pointermove", D), r.addEventListener("pointerup", A), r.addEventListener("pointercancel", A);
|
|
457
474
|
});
|
|
458
|
-
const
|
|
459
|
-
t = t.dock ? { ...t, ...U(t.dock, t) } : R(t),
|
|
475
|
+
const N = () => {
|
|
476
|
+
t = t.dock ? { ...t, ...U(t.dock, t) } : R(t), z();
|
|
460
477
|
};
|
|
461
|
-
window.addEventListener("resize",
|
|
462
|
-
const
|
|
478
|
+
window.addEventListener("resize", N);
|
|
479
|
+
const G = {
|
|
463
480
|
start(r) {
|
|
464
|
-
var b,
|
|
465
|
-
g = "drag",
|
|
481
|
+
var b, l;
|
|
482
|
+
g = "drag", c = { px: r.x, py: r.y, ...t }, h = { x: (b = r.cx) != null ? b : t.width / 2, y: (l = r.cy) != null ? l : 20 }, t.dock || (w = { width: t.width, height: t.height }), e.classList.add("bp-dragging");
|
|
466
483
|
},
|
|
467
484
|
move(r) {
|
|
468
|
-
if (g !== "drag" || !
|
|
469
|
-
const b = r.x -
|
|
470
|
-
j(b,
|
|
485
|
+
if (g !== "drag" || !c) return;
|
|
486
|
+
const b = r.x - c.px, l = r.y - c.py;
|
|
487
|
+
j(b, l, c.x + b + h.x, c.y + l + h.y);
|
|
471
488
|
},
|
|
472
489
|
end() {
|
|
473
|
-
g === "drag" && (e.classList.remove("bp-dragging"),
|
|
490
|
+
g === "drag" && (e.classList.remove("bp-dragging"), C(null), _(), g = null, c = null, x = null, K(t));
|
|
474
491
|
}
|
|
475
492
|
};
|
|
476
|
-
return
|
|
477
|
-
external:
|
|
493
|
+
return z(), {
|
|
494
|
+
external: G,
|
|
478
495
|
get geometry() {
|
|
479
496
|
return { ...t };
|
|
480
497
|
},
|
|
481
498
|
set(r) {
|
|
482
|
-
const b = he(
|
|
483
|
-
|
|
499
|
+
const b = he(d), l = { ...t, ...r, dock: null };
|
|
500
|
+
l.width = Math.min(b.maxWidth, Math.max(b.minWidth, l.width)), l.height = Math.min(b.maxHeight, Math.max(b.minHeight, l.height)), t = R(l), z(), K(t);
|
|
484
501
|
},
|
|
485
502
|
/** 'left' | 'right' | 'left-half' | 'right-half' | 'max' | 'float' */
|
|
486
503
|
dock(r) {
|
|
487
504
|
if (!r || r === "float") {
|
|
488
|
-
const b =
|
|
505
|
+
const b = w || { width: d.width, height: d.height };
|
|
489
506
|
t = R({ ...t, ...b, dock: null });
|
|
490
507
|
} else
|
|
491
|
-
t.dock || (
|
|
492
|
-
|
|
508
|
+
t.dock || (w = { width: t.width, height: t.height }), t = { ...t, ...U(r, t), dock: r };
|
|
509
|
+
z(), K(t);
|
|
493
510
|
},
|
|
494
511
|
destroy() {
|
|
495
|
-
window.removeEventListener("resize",
|
|
512
|
+
window.removeEventListener("resize", N);
|
|
496
513
|
}
|
|
497
514
|
};
|
|
498
515
|
}
|
|
499
|
-
const
|
|
500
|
-
function
|
|
516
|
+
const be = "bravophone/v1";
|
|
517
|
+
function Ee({ frame: e, origin: a, onEvent: n }) {
|
|
501
518
|
const o = /* @__PURE__ */ new Map();
|
|
502
|
-
let i = 0,
|
|
503
|
-
const u = [],
|
|
504
|
-
var
|
|
519
|
+
let i = 0, d = !1;
|
|
520
|
+
const u = [], f = (g) => {
|
|
521
|
+
var c;
|
|
505
522
|
if (g.origin !== a || g.source !== e.contentWindow) return;
|
|
506
523
|
const p = g.data;
|
|
507
|
-
if (!(!p || p.protocol !==
|
|
524
|
+
if (!(!p || p.protocol !== be)) {
|
|
508
525
|
if (p.type === "ready") {
|
|
509
|
-
for (
|
|
510
|
-
n == null || n("ready", (
|
|
526
|
+
for (d = !0; u.length; ) u.shift()();
|
|
527
|
+
n == null || n("ready", (c = p.payload) != null ? c : {});
|
|
511
528
|
return;
|
|
512
529
|
}
|
|
513
530
|
if (p.type === "reply") {
|
|
514
|
-
const
|
|
515
|
-
if (!
|
|
516
|
-
o.delete(p.id), clearTimeout(
|
|
531
|
+
const h = o.get(p.id);
|
|
532
|
+
if (!h) return;
|
|
533
|
+
o.delete(p.id), clearTimeout(h.timer), p.error ? h.reject(new Error(p.error)) : h.resolve(p.payload);
|
|
517
534
|
return;
|
|
518
535
|
}
|
|
519
536
|
p.type === "event" && (n == null || n(p.name, p.payload));
|
|
520
537
|
}
|
|
521
538
|
};
|
|
522
|
-
window.addEventListener("message",
|
|
523
|
-
function t(g, p, { timeout:
|
|
524
|
-
return new Promise((
|
|
525
|
-
const
|
|
539
|
+
window.addEventListener("message", f);
|
|
540
|
+
function t(g, p, { timeout: c = 15e3 } = {}) {
|
|
541
|
+
return new Promise((h, x) => {
|
|
542
|
+
const w = `${Date.now()}-${++i}`, z = () => {
|
|
526
543
|
var $;
|
|
527
|
-
const
|
|
528
|
-
o.delete(
|
|
529
|
-
},
|
|
530
|
-
o.set(
|
|
531
|
-
{ protocol:
|
|
544
|
+
const C = setTimeout(() => {
|
|
545
|
+
o.delete(w), x(new Error(`Bravophone: timeout no comando "${g}"`));
|
|
546
|
+
}, c);
|
|
547
|
+
o.set(w, { resolve: h, reject: x, timer: C }), ($ = e.contentWindow) == null || $.postMessage(
|
|
548
|
+
{ protocol: be, type: "command", id: w, command: g, payload: p },
|
|
532
549
|
a
|
|
533
550
|
);
|
|
534
551
|
};
|
|
535
|
-
|
|
552
|
+
d ? z() : u.push(z);
|
|
536
553
|
});
|
|
537
554
|
}
|
|
538
555
|
return {
|
|
539
556
|
call: t,
|
|
540
557
|
get ready() {
|
|
541
|
-
return
|
|
558
|
+
return d;
|
|
542
559
|
},
|
|
543
560
|
destroy() {
|
|
544
|
-
window.removeEventListener("message",
|
|
561
|
+
window.removeEventListener("message", f), o.forEach(({ reject: g, timer: p }) => {
|
|
545
562
|
clearTimeout(p), g(new Error("Bravophone: widget destruído"));
|
|
546
563
|
}), o.clear();
|
|
547
564
|
}
|
|
548
565
|
};
|
|
549
566
|
}
|
|
550
|
-
const
|
|
551
|
-
function
|
|
567
|
+
const me = "bravophone:launcher", He = 4, ie = 8;
|
|
568
|
+
function Te(e) {
|
|
552
569
|
try {
|
|
553
|
-
const a = localStorage.getItem(
|
|
570
|
+
const a = localStorage.getItem(me);
|
|
554
571
|
return a ? { ...e, ...JSON.parse(a) } : { ...e };
|
|
555
572
|
} catch (a) {
|
|
556
573
|
return { ...e };
|
|
557
574
|
}
|
|
558
575
|
}
|
|
559
|
-
function
|
|
576
|
+
function ne(e) {
|
|
560
577
|
try {
|
|
561
|
-
localStorage.setItem(
|
|
578
|
+
localStorage.setItem(me, JSON.stringify(e));
|
|
562
579
|
} catch (a) {
|
|
563
580
|
}
|
|
564
581
|
}
|
|
565
|
-
function
|
|
566
|
-
const n = Math.max(
|
|
567
|
-
return Math.min(Math.max(
|
|
582
|
+
function q(e, a) {
|
|
583
|
+
const n = Math.max(ie, window.innerHeight - a - ie);
|
|
584
|
+
return Math.min(Math.max(ie, e), n);
|
|
568
585
|
}
|
|
569
586
|
function $e({ el: e, side: a, y: n, onOpen: o }) {
|
|
570
|
-
let i = { side: a, y:
|
|
571
|
-
const
|
|
587
|
+
let i = { side: a, y: q(n, e.offsetHeight || 48) }, d = null, u = !1;
|
|
588
|
+
const f = () => {
|
|
572
589
|
e.dataset.side = i.side, e.style.top = `${i.y}px`, e.style.right = i.side === "right" ? "0px" : "auto", e.style.left = i.side === "left" ? "0px" : "auto";
|
|
573
|
-
}, t = (
|
|
574
|
-
|
|
575
|
-
}, g = (
|
|
576
|
-
if (!
|
|
577
|
-
const x =
|
|
578
|
-
!u && Math.abs(x) <
|
|
579
|
-
}, p = (
|
|
580
|
-
if (!
|
|
590
|
+
}, t = (h) => {
|
|
591
|
+
h.button === 0 && (d = { py: h.clientY, y: i.y }, u = !1, e.setPointerCapture(h.pointerId));
|
|
592
|
+
}, g = (h) => {
|
|
593
|
+
if (!d) return;
|
|
594
|
+
const x = h.clientY - d.py;
|
|
595
|
+
!u && Math.abs(x) < He || (u || (u = !0, e.classList.add("bp-launcher-dragging")), i.y = q(d.y + x, e.offsetHeight), f());
|
|
596
|
+
}, p = (h) => {
|
|
597
|
+
if (!d) return;
|
|
581
598
|
const x = u;
|
|
582
|
-
|
|
599
|
+
d = null, u = !1, e.classList.remove("bp-launcher-dragging");
|
|
583
600
|
try {
|
|
584
|
-
e.releasePointerCapture(
|
|
585
|
-
} catch (
|
|
601
|
+
e.releasePointerCapture(h.pointerId);
|
|
602
|
+
} catch (w) {
|
|
586
603
|
}
|
|
587
|
-
x ?
|
|
604
|
+
x ? ne(i) : o == null || o();
|
|
588
605
|
};
|
|
589
|
-
e.addEventListener("pointerdown", t), e.addEventListener("pointermove", g), e.addEventListener("pointerup", p), e.addEventListener("pointercancel", p), e.addEventListener("keydown", (
|
|
590
|
-
(
|
|
606
|
+
e.addEventListener("pointerdown", t), e.addEventListener("pointermove", g), e.addEventListener("pointerup", p), e.addEventListener("pointercancel", p), e.addEventListener("keydown", (h) => {
|
|
607
|
+
(h.key === "Enter" || h.key === " ") && (h.preventDefault(), o == null || o());
|
|
591
608
|
});
|
|
592
|
-
const
|
|
593
|
-
i.y =
|
|
609
|
+
const c = () => {
|
|
610
|
+
i.y = q(i.y, e.offsetHeight), f();
|
|
594
611
|
};
|
|
595
|
-
return window.addEventListener("resize",
|
|
612
|
+
return window.addEventListener("resize", c), f(), {
|
|
596
613
|
get state() {
|
|
597
614
|
return { ...i };
|
|
598
615
|
},
|
|
599
|
-
setSide(
|
|
600
|
-
i.side =
|
|
616
|
+
setSide(h) {
|
|
617
|
+
i.side = h, f(), ne(i);
|
|
601
618
|
},
|
|
602
|
-
moveTo(
|
|
603
|
-
i.y =
|
|
619
|
+
moveTo(h) {
|
|
620
|
+
i.y = q(h, e.offsetHeight), f(), ne(i);
|
|
604
621
|
},
|
|
605
622
|
destroy() {
|
|
606
|
-
window.removeEventListener("resize",
|
|
623
|
+
window.removeEventListener("resize", c);
|
|
607
624
|
}
|
|
608
625
|
};
|
|
609
626
|
}
|
|
610
|
-
const
|
|
611
|
-
function
|
|
612
|
-
return `${
|
|
627
|
+
const Ie = "https://cdn.jsdelivr.net/npm";
|
|
628
|
+
function Oe(e, a = "@bravophone/webphone") {
|
|
629
|
+
return `${Ie}/${a}@${e}/host/`;
|
|
613
630
|
}
|
|
614
|
-
function
|
|
615
|
-
const i = o ||
|
|
631
|
+
function We({ version: e, parentOrigin: a, token: n, base: o }) {
|
|
632
|
+
const i = o || Oe(e), d = JSON.stringify({ parentOrigin: a, token: n || null }).replace(/</g, "\\u003c");
|
|
616
633
|
return `<!doctype html>
|
|
617
634
|
<html lang="pt-BR">
|
|
618
635
|
<head>
|
|
619
636
|
<meta charset="UTF-8">
|
|
620
637
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
621
638
|
<title>Webphone BRAVOPHONE</title>
|
|
639
|
+
<!-- CRÍTICO no modo srcdoc. O bundle referencia as imagens por caminho
|
|
640
|
+
RELATIVO (src="images/answer.png"), fora do public_path. Sem <base>,
|
|
641
|
+
elas resolvem contra a página do integrador — o documento herda o
|
|
642
|
+
baseURI do pai — e somem todas: logo, atender, desligar, mudo, hold,
|
|
643
|
+
transferir. Com <base>, resolvem contra o CDN. -->
|
|
644
|
+
<base href="${i}">
|
|
622
645
|
<link rel="stylesheet" href="${i}css/dark-theme.css">
|
|
623
646
|
<link rel="stylesheet" href="${i}styles/theme-fixes.css">
|
|
624
647
|
<style>
|
|
@@ -627,7 +650,7 @@ function Oe({ version: e, parentOrigin: a, token: n, base: o }) {
|
|
|
627
650
|
</style>
|
|
628
651
|
<script>
|
|
629
652
|
(function () {
|
|
630
|
-
var cfg = ${
|
|
653
|
+
var cfg = ${d};
|
|
631
654
|
// O guest-bridge lê daqui: em srcdoc não há query string para carregar a
|
|
632
655
|
// origem do pai.
|
|
633
656
|
window.__bpParentOrigin = cfg.parentOrigin;
|
|
@@ -651,7 +674,7 @@ function Oe({ version: e, parentOrigin: a, token: n, base: o }) {
|
|
|
651
674
|
</body>
|
|
652
675
|
</html>`;
|
|
653
676
|
}
|
|
654
|
-
const
|
|
677
|
+
const ue = {
|
|
655
678
|
// 380x640 é a geometria da janela nativa da extensão — o layout do
|
|
656
679
|
// webphone é calibrado para ela, então é o ponto de partida aqui também.
|
|
657
680
|
width: 380,
|
|
@@ -664,212 +687,231 @@ const be = {
|
|
|
664
687
|
maxHeight: 1400,
|
|
665
688
|
margin: 24
|
|
666
689
|
};
|
|
667
|
-
function
|
|
690
|
+
function y(e, a = {}, n = []) {
|
|
668
691
|
const o = document.createElement(e);
|
|
669
|
-
for (const [i,
|
|
670
|
-
i === "class" ? o.className =
|
|
692
|
+
for (const [i, d] of Object.entries(a))
|
|
693
|
+
i === "class" ? o.className = d : i === "text" ? o.textContent = d : d != null && o.setAttribute(i, d);
|
|
671
694
|
return n.forEach((i) => o.appendChild(i)), o;
|
|
672
695
|
}
|
|
673
|
-
function
|
|
696
|
+
function Ce(e) {
|
|
674
697
|
const {
|
|
675
698
|
hostUrl: a,
|
|
676
699
|
token: n,
|
|
677
700
|
position: o = "bottom-right",
|
|
678
701
|
open: i = !1,
|
|
679
|
-
launcher:
|
|
702
|
+
launcher: d = !0,
|
|
680
703
|
title: u = "BRAVOPHONE",
|
|
681
|
-
// '
|
|
682
|
-
//
|
|
683
|
-
|
|
704
|
+
// 'bar' por padrão: título, indicador de estado e controles visíveis.
|
|
705
|
+
// 'none' preserva 100% da UI do webphone — sem barra, o arraste vem de
|
|
706
|
+
// dentro do iframe e só um botão de fechar aparece no hover.
|
|
707
|
+
frame: f = "bar",
|
|
684
708
|
// O que arrastar até a borda de cima faz. 'max' é o gesto universal;
|
|
685
709
|
// troque para 'top-half' se preferir as metades verticais no topo.
|
|
686
710
|
dockTop: t = "max",
|
|
687
711
|
// Lado da viewport em que a aba de abertura fica colada.
|
|
688
712
|
launcherSide: g = "right",
|
|
689
713
|
// Desenho da aba: 'phone-waves' | 'waveform' | 'headset' | 'chat-phone'
|
|
690
|
-
launcherIcon: p =
|
|
714
|
+
launcherIcon: p = ae,
|
|
691
715
|
// 'hosted' — o iframe navega para hostUrl (padrão)
|
|
692
716
|
// 'srcdoc' — o iframe roda na origem do site e busca o conteúdo no CDN
|
|
693
|
-
mode:
|
|
717
|
+
mode: c = "hosted",
|
|
694
718
|
// Base dos assets no modo srcdoc. Padrão: o CDN travado nesta versão.
|
|
695
719
|
// Serve para desenvolvimento (localhost) e para quem espelhar os assets.
|
|
696
|
-
hostBase:
|
|
720
|
+
hostBase: h,
|
|
697
721
|
version: x,
|
|
698
|
-
emit:
|
|
699
|
-
} = e,
|
|
722
|
+
emit: w
|
|
723
|
+
} = e, z = c === "srcdoc", C = z ? window.location.origin : new URL(a).origin, $ = y("div", { "data-bravophone": "root" });
|
|
700
724
|
$.style.cssText = "all:initial;position:static";
|
|
701
725
|
const j = $.attachShadow({ mode: "open" });
|
|
702
|
-
j.appendChild(
|
|
726
|
+
j.appendChild(y("style", { text: Me }));
|
|
703
727
|
const _ = (() => {
|
|
704
|
-
var
|
|
705
|
-
const { width:
|
|
706
|
-
"bottom-right": { x:
|
|
707
|
-
"bottom-left": { x:
|
|
708
|
-
"top-right": { x:
|
|
709
|
-
"top-left": { x:
|
|
728
|
+
var le;
|
|
729
|
+
const { width: s, height: M, margin: W } = ue, P = window.innerWidth - s - W, ce = window.innerHeight - M - W, pe = {
|
|
730
|
+
"bottom-right": { x: P, y: ce },
|
|
731
|
+
"bottom-left": { x: W, y: ce },
|
|
732
|
+
"top-right": { x: P, y: W },
|
|
733
|
+
"top-left": { x: W, y: W }
|
|
710
734
|
};
|
|
711
|
-
return R({ ...(
|
|
712
|
-
})(),
|
|
735
|
+
return R({ ...(le = pe[o]) != null ? le : pe["bottom-right"], width: s, height: M });
|
|
736
|
+
})(), F = R(Le(_)), D = y("span", { class: "bp-status", "data-state": "connecting" }), A = y("button", { class: "bp-btn bp-btn-min", title: "Minimizar", text: "—" }), N = y("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), G = y("div", { class: "bp-header" }, [
|
|
713
737
|
D,
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
]), r =
|
|
738
|
+
y("span", { class: "bp-title", text: u }),
|
|
739
|
+
A,
|
|
740
|
+
N
|
|
741
|
+
]), r = y("iframe", {
|
|
718
742
|
class: "bp-frame",
|
|
719
743
|
// allow= é obrigatório no modo hospedado (cross-origin). Em srcdoc o
|
|
720
744
|
// microfone já é herdado do topo, mas declarar não custa e documenta.
|
|
721
745
|
allow: "microphone; autoplay; clipboard-write; speaker-selection",
|
|
722
746
|
title: "Webphone BRAVOPHONE"
|
|
723
747
|
});
|
|
724
|
-
|
|
748
|
+
z ? r.setAttribute(
|
|
725
749
|
"srcdoc",
|
|
726
|
-
|
|
750
|
+
We({ version: x, parentOrigin: C, token: n, base: h })
|
|
727
751
|
) : r.setAttribute(
|
|
728
752
|
"src",
|
|
729
|
-
|
|
753
|
+
Ae(new URL(a), { token: n, embed: "1", parent: location.origin })
|
|
730
754
|
);
|
|
731
|
-
const
|
|
732
|
-
el:
|
|
733
|
-
dir:
|
|
734
|
-
})), v =
|
|
755
|
+
const l = ["n", "s", "w", "e", "nw", "ne", "sw", "se"].map((s) => ({
|
|
756
|
+
el: y("div", { class: `bp-h bp-h-${s}` }),
|
|
757
|
+
dir: s
|
|
758
|
+
})), v = y("div", { class: "bp-preview" });
|
|
735
759
|
v.hidden = !0;
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
const Q =
|
|
739
|
-
Q.innerHTML = J[p] || J[
|
|
740
|
-
const
|
|
741
|
-
|
|
742
|
-
const
|
|
760
|
+
const S = y("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), E = y("div", { class: "bp-overlay" }, [S]), H = y("div", { class: "bp-body" }, [r, E]), k = y("div", { class: "bp-root" }, [G, H, ...l.map((s) => s.el)]);
|
|
761
|
+
f !== "bar" && k.classList.add("bp-chromeless"), k.hidden = !i;
|
|
762
|
+
const Q = y("span", { class: "bp-launcher-icon" });
|
|
763
|
+
Q.innerHTML = J[p] || J[ae];
|
|
764
|
+
const oe = y("span", { class: "bp-launcher-grip", "aria-hidden": "true" });
|
|
765
|
+
oe.innerHTML = ve;
|
|
766
|
+
const T = y("div", {
|
|
743
767
|
class: "bp-launcher",
|
|
744
768
|
role: "button",
|
|
745
769
|
tabindex: "0",
|
|
746
770
|
title: "Abrir webphone",
|
|
747
771
|
"aria-label": "Abrir webphone"
|
|
748
772
|
}, [
|
|
749
|
-
|
|
773
|
+
oe,
|
|
750
774
|
Q,
|
|
751
|
-
|
|
775
|
+
y("span", { class: "bp-badge" })
|
|
752
776
|
]);
|
|
753
|
-
|
|
754
|
-
const
|
|
777
|
+
T.dataset.state = "connecting", T.hidden = !d, j.append(v, k, T), document.body.appendChild($);
|
|
778
|
+
const se = Te({
|
|
755
779
|
side: g,
|
|
756
780
|
y: Math.round(window.innerHeight / 2 - 24)
|
|
757
|
-
}),
|
|
758
|
-
el:
|
|
759
|
-
side:
|
|
760
|
-
y:
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
781
|
+
}), de = $e({
|
|
782
|
+
el: T,
|
|
783
|
+
side: se.side,
|
|
784
|
+
y: q(se.y, 48),
|
|
785
|
+
// A aba nunca some, então o clique tem dois papéis: abrir quando fechada,
|
|
786
|
+
// e localizar quando já aberta.
|
|
787
|
+
onOpen: () => O.reveal()
|
|
788
|
+
}), I = Se({
|
|
789
|
+
root: k,
|
|
790
|
+
handle: G,
|
|
791
|
+
handles: l,
|
|
766
792
|
preview: v,
|
|
767
|
-
geometry:
|
|
768
|
-
limits:
|
|
793
|
+
geometry: F,
|
|
794
|
+
limits: ue,
|
|
769
795
|
topDock: t,
|
|
770
|
-
onChange: (
|
|
771
|
-
}), ee =
|
|
796
|
+
onChange: (s) => w("resize", { width: s.width, height: s.height, dock: s.dock || null })
|
|
797
|
+
}), ee = Ee({
|
|
772
798
|
frame: r,
|
|
773
|
-
origin:
|
|
774
|
-
onEvent: (
|
|
775
|
-
var
|
|
776
|
-
if (
|
|
777
|
-
})),
|
|
778
|
-
const
|
|
779
|
-
D.dataset.state =
|
|
799
|
+
origin: C,
|
|
800
|
+
onEvent: (s, M) => {
|
|
801
|
+
var W;
|
|
802
|
+
if (s === "ready" && (D.dataset.state = "ready", T.dataset.state = "ready", n && ee.call("auth", { token: n }).catch(() => {
|
|
803
|
+
})), s === "state") {
|
|
804
|
+
const P = (W = M == null ? void 0 : M.state) != null ? W : "ready";
|
|
805
|
+
D.dataset.state = P, T.dataset.state = P;
|
|
780
806
|
}
|
|
781
|
-
if (
|
|
782
|
-
|
|
807
|
+
if (s === "call:incoming" && (O.show(), T.dataset.badge = "1", T.dataset.state = "ringing"), s === "call:answered" && (T.dataset.state = "incall"), s === "call:ended" && (delete T.dataset.badge, T.dataset.state = "ready"), s === "drag:start") {
|
|
808
|
+
I.external.start(M);
|
|
783
809
|
return;
|
|
784
810
|
}
|
|
785
|
-
if (
|
|
786
|
-
|
|
811
|
+
if (s === "drag:move") {
|
|
812
|
+
I.external.move(M);
|
|
787
813
|
return;
|
|
788
814
|
}
|
|
789
|
-
if (
|
|
790
|
-
|
|
815
|
+
if (s === "drag:end") {
|
|
816
|
+
I.external.end();
|
|
791
817
|
return;
|
|
792
818
|
}
|
|
793
|
-
|
|
819
|
+
w(s, M);
|
|
794
820
|
}
|
|
795
821
|
});
|
|
796
|
-
let
|
|
797
|
-
const
|
|
822
|
+
let Y = !1, te = null;
|
|
823
|
+
const O = {
|
|
798
824
|
el: $,
|
|
799
825
|
bridge: ee,
|
|
800
826
|
show() {
|
|
801
|
-
|
|
827
|
+
k.hidden = !1, w("open");
|
|
802
828
|
},
|
|
803
829
|
hide() {
|
|
804
|
-
|
|
830
|
+
k.hidden = !0, w("close");
|
|
805
831
|
},
|
|
806
832
|
toggle() {
|
|
807
|
-
|
|
833
|
+
k.hidden ? O.show() : O.hide();
|
|
834
|
+
},
|
|
835
|
+
/**
|
|
836
|
+
* Traz a janela para a atenção do usuário.
|
|
837
|
+
* Fechada: abre. Aberta e fora de vista: traz de volta. Aberta e
|
|
838
|
+
* visível: um halo curto, para o olho encontrá-la.
|
|
839
|
+
*/
|
|
840
|
+
reveal() {
|
|
841
|
+
if (k.hidden) {
|
|
842
|
+
O.show();
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
const s = I.geometry;
|
|
846
|
+
(s.x + s.width < 40 || s.x > window.innerWidth - 40 || s.y > window.innerHeight - 40) && I.set({
|
|
847
|
+
x: Math.round((window.innerWidth - s.width) / 2),
|
|
848
|
+
y: Math.round((window.innerHeight - s.height) / 2)
|
|
849
|
+
}), k.classList.remove("bp-attention"), k.offsetWidth, k.classList.add("bp-attention"), clearTimeout(te), te = setTimeout(() => k.classList.remove("bp-attention"), 1800), w("reveal");
|
|
808
850
|
},
|
|
809
851
|
get isOpen() {
|
|
810
|
-
return !
|
|
852
|
+
return !k.hidden;
|
|
811
853
|
},
|
|
812
|
-
minimize(
|
|
813
|
-
if (
|
|
814
|
-
|
|
854
|
+
minimize(s) {
|
|
855
|
+
if (f !== "bar") {
|
|
856
|
+
O.hide();
|
|
815
857
|
return;
|
|
816
858
|
}
|
|
817
|
-
|
|
859
|
+
Y = s != null ? s : !Y, k.classList.toggle("bp-minimized", Y), A.textContent = Y ? "▢" : "—";
|
|
818
860
|
},
|
|
819
|
-
move(
|
|
820
|
-
|
|
861
|
+
move(s, M) {
|
|
862
|
+
I.set({ x: s, y: M });
|
|
821
863
|
},
|
|
822
|
-
resize(
|
|
823
|
-
|
|
864
|
+
resize(s, M) {
|
|
865
|
+
I.set({ width: s, height: M });
|
|
824
866
|
},
|
|
825
|
-
dock(
|
|
826
|
-
|
|
867
|
+
dock(s) {
|
|
868
|
+
I.dock(s);
|
|
827
869
|
},
|
|
828
|
-
setLauncherSide(
|
|
829
|
-
|
|
870
|
+
setLauncherSide(s) {
|
|
871
|
+
de.setSide(s);
|
|
830
872
|
},
|
|
831
|
-
setLauncherIcon(
|
|
832
|
-
Q.innerHTML = J[
|
|
873
|
+
setLauncherIcon(s) {
|
|
874
|
+
Q.innerHTML = J[s] || J[ae];
|
|
833
875
|
},
|
|
834
876
|
get geometry() {
|
|
835
|
-
return
|
|
877
|
+
return I.geometry;
|
|
836
878
|
},
|
|
837
879
|
destroy() {
|
|
838
|
-
ee.destroy(),
|
|
880
|
+
clearTimeout(te), ee.destroy(), I.destroy(), de.destroy(), v.remove(), $.remove();
|
|
839
881
|
}
|
|
840
882
|
};
|
|
841
|
-
return
|
|
883
|
+
return N.addEventListener("click", () => O.hide()), A.addEventListener("click", () => O.minimize()), S.addEventListener("click", () => O.hide()), O;
|
|
842
884
|
}
|
|
843
|
-
function
|
|
885
|
+
function Ae(e, a) {
|
|
844
886
|
const n = new URL(e.href);
|
|
845
887
|
for (const [o, i] of Object.entries(a))
|
|
846
888
|
i != null && i !== "" && n.searchParams.set(o, i);
|
|
847
889
|
return a.token && (n.searchParams.delete("token"), n.hash = `token=${encodeURIComponent(a.token)}`), n.href;
|
|
848
890
|
}
|
|
849
|
-
const
|
|
850
|
-
let
|
|
851
|
-
const
|
|
852
|
-
function
|
|
891
|
+
const Be = "https://webphone.bravophone.com/embed/";
|
|
892
|
+
let L = null;
|
|
893
|
+
const B = /* @__PURE__ */ new Map();
|
|
894
|
+
function De(e, a) {
|
|
853
895
|
var n, o;
|
|
854
|
-
(n =
|
|
896
|
+
(n = B.get(e)) == null || n.forEach((i) => {
|
|
855
897
|
try {
|
|
856
898
|
i(a);
|
|
857
|
-
} catch (
|
|
858
|
-
console.error("[Bravophone] listener falhou:",
|
|
899
|
+
} catch (d) {
|
|
900
|
+
console.error("[Bravophone] listener falhou:", d);
|
|
859
901
|
}
|
|
860
|
-
}), (o =
|
|
902
|
+
}), (o = B.get("*")) == null || o.forEach((i) => {
|
|
861
903
|
try {
|
|
862
904
|
i({ event: e, payload: a });
|
|
863
|
-
} catch (
|
|
864
|
-
console.error("[Bravophone] listener falhou:",
|
|
905
|
+
} catch (d) {
|
|
906
|
+
console.error("[Bravophone] listener falhou:", d);
|
|
865
907
|
}
|
|
866
908
|
});
|
|
867
909
|
}
|
|
868
|
-
function
|
|
869
|
-
if (!
|
|
870
|
-
return
|
|
910
|
+
function m() {
|
|
911
|
+
if (!L) throw new Error("Bravophone: chame Bravophone.init() antes.");
|
|
912
|
+
return L;
|
|
871
913
|
}
|
|
872
|
-
const
|
|
914
|
+
const re = {
|
|
873
915
|
/**
|
|
874
916
|
* Monta o webphone na página.
|
|
875
917
|
* @param {object} opts
|
|
@@ -886,104 +928,108 @@ const ne = {
|
|
|
886
928
|
* precisa estar na allowlist de CORS dos backends.
|
|
887
929
|
*/
|
|
888
930
|
init(e = {}) {
|
|
889
|
-
if (
|
|
931
|
+
if (L) return L;
|
|
890
932
|
if (typeof window == "undefined" || !document.body)
|
|
891
933
|
throw new Error("Bravophone: init() precisa rodar no browser, após o <body> existir.");
|
|
892
|
-
return location.protocol !== "https:" && location.hostname !== "localhost" && console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."),
|
|
893
|
-
hostUrl:
|
|
894
|
-
version:
|
|
934
|
+
return location.protocol !== "https:" && location.hostname !== "localhost" && console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."), L = Ce({
|
|
935
|
+
hostUrl: Be,
|
|
936
|
+
version: re.version,
|
|
895
937
|
...e,
|
|
896
|
-
emit:
|
|
897
|
-
}),
|
|
938
|
+
emit: De
|
|
939
|
+
}), L;
|
|
898
940
|
},
|
|
899
941
|
// ---- Controle da janela ----
|
|
900
942
|
show() {
|
|
901
|
-
|
|
943
|
+
m().show();
|
|
902
944
|
},
|
|
903
945
|
hide() {
|
|
904
|
-
|
|
946
|
+
m().hide();
|
|
905
947
|
},
|
|
906
948
|
toggle() {
|
|
907
|
-
|
|
949
|
+
m().toggle();
|
|
950
|
+
},
|
|
951
|
+
/** Abre a janela; se já estiver aberta, traz para a vista e destaca. */
|
|
952
|
+
reveal() {
|
|
953
|
+
m().reveal();
|
|
908
954
|
},
|
|
909
955
|
minimize(e) {
|
|
910
|
-
|
|
956
|
+
m().minimize(e);
|
|
911
957
|
},
|
|
912
958
|
move(e, a) {
|
|
913
|
-
|
|
959
|
+
m().move(e, a);
|
|
914
960
|
},
|
|
915
961
|
resize(e, a) {
|
|
916
|
-
|
|
962
|
+
m().resize(e, a);
|
|
917
963
|
},
|
|
918
964
|
/** 'left' | 'right' | 'left-half' | 'right-half' | 'max' | 'float' */
|
|
919
965
|
dock(e) {
|
|
920
|
-
|
|
966
|
+
m().dock(e);
|
|
921
967
|
},
|
|
922
968
|
/** Move a aba de abertura para o outro lado da viewport. */
|
|
923
969
|
setLauncherSide(e) {
|
|
924
|
-
|
|
970
|
+
m().setLauncherSide(e);
|
|
925
971
|
},
|
|
926
972
|
/** 'phone-waves' | 'waveform' | 'headset' | 'chat-phone' */
|
|
927
973
|
setLauncherIcon(e) {
|
|
928
|
-
|
|
974
|
+
m().setLauncherIcon(e);
|
|
929
975
|
},
|
|
930
976
|
get isOpen() {
|
|
931
|
-
return
|
|
977
|
+
return L ? L.isOpen : !1;
|
|
932
978
|
},
|
|
933
979
|
get geometry() {
|
|
934
|
-
return
|
|
980
|
+
return L ? L.geometry : null;
|
|
935
981
|
},
|
|
936
982
|
// ---- Telefonia ----
|
|
937
983
|
/** Disca um número. Aceita formato livre; a normalização é a mesma da extensão. */
|
|
938
984
|
call(e, a) {
|
|
939
|
-
return
|
|
985
|
+
return m().bridge.call("call", { number: e, meta: a });
|
|
940
986
|
},
|
|
941
987
|
hangup() {
|
|
942
|
-
return
|
|
988
|
+
return m().bridge.call("hangup");
|
|
943
989
|
},
|
|
944
990
|
answer() {
|
|
945
|
-
return
|
|
991
|
+
return m().bridge.call("answer");
|
|
946
992
|
},
|
|
947
993
|
/** Alterna o mudo — o bundle só expõe toggle, não aceita estado alvo. */
|
|
948
994
|
mute() {
|
|
949
|
-
return
|
|
995
|
+
return m().bridge.call("mute");
|
|
950
996
|
},
|
|
951
997
|
/** Alterna a espera. Também toggle. */
|
|
952
998
|
hold() {
|
|
953
|
-
return
|
|
999
|
+
return m().bridge.call("hold");
|
|
954
1000
|
},
|
|
955
1001
|
sendDTMF(e) {
|
|
956
|
-
return
|
|
1002
|
+
return m().bridge.call("dtmf", { tone: e });
|
|
957
1003
|
},
|
|
958
1004
|
transfer(e) {
|
|
959
|
-
return
|
|
1005
|
+
return m().bridge.call("transfer", { to: e });
|
|
960
1006
|
},
|
|
961
1007
|
getStatus() {
|
|
962
|
-
return
|
|
1008
|
+
return m().bridge.call("status");
|
|
963
1009
|
},
|
|
964
1010
|
setAuth(e) {
|
|
965
|
-
return
|
|
1011
|
+
return m().bridge.call("auth", { token: e });
|
|
966
1012
|
},
|
|
967
1013
|
logout() {
|
|
968
|
-
return
|
|
1014
|
+
return m().bridge.call("logout");
|
|
969
1015
|
},
|
|
970
1016
|
// ---- Eventos ----
|
|
971
1017
|
/** Eventos: ready, state, call:dialing, call:incoming, call:answered,
|
|
972
1018
|
* call:ended, call:failed, resize, open, close, error. */
|
|
973
1019
|
on(e, a) {
|
|
974
|
-
return
|
|
1020
|
+
return B.has(e) || B.set(e, /* @__PURE__ */ new Set()), B.get(e).add(a), () => re.off(e, a);
|
|
975
1021
|
},
|
|
976
1022
|
off(e, a) {
|
|
977
1023
|
var n;
|
|
978
|
-
(n =
|
|
1024
|
+
(n = B.get(e)) == null || n.delete(a);
|
|
979
1025
|
},
|
|
980
1026
|
destroy() {
|
|
981
|
-
|
|
1027
|
+
L == null || L.destroy(), L = null, B.clear();
|
|
982
1028
|
},
|
|
983
1029
|
// Substituída em build time pelo valor do package.json (ver vite.config.js).
|
|
984
|
-
version: "0.2.
|
|
1030
|
+
version: "0.2.1"
|
|
985
1031
|
};
|
|
986
|
-
typeof window != "undefined" && (window.Bravophone =
|
|
1032
|
+
typeof window != "undefined" && (window.Bravophone = re);
|
|
987
1033
|
export {
|
|
988
|
-
|
|
1034
|
+
re as default
|
|
989
1035
|
};
|