AnesKAM commited on
Commit
3bf537a
·
verified ·
1 Parent(s): 16520ea

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +17 -45
index.html CHANGED
@@ -403,6 +403,7 @@ function initSpeechRecognition() {
403
  const rec = new SpeechRecognition();
404
  rec.continuous = false;
405
  rec.interimResults = true;
 
406
  const langMap = { en: 'en-US', ar: 'ar-DZ', fr: 'fr-FR', es: 'es-ES' };
407
  rec.lang = langMap[currentLang] || 'en-US';
408
 
@@ -412,6 +413,7 @@ function initSpeechRecognition() {
412
  document.getElementById('stt-text').textContent = i18n[currentLang].vListening;
413
  const voiceBtn = document.getElementById('voice-btn');
414
  voiceBtn.classList.add('recording');
 
415
  lucide.createIcons({ icons: { 'mic-off': lucide.icons['mic-off'] }, attrs: { class: 'icon' } });
416
  const micIcon = document.getElementById('mic-icon');
417
  micIcon.setAttribute('data-lucide', 'mic-off');
@@ -440,6 +442,7 @@ function initSpeechRecognition() {
440
  const micIcon = document.getElementById('mic-icon');
441
  micIcon.setAttribute('data-lucide', 'mic');
442
  lucide.createIcons({ nameAttr: 'data-lucide', attrs: { class: 'icon' } });
 
443
  const input = document.getElementById('msg-input');
444
  if (input.value.trim()) sendMessage();
445
  };
@@ -482,60 +485,27 @@ function saveTtsSetting() {
482
  localStorage.setItem('genisi_tts', autoTTS);
483
  }
484
 
485
- /**
486
- * مـكـتـب تـحـويـل وتـنـقـيـة الـنـص لـلـصـوت
487
- * يحول النص من Markdown إلى نص بسيط بدون إيموجيات وبدون رموز تشتت الصوت
488
- */
489
- function cleanTextForSpeech(text) {
490
- if (!text) return "";
491
-
492
- let cleaned = text;
493
-
494
- // 1. إزالة كتل الأكواد البرمجية (Code Blocks) بالكامل
495
- cleaned = cleaned.replace(/```[\s\S]*?```/g, '');
496
-
497
- // 2. إزالة علامات الماركدوان (Bold, Italic, Links)
498
- cleaned = cleaned.replace(/`([^`]+)`/g, '$1')
499
- .replace(/\*\*([^*]+)\*\*/g, '$1')
500
- .replace(/\*([^*]+)\*/g, '$1')
501
- .replace(/#{1,6}\s/g, '')
502
- .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
503
- .replace(/!\[([^\]]+)\]\([^)]+\)/g, '');
504
-
505
- // 3. إزالة الإيموجيات (Emojis & Symbols)
506
- // نستخدم regex شامل يغطي معظم نطاقات الرموز التعبيرية
507
- cleaned = cleaned.replace(/([\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{1F900}-\u{1F9FF}\u{1F1E6}-\u{1F1FF}])/gu, '');
508
-
509
- // 4. تنقية علامات الترقيم المزعجة صوتياً
510
- // نزيل: @ # $ % ^ & * ( ) _ + = { } [ ] | \ / < > ` ~
511
- // لكن نترك النقطة والفصلة والسين وعلامة الاستفهام ليعطي المحرك الصوتي نبرة طبيعية (Pause)
512
- cleaned = cleaned.replace(/[@#$%\^&\*\(_\+=\{\}\[\]|\\\/<>`~]/g, ' ');
513
-
514
- // 5. تحويل السطور الجديدة إلى مساحات لتفادي التقطيع المفاجئ
515
- cleaned = cleaned.replace(/\n+/g, ' ');
516
-
517
- // 6. تنظيف المسافات الزائدة
518
- cleaned = cleaned.replace(/\s+/g, ' ').trim();
519
-
520
- return cleaned;
521
- }
522
-
523
  function speakText(text) {
524
  if (!window.speechSynthesis) return;
525
-
526
  window.speechSynthesis.cancel();
527
-
528
- // استخدام مكتبة التنقية قبل القراءة
529
- const clean = cleanTextForSpeech(text);
530
-
531
- if (!clean) return null;
 
 
 
 
 
 
532
 
533
  const utterance = new SpeechSynthesisUtterance(clean);
534
  const langMap = { en: 'en-US', ar: 'ar-SA', fr: 'fr-FR', es: 'es-ES' };
535
  utterance.lang = langMap[currentLang] || 'en-US';
536
  utterance.rate = 1.0;
537
  utterance.pitch = 1.0;
538
-
539
  currentUtterance = utterance;
540
  window.speechSynthesis.speak(utterance);
541
  return utterance;
@@ -740,7 +710,9 @@ async function sendMessage(){
740
  }
741
  botContentDiv.innerHTML=safeMarked(fullBotResponse);
742
  renderKaTeX(botContentDiv);
 
743
  appendTTSBadge(botContentDiv, fullBotResponse);
 
744
  if(autoTTS) speakText(fullBotResponse);
745
  chat.history.push({user:text,bot:fullBotResponse,uiFiles});
746
  saveChats(); appendMemBadge(chat.history.length,chat.history.length);
 
403
  const rec = new SpeechRecognition();
404
  rec.continuous = false;
405
  rec.interimResults = true;
406
+ // Set language based on current UI language
407
  const langMap = { en: 'en-US', ar: 'ar-DZ', fr: 'fr-FR', es: 'es-ES' };
408
  rec.lang = langMap[currentLang] || 'en-US';
409
 
 
413
  document.getElementById('stt-text').textContent = i18n[currentLang].vListening;
414
  const voiceBtn = document.getElementById('voice-btn');
415
  voiceBtn.classList.add('recording');
416
+ // swap mic icon to mic-off
417
  lucide.createIcons({ icons: { 'mic-off': lucide.icons['mic-off'] }, attrs: { class: 'icon' } });
418
  const micIcon = document.getElementById('mic-icon');
419
  micIcon.setAttribute('data-lucide', 'mic-off');
 
442
  const micIcon = document.getElementById('mic-icon');
443
  micIcon.setAttribute('data-lucide', 'mic');
444
  lucide.createIcons({ nameAttr: 'data-lucide', attrs: { class: 'icon' } });
445
+ // Auto-send if there's text
446
  const input = document.getElementById('msg-input');
447
  if (input.value.trim()) sendMessage();
448
  };
 
485
  localStorage.setItem('genisi_tts', autoTTS);
486
  }
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  function speakText(text) {
489
  if (!window.speechSynthesis) return;
490
+ // Cancel any ongoing speech
491
  window.speechSynthesis.cancel();
492
+ // Strip markdown symbols for cleaner speech
493
+ const clean = text
494
+ .replace(/```[\s\S]*?```/g, 'code block.')
495
+ .replace(/`([^`]+)`/g, '$1')
496
+ .replace(/\*\*([^*]+)\*\*/g, '$1')
497
+ .replace(/\*([^*]+)\*/g, '$1')
498
+ .replace(/#{1,6}\s/g, '')
499
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
500
+ .replace(/!\[([^\]]+)\]\([^)]+\)/g, 'image.')
501
+ .replace(/\n+/g, '. ')
502
+ .trim();
503
 
504
  const utterance = new SpeechSynthesisUtterance(clean);
505
  const langMap = { en: 'en-US', ar: 'ar-SA', fr: 'fr-FR', es: 'es-ES' };
506
  utterance.lang = langMap[currentLang] || 'en-US';
507
  utterance.rate = 1.0;
508
  utterance.pitch = 1.0;
 
509
  currentUtterance = utterance;
510
  window.speechSynthesis.speak(utterance);
511
  return utterance;
 
710
  }
711
  botContentDiv.innerHTML=safeMarked(fullBotResponse);
712
  renderKaTeX(botContentDiv);
713
+ // Add TTS play button
714
  appendTTSBadge(botContentDiv, fullBotResponse);
715
+ // Auto TTS
716
  if(autoTTS) speakText(fullBotResponse);
717
  chat.history.push({user:text,bot:fullBotResponse,uiFiles});
718
  saveChats(); appendMemBadge(chat.history.length,chat.history.length);