@mukko/react 1.0.0 → 1.1.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- "use strict";"use client";var d=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var g=(i,t)=>{for(var e in t)d(i,e,{get:t[e],enumerable:!0})},k=(i,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of h(t))!m.call(i,a)&&a!==e&&d(i,a,{get:()=>t[a],enumerable:!(o=p(t,a))||o.enumerable});return i};var f=i=>k(d({},"__esModule",{value:!0}),i);var b={};g(b,{MukkoWidget:()=>x,MukkoWidgetEngine:()=>l});module.exports=f(b);var c=require("react");var l=class{constructor(t,e){this.apiUrl="http://localhost:8000/v1";this.widgetContainer=null;this.cardBox=null;this.fabButton=null;this.textBox=null;this.playBtn=null;this.closeBtn=null;this.currentAudio=null;this.cachedDOMText="";this.cachedAudioUrl="";this.isPlaying=!1;this.isExpanded=!1;this.highlightedElements=[];this.apiKey=t,e&&(this.apiUrl=e),this.injectCustomCSS(),this.initUI(),this.scheduleAutoShow()}injectCustomCSS(){let t=document.createElement("style");t.innerHTML=`
2
+ "use strict";"use client";var l=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var g=(i,t)=>{for(var e in t)l(i,e,{get:t[e],enumerable:!0})},k=(i,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of h(t))!m.call(i,n)&&n!==e&&l(i,n,{get:()=>t[n],enumerable:!(o=p(t,n))||o.enumerable});return i};var f=i=>k(l({},"__esModule",{value:!0}),i);var b={};g(b,{MukkoWidget:()=>x,MukkoWidgetEngine:()=>d});module.exports=f(b);var c=require("react");var d=class{constructor(t,e){this.apiUrl="http://localhost:8000/v1";this.widgetContainer=null;this.cardBox=null;this.fabButton=null;this.textBox=null;this.playBtn=null;this.closeBtn=null;this.currentAudio=null;this.cachedDOMText="";this.cachedAudioUrl="";this.isPlaying=!1;this.isExpanded=!1;this.highlightedElements=[];this.apiKey=t,e&&(this.apiUrl=e),this.injectCustomCSS(),this.initUI(),this.scheduleAutoShow()}injectCustomCSS(){let t=document.createElement("style");t.innerHTML=`
3
3
  #mukko-root {
4
4
  position: fixed;
5
5
  bottom: 24px;
@@ -36,7 +36,7 @@
36
36
  fill: currentColor;
37
37
  }
38
38
  .mukko-card {
39
- width: 310px;
39
+ width: 330px;
40
40
  background: #ffffff;
41
41
  border-radius: 16px;
42
42
  padding: 16px;
@@ -95,7 +95,7 @@
95
95
  line-height: 1.5;
96
96
  color: #3a3a3c;
97
97
  margin: 0 0 14px 0;
98
- max-height: 120px;
98
+ max-height: 150px;
99
99
  overflow-y: auto;
100
100
  }
101
101
  .mukko-action-btn {
@@ -117,9 +117,6 @@
117
117
  .mukko-action-btn:hover {
118
118
  background: #006644;
119
119
  }
120
- .mukko-action-btn:active {
121
- transform: scale(0.98);
122
- }
123
120
  .mukko-highlight-interactive {
124
121
  outline: 3px solid #00c853 !important;
125
122
  outline-offset: 3px !important;
@@ -142,9 +139,9 @@
142
139
  </div>
143
140
  <button id="mukko-close-btn" class="mukko-close-btn" title="Minimizar">&times;</button>
144
141
  </div>
145
- <p id="mukko-text" class="mukko-text">
146
- Ol\xE1! Posso explicar o funcionamento desta tela em \xE1udio para facilitar a sua navega\xE7\xE3o.
147
- </p>
142
+ <div id="mukko-text" class="mukko-text">
143
+ Ol\xE1! Posso explicar o funcionamento desta tela em voz e em Xichangana para facilitar a sua navega\xE7\xE3o.
144
+ </div>
148
145
  <button id="mukko-play-btn" class="mukko-action-btn">
149
146
  <span>\u{1F50A}</span>
150
147
  <span id="mukko-btn-text">Ouvir Explica\xE7\xE3o</span>
@@ -156,6 +153,9 @@
156
153
  <path d="M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.35 20.35c-.2.2-.2.51 0 .71.2.2.51.2.71 0l2.76-.92C9.35 20.67 10.63 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-1.22 0-2.38-.3-3.41-.85l-.24-.13-1.87.62.62-1.87-.13-.24C6.3 15.38 6 14.22 6 13c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6zm1-9h-2v4h2v-4zm0 6h-2v2h2v-2z"/>
157
154
  </svg>
158
155
  </button>
159
- `,document.body.appendChild(t),this.widgetContainer=t,this.cardBox=document.getElementById("mukko-card"),this.fabButton=document.getElementById("mukko-fab"),this.textBox=document.getElementById("mukko-text"),this.playBtn=document.getElementById("mukko-play-btn"),this.closeBtn=document.getElementById("mukko-close-btn"),this.fabButton?.addEventListener("click",()=>this.toggleCard()),this.closeBtn?.addEventListener("click",()=>this.hideCard()),this.playBtn?.addEventListener("click",()=>this.handleAction())}scheduleAutoShow(){setTimeout(()=>{this.isExpanded||this.showCard()},5e3)}toggleCard(){this.isExpanded?this.hideCard():this.showCard()}showCard(){this.isExpanded=!0,this.cardBox?.classList.add("active")}hideCard(){this.isExpanded=!1,this.cardBox?.classList.remove("active")}async handleAction(){if(this.isPlaying&&this.currentAudio){this.pauseAudio();return}let t=this.extractInteractiveElements();if(this.cachedAudioUrl&&this.cachedDOMText===t){this.playAudio(this.cachedAudioUrl);return}await this.fetchAndProcess(t)}async fetchAndProcess(t){this.textBox&&(this.textBox.innerText="A analisar os elementos da p\xE1gina..."),this.updateButtonState("loading");try{let e=await fetch(`${this.apiUrl}/process-screen`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_key:this.apiKey,screen_text:t})});if(!e.ok)throw new Error("Erro na requisi\xE7\xE3o");let o=await e.json();this.cachedDOMText=t,this.cachedAudioUrl=o.audio_url,this.textBox&&(this.textBox.innerText=o.simplified_text),o.audio_url?this.playAudio(o.audio_url):this.updateButtonState("idle")}catch{this.textBox&&(this.textBox.innerText="Erro ao conectar com o servidor Mukko."),this.updateButtonState("idle")}}playAudio(t){this.currentAudio&&this.currentAudio.pause(),this.currentAudio=new Audio(t),this.currentAudio.onplay=()=>{this.isPlaying=!0,this.applyHighlights(),this.updateButtonState("playing")},this.currentAudio.onpause=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("paused")},this.currentAudio.onended=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("ended")},this.currentAudio.play().catch(e=>{console.error("Erro ao tocar \xE1udio:",e),this.updateButtonState("idle")})}pauseAudio(){this.currentAudio&&this.currentAudio.pause()}applyHighlights(){this.highlightedElements.forEach(t=>{t.classList.add("mukko-highlight-interactive")})}removeHighlights(){this.highlightedElements.forEach(t=>{t.classList.remove("mukko-highlight-interactive")})}extractInteractiveElements(){let e=document.querySelectorAll("input:not([type='hidden']), textarea, select");this.highlightedElements=[];let o="";return e.forEach(a=>{let n=a;if(n.closest("#mukko-root")||n.offsetWidth===0&&n.offsetHeight===0)return;let r="",u=n.getAttribute("id");if(u){let s=document.querySelector(`label[for="${u}"]`);s&&(r=s.innerText?.trim())}if(!r){let s=n;r=s.placeholder||s.ariaLabel||s.name||s.type||"Campo de texto"}r&&(this.highlightedElements.push(n),o+=`Campo de Entrada (${n.type||"input"}): ${r}
160
- `)}),o.substring(0,1500)}updateButtonState(t){let e=document.getElementById("mukko-btn-text");if(!(!this.playBtn||!e))switch(t){case"loading":e.innerText="A analisar...",this.playBtn.disabled=!0,this.playBtn.style.background="#8e8e93";break;case"playing":e.innerText="Pausar Voz",this.playBtn.disabled=!1,this.playBtn.style.background="#d9534f";break;case"paused":case"ended":e.innerText="Reouvir Explica\xE7\xE3o",this.playBtn.disabled=!1,this.playBtn.style.background="#008055";break;default:e.innerText="Ouvir Explica\xE7\xE3o",this.playBtn.disabled=!1,this.playBtn.style.background="#008055";break}}destroy(){this.removeHighlights(),this.pauseAudio(),this.widgetContainer?.remove()}};var x=({apiKey:i,apiUrl:t})=>((0,c.useEffect)(()=>{let e=new l(i,t);return()=>{e.destroy()}},[i,t]),null);0&&(module.exports={MukkoWidget,MukkoWidgetEngine});
156
+ `,document.body.appendChild(t),this.widgetContainer=t,this.cardBox=document.getElementById("mukko-card"),this.fabButton=document.getElementById("mukko-fab"),this.textBox=document.getElementById("mukko-text"),this.playBtn=document.getElementById("mukko-play-btn"),this.closeBtn=document.getElementById("mukko-close-btn"),this.fabButton?.addEventListener("click",()=>this.toggleCard()),this.closeBtn?.addEventListener("click",()=>this.hideCard()),this.playBtn?.addEventListener("click",()=>this.handleAction())}scheduleAutoShow(){setTimeout(()=>{this.isExpanded||this.showCard()},5e3)}toggleCard(){this.isExpanded?this.hideCard():this.showCard()}showCard(){this.isExpanded=!0,this.cardBox?.classList.add("active")}hideCard(){this.isExpanded=!1,this.cardBox?.classList.remove("active")}async handleAction(){if(this.isPlaying&&this.currentAudio){this.pauseAudio();return}let t=this.extractInteractiveElements();if(this.cachedAudioUrl&&this.cachedDOMText===t){this.playAudio(this.cachedAudioUrl);return}await this.fetchAndProcess(t)}async fetchAndProcess(t){this.textBox&&(this.textBox.innerText="A analisar os elementos da p\xE1gina e a traduzir..."),this.updateButtonState("loading");try{let e=await fetch(`${this.apiUrl}/process-screen`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_key:this.apiKey,screen_text:t})});if(!e.ok)throw new Error("Erro na requisi\xE7\xE3o");let o=await e.json();this.cachedDOMText=t,this.cachedAudioUrl=o.audio_url_pt,this.textBox&&(this.textBox.innerHTML=`
157
+ <strong>PT:</strong> ${o.simplified_text_pt}<br><br>
158
+ <strong>Xh:</strong> ${o.translated_text_ch}
159
+ `),o.audio_url_pt?this.playAudio(o.audio_url_pt):this.updateButtonState("idle")}catch{this.textBox&&(this.textBox.innerText="Erro ao conectar com o servidor Mukko."),this.updateButtonState("idle")}}playAudio(t){this.currentAudio&&this.currentAudio.pause(),this.currentAudio=new Audio(t),this.currentAudio.onplay=()=>{this.isPlaying=!0,this.applyHighlights(),this.updateButtonState("playing")},this.currentAudio.onpause=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("paused")},this.currentAudio.onended=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("ended")},this.currentAudio.play().catch(e=>{console.error("Erro ao tocar \xE1udio:",e),this.updateButtonState("idle")})}pauseAudio(){this.currentAudio&&this.currentAudio.pause()}applyHighlights(){this.highlightedElements.forEach(t=>{t.classList.add("mukko-highlight-interactive")})}removeHighlights(){this.highlightedElements.forEach(t=>{t.classList.remove("mukko-highlight-interactive")})}extractInteractiveElements(){let e=document.querySelectorAll("input:not([type='hidden']), textarea, select");this.highlightedElements=[];let o="";return e.forEach(n=>{let a=n;if(a.closest("#mukko-root")||a.offsetWidth===0&&a.offsetHeight===0)return;let r="",u=a.getAttribute("id");if(u){let s=document.querySelector(`label[for="${u}"]`);s&&(r=s.innerText?.trim())}if(!r){let s=a;r=s.placeholder||s.ariaLabel||s.name||s.type||"Campo de texto"}r&&(this.highlightedElements.push(a),o+=`Campo de Entrada (${a.type||"input"}): ${r}
160
+ `)}),o.substring(0,1500)}updateButtonState(t){let e=document.getElementById("mukko-btn-text");if(!(!this.playBtn||!e))switch(t){case"loading":e.innerText="A analisar...",this.playBtn.disabled=!0,this.playBtn.style.background="#8e8e93";break;case"playing":e.innerText="Pausar Voz",this.playBtn.disabled=!1,this.playBtn.style.background="#d9534f";break;case"paused":case"ended":e.innerText="Reouvir Explica\xE7\xE3o",this.playBtn.disabled=!1,this.playBtn.style.background="#008055";break;default:e.innerText="Ouvir Explica\xE7\xE3o",this.playBtn.disabled=!1,this.playBtn.style.background="#008055";break}}destroy(){this.removeHighlights(),this.pauseAudio(),this.widgetContainer?.remove()}};var x=({apiKey:i,apiUrl:t})=>((0,c.useEffect)(()=>{let e=new d(i,t);return()=>{e.destroy()}},[i,t]),null);0&&(module.exports={MukkoWidget,MukkoWidgetEngine});
161
161
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/MukkoWidget.ts"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { MukkoWidgetEngine } from \"./MukkoWidget\";\n\nexport interface MukkoWidgetProps {\n apiKey: string;\n apiUrl?: string;\n}\n\nexport const MukkoWidget: React.FC<MukkoWidgetProps> = ({ apiKey, apiUrl }) => {\n useEffect(() => {\n // Instancia a classe quando o componente React é montado na tela\n const widgetInstance = new MukkoWidgetEngine(apiKey, apiUrl);\n\n // Destrói o widget do DOM se o usuário mudar de página\n return () => {\n widgetInstance.destroy();\n };\n }, [apiKey, apiUrl]);\n\n return null; // A classe engrena diretamente no DOM através do document.body\n};\n\nexport { MukkoWidgetEngine };","export interface MukkoResponse {\n simplified_text: string;\n audio_url: string;\n}\n\nexport class MukkoWidgetEngine {\n private apiKey: string;\n private apiUrl: string = \"http://localhost:8000/v1\";\n\n // Elementos do DOM\n private widgetContainer: HTMLElement | null = null;\n private cardBox: HTMLElement | null = null;\n private fabButton: HTMLElement | null = null;\n private textBox: HTMLElement | null = null;\n private playBtn: HTMLButtonElement | null = null;\n private closeBtn: HTMLButtonElement | null = null;\n\n // Estado e Cache\n private currentAudio: HTMLAudioElement | null = null;\n private cachedDOMText: string = \"\";\n private cachedAudioUrl: string = \"\";\n private isPlaying: boolean = false;\n private isExpanded: boolean = false;\n\n private highlightedElements: HTMLElement[] = [];\n\n constructor(apiKey: string, apiUrl?: string) {\n this.apiKey = apiKey;\n if (apiUrl) this.apiUrl = apiUrl;\n \n this.injectCustomCSS();\n this.initUI();\n this.scheduleAutoShow();\n }\n\n private injectCustomCSS(): void {\n const style = document.createElement(\"style\");\n style.innerHTML = `\n #mukko-root {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 999999;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n }\n .mukko-fab {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: #008055;\n color: #ffffff;\n border: none;\n box-shadow: 0 4px 14px rgba(0, 128, 85, 0.35);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.2s;\n outline: none;\n }\n .mukko-fab:hover {\n transform: scale(1.08);\n background: #006644;\n }\n .mukko-fab svg {\n width: 26px;\n height: 26px;\n fill: currentColor;\n }\n .mukko-card {\n width: 310px;\n background: #ffffff;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);\n border: 1px solid rgba(0, 0, 0, 0.06);\n opacity: 0;\n transform: translateY(12px) scale(0.96);\n pointer-events: none;\n transition: opacity 0.3s ease, transform 0.3s ease;\n }\n .mukko-card.active {\n opacity: 1;\n transform: translateY(0) scale(1);\n pointer-events: auto;\n }\n .mukko-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n }\n .mukko-title-group {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .mukko-badge {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #008055;\n }\n .mukko-title {\n font-size: 13px;\n font-weight: 700;\n color: #1a1a1a;\n letter-spacing: -0.2px;\n }\n .mukko-close-btn {\n background: transparent;\n border: none;\n color: #8e8e93;\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 2px 6px;\n border-radius: 50%;\n transition: color 0.2s, background 0.2s;\n }\n .mukko-close-btn:hover {\n color: #1a1a1a;\n background: #f2f2f7;\n }\n .mukko-text {\n font-size: 13px;\n line-height: 1.5;\n color: #3a3a3c;\n margin: 0 0 14px 0;\n max-height: 120px;\n overflow-y: auto;\n }\n .mukko-action-btn {\n width: 100%;\n padding: 10px 14px;\n border-radius: 10px;\n background: #008055;\n color: #ffffff;\n border: none;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background-color 0.2s, transform 0.1s;\n }\n .mukko-action-btn:hover {\n background: #006644;\n }\n .mukko-action-btn:active {\n transform: scale(0.98);\n }\n .mukko-highlight-interactive {\n outline: 3px solid #00c853 !important;\n outline-offset: 3px !important;\n background-color: rgba(0, 200, 83, 0.12) !important;\n transition: outline 0.3s ease, background-color 0.3s ease !important;\n animation: mukko-pulse-green 1.8s infinite ease-in-out !important;\n border-radius: 6px !important;\n }\n @keyframes mukko-pulse-green {\n 0% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0.4); }\n 50% { outline-color: #ffd600; box-shadow: 0 0 0 6px rgba(255, 214, 0, 0); }\n 100% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0); }\n }\n `;\n document.head.appendChild(style);\n }\n\n private initUI(): void {\n if (document.getElementById(\"mukko-root\")) return;\n\n const root = document.createElement(\"div\");\n root.id = \"mukko-root\";\n\n root.innerHTML = `\n <div id=\"mukko-card\" class=\"mukko-card\">\n <div class=\"mukko-card-header\">\n <div class=\"mukko-title-group\">\n <span class=\"mukko-badge\"></span>\n <span class=\"mukko-title\">Acessibilidade Mukko</span>\n </div>\n <button id=\"mukko-close-btn\" class=\"mukko-close-btn\" title=\"Minimizar\">&times;</button>\n </div>\n <p id=\"mukko-text\" class=\"mukko-text\">\n Olá! Posso explicar o funcionamento desta tela em áudio para facilitar a sua navegação.\n </p>\n <button id=\"mukko-play-btn\" class=\"mukko-action-btn\">\n <span>🔊</span>\n <span id=\"mukko-btn-text\">Ouvir Explicação</span>\n </button>\n </div>\n\n <button id=\"mukko-fab\" class=\"mukko-fab\" title=\"Acessibilidade em Voz\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.35 20.35c-.2.2-.2.51 0 .71.2.2.51.2.71 0l2.76-.92C9.35 20.67 10.63 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-1.22 0-2.38-.3-3.41-.85l-.24-.13-1.87.62.62-1.87-.13-.24C6.3 15.38 6 14.22 6 13c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6zm1-9h-2v4h2v-4zm0 6h-2v2h2v-2z\"/>\n </svg>\n </button>\n `;\n\n document.body.appendChild(root);\n\n this.widgetContainer = root;\n this.cardBox = document.getElementById(\"mukko-card\");\n this.fabButton = document.getElementById(\"mukko-fab\");\n this.textBox = document.getElementById(\"mukko-text\");\n this.playBtn = document.getElementById(\"mukko-play-btn\") as HTMLButtonElement;\n this.closeBtn = document.getElementById(\"mukko-close-btn\") as HTMLButtonElement;\n\n this.fabButton?.addEventListener(\"click\", () => this.toggleCard());\n this.closeBtn?.addEventListener(\"click\", () => this.hideCard());\n this.playBtn?.addEventListener(\"click\", () => this.handleAction());\n }\n\n private scheduleAutoShow(): void {\n setTimeout(() => {\n if (!this.isExpanded) {\n this.showCard();\n }\n }, 5000);\n }\n\n private toggleCard(): void {\n if (this.isExpanded) {\n this.hideCard();\n } else {\n this.showCard();\n }\n }\n\n private showCard(): void {\n this.isExpanded = true;\n this.cardBox?.classList.add(\"active\");\n }\n\n private hideCard(): void {\n this.isExpanded = false;\n this.cardBox?.classList.remove(\"active\");\n }\n\n private async handleAction(): Promise<void> {\n if (this.isPlaying && this.currentAudio) {\n this.pauseAudio();\n return;\n }\n\n const currentDOMText = this.extractInteractiveElements();\n\n if (this.cachedAudioUrl && this.cachedDOMText === currentDOMText) {\n this.playAudio(this.cachedAudioUrl);\n return;\n }\n\n await this.fetchAndProcess(currentDOMText);\n }\n\n private async fetchAndProcess(domText: string): Promise<void> {\n if (this.textBox) this.textBox.innerText = \"A analisar os elementos da página...\";\n this.updateButtonState(\"loading\");\n\n try {\n const response = await fetch(`${this.apiUrl}/process-screen`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n app_key: this.apiKey,\n screen_text: domText\n })\n });\n\n if (!response.ok) throw new Error(\"Erro na requisição\");\n\n const data: MukkoResponse = await response.json();\n\n this.cachedDOMText = domText;\n this.cachedAudioUrl = data.audio_url;\n\n if (this.textBox) this.textBox.innerText = data.simplified_text;\n\n if (data.audio_url) {\n this.playAudio(data.audio_url);\n } else {\n this.updateButtonState(\"idle\");\n }\n\n } catch (error) {\n if (this.textBox) this.textBox.innerText = \"Erro ao conectar com o servidor Mukko.\";\n this.updateButtonState(\"idle\");\n }\n }\n\n private playAudio(audioUrl: string): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n\n this.currentAudio = new Audio(audioUrl);\n\n this.currentAudio.onplay = () => {\n this.isPlaying = true;\n this.applyHighlights();\n this.updateButtonState(\"playing\");\n };\n\n this.currentAudio.onpause = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"paused\");\n };\n\n this.currentAudio.onended = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"ended\");\n };\n\n this.currentAudio.play().catch(err => {\n console.error(\"Erro ao tocar áudio:\", err);\n this.updateButtonState(\"idle\");\n });\n }\n\n private pauseAudio(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n }\n\n private applyHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.add(\"mukko-highlight-interactive\");\n });\n }\n\n private removeHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.remove(\"mukko-highlight-interactive\");\n });\n }\n\n private extractInteractiveElements(): string {\n const selector = \"input:not([type='hidden']), textarea, select\";\n const nodes = document.querySelectorAll(selector);\n\n this.highlightedElements = [];\n let extractedText = \"\";\n\n nodes.forEach(node => {\n const el = node as HTMLElement;\n\n if (el.closest(\"#mukko-root\")) return;\n if (el.offsetWidth === 0 && el.offsetHeight === 0) return;\n\n let fieldLabel = \"\";\n\n const inputId = el.getAttribute(\"id\");\n if (inputId) {\n const associatedLabel = document.querySelector(`label[for=\"${inputId}\"]`);\n if (associatedLabel) {\n fieldLabel = (associatedLabel as HTMLElement).innerText?.trim();\n }\n }\n\n if (!fieldLabel) {\n const input = el as HTMLInputElement;\n fieldLabel = input.placeholder || input.ariaLabel || input.name || input.type || \"Campo de texto\";\n }\n\n if (fieldLabel) {\n this.highlightedElements.push(el);\n extractedText += `Campo de Entrada (${(el as HTMLInputElement).type || 'input'}): ${fieldLabel}\\n`;\n }\n });\n\n return extractedText.substring(0, 1500);\n }\n\n private updateButtonState(state: \"idle\" | \"loading\" | \"playing\" | \"paused\" | \"ended\"): void {\n const btnText = document.getElementById(\"mukko-btn-text\");\n if (!this.playBtn || !btnText) return;\n\n switch (state) {\n case \"loading\":\n btnText.innerText = \"A analisar...\";\n this.playBtn.disabled = true;\n this.playBtn.style.background = \"#8e8e93\";\n break;\n case \"playing\":\n btnText.innerText = \"Pausar Voz\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#d9534f\";\n break;\n case \"paused\":\n case \"ended\":\n btnText.innerText = \"Reouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n case \"idle\":\n default:\n btnText.innerText = \"Ouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n }\n }\n\n public destroy(): void {\n this.removeHighlights();\n this.pauseAudio();\n this.widgetContainer?.remove();\n }\n}"],"mappings":"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","names":["index_exports","__export","MukkoWidget","MukkoWidgetEngine","__toCommonJS","import_react","MukkoWidgetEngine","apiKey","apiUrl","style","root","currentDOMText","domText","response","data","audioUrl","err","el","nodes","extractedText","node","fieldLabel","inputId","associatedLabel","input","state","btnText","MukkoWidget","apiKey","apiUrl","widgetInstance","MukkoWidgetEngine"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/MukkoWidget.ts"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { MukkoWidgetEngine } from \"./MukkoWidget\";\n\nexport interface MukkoWidgetProps {\n apiKey: string;\n apiUrl?: string;\n}\n\nexport const MukkoWidget: React.FC<MukkoWidgetProps> = ({ apiKey, apiUrl }) => {\n useEffect(() => {\n // Instancia a classe quando o componente React é montado na tela\n const widgetInstance = new MukkoWidgetEngine(apiKey, apiUrl);\n\n // Destrói o widget do DOM se o usuário mudar de página\n return () => {\n widgetInstance.destroy();\n };\n }, [apiKey, apiUrl]);\n\n return null; // A classe engrena diretamente no DOM através do document.body\n};\n\nexport { MukkoWidgetEngine };","export interface MukkoResponse {\n simplified_text_pt: string;\n translated_text_ch: string;\n audio_url_pt: string;\n}\n\nexport class MukkoWidgetEngine {\n private apiKey: string;\n private apiUrl: string = \"http://localhost:8000/v1\";\n\n private widgetContainer: HTMLElement | null = null;\n private cardBox: HTMLElement | null = null;\n private fabButton: HTMLElement | null = null;\n private textBox: HTMLElement | null = null;\n private playBtn: HTMLButtonElement | null = null;\n private closeBtn: HTMLButtonElement | null = null;\n\n private currentAudio: HTMLAudioElement | null = null;\n private cachedDOMText: string = \"\";\n private cachedAudioUrl: string = \"\";\n private isPlaying: boolean = false;\n private isExpanded: boolean = false;\n private highlightedElements: HTMLElement[] = [];\n\n constructor(apiKey: string, apiUrl?: string) {\n this.apiKey = apiKey;\n if (apiUrl) this.apiUrl = apiUrl;\n \n this.injectCustomCSS();\n this.initUI();\n this.scheduleAutoShow();\n }\n\n private injectCustomCSS(): void {\n const style = document.createElement(\"style\");\n style.innerHTML = `\n #mukko-root {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 999999;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n }\n .mukko-fab {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: #008055;\n color: #ffffff;\n border: none;\n box-shadow: 0 4px 14px rgba(0, 128, 85, 0.35);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.2s;\n outline: none;\n }\n .mukko-fab:hover {\n transform: scale(1.08);\n background: #006644;\n }\n .mukko-fab svg {\n width: 26px;\n height: 26px;\n fill: currentColor;\n }\n .mukko-card {\n width: 330px;\n background: #ffffff;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);\n border: 1px solid rgba(0, 0, 0, 0.06);\n opacity: 0;\n transform: translateY(12px) scale(0.96);\n pointer-events: none;\n transition: opacity 0.3s ease, transform 0.3s ease;\n }\n .mukko-card.active {\n opacity: 1;\n transform: translateY(0) scale(1);\n pointer-events: auto;\n }\n .mukko-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n }\n .mukko-title-group {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .mukko-badge {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #008055;\n }\n .mukko-title {\n font-size: 13px;\n font-weight: 700;\n color: #1a1a1a;\n letter-spacing: -0.2px;\n }\n .mukko-close-btn {\n background: transparent;\n border: none;\n color: #8e8e93;\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 2px 6px;\n border-radius: 50%;\n transition: color 0.2s, background 0.2s;\n }\n .mukko-close-btn:hover {\n color: #1a1a1a;\n background: #f2f2f7;\n }\n .mukko-text {\n font-size: 13px;\n line-height: 1.5;\n color: #3a3a3c;\n margin: 0 0 14px 0;\n max-height: 150px;\n overflow-y: auto;\n }\n .mukko-action-btn {\n width: 100%;\n padding: 10px 14px;\n border-radius: 10px;\n background: #008055;\n color: #ffffff;\n border: none;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background-color 0.2s, transform 0.1s;\n }\n .mukko-action-btn:hover {\n background: #006644;\n }\n .mukko-highlight-interactive {\n outline: 3px solid #00c853 !important;\n outline-offset: 3px !important;\n background-color: rgba(0, 200, 83, 0.12) !important;\n transition: outline 0.3s ease, background-color 0.3s ease !important;\n animation: mukko-pulse-green 1.8s infinite ease-in-out !important;\n border-radius: 6px !important;\n }\n @keyframes mukko-pulse-green {\n 0% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0.4); }\n 50% { outline-color: #ffd600; box-shadow: 0 0 0 6px rgba(255, 214, 0, 0); }\n 100% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0); }\n }\n `;\n document.head.appendChild(style);\n }\n\n private initUI(): void {\n if (document.getElementById(\"mukko-root\")) return;\n\n const root = document.createElement(\"div\");\n root.id = \"mukko-root\";\n\n root.innerHTML = `\n <div id=\"mukko-card\" class=\"mukko-card\">\n <div class=\"mukko-card-header\">\n <div class=\"mukko-title-group\">\n <span class=\"mukko-badge\"></span>\n <span class=\"mukko-title\">Acessibilidade Mukko</span>\n </div>\n <button id=\"mukko-close-btn\" class=\"mukko-close-btn\" title=\"Minimizar\">&times;</button>\n </div>\n <div id=\"mukko-text\" class=\"mukko-text\">\n Olá! Posso explicar o funcionamento desta tela em voz e em Xichangana para facilitar a sua navegação.\n </div>\n <button id=\"mukko-play-btn\" class=\"mukko-action-btn\">\n <span>🔊</span>\n <span id=\"mukko-btn-text\">Ouvir Explicação</span>\n </button>\n </div>\n\n <button id=\"mukko-fab\" class=\"mukko-fab\" title=\"Acessibilidade em Voz\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.35 20.35c-.2.2-.2.51 0 .71.2.2.51.2.71 0l2.76-.92C9.35 20.67 10.63 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-1.22 0-2.38-.3-3.41-.85l-.24-.13-1.87.62.62-1.87-.13-.24C6.3 15.38 6 14.22 6 13c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6zm1-9h-2v4h2v-4zm0 6h-2v2h2v-2z\"/>\n </svg>\n </button>\n `;\n\n document.body.appendChild(root);\n\n this.widgetContainer = root;\n this.cardBox = document.getElementById(\"mukko-card\");\n this.fabButton = document.getElementById(\"mukko-fab\");\n this.textBox = document.getElementById(\"mukko-text\");\n this.playBtn = document.getElementById(\"mukko-play-btn\") as HTMLButtonElement;\n this.closeBtn = document.getElementById(\"mukko-close-btn\") as HTMLButtonElement;\n\n this.fabButton?.addEventListener(\"click\", () => this.toggleCard());\n this.closeBtn?.addEventListener(\"click\", () => this.hideCard());\n this.playBtn?.addEventListener(\"click\", () => this.handleAction());\n }\n\n private scheduleAutoShow(): void {\n setTimeout(() => {\n if (!this.isExpanded) {\n this.showCard();\n }\n }, 5000);\n }\n\n private toggleCard(): void {\n if (this.isExpanded) {\n this.hideCard();\n } else {\n this.showCard();\n }\n }\n\n private showCard(): void {\n this.isExpanded = true;\n this.cardBox?.classList.add(\"active\");\n }\n\n private hideCard(): void {\n this.isExpanded = false;\n this.cardBox?.classList.remove(\"active\");\n }\n\n private async handleAction(): Promise<void> {\n if (this.isPlaying && this.currentAudio) {\n this.pauseAudio();\n return;\n }\n\n const currentDOMText = this.extractInteractiveElements();\n\n if (this.cachedAudioUrl && this.cachedDOMText === currentDOMText) {\n this.playAudio(this.cachedAudioUrl);\n return;\n }\n\n await this.fetchAndProcess(currentDOMText);\n }\n\n private async fetchAndProcess(domText: string): Promise<void> {\n if (this.textBox) this.textBox.innerText = \"A analisar os elementos da página e a traduzir...\";\n this.updateButtonState(\"loading\");\n\n try {\n const response = await fetch(`${this.apiUrl}/process-screen`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n app_key: this.apiKey,\n screen_text: domText\n })\n });\n\n if (!response.ok) throw new Error(\"Erro na requisição\");\n\n const data: MukkoResponse = await response.json();\n\n this.cachedDOMText = domText;\n this.cachedAudioUrl = data.audio_url_pt;\n\n if (this.textBox) {\n this.textBox.innerHTML = `\n <strong>PT:</strong> ${data.simplified_text_pt}<br><br>\n <strong>Xh:</strong> ${data.translated_text_ch}\n `;\n }\n\n if (data.audio_url_pt) {\n this.playAudio(data.audio_url_pt);\n } else {\n this.updateButtonState(\"idle\");\n }\n\n } catch (error) {\n if (this.textBox) this.textBox.innerText = \"Erro ao conectar com o servidor Mukko.\";\n this.updateButtonState(\"idle\");\n }\n }\n\n private playAudio(audioUrl: string): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n\n this.currentAudio = new Audio(audioUrl);\n\n this.currentAudio.onplay = () => {\n this.isPlaying = true;\n this.applyHighlights();\n this.updateButtonState(\"playing\");\n };\n\n this.currentAudio.onpause = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"paused\");\n };\n\n this.currentAudio.onended = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"ended\");\n };\n\n this.currentAudio.play().catch(err => {\n console.error(\"Erro ao tocar áudio:\", err);\n this.updateButtonState(\"idle\");\n });\n }\n\n private pauseAudio(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n }\n\n private applyHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.add(\"mukko-highlight-interactive\");\n });\n }\n\n private removeHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.remove(\"mukko-highlight-interactive\");\n });\n }\n\n private extractInteractiveElements(): string {\n const selector = \"input:not([type='hidden']), textarea, select\";\n const nodes = document.querySelectorAll(selector);\n\n this.highlightedElements = [];\n let extractedText = \"\";\n\n nodes.forEach(node => {\n const el = node as HTMLElement;\n\n if (el.closest(\"#mukko-root\")) return;\n if (el.offsetWidth === 0 && el.offsetHeight === 0) return;\n\n let fieldLabel = \"\";\n\n const inputId = el.getAttribute(\"id\");\n if (inputId) {\n const associatedLabel = document.querySelector(`label[for=\"${inputId}\"]`);\n if (associatedLabel) {\n fieldLabel = (associatedLabel as HTMLElement).innerText?.trim();\n }\n }\n\n if (!fieldLabel) {\n const input = el as HTMLInputElement;\n fieldLabel = input.placeholder || input.ariaLabel || input.name || input.type || \"Campo de texto\";\n }\n\n if (fieldLabel) {\n this.highlightedElements.push(el);\n extractedText += `Campo de Entrada (${(el as HTMLInputElement).type || 'input'}): ${fieldLabel}\\n`;\n }\n });\n\n return extractedText.substring(0, 1500);\n }\n\n private updateButtonState(state: \"idle\" | \"loading\" | \"playing\" | \"paused\" | \"ended\"): void {\n const btnText = document.getElementById(\"mukko-btn-text\");\n if (!this.playBtn || !btnText) return;\n\n switch (state) {\n case \"loading\":\n btnText.innerText = \"A analisar...\";\n this.playBtn.disabled = true;\n this.playBtn.style.background = \"#8e8e93\";\n break;\n case \"playing\":\n btnText.innerText = \"Pausar Voz\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#d9534f\";\n break;\n case \"paused\":\n case \"ended\":\n btnText.innerText = \"Reouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n case \"idle\":\n default:\n btnText.innerText = \"Ouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n }\n }\n\n public destroy(): void {\n this.removeHighlights();\n this.pauseAudio();\n this.widgetContainer?.remove();\n }\n}"],"mappings":"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","names":["index_exports","__export","MukkoWidget","MukkoWidgetEngine","__toCommonJS","import_react","MukkoWidgetEngine","apiKey","apiUrl","style","root","currentDOMText","domText","response","data","audioUrl","err","el","nodes","extractedText","node","fieldLabel","inputId","associatedLabel","input","state","btnText","MukkoWidget","apiKey","apiUrl","widgetInstance","MukkoWidgetEngine"]}
package/dist/index.mjs CHANGED
@@ -36,7 +36,7 @@
36
36
  fill: currentColor;
37
37
  }
38
38
  .mukko-card {
39
- width: 310px;
39
+ width: 330px;
40
40
  background: #ffffff;
41
41
  border-radius: 16px;
42
42
  padding: 16px;
@@ -95,7 +95,7 @@
95
95
  line-height: 1.5;
96
96
  color: #3a3a3c;
97
97
  margin: 0 0 14px 0;
98
- max-height: 120px;
98
+ max-height: 150px;
99
99
  overflow-y: auto;
100
100
  }
101
101
  .mukko-action-btn {
@@ -117,9 +117,6 @@
117
117
  .mukko-action-btn:hover {
118
118
  background: #006644;
119
119
  }
120
- .mukko-action-btn:active {
121
- transform: scale(0.98);
122
- }
123
120
  .mukko-highlight-interactive {
124
121
  outline: 3px solid #00c853 !important;
125
122
  outline-offset: 3px !important;
@@ -142,9 +139,9 @@
142
139
  </div>
143
140
  <button id="mukko-close-btn" class="mukko-close-btn" title="Minimizar">&times;</button>
144
141
  </div>
145
- <p id="mukko-text" class="mukko-text">
146
- Ol\xE1! Posso explicar o funcionamento desta tela em \xE1udio para facilitar a sua navega\xE7\xE3o.
147
- </p>
142
+ <div id="mukko-text" class="mukko-text">
143
+ Ol\xE1! Posso explicar o funcionamento desta tela em voz e em Xichangana para facilitar a sua navega\xE7\xE3o.
144
+ </div>
148
145
  <button id="mukko-play-btn" class="mukko-action-btn">
149
146
  <span>\u{1F50A}</span>
150
147
  <span id="mukko-btn-text">Ouvir Explica\xE7\xE3o</span>
@@ -156,6 +153,9 @@
156
153
  <path d="M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.35 20.35c-.2.2-.2.51 0 .71.2.2.51.2.71 0l2.76-.92C9.35 20.67 10.63 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-1.22 0-2.38-.3-3.41-.85l-.24-.13-1.87.62.62-1.87-.13-.24C6.3 15.38 6 14.22 6 13c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6zm1-9h-2v4h2v-4zm0 6h-2v2h2v-2z"/>
157
154
  </svg>
158
155
  </button>
159
- `,document.body.appendChild(t),this.widgetContainer=t,this.cardBox=document.getElementById("mukko-card"),this.fabButton=document.getElementById("mukko-fab"),this.textBox=document.getElementById("mukko-text"),this.playBtn=document.getElementById("mukko-play-btn"),this.closeBtn=document.getElementById("mukko-close-btn"),this.fabButton?.addEventListener("click",()=>this.toggleCard()),this.closeBtn?.addEventListener("click",()=>this.hideCard()),this.playBtn?.addEventListener("click",()=>this.handleAction())}scheduleAutoShow(){setTimeout(()=>{this.isExpanded||this.showCard()},5e3)}toggleCard(){this.isExpanded?this.hideCard():this.showCard()}showCard(){this.isExpanded=!0,this.cardBox?.classList.add("active")}hideCard(){this.isExpanded=!1,this.cardBox?.classList.remove("active")}async handleAction(){if(this.isPlaying&&this.currentAudio){this.pauseAudio();return}let t=this.extractInteractiveElements();if(this.cachedAudioUrl&&this.cachedDOMText===t){this.playAudio(this.cachedAudioUrl);return}await this.fetchAndProcess(t)}async fetchAndProcess(t){this.textBox&&(this.textBox.innerText="A analisar os elementos da p\xE1gina..."),this.updateButtonState("loading");try{let e=await fetch(`${this.apiUrl}/process-screen`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_key:this.apiKey,screen_text:t})});if(!e.ok)throw new Error("Erro na requisi\xE7\xE3o");let i=await e.json();this.cachedDOMText=t,this.cachedAudioUrl=i.audio_url,this.textBox&&(this.textBox.innerText=i.simplified_text),i.audio_url?this.playAudio(i.audio_url):this.updateButtonState("idle")}catch{this.textBox&&(this.textBox.innerText="Erro ao conectar com o servidor Mukko."),this.updateButtonState("idle")}}playAudio(t){this.currentAudio&&this.currentAudio.pause(),this.currentAudio=new Audio(t),this.currentAudio.onplay=()=>{this.isPlaying=!0,this.applyHighlights(),this.updateButtonState("playing")},this.currentAudio.onpause=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("paused")},this.currentAudio.onended=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("ended")},this.currentAudio.play().catch(e=>{console.error("Erro ao tocar \xE1udio:",e),this.updateButtonState("idle")})}pauseAudio(){this.currentAudio&&this.currentAudio.pause()}applyHighlights(){this.highlightedElements.forEach(t=>{t.classList.add("mukko-highlight-interactive")})}removeHighlights(){this.highlightedElements.forEach(t=>{t.classList.remove("mukko-highlight-interactive")})}extractInteractiveElements(){let e=document.querySelectorAll("input:not([type='hidden']), textarea, select");this.highlightedElements=[];let i="";return e.forEach(d=>{let o=d;if(o.closest("#mukko-root")||o.offsetWidth===0&&o.offsetHeight===0)return;let n="",l=o.getAttribute("id");if(l){let a=document.querySelector(`label[for="${l}"]`);a&&(n=a.innerText?.trim())}if(!n){let a=o;n=a.placeholder||a.ariaLabel||a.name||a.type||"Campo de texto"}n&&(this.highlightedElements.push(o),i+=`Campo de Entrada (${o.type||"input"}): ${n}
156
+ `,document.body.appendChild(t),this.widgetContainer=t,this.cardBox=document.getElementById("mukko-card"),this.fabButton=document.getElementById("mukko-fab"),this.textBox=document.getElementById("mukko-text"),this.playBtn=document.getElementById("mukko-play-btn"),this.closeBtn=document.getElementById("mukko-close-btn"),this.fabButton?.addEventListener("click",()=>this.toggleCard()),this.closeBtn?.addEventListener("click",()=>this.hideCard()),this.playBtn?.addEventListener("click",()=>this.handleAction())}scheduleAutoShow(){setTimeout(()=>{this.isExpanded||this.showCard()},5e3)}toggleCard(){this.isExpanded?this.hideCard():this.showCard()}showCard(){this.isExpanded=!0,this.cardBox?.classList.add("active")}hideCard(){this.isExpanded=!1,this.cardBox?.classList.remove("active")}async handleAction(){if(this.isPlaying&&this.currentAudio){this.pauseAudio();return}let t=this.extractInteractiveElements();if(this.cachedAudioUrl&&this.cachedDOMText===t){this.playAudio(this.cachedAudioUrl);return}await this.fetchAndProcess(t)}async fetchAndProcess(t){this.textBox&&(this.textBox.innerText="A analisar os elementos da p\xE1gina e a traduzir..."),this.updateButtonState("loading");try{let e=await fetch(`${this.apiUrl}/process-screen`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_key:this.apiKey,screen_text:t})});if(!e.ok)throw new Error("Erro na requisi\xE7\xE3o");let i=await e.json();this.cachedDOMText=t,this.cachedAudioUrl=i.audio_url_pt,this.textBox&&(this.textBox.innerHTML=`
157
+ <strong>PT:</strong> ${i.simplified_text_pt}<br><br>
158
+ <strong>Xh:</strong> ${i.translated_text_ch}
159
+ `),i.audio_url_pt?this.playAudio(i.audio_url_pt):this.updateButtonState("idle")}catch{this.textBox&&(this.textBox.innerText="Erro ao conectar com o servidor Mukko."),this.updateButtonState("idle")}}playAudio(t){this.currentAudio&&this.currentAudio.pause(),this.currentAudio=new Audio(t),this.currentAudio.onplay=()=>{this.isPlaying=!0,this.applyHighlights(),this.updateButtonState("playing")},this.currentAudio.onpause=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("paused")},this.currentAudio.onended=()=>{this.isPlaying=!1,this.removeHighlights(),this.updateButtonState("ended")},this.currentAudio.play().catch(e=>{console.error("Erro ao tocar \xE1udio:",e),this.updateButtonState("idle")})}pauseAudio(){this.currentAudio&&this.currentAudio.pause()}applyHighlights(){this.highlightedElements.forEach(t=>{t.classList.add("mukko-highlight-interactive")})}removeHighlights(){this.highlightedElements.forEach(t=>{t.classList.remove("mukko-highlight-interactive")})}extractInteractiveElements(){let e=document.querySelectorAll("input:not([type='hidden']), textarea, select");this.highlightedElements=[];let i="";return e.forEach(l=>{let o=l;if(o.closest("#mukko-root")||o.offsetWidth===0&&o.offsetHeight===0)return;let a="",d=o.getAttribute("id");if(d){let n=document.querySelector(`label[for="${d}"]`);n&&(a=n.innerText?.trim())}if(!a){let n=o;a=n.placeholder||n.ariaLabel||n.name||n.type||"Campo de texto"}a&&(this.highlightedElements.push(o),i+=`Campo de Entrada (${o.type||"input"}): ${a}
160
160
  `)}),i.substring(0,1500)}updateButtonState(t){let e=document.getElementById("mukko-btn-text");if(!(!this.playBtn||!e))switch(t){case"loading":e.innerText="A analisar...",this.playBtn.disabled=!0,this.playBtn.style.background="#8e8e93";break;case"playing":e.innerText="Pausar Voz",this.playBtn.disabled=!1,this.playBtn.style.background="#d9534f";break;case"paused":case"ended":e.innerText="Reouvir Explica\xE7\xE3o",this.playBtn.disabled=!1,this.playBtn.style.background="#008055";break;default:e.innerText="Ouvir Explica\xE7\xE3o",this.playBtn.disabled=!1,this.playBtn.style.background="#008055";break}}destroy(){this.removeHighlights(),this.pauseAudio(),this.widgetContainer?.remove()}};var g=({apiKey:r,apiUrl:t})=>(u(()=>{let e=new s(r,t);return()=>{e.destroy()}},[r,t]),null);export{g as MukkoWidget,s as MukkoWidgetEngine};
161
161
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/MukkoWidget.ts"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { MukkoWidgetEngine } from \"./MukkoWidget\";\n\nexport interface MukkoWidgetProps {\n apiKey: string;\n apiUrl?: string;\n}\n\nexport const MukkoWidget: React.FC<MukkoWidgetProps> = ({ apiKey, apiUrl }) => {\n useEffect(() => {\n // Instancia a classe quando o componente React é montado na tela\n const widgetInstance = new MukkoWidgetEngine(apiKey, apiUrl);\n\n // Destrói o widget do DOM se o usuário mudar de página\n return () => {\n widgetInstance.destroy();\n };\n }, [apiKey, apiUrl]);\n\n return null; // A classe engrena diretamente no DOM através do document.body\n};\n\nexport { MukkoWidgetEngine };","export interface MukkoResponse {\n simplified_text: string;\n audio_url: string;\n}\n\nexport class MukkoWidgetEngine {\n private apiKey: string;\n private apiUrl: string = \"http://localhost:8000/v1\";\n\n // Elementos do DOM\n private widgetContainer: HTMLElement | null = null;\n private cardBox: HTMLElement | null = null;\n private fabButton: HTMLElement | null = null;\n private textBox: HTMLElement | null = null;\n private playBtn: HTMLButtonElement | null = null;\n private closeBtn: HTMLButtonElement | null = null;\n\n // Estado e Cache\n private currentAudio: HTMLAudioElement | null = null;\n private cachedDOMText: string = \"\";\n private cachedAudioUrl: string = \"\";\n private isPlaying: boolean = false;\n private isExpanded: boolean = false;\n\n private highlightedElements: HTMLElement[] = [];\n\n constructor(apiKey: string, apiUrl?: string) {\n this.apiKey = apiKey;\n if (apiUrl) this.apiUrl = apiUrl;\n \n this.injectCustomCSS();\n this.initUI();\n this.scheduleAutoShow();\n }\n\n private injectCustomCSS(): void {\n const style = document.createElement(\"style\");\n style.innerHTML = `\n #mukko-root {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 999999;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n }\n .mukko-fab {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: #008055;\n color: #ffffff;\n border: none;\n box-shadow: 0 4px 14px rgba(0, 128, 85, 0.35);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.2s;\n outline: none;\n }\n .mukko-fab:hover {\n transform: scale(1.08);\n background: #006644;\n }\n .mukko-fab svg {\n width: 26px;\n height: 26px;\n fill: currentColor;\n }\n .mukko-card {\n width: 310px;\n background: #ffffff;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);\n border: 1px solid rgba(0, 0, 0, 0.06);\n opacity: 0;\n transform: translateY(12px) scale(0.96);\n pointer-events: none;\n transition: opacity 0.3s ease, transform 0.3s ease;\n }\n .mukko-card.active {\n opacity: 1;\n transform: translateY(0) scale(1);\n pointer-events: auto;\n }\n .mukko-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n }\n .mukko-title-group {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .mukko-badge {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #008055;\n }\n .mukko-title {\n font-size: 13px;\n font-weight: 700;\n color: #1a1a1a;\n letter-spacing: -0.2px;\n }\n .mukko-close-btn {\n background: transparent;\n border: none;\n color: #8e8e93;\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 2px 6px;\n border-radius: 50%;\n transition: color 0.2s, background 0.2s;\n }\n .mukko-close-btn:hover {\n color: #1a1a1a;\n background: #f2f2f7;\n }\n .mukko-text {\n font-size: 13px;\n line-height: 1.5;\n color: #3a3a3c;\n margin: 0 0 14px 0;\n max-height: 120px;\n overflow-y: auto;\n }\n .mukko-action-btn {\n width: 100%;\n padding: 10px 14px;\n border-radius: 10px;\n background: #008055;\n color: #ffffff;\n border: none;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background-color 0.2s, transform 0.1s;\n }\n .mukko-action-btn:hover {\n background: #006644;\n }\n .mukko-action-btn:active {\n transform: scale(0.98);\n }\n .mukko-highlight-interactive {\n outline: 3px solid #00c853 !important;\n outline-offset: 3px !important;\n background-color: rgba(0, 200, 83, 0.12) !important;\n transition: outline 0.3s ease, background-color 0.3s ease !important;\n animation: mukko-pulse-green 1.8s infinite ease-in-out !important;\n border-radius: 6px !important;\n }\n @keyframes mukko-pulse-green {\n 0% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0.4); }\n 50% { outline-color: #ffd600; box-shadow: 0 0 0 6px rgba(255, 214, 0, 0); }\n 100% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0); }\n }\n `;\n document.head.appendChild(style);\n }\n\n private initUI(): void {\n if (document.getElementById(\"mukko-root\")) return;\n\n const root = document.createElement(\"div\");\n root.id = \"mukko-root\";\n\n root.innerHTML = `\n <div id=\"mukko-card\" class=\"mukko-card\">\n <div class=\"mukko-card-header\">\n <div class=\"mukko-title-group\">\n <span class=\"mukko-badge\"></span>\n <span class=\"mukko-title\">Acessibilidade Mukko</span>\n </div>\n <button id=\"mukko-close-btn\" class=\"mukko-close-btn\" title=\"Minimizar\">&times;</button>\n </div>\n <p id=\"mukko-text\" class=\"mukko-text\">\n Olá! Posso explicar o funcionamento desta tela em áudio para facilitar a sua navegação.\n </p>\n <button id=\"mukko-play-btn\" class=\"mukko-action-btn\">\n <span>🔊</span>\n <span id=\"mukko-btn-text\">Ouvir Explicação</span>\n </button>\n </div>\n\n <button id=\"mukko-fab\" class=\"mukko-fab\" title=\"Acessibilidade em Voz\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.35 20.35c-.2.2-.2.51 0 .71.2.2.51.2.71 0l2.76-.92C9.35 20.67 10.63 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-1.22 0-2.38-.3-3.41-.85l-.24-.13-1.87.62.62-1.87-.13-.24C6.3 15.38 6 14.22 6 13c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6zm1-9h-2v4h2v-4zm0 6h-2v2h2v-2z\"/>\n </svg>\n </button>\n `;\n\n document.body.appendChild(root);\n\n this.widgetContainer = root;\n this.cardBox = document.getElementById(\"mukko-card\");\n this.fabButton = document.getElementById(\"mukko-fab\");\n this.textBox = document.getElementById(\"mukko-text\");\n this.playBtn = document.getElementById(\"mukko-play-btn\") as HTMLButtonElement;\n this.closeBtn = document.getElementById(\"mukko-close-btn\") as HTMLButtonElement;\n\n this.fabButton?.addEventListener(\"click\", () => this.toggleCard());\n this.closeBtn?.addEventListener(\"click\", () => this.hideCard());\n this.playBtn?.addEventListener(\"click\", () => this.handleAction());\n }\n\n private scheduleAutoShow(): void {\n setTimeout(() => {\n if (!this.isExpanded) {\n this.showCard();\n }\n }, 5000);\n }\n\n private toggleCard(): void {\n if (this.isExpanded) {\n this.hideCard();\n } else {\n this.showCard();\n }\n }\n\n private showCard(): void {\n this.isExpanded = true;\n this.cardBox?.classList.add(\"active\");\n }\n\n private hideCard(): void {\n this.isExpanded = false;\n this.cardBox?.classList.remove(\"active\");\n }\n\n private async handleAction(): Promise<void> {\n if (this.isPlaying && this.currentAudio) {\n this.pauseAudio();\n return;\n }\n\n const currentDOMText = this.extractInteractiveElements();\n\n if (this.cachedAudioUrl && this.cachedDOMText === currentDOMText) {\n this.playAudio(this.cachedAudioUrl);\n return;\n }\n\n await this.fetchAndProcess(currentDOMText);\n }\n\n private async fetchAndProcess(domText: string): Promise<void> {\n if (this.textBox) this.textBox.innerText = \"A analisar os elementos da página...\";\n this.updateButtonState(\"loading\");\n\n try {\n const response = await fetch(`${this.apiUrl}/process-screen`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n app_key: this.apiKey,\n screen_text: domText\n })\n });\n\n if (!response.ok) throw new Error(\"Erro na requisição\");\n\n const data: MukkoResponse = await response.json();\n\n this.cachedDOMText = domText;\n this.cachedAudioUrl = data.audio_url;\n\n if (this.textBox) this.textBox.innerText = data.simplified_text;\n\n if (data.audio_url) {\n this.playAudio(data.audio_url);\n } else {\n this.updateButtonState(\"idle\");\n }\n\n } catch (error) {\n if (this.textBox) this.textBox.innerText = \"Erro ao conectar com o servidor Mukko.\";\n this.updateButtonState(\"idle\");\n }\n }\n\n private playAudio(audioUrl: string): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n\n this.currentAudio = new Audio(audioUrl);\n\n this.currentAudio.onplay = () => {\n this.isPlaying = true;\n this.applyHighlights();\n this.updateButtonState(\"playing\");\n };\n\n this.currentAudio.onpause = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"paused\");\n };\n\n this.currentAudio.onended = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"ended\");\n };\n\n this.currentAudio.play().catch(err => {\n console.error(\"Erro ao tocar áudio:\", err);\n this.updateButtonState(\"idle\");\n });\n }\n\n private pauseAudio(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n }\n\n private applyHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.add(\"mukko-highlight-interactive\");\n });\n }\n\n private removeHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.remove(\"mukko-highlight-interactive\");\n });\n }\n\n private extractInteractiveElements(): string {\n const selector = \"input:not([type='hidden']), textarea, select\";\n const nodes = document.querySelectorAll(selector);\n\n this.highlightedElements = [];\n let extractedText = \"\";\n\n nodes.forEach(node => {\n const el = node as HTMLElement;\n\n if (el.closest(\"#mukko-root\")) return;\n if (el.offsetWidth === 0 && el.offsetHeight === 0) return;\n\n let fieldLabel = \"\";\n\n const inputId = el.getAttribute(\"id\");\n if (inputId) {\n const associatedLabel = document.querySelector(`label[for=\"${inputId}\"]`);\n if (associatedLabel) {\n fieldLabel = (associatedLabel as HTMLElement).innerText?.trim();\n }\n }\n\n if (!fieldLabel) {\n const input = el as HTMLInputElement;\n fieldLabel = input.placeholder || input.ariaLabel || input.name || input.type || \"Campo de texto\";\n }\n\n if (fieldLabel) {\n this.highlightedElements.push(el);\n extractedText += `Campo de Entrada (${(el as HTMLInputElement).type || 'input'}): ${fieldLabel}\\n`;\n }\n });\n\n return extractedText.substring(0, 1500);\n }\n\n private updateButtonState(state: \"idle\" | \"loading\" | \"playing\" | \"paused\" | \"ended\"): void {\n const btnText = document.getElementById(\"mukko-btn-text\");\n if (!this.playBtn || !btnText) return;\n\n switch (state) {\n case \"loading\":\n btnText.innerText = \"A analisar...\";\n this.playBtn.disabled = true;\n this.playBtn.style.background = \"#8e8e93\";\n break;\n case \"playing\":\n btnText.innerText = \"Pausar Voz\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#d9534f\";\n break;\n case \"paused\":\n case \"ended\":\n btnText.innerText = \"Reouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n case \"idle\":\n default:\n btnText.innerText = \"Ouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n }\n }\n\n public destroy(): void {\n this.removeHighlights();\n this.pauseAudio();\n this.widgetContainer?.remove();\n }\n}"],"mappings":"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","names":["useEffect","MukkoWidgetEngine","apiKey","apiUrl","style","root","currentDOMText","domText","response","data","audioUrl","err","el","nodes","extractedText","node","fieldLabel","inputId","associatedLabel","input","state","btnText","MukkoWidget","apiKey","apiUrl","useEffect","widgetInstance","MukkoWidgetEngine"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/MukkoWidget.ts"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { MukkoWidgetEngine } from \"./MukkoWidget\";\n\nexport interface MukkoWidgetProps {\n apiKey: string;\n apiUrl?: string;\n}\n\nexport const MukkoWidget: React.FC<MukkoWidgetProps> = ({ apiKey, apiUrl }) => {\n useEffect(() => {\n // Instancia a classe quando o componente React é montado na tela\n const widgetInstance = new MukkoWidgetEngine(apiKey, apiUrl);\n\n // Destrói o widget do DOM se o usuário mudar de página\n return () => {\n widgetInstance.destroy();\n };\n }, [apiKey, apiUrl]);\n\n return null; // A classe engrena diretamente no DOM através do document.body\n};\n\nexport { MukkoWidgetEngine };","export interface MukkoResponse {\n simplified_text_pt: string;\n translated_text_ch: string;\n audio_url_pt: string;\n}\n\nexport class MukkoWidgetEngine {\n private apiKey: string;\n private apiUrl: string = \"http://localhost:8000/v1\";\n\n private widgetContainer: HTMLElement | null = null;\n private cardBox: HTMLElement | null = null;\n private fabButton: HTMLElement | null = null;\n private textBox: HTMLElement | null = null;\n private playBtn: HTMLButtonElement | null = null;\n private closeBtn: HTMLButtonElement | null = null;\n\n private currentAudio: HTMLAudioElement | null = null;\n private cachedDOMText: string = \"\";\n private cachedAudioUrl: string = \"\";\n private isPlaying: boolean = false;\n private isExpanded: boolean = false;\n private highlightedElements: HTMLElement[] = [];\n\n constructor(apiKey: string, apiUrl?: string) {\n this.apiKey = apiKey;\n if (apiUrl) this.apiUrl = apiUrl;\n \n this.injectCustomCSS();\n this.initUI();\n this.scheduleAutoShow();\n }\n\n private injectCustomCSS(): void {\n const style = document.createElement(\"style\");\n style.innerHTML = `\n #mukko-root {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 999999;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n }\n .mukko-fab {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: #008055;\n color: #ffffff;\n border: none;\n box-shadow: 0 4px 14px rgba(0, 128, 85, 0.35);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.2s;\n outline: none;\n }\n .mukko-fab:hover {\n transform: scale(1.08);\n background: #006644;\n }\n .mukko-fab svg {\n width: 26px;\n height: 26px;\n fill: currentColor;\n }\n .mukko-card {\n width: 330px;\n background: #ffffff;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);\n border: 1px solid rgba(0, 0, 0, 0.06);\n opacity: 0;\n transform: translateY(12px) scale(0.96);\n pointer-events: none;\n transition: opacity 0.3s ease, transform 0.3s ease;\n }\n .mukko-card.active {\n opacity: 1;\n transform: translateY(0) scale(1);\n pointer-events: auto;\n }\n .mukko-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n }\n .mukko-title-group {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .mukko-badge {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #008055;\n }\n .mukko-title {\n font-size: 13px;\n font-weight: 700;\n color: #1a1a1a;\n letter-spacing: -0.2px;\n }\n .mukko-close-btn {\n background: transparent;\n border: none;\n color: #8e8e93;\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 2px 6px;\n border-radius: 50%;\n transition: color 0.2s, background 0.2s;\n }\n .mukko-close-btn:hover {\n color: #1a1a1a;\n background: #f2f2f7;\n }\n .mukko-text {\n font-size: 13px;\n line-height: 1.5;\n color: #3a3a3c;\n margin: 0 0 14px 0;\n max-height: 150px;\n overflow-y: auto;\n }\n .mukko-action-btn {\n width: 100%;\n padding: 10px 14px;\n border-radius: 10px;\n background: #008055;\n color: #ffffff;\n border: none;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: background-color 0.2s, transform 0.1s;\n }\n .mukko-action-btn:hover {\n background: #006644;\n }\n .mukko-highlight-interactive {\n outline: 3px solid #00c853 !important;\n outline-offset: 3px !important;\n background-color: rgba(0, 200, 83, 0.12) !important;\n transition: outline 0.3s ease, background-color 0.3s ease !important;\n animation: mukko-pulse-green 1.8s infinite ease-in-out !important;\n border-radius: 6px !important;\n }\n @keyframes mukko-pulse-green {\n 0% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0.4); }\n 50% { outline-color: #ffd600; box-shadow: 0 0 0 6px rgba(255, 214, 0, 0); }\n 100% { outline-color: #00c853; box-shadow: 0 0 0 0 rgba(0, 200, 83, 0); }\n }\n `;\n document.head.appendChild(style);\n }\n\n private initUI(): void {\n if (document.getElementById(\"mukko-root\")) return;\n\n const root = document.createElement(\"div\");\n root.id = \"mukko-root\";\n\n root.innerHTML = `\n <div id=\"mukko-card\" class=\"mukko-card\">\n <div class=\"mukko-card-header\">\n <div class=\"mukko-title-group\">\n <span class=\"mukko-badge\"></span>\n <span class=\"mukko-title\">Acessibilidade Mukko</span>\n </div>\n <button id=\"mukko-close-btn\" class=\"mukko-close-btn\" title=\"Minimizar\">&times;</button>\n </div>\n <div id=\"mukko-text\" class=\"mukko-text\">\n Olá! Posso explicar o funcionamento desta tela em voz e em Xichangana para facilitar a sua navegação.\n </div>\n <button id=\"mukko-play-btn\" class=\"mukko-action-btn\">\n <span>🔊</span>\n <span id=\"mukko-btn-text\">Ouvir Explicação</span>\n </button>\n </div>\n\n <button id=\"mukko-fab\" class=\"mukko-fab\" title=\"Acessibilidade em Voz\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.35 20.35c-.2.2-.2.51 0 .71.2.2.51.2.71 0l2.76-.92C9.35 20.67 10.63 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-1.22 0-2.38-.3-3.41-.85l-.24-.13-1.87.62.62-1.87-.13-.24C6.3 15.38 6 14.22 6 13c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6zm1-9h-2v4h2v-4zm0 6h-2v2h2v-2z\"/>\n </svg>\n </button>\n `;\n\n document.body.appendChild(root);\n\n this.widgetContainer = root;\n this.cardBox = document.getElementById(\"mukko-card\");\n this.fabButton = document.getElementById(\"mukko-fab\");\n this.textBox = document.getElementById(\"mukko-text\");\n this.playBtn = document.getElementById(\"mukko-play-btn\") as HTMLButtonElement;\n this.closeBtn = document.getElementById(\"mukko-close-btn\") as HTMLButtonElement;\n\n this.fabButton?.addEventListener(\"click\", () => this.toggleCard());\n this.closeBtn?.addEventListener(\"click\", () => this.hideCard());\n this.playBtn?.addEventListener(\"click\", () => this.handleAction());\n }\n\n private scheduleAutoShow(): void {\n setTimeout(() => {\n if (!this.isExpanded) {\n this.showCard();\n }\n }, 5000);\n }\n\n private toggleCard(): void {\n if (this.isExpanded) {\n this.hideCard();\n } else {\n this.showCard();\n }\n }\n\n private showCard(): void {\n this.isExpanded = true;\n this.cardBox?.classList.add(\"active\");\n }\n\n private hideCard(): void {\n this.isExpanded = false;\n this.cardBox?.classList.remove(\"active\");\n }\n\n private async handleAction(): Promise<void> {\n if (this.isPlaying && this.currentAudio) {\n this.pauseAudio();\n return;\n }\n\n const currentDOMText = this.extractInteractiveElements();\n\n if (this.cachedAudioUrl && this.cachedDOMText === currentDOMText) {\n this.playAudio(this.cachedAudioUrl);\n return;\n }\n\n await this.fetchAndProcess(currentDOMText);\n }\n\n private async fetchAndProcess(domText: string): Promise<void> {\n if (this.textBox) this.textBox.innerText = \"A analisar os elementos da página e a traduzir...\";\n this.updateButtonState(\"loading\");\n\n try {\n const response = await fetch(`${this.apiUrl}/process-screen`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n app_key: this.apiKey,\n screen_text: domText\n })\n });\n\n if (!response.ok) throw new Error(\"Erro na requisição\");\n\n const data: MukkoResponse = await response.json();\n\n this.cachedDOMText = domText;\n this.cachedAudioUrl = data.audio_url_pt;\n\n if (this.textBox) {\n this.textBox.innerHTML = `\n <strong>PT:</strong> ${data.simplified_text_pt}<br><br>\n <strong>Xh:</strong> ${data.translated_text_ch}\n `;\n }\n\n if (data.audio_url_pt) {\n this.playAudio(data.audio_url_pt);\n } else {\n this.updateButtonState(\"idle\");\n }\n\n } catch (error) {\n if (this.textBox) this.textBox.innerText = \"Erro ao conectar com o servidor Mukko.\";\n this.updateButtonState(\"idle\");\n }\n }\n\n private playAudio(audioUrl: string): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n\n this.currentAudio = new Audio(audioUrl);\n\n this.currentAudio.onplay = () => {\n this.isPlaying = true;\n this.applyHighlights();\n this.updateButtonState(\"playing\");\n };\n\n this.currentAudio.onpause = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"paused\");\n };\n\n this.currentAudio.onended = () => {\n this.isPlaying = false;\n this.removeHighlights();\n this.updateButtonState(\"ended\");\n };\n\n this.currentAudio.play().catch(err => {\n console.error(\"Erro ao tocar áudio:\", err);\n this.updateButtonState(\"idle\");\n });\n }\n\n private pauseAudio(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n }\n }\n\n private applyHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.add(\"mukko-highlight-interactive\");\n });\n }\n\n private removeHighlights(): void {\n this.highlightedElements.forEach(el => {\n el.classList.remove(\"mukko-highlight-interactive\");\n });\n }\n\n private extractInteractiveElements(): string {\n const selector = \"input:not([type='hidden']), textarea, select\";\n const nodes = document.querySelectorAll(selector);\n\n this.highlightedElements = [];\n let extractedText = \"\";\n\n nodes.forEach(node => {\n const el = node as HTMLElement;\n\n if (el.closest(\"#mukko-root\")) return;\n if (el.offsetWidth === 0 && el.offsetHeight === 0) return;\n\n let fieldLabel = \"\";\n\n const inputId = el.getAttribute(\"id\");\n if (inputId) {\n const associatedLabel = document.querySelector(`label[for=\"${inputId}\"]`);\n if (associatedLabel) {\n fieldLabel = (associatedLabel as HTMLElement).innerText?.trim();\n }\n }\n\n if (!fieldLabel) {\n const input = el as HTMLInputElement;\n fieldLabel = input.placeholder || input.ariaLabel || input.name || input.type || \"Campo de texto\";\n }\n\n if (fieldLabel) {\n this.highlightedElements.push(el);\n extractedText += `Campo de Entrada (${(el as HTMLInputElement).type || 'input'}): ${fieldLabel}\\n`;\n }\n });\n\n return extractedText.substring(0, 1500);\n }\n\n private updateButtonState(state: \"idle\" | \"loading\" | \"playing\" | \"paused\" | \"ended\"): void {\n const btnText = document.getElementById(\"mukko-btn-text\");\n if (!this.playBtn || !btnText) return;\n\n switch (state) {\n case \"loading\":\n btnText.innerText = \"A analisar...\";\n this.playBtn.disabled = true;\n this.playBtn.style.background = \"#8e8e93\";\n break;\n case \"playing\":\n btnText.innerText = \"Pausar Voz\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#d9534f\";\n break;\n case \"paused\":\n case \"ended\":\n btnText.innerText = \"Reouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n case \"idle\":\n default:\n btnText.innerText = \"Ouvir Explicação\";\n this.playBtn.disabled = false;\n this.playBtn.style.background = \"#008055\";\n break;\n }\n }\n\n public destroy(): void {\n this.removeHighlights();\n this.pauseAudio();\n this.widgetContainer?.remove();\n }\n}"],"mappings":"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","names":["useEffect","MukkoWidgetEngine","apiKey","apiUrl","style","root","currentDOMText","domText","response","data","audioUrl","err","el","nodes","extractedText","node","fieldLabel","inputId","associatedLabel","input","state","btnText","MukkoWidget","apiKey","apiUrl","useEffect","widgetInstance","MukkoWidgetEngine"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mukko/react",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Widget de acessibilidade em áudio guiado por IA da Mukko para aplicações React e Next.js.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -18,7 +18,8 @@
18
18
  "scripts": {
19
19
  "build": "tsup",
20
20
  "dev": "tsup --watch",
21
- "prepublishOnly": "npm run build"
21
+ "prepublishOnly": "npm run build",
22
+ "release": "npm run build && npm publish --access public"
22
23
  },
23
24
  "peerDependencies": {
24
25
  "react": ">=16.8.0",
@@ -42,4 +43,4 @@
42
43
  "mukko"
43
44
  ],
44
45
  "license": "MIT"
45
- }
46
+ }