@bravophone/webphone 0.1.0 → 0.1.2

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 CHANGED
@@ -5,7 +5,7 @@ softphone aparece como uma janela flutuante arrastável, com as mesmas
5
5
  funcionalidades da extensão de navegador.
6
6
 
7
7
  ```html
8
- <script src="https://cdn.jsdelivr.net/npm/@bravophone/webphone"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/@bravophone/webphone@0.1"></script>
9
9
  <script>
10
10
  Bravophone.init({ token: 'TOKEN_DO_USUARIO' })
11
11
  </script>
@@ -909,7 +909,8 @@ const le = {
909
909
  destroy() {
910
910
  M == null || M.destroy(), M = null, A.clear();
911
911
  },
912
- version: "0.1.0"
912
+ // Substituída em build time pelo valor do package.json (ver vite.config.js).
913
+ version: "0.1.2"
913
914
  };
914
915
  typeof window != "undefined" && (window.Bravophone = le);
915
916
  export {
@@ -337,4 +337,4 @@
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.0"};return typeof window!="undefined"&&(window.Bravophone=te),te});
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});
package/package.json CHANGED
@@ -1,24 +1,22 @@
1
1
  {
2
2
  "name": "@bravophone/webphone",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Webphone BRAVOPHONE embutível em qualquer página web. Renderiza uma janela flutuante arrastável com todas as funcionalidades do softphone.",
5
- "type": "module",
6
- "main": "./dist/bravophone.umd.cjs",
7
- "module": "./dist/bravophone.js",
5
+ "main": "./dist/bravophone.umd.js",
6
+ "module": "./dist/bravophone.mjs",
8
7
  "types": "./types/index.d.ts",
9
- "unpkg": "./dist/bravophone.umd.cjs",
10
- "jsdelivr": "./dist/bravophone.umd.cjs",
8
+ "unpkg": "./dist/bravophone.umd.js",
9
+ "jsdelivr": "./dist/bravophone.umd.js",
11
10
  "exports": {
12
11
  ".": {
13
12
  "types": "./types/index.d.ts",
14
- "import": "./dist/bravophone.js",
15
- "require": "./dist/bravophone.umd.cjs"
16
- },
17
- "./style.css": "./dist/bravophone.css"
13
+ "import": "./dist/bravophone.mjs",
14
+ "require": "./dist/bravophone.umd.js"
15
+ }
18
16
  },
19
17
  "files": [
20
18
  "dist/*.js",
21
- "dist/*.cjs",
19
+ "dist/*.mjs",
22
20
  "types",
23
21
  "README.md"
24
22
  ],
@@ -28,7 +26,7 @@
28
26
  "dev": "node scripts/dev-server.mjs",
29
27
  "build": "vite build",
30
28
  "build:host": "npm run sync && vite build --config vite.host.config.js",
31
- "test": "node scripts/smoke-shim.mjs && node scripts/smoke-geometry.mjs && node scripts/smoke-launcher.mjs",
29
+ "test": "node scripts/smoke-shim.mjs && node scripts/smoke-geometry.mjs && node scripts/smoke-launcher.mjs && node scripts/smoke-package.mjs",
32
30
  "start": "node scripts/dev-server.mjs",
33
31
  "audit:theme": "node scripts/audit-theme.mjs",
34
32
  "prepublishOnly": "npm run build && npm test"
@@ -61,5 +59,5 @@
61
59
  "engines": {
62
60
  "node": ">=18"
63
61
  },
64
- "browser": "./dist/bravophone.umd.cjs"
62
+ "browser": "./dist/bravophone.umd.js"
65
63
  }