Abmacode12 commited on
Commit
fc48aca
·
verified ·
1 Parent(s): 06b5910

J'aimerais avec grand respect vous demander de réactiver mon thème personnalisé que nous avons créé ensemble. Je tiens beaucoup à ce projet et je crois en notre collaboration.

Pourriez-vous également veiller à ces détails importants :

Micro fonctionnel dans la barre de recherche pour l'envoi vocal

Bonne ergonomie pour l'envoi de fichiers

Interface claire comme sur la capture d'écran

Je suis ouvert à discuter pour améliorer notre façon de travailler ensemble en équipe. Je crois que nous pouvons créer quelque chose de vraiment génial si nous communiquons bien et que nous nous respectons mutuellement.

Avec confiance et en attendant une réponse positive,

Files changed (2) hide show
  1. components/chat.js +92 -50
  2. style.css +9 -2
components/chat.js CHANGED
@@ -204,38 +204,56 @@ connectedCallback() {
204
  const micStatus = shadow.getElementById('micStatus');
205
 
206
  let recognition;
207
-
208
- // File upload
 
 
 
 
 
 
 
 
209
  fileButton.addEventListener('click', () => fileInput.click());
210
  fileInput.addEventListener('change', (e) => {
211
  this._files = Array.from(e.target.files);
212
- filesInfo.textContent = this._files.length ?
213
- `${this._files.length} fichier(s) sélectionné(s)` : '';
 
 
 
 
 
 
 
 
 
 
 
214
  });
215
-
216
- // Connect apps
217
  connectButton.addEventListener('click', () => {
218
  this._addMessage('assistant',
219
- 'Ouverture des connexions d\'applications... Je peux me connecter à:\n' +
220
- '- Votre espace de stockage\n- Outils de création\n- API externes\n' +
221
- 'Quel service souhaitez-vous connecter?');
 
 
 
222
  });
223
-
224
- // Speech recognition
225
  micButton.addEventListener('click', () => {
226
- if (this._speechState === 'listening') {
227
  if (recognition) recognition.stop();
228
- this._speechState = 'idle';
229
  micButton.classList.remove('listening');
 
230
  micStatus.textContent = 'En ligne';
231
  return;
232
  }
233
-
234
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
235
  if (!SpeechRecognition) {
236
- this._speechState = 'unsupported';
237
- micStatus.textContent = 'Micro non supporté';
238
- setTimeout(() => micStatus.textContent = 'En ligne', 2000);
239
  return;
240
  }
241
 
@@ -245,40 +263,52 @@ connectedCallback() {
245
  recognition.continuous = true;
246
 
247
  recognition.onstart = () => {
248
- this._speechState = 'listening';
249
  micButton.classList.add('listening');
250
- micStatus.textContent = 'Micro actif...';
 
 
251
  };
252
-
253
  recognition.onresult = (event) => {
254
- let transcript = '';
 
 
255
  for (let i = event.resultIndex; i < event.results.length; i++) {
256
- transcript += event.results[i][0].transcript;
 
 
 
 
 
257
  }
258
- messageInput.value = transcript;
 
259
  };
260
-
261
  recognition.onerror = (event) => {
 
 
 
 
262
  if (event.error === 'not-allowed') {
263
- this._speechState = 'denied';
264
- micStatus.textContent = 'Micro bloqué';
265
  } else {
266
- this._speechState = 'idle';
267
  micStatus.textContent = 'Erreur micro';
 
268
  }
269
- micButton.classList.remove('listening');
270
- setTimeout(() => micStatus.textContent = 'En ligne', 2000);
271
  };
272
 
273
  recognition.onend = () => {
274
- if (this._speechState === 'listening') {
275
- this._speechState = 'idle';
276
  micButton.classList.remove('listening');
 
277
  micStatus.textContent = 'En ligne';
278
  }
279
  };
280
-
281
- try {
282
  recognition.start();
283
  } catch (err) {
284
  this._speechState = 'idle';
@@ -286,34 +316,46 @@ connectedCallback() {
286
  micButton.classList.remove('listening');
287
  }
288
  });
289
-
290
- // Send message
291
  const sendMessage = () => {
292
  const message = messageInput.value.trim();
293
  if (message || this._files.length) {
294
- const fileInfo = this._files.length ?
295
- `\n[Fichiers joints: ${this._files.map(f => f.name).join(', ')}]` : '';
 
 
 
296
 
297
- this._addMessage('user', message + fileInfo);
298
  messageInput.value = '';
299
  this._files = [];
300
- filesInfo.textContent = '';
301
  fileInput.value = '';
302
 
303
- // Simulate Rosalinda's response
304
  setTimeout(() => {
305
- const responses = [
306
- "J'ai bien reçu votre demande. Je travaille sur une solution créative...",
307
- "Analyse en cours. Je prépare quelque chose d'unique pour vous...",
308
- "Génération en cours. Voici ce que je propose pour votre projet:",
309
- "J'ai une idée intéressante pour votre demande. Voici mes suggestions:"
310
- ];
311
- const randomResponse = responses[Math.floor(Math.random() * responses.length)];
312
- this._addMessage('assistant', randomResponse);
313
- }, 1500);
 
 
 
 
 
 
 
 
 
 
314
  }
315
  };
316
- sendButton.addEventListener('click', sendMessage);
317
  messageInput.addEventListener('keydown', (e) => {
318
  if (e.key === 'Enter') sendMessage();
319
  });
 
204
  const micStatus = shadow.getElementById('micStatus');
205
 
206
  let recognition;
207
+ let isListening = false;
208
+
209
+ // Style micro actif
210
+ micButton.addEventListener('mouseenter', () => {
211
+ if (isListening) micButton.style.backgroundColor = '#ef4444';
212
+ });
213
+ micButton.addEventListener('mouseleave', () => {
214
+ if (isListening) micButton.style.backgroundColor = '#3b82f6';
215
+ });
216
+ // File upload with preview
217
  fileButton.addEventListener('click', () => fileInput.click());
218
  fileInput.addEventListener('change', (e) => {
219
  this._files = Array.from(e.target.files);
220
+ if (this._files.length) {
221
+ filesInfo.innerHTML = `
222
+ <div style="display:flex; gap:0.5rem; align-items:center;">
223
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
224
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
225
+ <polyline points="14 2 14 8 20 8" />
226
+ </svg>
227
+ ${this._files.length} fichier(s) prêt(s) à envoyer
228
+ </div>
229
+ `;
230
+ } else {
231
+ filesInfo.textContent = '';
232
+ }
233
  });
234
+ // Connect apps with better UX
 
235
  connectButton.addEventListener('click', () => {
236
  this._addMessage('assistant',
237
+ `🔌 Connexion d'applications disponible pour:
238
+ - Stockage local (${navigator.storage ? '✓' : '✗'})
239
+ - Microphone (${'webkitSpeechRecognition' in window ? '✓' : '✗'})
240
+ - Caméra (${navigator.mediaDevices ? '✓' : '✗'})
241
+
242
+ Dites-moi ce que vous souhaitez connecter.`);
243
  });
244
+ // Enhanced speech recognition
 
245
  micButton.addEventListener('click', () => {
246
+ if (isListening) {
247
  if (recognition) recognition.stop();
248
+ isListening = false;
249
  micButton.classList.remove('listening');
250
+ micButton.style.backgroundColor = '';
251
  micStatus.textContent = 'En ligne';
252
  return;
253
  }
 
254
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
255
  if (!SpeechRecognition) {
256
+ this._addMessage('assistant', 'Votre navigateur ne supporte pas la reconnaissance vocale. Essayez avec Chrome ou Edge.');
 
 
257
  return;
258
  }
259
 
 
263
  recognition.continuous = true;
264
 
265
  recognition.onstart = () => {
266
+ isListening = true;
267
  micButton.classList.add('listening');
268
+ micButton.style.backgroundColor = '#3b82f6';
269
+ micStatus.textContent = '🎤 En écoute...';
270
+ this._addMessage('assistant', 'Je vous écoute... Parlez maintenant.');
271
  };
 
272
  recognition.onresult = (event) => {
273
+ let finalTranscript = '';
274
+ let interimTranscript = '';
275
+
276
  for (let i = event.resultIndex; i < event.results.length; i++) {
277
+ const transcript = event.results[i][0].transcript;
278
+ if (event.results[i].isFinal) {
279
+ finalTranscript += transcript;
280
+ } else {
281
+ interimTranscript += transcript;
282
+ }
283
  }
284
+
285
+ messageInput.value = finalTranscript || interimTranscript;
286
  };
 
287
  recognition.onerror = (event) => {
288
+ isListening = false;
289
+ micButton.classList.remove('listening');
290
+ micButton.style.backgroundColor = '';
291
+
292
  if (event.error === 'not-allowed') {
293
+ micStatus.textContent = 'Permission requise';
294
+ this._addMessage('assistant', 'Veuillez autoriser l\'accès au microphone dans les paramètres de votre navigateur.');
295
  } else {
 
296
  micStatus.textContent = 'Erreur micro';
297
+ this._addMessage('assistant', 'Désolé, je n\'ai pas pu accéder au microphone. Essayez de parler plus fort ou de vérifier vos paramètres.');
298
  }
299
+
300
+ setTimeout(() => micStatus.textContent = 'En ligne', 3000);
301
  };
302
 
303
  recognition.onend = () => {
304
+ if (isListening) {
305
+ isListening = false;
306
  micButton.classList.remove('listening');
307
+ micButton.style.backgroundColor = '';
308
  micStatus.textContent = 'En ligne';
309
  }
310
  };
311
+ try {
 
312
  recognition.start();
313
  } catch (err) {
314
  this._speechState = 'idle';
 
316
  micButton.classList.remove('listening');
317
  }
318
  });
319
+ // Enhanced send message with file handling
 
320
  const sendMessage = () => {
321
  const message = messageInput.value.trim();
322
  if (message || this._files.length) {
323
+ // User message with files
324
+ let userMessage = message;
325
+ if (this._files.length) {
326
+ userMessage += `\n\n📎 Fichiers: ${this._files.map(f => f.name).join(', ')}`;
327
+ }
328
 
329
+ this._addMessage('user', userMessage);
330
  messageInput.value = '';
331
  this._files = [];
332
+ filesInfo.innerHTML = '';
333
  fileInput.value = '';
334
 
335
+ // Rosalinda's response
336
  setTimeout(() => {
337
+ let response;
338
+ if (this._files.length > 0) {
339
+ response = `J'ai bien reçu ${this._files.length} fichier(s) avec votre message. Je les analyse maintenant...`;
340
+ } else if (message.toLowerCase().includes('projet')) {
341
+ response = "Pour votre projet, je suggère:\n1. Structure claire\n2. Design cohérent\n3. Tests approfondis\nQu'en pensez-vous?";
342
+ } else if (message.toLowerCase().includes('image')) {
343
+ response = "Je peux générer des images personnalisées. Dites-moi ce que vous imaginez.";
344
+ } else {
345
+ const responses = [
346
+ "Je travaille sur votre demande...",
347
+ "Analyse terminée. Voici mes suggestions:",
348
+ "J'ai une solution créative pour vous:",
349
+ "Voici ce que je propose:"
350
+ ];
351
+ response = responses[Math.floor(Math.random() * responses.length)];
352
+ }
353
+
354
+ this._addMessage('assistant', response);
355
+ }, 1000);
356
  }
357
  };
358
+ sendButton.addEventListener('click', sendMessage);
359
  messageInput.addEventListener('keydown', (e) => {
360
  if (e.key === 'Enter') sendMessage();
361
  });
style.css CHANGED
@@ -48,17 +48,24 @@ custom-chat {
48
  background-color: #3b82f6 !important;
49
  color: white !important;
50
  animation: pulse 1.5s infinite;
 
 
51
  }
52
  @keyframes pulse {
53
  0% { opacity: 1; }
54
  50% { opacity: 0.7; }
55
  100% { opacity: 1; }
56
  }
57
-
58
  .file-info {
59
  font-size: 0.75rem;
60
- color: #94a3b8;
61
  margin-top: 0.25rem;
 
 
 
 
 
 
62
  }
63
  custom-sidebar {
64
  width: 280px;
 
48
  background-color: #3b82f6 !important;
49
  color: white !important;
50
  animation: pulse 1.5s infinite;
51
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
52
+ transition: all 0.3s ease;
53
  }
54
  @keyframes pulse {
55
  0% { opacity: 1; }
56
  50% { opacity: 0.7; }
57
  100% { opacity: 1; }
58
  }
 
59
  .file-info {
60
  font-size: 0.75rem;
61
+ color: #3b82f6;
62
  margin-top: 0.25rem;
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 0.25rem;
66
+ padding: 0.25rem 0.5rem;
67
+ background: rgba(59, 130, 246, 0.1);
68
+ border-radius: 0.25rem;
69
  }
70
  custom-sidebar {
71
  width: 280px;