Auto-deploy: 2026-06-02 18:28:17

This commit is contained in:
Hamza-Ayed
2026-06-02 18:28:17 +03:00
parent 96986eb302
commit 7cf9b474bb
3 changed files with 179 additions and 18 deletions

162
popup.js
View File

@@ -262,7 +262,169 @@ document.getElementById('autofill-btn').addEventListener('click', async () => {
}
});
// ─── Voice Dictation ───────────────────────────────────────────────────────────
function initDictation() {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const statusEl = document.getElementById('dictation-status');
const micBtn = document.getElementById('dictation-mic-btn');
const resultArea = document.getElementById('dictation-result');
const copyBtn = document.getElementById('copy-dictation-btn');
if (!SpeechRecognition) {
statusEl.textContent = '❌ المتصفح لا يدعم التعرف على الصوت';
micBtn.disabled = true;
micBtn.style.opacity = '0.5';
return;
}
let recognition = new SpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = 'ar-SA';
let isRecording = false;
let finalTranscript = '';
recognition.onstart = () => {
isRecording = true;
micBtn.style.background = 'linear-gradient(135deg, #ff4d6d, #c9184a)';
micBtn.innerHTML = '🔴';
micBtn.style.animation = 'claude-voice-pulse 1.5s infinite'; // We can add this via inline or just rely on color
statusEl.textContent = 'جارٍ الاستماع... اضغط للإيقاف';
finalTranscript = '';
resultArea.value = '';
copyBtn.style.display = 'none';
};
recognition.onresult = (event) => {
let interimTranscript = '';
let currentFinal = '';
for (let i = event.resultIndex; i < event.results.length; i++) {
const transcript = event.results[i][0].transcript;
if (event.results[i].isFinal) {
currentFinal += transcript + ' ';
} else {
interimTranscript += transcript;
}
}
finalTranscript += currentFinal;
resultArea.value = finalTranscript + interimTranscript;
};
recognition.onerror = (event) => {
console.error('Speech recognition error', event.error);
if (event.error === 'not-allowed') {
statusEl.textContent = '❌ يرجى السماح للميكروفون من إعدادات المتصفح';
} else if (event.error !== 'no-speech') {
statusEl.textContent = '❌ خطأ: ' + event.error;
}
stopRecording(false);
};
recognition.onend = () => {
if (isRecording) {
stopRecording(true);
}
};
function stopRecording(process = true) {
if (!isRecording) return;
isRecording = false;
recognition.stop();
micBtn.style.background = 'linear-gradient(135deg, var(--accent), #9b5de5)';
micBtn.innerHTML = '🎤';
const textToProcess = resultArea.value.trim();
if (textToProcess && process) {
statusEl.textContent = '✨ جارٍ التحسين بواسطة الذكاء الاصطناعي...';
refineWithGemini(textToProcess);
} else {
statusEl.textContent = 'اضغط للتحدث (بالعربية)';
}
}
micBtn.addEventListener('click', async () => {
if (isRecording) {
stopRecording(true);
} else {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getTracks().forEach(t => t.stop());
recognition.start();
} catch (err) {
statusEl.textContent = '❌ يجب السماح باستخدام الميكروفون';
}
}
});
copyBtn.addEventListener('click', () => {
navigator.clipboard.writeText(resultArea.value);
const originalText = copyBtn.textContent;
copyBtn.textContent = '✅ تم النسخ!';
setTimeout(() => { copyBtn.textContent = originalText; }, 2000);
});
async function refineWithGemini(text) {
const apiKey = document.getElementById('api-key-input').value.trim();
if (!apiKey) {
statusEl.textContent = '⚠️ الرجاء إدخال مفتاح Gemini لتحسين النص';
copyBtn.style.display = 'inline-flex';
return;
}
try {
const prompt = `You are an expert Arabic text refinement assistant. Your task is to:
1. Correct any speech recognition errors in the following Arabic text
2. Fix punctuation, capitalization, and formatting
3. Keep the original meaning and content intact
4. Do NOT add any new information or commentary
5. Return ONLY the corrected text, nothing else
TEXT TO REFINE:
${text}
CORRECTED TEXT:`;
const response = await fetch('https://cv.intaleqapp.com/cv/server/generate_cv.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'generateText',
apiKey: apiKey,
prompt: prompt
})
});
if (response.ok) {
const rawText = await response.text();
let data;
try { data = JSON.parse(rawText); } catch(e) { data = rawText; }
let processedText = text;
if (data && data.candidates && data.candidates[0]) {
processedText = data.candidates[0].content?.parts?.[0]?.text;
} else if (typeof data === 'string') {
processedText = data;
}
resultArea.value = processedText.trim();
statusEl.textContent = '✅ تم التحسين بنجاح! يمكنك النسخ الآن.';
copyBtn.style.display = 'inline-flex';
} else {
throw new Error('Server error');
}
} catch (e) {
statusEl.textContent = '⚠️ فشل التحسين الذكي، نعرض النص الأصلي.';
copyBtn.style.display = 'inline-flex';
}
}
}
// ─── Init ────────────────────────────────────────────────────────────────────
loadSettings();
initDictation();