-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.js
More file actions
172 lines (144 loc) · 5.85 KB
/
Copy pathcontent.js
File metadata and controls
172 lines (144 loc) · 5.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
class NMBlipIA {
constructor() {
// text area do blip
this.seletorTextarea = 'textarea#text-input, textarea[placeholder="Escreva uma mensagem..."]';
this.containerSugestoes = null;
this.textareaAtual = null;
this.estaProcessando = false;
this.timerInput = null;
this.configuracoes = {
sugestaoAutomatica: true,
atrasoSugestao: 1000
};
this.iniciar();
}
async iniciar() {
console.log('NM Blip IA iniciado para o Blip Desk.');
const configuracoesArmazenadas = await chrome.runtime.sendMessage({ acao: 'obterConfiguracoes' });
if (configuracoesArmazenadas.sucesso) {
this.configuracoes = configuracoesArmazenadas.configuracoes;
}
// observador de mudancas (responsividade, etc) no textarea
const observador = new MutationObserver(() => this.encontrarEConfigurarInterface());
observador.observe(document.body, { childList: true, subtree: true });
chrome.runtime.onMessage.addListener((requisicao) => {
if (requisicao.acao === 'configuracoesAlteradas') {
this.configuracoes = requisicao.alteracoes;
}
});
}
// configuracao de interface
encontrarEConfigurarInterface() {
const textarea = document.querySelector(this.seletorTextarea);
if (textarea && !textarea.dataset.assistenteIaConfigurado) {
textarea.dataset.assistenteIaConfigurado = 'true';
console.log('textarea do blip encontrada com sucesso!', textarea);
const wrapper = textarea.closest('.input-wrapper');
if (wrapper && !wrapper.querySelector('.ai-container-sugestoes')) {
this.containerSugestoes = document.createElement('div');
this.containerSugestoes.className = 'ai-container-sugestoes';
wrapper.prepend(this.containerSugestoes);
console.log('conteiner de sugestões fixo injetado com sucesso.');
}
this.textareaAtual = textarea;
this.gerarSugestoes(textarea);
textarea.addEventListener('input', () => this.aoDigitarTextarea(textarea));
}
}
// sugestoes aparecendo ao digitar
aoDigitarTextarea(textarea) {
if (!this.configuracoes.sugestaoAutomatica) return;
clearTimeout(this.timerInput);
this.timerInput = setTimeout(() => {
if (textarea.value.length > 3) {
this.gerarSugestoes(textarea);
} else {
this.gerarSugestoes(textarea);
}
}, this.configuracoes.atrasoSugestao || 1000);
}
// ler contexto do cliente
capturarContextoConversa() {
// ler div bubble-left do blip
const elementosMensagem = document.querySelectorAll('.bubble.left');
const historico = Array.from(elementosMensagem).map(el => el.textContent?.trim()).filter(Boolean);
const historicoRecente = historico.slice(-10);
console.log(`contexto capturado: ${historicoRecente.length} mensagens do cliente.`);
return historicoRecente;
}
async gerarSugestoes(textarea) {
if (this.estaProcessando || !this.containerSugestoes) return;
this.estaProcessando = true;
this.mostrarCarregamento();
try {
const contexto = {
mensagemAtual: textarea.value,
historicoConversa: this.capturarContextoConversa()
};
const resposta = await chrome.runtime.sendMessage({
acao: 'gerarSugestoes',
dados: contexto
});
if (resposta.sucesso && resposta.sugestoes && resposta.sugestoes.length > 0) {
this.mostrarSugestoes(resposta.sugestoes, textarea);
chrome.runtime.sendMessage({ acao: 'salvarFeedback', dados: { usado: false } });
} else {
this.mostrarCarregamento("Sem sugestões no momento.");
if (resposta.erro) console.error('falha ao gerar sugestões:', resposta.erro);
}
} catch (erro) {
this.mostrarCarregamento("Erro ao buscar sugestões.");
console.error('erro ao comunicar com o script de fundo:', erro);
} finally {
this.estaProcessando = false;
}
}
// carregamento no conteiner atual
mostrarCarregamento(mensagem = "Gerando sugestões...") {
if (!this.containerSugestoes) return;
this.containerSugestoes.innerHTML = `
<div class="ai-sugestao-carregando">
<div class="ai-spinner"></div>
<span>${mensagem}</span>
</div>`;
this.containerSugestoes.style.display = 'flex';
}
// sugestoes
mostrarSugestoes(sugestoes, textarea) {
if (!this.containerSugestoes) return;
this.containerSugestoes.innerHTML = sugestoes.map(sugestao => `
<div class="ai-item-sugestao" title="Usar esta sugestão">
<span class="ai-fonte">Gerado por NM BLiP IA</span>
<span class="texto-sugestao">${sugestao}</span>
</div>
`).join('');
this.containerSugestoes.style.display = 'flex';
this.configurarOuvintesSugestao(textarea);
}
// ouvintes de sugestao no container
configurarOuvintesSugestao(textarea) {
if (!this.containerSugestoes) return;
this.containerSugestoes.querySelectorAll('.ai-item-sugestao').forEach(item => {
item.addEventListener('click', () => {
const textoSugestao = item.querySelector('.texto-sugestao').textContent;
textarea.value = textoSugestao;
textarea.focus();
textarea.dispatchEvent(new Event('input', { bubbles: true }));
chrome.runtime.sendMessage({
acao: 'salvarFeedback',
dados: { sugestao: textoSugestao, usado: true }
});
this.limparSugestoes();
});
});
}
// clean
limparSugestoes() {
if (this.containerSugestoes) {
this.containerSugestoes.innerHTML = '';
this.containerSugestoes.style.display = 'none';
}
}
}
// init
new NMBlipIA();