@bravophone/webphone 0.1.2 → 0.2.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/README.md +49 -3
- package/dist/bravophone.mjs +358 -287
- package/dist/bravophone.umd.js +43 -7
- package/host/_locales/pt_BR/messages.json +1430 -0
- package/host/allowed-origins.json +8 -0
- package/host/css/bravophoneContactDialer.css +385 -0
- package/host/css/dark-theme.css +116 -0
- package/host/favicon.ico +0 -0
- package/host/fonts/Audiowide-Regular.ttf +0 -0
- package/host/fonts/Seguiemj.ttf +0 -0
- package/host/images/answer-gray.png +0 -0
- package/host/images/answer.png +0 -0
- package/host/images/auto-answer-off.png +0 -0
- package/host/images/auto-answer-on.png +0 -0
- package/host/images/avatar.png +0 -0
- package/host/images/bravophone-logo.svg +39 -0
- package/host/images/bravotech_Bravotech_logo.png +0 -0
- package/host/images/circle-green.png +0 -0
- package/host/images/circle-orange.png +0 -0
- package/host/images/circle-red.png +0 -0
- package/host/images/dialer-button-down.png +0 -0
- package/host/images/dialer-button.png +0 -0
- package/host/images/gateways/activecampaign.png +0 -0
- package/host/images/gateways/agendor.png +0 -0
- package/host/images/gateways/appfacilita.png +0 -0
- package/host/images/gateways/call-in.png +0 -0
- package/host/images/gateways/click-to-call.png +0 -0
- package/host/images/gateways/clickup.png +0 -0
- package/host/images/gateways/exactsales.png +0 -0
- package/host/images/gateways/go-high-lvl.png +0 -0
- package/host/images/gateways/groner.png +0 -0
- package/host/images/gateways/hubspot.png +0 -0
- package/host/images/gateways/kommo.png +0 -0
- package/host/images/gateways/moskit.png +0 -0
- package/host/images/gateways/nectar.png +0 -0
- package/host/images/gateways/pipedrive.png +0 -0
- package/host/images/gateways/pipefy.png +0 -0
- package/host/images/gateways/piperun.png +0 -0
- package/host/images/gateways/ploomes.png +0 -0
- package/host/images/gateways/rdstation-crm.png +0 -0
- package/host/images/gateways/salesforce.png +0 -0
- package/host/images/gateways/sharpspring.png +0 -0
- package/host/images/gateways/sunhub.png +0 -0
- package/host/images/gateways/vendfly.png +0 -0
- package/host/images/gateways/zendesk.png +0 -0
- package/host/images/gateways/zoho.png +0 -0
- package/host/images/hangup.png +0 -0
- package/host/images/hold.png +0 -0
- package/host/images/icons/logo-128-christmas-celebration.png +0 -0
- package/host/images/icons/logo-128.png +0 -0
- package/host/images/icons/logo-16-christmas-celebration.png +0 -0
- package/host/images/icons/logo-16.png +0 -0
- package/host/images/icons/logo-24-christmas-celebration.png +0 -0
- package/host/images/icons/logo-24.png +0 -0
- package/host/images/icons/logo-32-christmas-celebration.png +0 -0
- package/host/images/icons/logo-32.png +0 -0
- package/host/images/icons/logo-48-christmas-celebration.png +0 -0
- package/host/images/icons/logo-48.png +0 -0
- package/host/images/loading.gif +0 -0
- package/host/images/logo-bravotech-white.png +0 -0
- package/host/images/logo-bravotech.png +0 -0
- package/host/images/logo-inline-christmas-celebration.png +0 -0
- package/host/images/logo-inline.png +0 -0
- package/host/images/mic-off.png +0 -0
- package/host/images/mic-on.png +0 -0
- package/host/images/play.png +0 -0
- package/host/images/transfer.png +0 -0
- package/host/index.html +34 -0
- package/host/js/bravophone-noise-suppressor.js +418 -0
- package/host/js/bravophone-route-selector.js +1099 -0
- package/host/js/libwebphone.js +20 -0
- package/host/js/noise/LICENSE-web-noise-suppressor.txt +21 -0
- package/host/js/noise/rnnoise-worklet.js +13 -0
- package/host/js/noise/rnnoise.wasm +0 -0
- package/host/js/noise/rnnoise_simd.wasm +0 -0
- package/host/mock-webphone.js +195 -0
- package/host/mock.html +54 -0
- package/host/popup.js +23 -0
- package/host/shim/chrome-shim.js +287 -0
- package/host/shim/guest-bridge.js +353 -0
- package/host/shim/messages.js +13 -0
- package/host/styles/theme-fixes.css +92 -0
- package/package.json +4 -2
- package/types/index.d.ts +21 -1
package/dist/bravophone.umd.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(B,N){typeof exports=="object"&&typeof module!="undefined"?module.exports=N():typeof define=="function"&&define.amd?define(N):(B=typeof globalThis!="undefined"?globalThis:B||self,B.Bravophone=N())})(this,function(){"use strict";const B='stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"',N=`<svg viewBox="0 0 24 24" fill="none" ${B} 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>`,me=`<svg viewBox="0 0 24 24" fill="none" ${B} 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>`,xe=`<svg viewBox="0 0 24 24" fill="none" ${B} 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>`,we=`<svg viewBox="0 0 24 24" fill="none" ${B} 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>`,ye=`<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
|
-
</svg>`,
|
|
23
|
+
</svg>`,Y={"phone-waves":N,waveform:me,headset:xe,"chat-phone":we},te="phone-waves",ve=`
|
|
24
24
|
:host { all: initial; }
|
|
25
25
|
* { box-sizing: border-box; }
|
|
26
26
|
|
|
@@ -337,4 +337,40 @@
|
|
|
337
337
|
.bp-launcher-icon { transition: none; }
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
-
`,ie="bravophone:widget:geometry",q=28,J=32;function we(e){try{const a=localStorage.getItem(ie);if(!a)return{...e};const i=JSON.parse(a);return i.dock?{...e,...i,...U(i.dock,i)}:{...e,...i}}catch(a){return{...e}}}function X(e){try{localStorage.setItem(ie,JSON.stringify(e))}catch(a){}}function re(e){return{minWidth:e.minWidth,minHeight:e.minHeight,maxWidth:Math.max(e.minWidth,Math.min(e.maxWidth,window.innerWidth)),maxHeight:Math.max(e.minHeight,Math.min(e.maxHeight,window.innerHeight))}}function O(e){const a=Math.max(0,window.innerWidth-e.width),i=Math.max(0,window.innerHeight-40);return{...e,x:Math.min(Math.max(0,e.x),a),y:Math.min(Math.max(0,e.y),i)}}function U(e,a){const i=window.innerWidth,r=window.innerHeight,o=Math.round(i/2),s=Math.round(r/2),u=Math.min(a.width,i);switch(e){case"left":return{x:0,y:0,width:u,height:r};case"right":return{x:i-u,y:0,width:u,height:r};case"left-half":return{x:0,y:0,width:o,height:r};case"right-half":return{x:i-o,y:0,width:o,height:r};case"top":return{x:a.x,y:0,width:u,height:s};case"bottom":return{x:a.x,y:r-s,width:u,height:s};case"top-half":return{x:0,y:0,width:i,height:s};case"bottom-half":return{x:0,y:r-s,width:i,height:s};case"max":return{x:0,y:0,width:i,height:r};default:return{x:a.x,y:a.y,width:a.width,height:a.height}}}function ye(e,a,i){const r=window.innerWidth,o=window.innerHeight,s=e<=q,u=e>=r-q,x=a<=q,t=a>=o-q;return(x||t)&&s?"left-half":(x||t)&&u?"right-half":x?i||"max":t?"bottom-half":s?"left":u?"right":null}function ve({root:e,handle:a,handles:i,preview:r,geometry:o,limits:s,topDock:u,onChange:x}){let t={...o},g=null,p="",d=null,h=null,y=null,v=null;const z=()=>{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),x==null||x(t)},A=n=>{if(r){if(!n){r.hidden=!0;return}r.hidden=!1,r.style.left=`${n.x}px`,r.style.top=`${n.y}px`,r.style.width=`${n.width}px`,r.style.height=`${n.height}px`}},$=(n,b)=>{const l=re(s);let{x:E,y:f,width:k,height:H}=d;p.includes("e")&&(k=d.width+n),p.includes("w")&&(k=d.width-n),p.includes("s")&&(H=d.height+b),p.includes("n")&&(H=d.height-b),k=Math.min(l.maxWidth,Math.max(l.minWidth,k)),H=Math.min(l.maxHeight,Math.max(l.minHeight,H)),p.includes("w")&&(E=d.x+(d.width-k)),p.includes("n")&&(f=d.y+(d.height-H)),p.includes("e")&&Math.abs(E+k-window.innerWidth)<=J&&(k=window.innerWidth-E),p.includes("w")&&Math.abs(E)<=J&&(k+=E,E=0),p.includes("s")&&Math.abs(f+H-window.innerHeight)<=J&&(H=window.innerHeight-f),p.includes("n")&&Math.abs(f)<=J&&(H+=f,f=0),t={...t,x:E,y:f,width:k,height:H,dock:null},z()},R=(n,b,l,E)=>{if(t.dock){const f=v||{width:s.width,height:s.height},k=h.x/Math.max(1,t.width);t={...t,...f,dock:null},h={x:Math.round(f.width*k),y:Math.min(h.y,32)},d={...d,x:l-h.x,y:E-h.y,px:d.px+n,py:d.py+b},n=0,b=0}t=O({...t,x:d.x+n,y:d.y+b}),z(),y=ye(l,E,u),A(y?U(y,t):null)},P=()=>{y&&(v=v||{width:t.width,height:t.height},t={...t,...U(y,t),dock:y},z())},F=(n,b)=>l=>{l.button===0&&(n==="drag"&&l.target.closest(".bp-btn")||(g=n,p=b||"",d={px:l.clientX,py:l.clientY,...t},h={x:l.clientX-t.x,y:l.clientY-t.y},t.dock||(v={width:t.width,height:t.height}),e.classList.add(n==="drag"?"bp-dragging":"bp-resizing"),l.currentTarget.setPointerCapture(l.pointerId),l.preventDefault()))},Y=n=>{if(!g||!d)return;const b=n.clientX-d.px,l=n.clientY-d.py;g==="drag"?R(b,l,n.clientX,n.clientY):$(b,l)},D=n=>{if(g){e.classList.remove("bp-dragging","bp-resizing"),A(null),g==="drag"&&P(),g=null,p="",d=null,y=null;try{n.currentTarget.releasePointerCapture(n.pointerId)}catch(b){}X(t)}};a.addEventListener("pointerdown",F("drag")),a.addEventListener("pointermove",Y),a.addEventListener("pointerup",D),a.addEventListener("pointercancel",D),(i||[]).forEach(({el:n,dir:b})=>{n.addEventListener("pointerdown",F("resize",b)),n.addEventListener("pointermove",Y),n.addEventListener("pointerup",D),n.addEventListener("pointercancel",D)});const ae=()=>{t=t.dock?{...t,...U(t.dock,t)}:O(t),z()};window.addEventListener("resize",ae);const K={start(n){var b,l;g="drag",d={px:n.x,py:n.y,...t},h={x:(b=n.cx)!=null?b:t.width/2,y:(l=n.cy)!=null?l:20},t.dock||(v={width:t.width,height:t.height}),e.classList.add("bp-dragging")},move(n){if(g!=="drag"||!d)return;const b=n.x-d.px,l=n.y-d.py;R(b,l,d.x+b+h.x,d.y+l+h.y)},end(){g==="drag"&&(e.classList.remove("bp-dragging"),A(null),P(),g=null,d=null,y=null,X(t))}};return z(),{external:K,get geometry(){return{...t}},set(n){const b=re(s),l={...t,...n,dock:null};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=O(l),z(),X(t)},dock(n){if(!n||n==="float"){const b=v||{width:s.width,height:s.height};t=O({...t,...b,dock:null})}else t.dock||(v={width:t.width,height:t.height}),t={...t,...U(n,t),dock:n};z(),X(t)},destroy(){window.removeEventListener("resize",ae)}}}const oe="bravophone/v1";function ke({frame:e,origin:a,onEvent:i}){const r=new Map;let o=0,s=!1;const u=[],x=g=>{var d;if(g.origin!==a||g.source!==e.contentWindow)return;const p=g.data;if(!(!p||p.protocol!==oe)){if(p.type==="ready"){for(s=!0;u.length;)u.shift()();i==null||i("ready",(d=p.payload)!=null?d:{});return}if(p.type==="reply"){const h=r.get(p.id);if(!h)return;r.delete(p.id),clearTimeout(h.timer),p.error?h.reject(new Error(p.error)):h.resolve(p.payload);return}p.type==="event"&&(i==null||i(p.name,p.payload))}};window.addEventListener("message",x);function t(g,p,{timeout:d=15e3}={}){return new Promise((h,y)=>{const v=`${Date.now()}-${++o}`,z=()=>{var $;const A=setTimeout(()=>{r.delete(v),y(new Error(`Bravophone: timeout no comando "${g}"`))},d);r.set(v,{resolve:h,reject:y,timer:A}),($=e.contentWindow)==null||$.postMessage({protocol:oe,type:"command",id:v,command:g,payload:p},a)};s?z():u.push(z)})}return{call:t,get ready(){return s},destroy(){window.removeEventListener("message",x),r.forEach(({reject:g,timer:p})=>{clearTimeout(p),g(new Error("Bravophone: widget destruído"))}),r.clear()}}}const se="bravophone:launcher",Me=4,Q=8;function ze(e){try{const a=localStorage.getItem(se);return a?{...e,...JSON.parse(a)}:{...e}}catch(a){return{...e}}}function ee(e){try{localStorage.setItem(se,JSON.stringify(e))}catch(a){}}function _(e,a){const i=Math.max(Q,window.innerHeight-a-Q);return Math.min(Math.max(Q,e),i)}function Le({el:e,side:a,y:i,onOpen:r}){let o={side:a,y:_(i,e.offsetHeight||48)},s=null,u=!1;const x=()=>{e.dataset.side=o.side,e.style.top=`${o.y}px`,e.style.right=o.side==="right"?"0px":"auto",e.style.left=o.side==="left"?"0px":"auto"},t=h=>{h.button===0&&(s={py:h.clientY,y:o.y},u=!1,e.setPointerCapture(h.pointerId))},g=h=>{if(!s)return;const y=h.clientY-s.py;!u&&Math.abs(y)<Me||(u||(u=!0,e.classList.add("bp-launcher-dragging")),o.y=_(s.y+y,e.offsetHeight),x())},p=h=>{if(!s)return;const y=u;s=null,u=!1,e.classList.remove("bp-launcher-dragging");try{e.releasePointerCapture(h.pointerId)}catch(v){}y?ee(o):r==null||r()};e.addEventListener("pointerdown",t),e.addEventListener("pointermove",g),e.addEventListener("pointerup",p),e.addEventListener("pointercancel",p),e.addEventListener("keydown",h=>{(h.key==="Enter"||h.key===" ")&&(h.preventDefault(),r==null||r())});const d=()=>{o.y=_(o.y,e.offsetHeight),x()};return window.addEventListener("resize",d),x(),{get state(){return{...o}},setSide(h){o.side=h,x(),ee(o)},moveTo(h){o.y=_(h,e.offsetHeight),x(),ee(o)},destroy(){window.removeEventListener("resize",d)}}}const de={width:380,height:640,minWidth:320,minHeight:420,maxWidth:1600,maxHeight:1400,margin:24};function w(e,a={},i=[]){const r=document.createElement(e);for(const[o,s]of Object.entries(a))o==="class"?r.className=s:o==="text"?r.textContent=s:s!=null&&r.setAttribute(o,s);return i.forEach(o=>r.appendChild(o)),r}function Se(e){const{hostUrl:a,token:i,position:r="bottom-right",open:o=!1,launcher:s=!0,title:u="BRAVOPHONE",frame:x="none",dockTop:t="max",launcherSide:g="right",launcherIcon:p=Z,emit:d}=e,h=new URL(a),y=h.origin,v=w("div",{"data-bravophone":"root"});v.style.cssText="all:initial;position:static";const z=v.attachShadow({mode:"open"});z.appendChild(w("style",{text:xe}));const A=(()=>{var be;const{width:c,height:S,margin:I}=de,G=window.innerWidth-c-I,he=window.innerHeight-S-I,le={"bottom-right":{x:G,y:he},"bottom-left":{x:I,y:he},"top-right":{x:G,y:I},"top-left":{x:I,y:I}};return O({...(be=le[r])!=null?be:le["bottom-right"],width:c,height:S})})(),$=O(we(A)),R=w("span",{class:"bp-status","data-state":"connecting"}),P=w("button",{class:"bp-btn bp-btn-min",title:"Minimizar",text:"—"}),F=w("button",{class:"bp-btn bp-btn-close",title:"Fechar",text:"×"}),Y=w("div",{class:"bp-header"},[R,w("span",{class:"bp-title",text:u}),P,F]),D=w("iframe",{class:"bp-frame",src:Ee(h,{token:i,embed:"1",parent:location.origin}),allow:"microphone; autoplay; clipboard-write; speaker-selection",title:"Webphone BRAVOPHONE"}),K=["n","s","w","e","nw","ne","sw","se"].map(c=>({el:w("div",{class:`bp-h bp-h-${c}`}),dir:c})),n=w("div",{class:"bp-preview"});n.hidden=!0;const b=w("button",{class:"bp-btn bp-btn-close",title:"Fechar",text:"×"}),l=w("div",{class:"bp-overlay"},[b]),E=w("div",{class:"bp-body"},[D,l]),f=w("div",{class:"bp-root"},[Y,E,...K.map(c=>c.el)]);x!=="bar"&&f.classList.add("bp-chromeless"),f.hidden=!o;const k=w("span",{class:"bp-launcher-icon"});k.innerHTML=j[p]||j[Z];const H=w("span",{class:"bp-launcher-grip","aria-hidden":"true"});H.innerHTML=me;const L=w("div",{class:"bp-launcher",role:"button",tabindex:"0",title:"Abrir webphone","aria-label":"Abrir webphone"},[H,k,w("span",{class:"bp-badge"})]);L.dataset.state="connecting",L.hidden=!s||o,z.append(n,f,L),document.body.appendChild(v);const ce=ze({side:g,y:Math.round(window.innerHeight/2-24)}),pe=Le({el:L,side:ce.side,y:_(ce.y,48),onOpen:()=>T.show()}),C=ve({root:f,handle:Y,handles:K,preview:n,geometry:$,limits:de,topDock:t,onChange:c=>d("resize",{width:c.width,height:c.height,dock:c.dock||null})}),ne=ke({frame:D,origin:y,onEvent:(c,S)=>{var I;if(c==="ready"&&(R.dataset.state="ready",L.dataset.state="ready",i&&ne.call("auth",{token:i}).catch(()=>{})),c==="state"){const G=(I=S==null?void 0:S.state)!=null?I:"ready";R.dataset.state=G,L.dataset.state=G}if(c==="call:incoming"&&(T.show(),L.dataset.badge="1",L.dataset.state="ringing"),c==="call:answered"&&(L.dataset.state="incall"),(c==="call:ended"||c==="call:failed")&&(delete L.dataset.badge,L.dataset.state="ready"),c==="drag:start"){C.external.start(S);return}if(c==="drag:move"){C.external.move(S);return}if(c==="drag:end"){C.external.end();return}d(c,S)}});let V=!1;const T={el:v,bridge:ne,show(){f.hidden=!1,L.hidden=!0,d("open")},hide(){f.hidden=!0,s&&(L.hidden=!1),d("close")},toggle(){f.hidden?T.show():T.hide()},get isOpen(){return!f.hidden},minimize(c){if(x!=="bar"){T.hide();return}V=c!=null?c:!V,f.classList.toggle("bp-minimized",V),P.textContent=V?"▢":"—"},move(c,S){C.set({x:c,y:S})},resize(c,S){C.set({width:c,height:S})},dock(c){C.dock(c)},setLauncherSide(c){pe.setSide(c)},setLauncherIcon(c){k.innerHTML=j[c]||j[Z]},get geometry(){return C.geometry},destroy(){ne.destroy(),C.destroy(),pe.destroy(),n.remove(),v.remove()}};return F.addEventListener("click",()=>T.hide()),P.addEventListener("click",()=>T.minimize()),b.addEventListener("click",()=>T.hide()),T}function Ee(e,a){const i=new URL(e.href);for(const[r,o]of Object.entries(a))o!=null&&o!==""&&i.searchParams.set(r,o);return a.token&&(i.searchParams.delete("token"),i.hash=`token=${encodeURIComponent(a.token)}`),i.href}const He="https://webphone.bravophone.com/embed/";let M=null;const B=new Map;function Te(e,a){var i,r;(i=B.get(e))==null||i.forEach(o=>{try{o(a)}catch(s){console.error("[Bravophone] listener falhou:",s)}}),(r=B.get("*"))==null||r.forEach(o=>{try{o({event:e,payload:a})}catch(s){console.error("[Bravophone] listener falhou:",s)}})}function m(){if(!M)throw new Error("Bravophone: chame Bravophone.init() antes.");return M}const te={init(e={}){if(M)return M;if(typeof window=="undefined"||!document.body)throw new Error("Bravophone: init() precisa rodar no browser, após o <body> existir.");return location.protocol!=="https:"&&location.hostname!=="localhost"&&console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."),M=Se({hostUrl:He,...e,emit:Te}),M},show(){m().show()},hide(){m().hide()},toggle(){m().toggle()},minimize(e){m().minimize(e)},move(e,a){m().move(e,a)},resize(e,a){m().resize(e,a)},dock(e){m().dock(e)},setLauncherSide(e){m().setLauncherSide(e)},setLauncherIcon(e){m().setLauncherIcon(e)},get isOpen(){return M?M.isOpen:!1},get geometry(){return M?M.geometry:null},call(e,a){return m().bridge.call("call",{number:e,meta:a})},hangup(){return m().bridge.call("hangup")},answer(){return m().bridge.call("answer")},mute(){return m().bridge.call("mute")},hold(){return m().bridge.call("hold")},sendDTMF(e){return m().bridge.call("dtmf",{tone:e})},transfer(e){return m().bridge.call("transfer",{to:e})},getStatus(){return m().bridge.call("status")},setAuth(e){return m().bridge.call("auth",{token:e})},logout(){return m().bridge.call("logout")},on(e,a){return B.has(e)||B.set(e,new Set),B.get(e).add(a),()=>te.off(e,a)},off(e,a){var i;(i=B.get(e))==null||i.delete(a)},destroy(){M==null||M.destroy(),M=null,B.clear()},version:"0.1.2"};return typeof window!="undefined"&&(window.Bravophone=te),te});
|
|
340
|
+
`,oe="bravophone:widget:geometry",q=28,J=32;function ke(e){try{const i=localStorage.getItem(oe);if(!i)return{...e};const a=JSON.parse(i);return a.dock?{...e,...a,...P(a.dock,a)}:{...e,...a}}catch(i){return{...e}}}function V(e){try{localStorage.setItem(oe,JSON.stringify(e))}catch(i){}}function se(e){return{minWidth:e.minWidth,minHeight:e.minHeight,maxWidth:Math.max(e.minWidth,Math.min(e.maxWidth,window.innerWidth)),maxHeight:Math.max(e.minHeight,Math.min(e.maxHeight,window.innerHeight))}}function R(e){const i=Math.max(0,window.innerWidth-e.width),a=Math.max(0,window.innerHeight-40);return{...e,x:Math.min(Math.max(0,e.x),i),y:Math.min(Math.max(0,e.y),a)}}function P(e,i){const a=window.innerWidth,o=window.innerHeight,n=Math.round(a/2),s=Math.round(o/2),u=Math.min(i.width,a);switch(e){case"left":return{x:0,y:0,width:u,height:o};case"right":return{x:a-u,y:0,width:u,height:o};case"left-half":return{x:0,y:0,width:n,height:o};case"right-half":return{x:a-n,y:0,width:n,height:o};case"top":return{x:i.x,y:0,width:u,height:s};case"bottom":return{x:i.x,y:o-s,width:u,height:s};case"top-half":return{x:0,y:0,width:a,height:s};case"bottom-half":return{x:0,y:o-s,width:a,height:s};case"max":return{x:0,y:0,width:a,height:o};default:return{x:i.x,y:i.y,width:i.width,height:i.height}}}function Me(e,i,a){const o=window.innerWidth,n=window.innerHeight,s=e<=q,u=e>=o-q,m=i<=q,t=i>=n-q;return(m||t)&&s?"left-half":(m||t)&&u?"right-half":m?a||"max":t?"bottom-half":s?"left":u?"right":null}function ze({root:e,handle:i,handles:a,preview:o,geometry:n,limits:s,topDock:u,onChange:m}){let t={...n},g=null,p="",d=null,l=null,w=null,y=null;const M=()=>{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),m==null||m(t)},W=r=>{if(o){if(!r){o.hidden=!0;return}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`}},T=(r,b)=>{const h=se(s);let{x:v,y:z,width:L,height:H}=d;p.includes("e")&&(L=d.width+r),p.includes("w")&&(L=d.width-r),p.includes("s")&&(H=d.height+b),p.includes("n")&&(H=d.height-b),L=Math.min(h.maxWidth,Math.max(h.minWidth,L)),H=Math.min(h.maxHeight,Math.max(h.minHeight,H)),p.includes("w")&&(v=d.x+(d.width-L)),p.includes("n")&&(z=d.y+(d.height-H)),p.includes("e")&&Math.abs(v+L-window.innerWidth)<=J&&(L=window.innerWidth-v),p.includes("w")&&Math.abs(v)<=J&&(L+=v,v=0),p.includes("s")&&Math.abs(z+H-window.innerHeight)<=J&&(H=window.innerHeight-z),p.includes("n")&&Math.abs(z)<=J&&(H+=z,z=0),t={...t,x:v,y:z,width:L,height:H,dock:null},M()},_=(r,b,h,v)=>{if(t.dock){const z=y||{width:s.width,height:s.height},L=l.x/Math.max(1,t.width);t={...t,...z,dock:null},l={x:Math.round(z.width*L),y:Math.min(l.y,32)},d={...d,x:h-l.x,y:v-l.y,px:d.px+r,py:d.py+b},r=0,b=0}t=R({...t,x:d.x+r,y:d.y+b}),M(),w=Me(h,v,u),W(w?P(w,t):null)},K=()=>{w&&(y=y||{width:t.width,height:t.height},t={...t,...P(w,t),dock:w},M())},Z=(r,b)=>h=>{h.button===0&&(r==="drag"&&h.target.closest(".bp-btn")||(g=r,p=b||"",d={px:h.clientX,py:h.clientY,...t},l={x:h.clientX-t.x,y:h.clientY-t.y},t.dock||(y={width:t.width,height:t.height}),e.classList.add(r==="drag"?"bp-dragging":"bp-resizing"),h.currentTarget.setPointerCapture(h.pointerId),h.preventDefault()))},j=r=>{if(!g||!d)return;const b=r.clientX-d.px,h=r.clientY-d.py;g==="drag"?_(b,h,r.clientX,r.clientY):T(b,h)},C=r=>{if(g){e.classList.remove("bp-dragging","bp-resizing"),W(null),g==="drag"&&K(),g=null,p="",d=null,w=null;try{r.currentTarget.releasePointerCapture(r.pointerId)}catch(b){}V(t)}};i.addEventListener("pointerdown",Z("drag")),i.addEventListener("pointermove",j),i.addEventListener("pointerup",C),i.addEventListener("pointercancel",C),(a||[]).forEach(({el:r,dir:b})=>{r.addEventListener("pointerdown",Z("resize",b)),r.addEventListener("pointermove",j),r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C)});const F=()=>{t=t.dock?{...t,...P(t.dock,t)}:R(t),M()};window.addEventListener("resize",F);const Q={start(r){var b,h;g="drag",d={px:r.x,py:r.y,...t},l={x:(b=r.cx)!=null?b:t.width/2,y:(h=r.cy)!=null?h:20},t.dock||(y={width:t.width,height:t.height}),e.classList.add("bp-dragging")},move(r){if(g!=="drag"||!d)return;const b=r.x-d.px,h=r.y-d.py;_(b,h,d.x+b+l.x,d.y+h+l.y)},end(){g==="drag"&&(e.classList.remove("bp-dragging"),W(null),K(),g=null,d=null,w=null,V(t))}};return M(),{external:Q,get geometry(){return{...t}},set(r){const b=se(s),h={...t,...r,dock:null};h.width=Math.min(b.maxWidth,Math.max(b.minWidth,h.width)),h.height=Math.min(b.maxHeight,Math.max(b.minHeight,h.height)),t=R(h),M(),V(t)},dock(r){if(!r||r==="float"){const b=y||{width:s.width,height:s.height};t=R({...t,...b,dock:null})}else t.dock||(y={width:t.width,height:t.height}),t={...t,...P(r,t),dock:r};M(),V(t)},destroy(){window.removeEventListener("resize",F)}}}const de="bravophone/v1";function Le({frame:e,origin:i,onEvent:a}){const o=new Map;let n=0,s=!1;const u=[],m=g=>{var d;if(g.origin!==i||g.source!==e.contentWindow)return;const p=g.data;if(!(!p||p.protocol!==de)){if(p.type==="ready"){for(s=!0;u.length;)u.shift()();a==null||a("ready",(d=p.payload)!=null?d:{});return}if(p.type==="reply"){const l=o.get(p.id);if(!l)return;o.delete(p.id),clearTimeout(l.timer),p.error?l.reject(new Error(p.error)):l.resolve(p.payload);return}p.type==="event"&&(a==null||a(p.name,p.payload))}};window.addEventListener("message",m);function t(g,p,{timeout:d=15e3}={}){return new Promise((l,w)=>{const y=`${Date.now()}-${++n}`,M=()=>{var T;const W=setTimeout(()=>{o.delete(y),w(new Error(`Bravophone: timeout no comando "${g}"`))},d);o.set(y,{resolve:l,reject:w,timer:W}),(T=e.contentWindow)==null||T.postMessage({protocol:de,type:"command",id:y,command:g,payload:p},i)};s?M():u.push(M)})}return{call:t,get ready(){return s},destroy(){window.removeEventListener("message",m),o.forEach(({reject:g,timer:p})=>{clearTimeout(p),g(new Error("Bravophone: widget destruído"))}),o.clear()}}}const ce="bravophone:launcher",Se=4,ie=8;function Ee(e){try{const i=localStorage.getItem(ce);return i?{...e,...JSON.parse(i)}:{...e}}catch(i){return{...e}}}function ne(e){try{localStorage.setItem(ce,JSON.stringify(e))}catch(i){}}function U(e,i){const a=Math.max(ie,window.innerHeight-i-ie);return Math.min(Math.max(ie,e),a)}function He({el:e,side:i,y:a,onOpen:o}){let n={side:i,y:U(a,e.offsetHeight||48)},s=null,u=!1;const m=()=>{e.dataset.side=n.side,e.style.top=`${n.y}px`,e.style.right=n.side==="right"?"0px":"auto",e.style.left=n.side==="left"?"0px":"auto"},t=l=>{l.button===0&&(s={py:l.clientY,y:n.y},u=!1,e.setPointerCapture(l.pointerId))},g=l=>{if(!s)return;const w=l.clientY-s.py;!u&&Math.abs(w)<Se||(u||(u=!0,e.classList.add("bp-launcher-dragging")),n.y=U(s.y+w,e.offsetHeight),m())},p=l=>{if(!s)return;const w=u;s=null,u=!1,e.classList.remove("bp-launcher-dragging");try{e.releasePointerCapture(l.pointerId)}catch(y){}w?ne(n):o==null||o()};e.addEventListener("pointerdown",t),e.addEventListener("pointermove",g),e.addEventListener("pointerup",p),e.addEventListener("pointercancel",p),e.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),o==null||o())});const d=()=>{n.y=U(n.y,e.offsetHeight),m()};return window.addEventListener("resize",d),m(),{get state(){return{...n}},setSide(l){n.side=l,m(),ne(n)},moveTo(l){n.y=U(l,e.offsetHeight),m(),ne(n)},destroy(){window.removeEventListener("resize",d)}}}const Te="https://cdn.jsdelivr.net/npm";function $e(e,i="@bravophone/webphone"){return`${Te}/${i}@${e}/host/`}function Ie({version:e,parentOrigin:i,token:a,base:o}){const n=o||$e(e),s=JSON.stringify({parentOrigin:i,token:a||null}).replace(/</g,"\\u003c");return`<!doctype html>
|
|
341
|
+
<html lang="pt-BR">
|
|
342
|
+
<head>
|
|
343
|
+
<meta charset="UTF-8">
|
|
344
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
345
|
+
<title>Webphone BRAVOPHONE</title>
|
|
346
|
+
<link rel="stylesheet" href="${n}css/dark-theme.css">
|
|
347
|
+
<link rel="stylesheet" href="${n}styles/theme-fixes.css">
|
|
348
|
+
<style>
|
|
349
|
+
html, body { margin: 0; height: 100%; background: #10131c; overflow: hidden; }
|
|
350
|
+
#app { height: 100%; }
|
|
351
|
+
</style>
|
|
352
|
+
<script>
|
|
353
|
+
(function () {
|
|
354
|
+
var cfg = ${s};
|
|
355
|
+
// O guest-bridge lê daqui: em srcdoc não há query string para carregar a
|
|
356
|
+
// origem do pai.
|
|
357
|
+
window.__bpParentOrigin = cfg.parentOrigin;
|
|
358
|
+
if (cfg.token) {
|
|
359
|
+
// Grava onde o bundle procura, antes dele avaliar, para a sessão já subir
|
|
360
|
+
// autenticada em vez de piscar a tela de login.
|
|
361
|
+
try { localStorage.setItem('bp.local.vxToken', JSON.stringify(cfg.token)); } catch (e) {}
|
|
362
|
+
}
|
|
363
|
+
})();
|
|
364
|
+
<\/script>
|
|
365
|
+
<script src="${n}shim/messages.js"><\/script>
|
|
366
|
+
<script src="${n}shim/chrome-shim.js"><\/script>
|
|
367
|
+
<script src="${n}js/libwebphone.js"><\/script>
|
|
368
|
+
<script src="${n}js/bravophone-route-selector.js"><\/script>
|
|
369
|
+
<script defer src="${n}popup.js"><\/script>
|
|
370
|
+
<script defer src="${n}shim/guest-bridge.js"><\/script>
|
|
371
|
+
</head>
|
|
372
|
+
<body>
|
|
373
|
+
<noscript><strong>O webphone precisa de JavaScript habilitado.</strong></noscript>
|
|
374
|
+
<div id="app"></div>
|
|
375
|
+
</body>
|
|
376
|
+
</html>`}const pe={width:380,height:640,minWidth:320,minHeight:420,maxWidth:1600,maxHeight:1400,margin:24};function x(e,i={},a=[]){const o=document.createElement(e);for(const[n,s]of Object.entries(i))n==="class"?o.className=s:n==="text"?o.textContent=s:s!=null&&o.setAttribute(n,s);return a.forEach(n=>o.appendChild(n)),o}function Oe(e){const{hostUrl:i,token:a,position:o="bottom-right",open:n=!1,launcher:s=!0,title:u="BRAVOPHONE",frame:m="none",dockTop:t="max",launcherSide:g="right",launcherIcon:p=te,mode:d="hosted",hostBase:l,version:w,emit:y}=e,M=d==="srcdoc",W=M?window.location.origin:new URL(i).origin,T=x("div",{"data-bravophone":"root"});T.style.cssText="all:initial;position:static";const _=T.attachShadow({mode:"open"});_.appendChild(x("style",{text:ve}));const K=(()=>{var fe;const{width:c,height:E,margin:O}=pe,G=window.innerWidth-c-O,ue=window.innerHeight-E-O,ge={"bottom-right":{x:G,y:ue},"bottom-left":{x:O,y:ue},"top-right":{x:G,y:O},"top-left":{x:O,y:O}};return R({...(fe=ge[o])!=null?fe:ge["bottom-right"],width:c,height:E})})(),Z=R(ke(K)),j=x("span",{class:"bp-status","data-state":"connecting"}),C=x("button",{class:"bp-btn bp-btn-min",title:"Minimizar",text:"—"}),F=x("button",{class:"bp-btn bp-btn-close",title:"Fechar",text:"×"}),Q=x("div",{class:"bp-header"},[j,x("span",{class:"bp-title",text:u}),C,F]),r=x("iframe",{class:"bp-frame",allow:"microphone; autoplay; clipboard-write; speaker-selection",title:"Webphone BRAVOPHONE"});M?r.setAttribute("srcdoc",Ie({version:w,parentOrigin:W,token:a,base:l})):r.setAttribute("src",Be(new URL(i),{token:a,embed:"1",parent:location.origin}));const h=["n","s","w","e","nw","ne","sw","se"].map(c=>({el:x("div",{class:`bp-h bp-h-${c}`}),dir:c})),v=x("div",{class:"bp-preview"});v.hidden=!0;const z=x("button",{class:"bp-btn bp-btn-close",title:"Fechar",text:"×"}),L=x("div",{class:"bp-overlay"},[z]),H=x("div",{class:"bp-body"},[r,L]),$=x("div",{class:"bp-root"},[Q,H,...h.map(c=>c.el)]);m!=="bar"&&$.classList.add("bp-chromeless"),$.hidden=!n;const ae=x("span",{class:"bp-launcher-icon"});ae.innerHTML=Y[p]||Y[te];const he=x("span",{class:"bp-launcher-grip","aria-hidden":"true"});he.innerHTML=ye;const S=x("div",{class:"bp-launcher",role:"button",tabindex:"0",title:"Abrir webphone","aria-label":"Abrir webphone"},[he,ae,x("span",{class:"bp-badge"})]);S.dataset.state="connecting",S.hidden=!s||n,_.append(v,$,S),document.body.appendChild(T);const le=Ee({side:g,y:Math.round(window.innerHeight/2-24)}),be=He({el:S,side:le.side,y:U(le.y,48),onOpen:()=>I.show()}),A=ze({root:$,handle:Q,handles:h,preview:v,geometry:Z,limits:pe,topDock:t,onChange:c=>y("resize",{width:c.width,height:c.height,dock:c.dock||null})}),re=Le({frame:r,origin:W,onEvent:(c,E)=>{var O;if(c==="ready"&&(j.dataset.state="ready",S.dataset.state="ready",a&&re.call("auth",{token:a}).catch(()=>{})),c==="state"){const G=(O=E==null?void 0:E.state)!=null?O:"ready";j.dataset.state=G,S.dataset.state=G}if(c==="call:incoming"&&(I.show(),S.dataset.badge="1",S.dataset.state="ringing"),c==="call:answered"&&(S.dataset.state="incall"),(c==="call:ended"||c==="call:failed")&&(delete S.dataset.badge,S.dataset.state="ready"),c==="drag:start"){A.external.start(E);return}if(c==="drag:move"){A.external.move(E);return}if(c==="drag:end"){A.external.end();return}y(c,E)}});let ee=!1;const I={el:T,bridge:re,show(){$.hidden=!1,S.hidden=!0,y("open")},hide(){$.hidden=!0,s&&(S.hidden=!1),y("close")},toggle(){$.hidden?I.show():I.hide()},get isOpen(){return!$.hidden},minimize(c){if(m!=="bar"){I.hide();return}ee=c!=null?c:!ee,$.classList.toggle("bp-minimized",ee),C.textContent=ee?"▢":"—"},move(c,E){A.set({x:c,y:E})},resize(c,E){A.set({width:c,height:E})},dock(c){A.dock(c)},setLauncherSide(c){be.setSide(c)},setLauncherIcon(c){ae.innerHTML=Y[c]||Y[te]},get geometry(){return A.geometry},destroy(){re.destroy(),A.destroy(),be.destroy(),v.remove(),T.remove()}};return F.addEventListener("click",()=>I.hide()),C.addEventListener("click",()=>I.minimize()),z.addEventListener("click",()=>I.hide()),I}function Be(e,i){const a=new URL(e.href);for(const[o,n]of Object.entries(i))n!=null&&n!==""&&a.searchParams.set(o,n);return i.token&&(a.searchParams.delete("token"),a.hash=`token=${encodeURIComponent(i.token)}`),a.href}const We="https://webphone.bravophone.com/embed/";let k=null;const D=new Map;function Ce(e,i){var a,o;(a=D.get(e))==null||a.forEach(n=>{try{n(i)}catch(s){console.error("[Bravophone] listener falhou:",s)}}),(o=D.get("*"))==null||o.forEach(n=>{try{n({event:e,payload:i})}catch(s){console.error("[Bravophone] listener falhou:",s)}})}function f(){if(!k)throw new Error("Bravophone: chame Bravophone.init() antes.");return k}const X={init(e={}){if(k)return k;if(typeof window=="undefined"||!document.body)throw new Error("Bravophone: init() precisa rodar no browser, após o <body> existir.");return location.protocol!=="https:"&&location.hostname!=="localhost"&&console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."),k=Oe({hostUrl:We,version:X.version,...e,emit:Ce}),k},show(){f().show()},hide(){f().hide()},toggle(){f().toggle()},minimize(e){f().minimize(e)},move(e,i){f().move(e,i)},resize(e,i){f().resize(e,i)},dock(e){f().dock(e)},setLauncherSide(e){f().setLauncherSide(e)},setLauncherIcon(e){f().setLauncherIcon(e)},get isOpen(){return k?k.isOpen:!1},get geometry(){return k?k.geometry:null},call(e,i){return f().bridge.call("call",{number:e,meta:i})},hangup(){return f().bridge.call("hangup")},answer(){return f().bridge.call("answer")},mute(){return f().bridge.call("mute")},hold(){return f().bridge.call("hold")},sendDTMF(e){return f().bridge.call("dtmf",{tone:e})},transfer(e){return f().bridge.call("transfer",{to:e})},getStatus(){return f().bridge.call("status")},setAuth(e){return f().bridge.call("auth",{token:e})},logout(){return f().bridge.call("logout")},on(e,i){return D.has(e)||D.set(e,new Set),D.get(e).add(i),()=>X.off(e,i)},off(e,i){var a;(a=D.get(e))==null||a.delete(i)},destroy(){k==null||k.destroy(),k=null,D.clear()},version:"0.2.0"};return typeof window!="undefined"&&(window.Bravophone=X),X});
|