Auto-deploy: 2026-06-02 19:20:39

This commit is contained in:
Hamza-Ayed
2026-06-02 19:20:39 +03:00
parent a615ee53af
commit 6d054901dc

108
popup.js
View File

@@ -284,7 +284,7 @@ function initDictation() {
resultArea.addEventListener('input', updateCopyBtnVisibility);
function stopRecording(process = true) {
function stopRecording() {
if (!isRecording) return;
isRecording = false;
chrome.runtime.sendMessage({ type: 'STOP_RECORDING_FROM_POPUP' });
@@ -293,14 +293,8 @@ function initDictation() {
updateCopyBtnVisibility();
const textToProcess = resultArea.value.trim();
if (textToProcess && process) {
statusEl.textContent = '✨ جارٍ التحسين بواسطة الذكاء الاصطناعي...';
refineWithGemini(textToProcess);
} else {
if (!statusEl.textContent.includes('❌')) {
statusEl.textContent = 'اضغط للتحدث (بالعربية)';
}
if (!statusEl.textContent.includes('❌')) {
statusEl.textContent = 'اضغط للتحدث (بالعربية)';
}
}
@@ -324,17 +318,17 @@ function initDictation() {
} else if (message.payload.error !== 'no-speech') {
statusEl.textContent = '❌ خطأ: ' + message.payload.error;
}
stopRecording(false);
stopRecording();
} else if (message.type === 'SPEECH_END') {
if (isRecording) {
stopRecording(true);
stopRecording();
}
}
});
micBtn.addEventListener('click', async () => {
if (isRecording) {
stopRecording(true);
stopRecording();
} else {
// First, get the active tab
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
@@ -358,10 +352,14 @@ function initDictation() {
chrome.scripting.executeScript({
target: { tabId: activeTab.id },
func: (lang) => {
// Prevent multiple instances
if (window.__ljaDictationActive) {
return;
// Clean up any existing instances in this tab first
if (window.__ljaSpeechActiveRecognition) {
try { window.__ljaSpeechActiveRecognition.stop(); } catch(e) {}
}
if (window.__ljaSpeechStopListener) {
try { chrome.runtime.onMessage.removeListener(window.__ljaSpeechStopListener); } catch(e) {}
}
window.__ljaDictationActive = true;
window.__ljaSpeechUserStopped = false;
window.__ljaSpeechAccumulatedText = '';
@@ -380,6 +378,8 @@ function initDictation() {
if (window.__ljaSpeechUserStopped) return;
recognition = new SpeechRecognition();
window.__ljaSpeechActiveRecognition = recognition;
recognition.lang = lang;
recognition.continuous = true;
recognition.interimResults = true;
@@ -417,9 +417,11 @@ function initDictation() {
recognition.onerror = (event) => {
console.error('[LJA Dictation] Error:', event.error);
if (event.error === 'not-allowed') {
if (event.error === 'not-allowed' || event.error === 'service-not-allowed') {
chrome.runtime.sendMessage({ type: 'SPEECH_ERROR', payload: { error: event.error } });
window.__ljaDictationActive = false;
window.__ljaSpeechUserStopped = true;
window.__ljaSpeechActiveRecognition = null;
} else {
console.warn('[LJA Dictation] Recoverable error:', event.error);
}
@@ -430,6 +432,7 @@ function initDictation() {
// User explicitly stopped
chrome.runtime.sendMessage({ type: 'SPEECH_END' });
window.__ljaDictationActive = false;
window.__ljaSpeechActiveRecognition = null;
} else {
// Ended due to browser timeout / silence, restart it
window.__ljaSpeechAccumulatedText += window.__ljaSpeechCurrentSessionFinalText;
@@ -448,20 +451,26 @@ function initDictation() {
} catch (e) {
chrome.runtime.sendMessage({ type: 'SPEECH_ERROR', payload: { error: e.message } });
window.__ljaDictationActive = false;
window.__ljaSpeechUserStopped = true;
window.__ljaSpeechActiveRecognition = null;
}
}
// Listen for STOP message from popup
const stopListener = (msg, sender, sendResponse) => {
window.__ljaSpeechStopListener = (msg, sender, sendResponse) => {
if (msg.type === 'STOP_RECORDING_FROM_POPUP') {
window.__ljaSpeechUserStopped = true;
try { recognition.stop(); } catch(e) {}
window.__ljaDictationActive = false;
chrome.runtime.onMessage.removeListener(stopListener);
window.__ljaSpeechActiveRecognition = null;
if (window.__ljaSpeechStopListener) {
try { chrome.runtime.onMessage.removeListener(window.__ljaSpeechStopListener); } catch(e) {}
window.__ljaSpeechStopListener = null;
}
sendResponse({ success: true });
}
};
chrome.runtime.onMessage.addListener(stopListener);
chrome.runtime.onMessage.addListener(window.__ljaSpeechStopListener);
startRecognition();
},
@@ -480,63 +489,12 @@ function initDictation() {
navigator.clipboard.writeText(resultArea.value);
const originalText = copyBtn.textContent;
copyBtn.textContent = '✅ تم النسخ!';
setTimeout(() => { copyBtn.textContent = originalText; }, 2000);
setTimeout(() => {
copyBtn.textContent = originalText;
resultArea.value = '';
updateCopyBtnVisibility();
}, 1000);
});
async function refineWithGemini(text) {
const apiKey = document.getElementById('api-key-input').value.trim();
if (!apiKey) {
statusEl.textContent = '⚠️ الرجاء إدخال مفتاح Gemini لتحسين النص';
updateCopyBtnVisibility();
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 = '✅ تم التحسين بنجاح! يمكنك النسخ الآن.';
updateCopyBtnVisibility();
} else {
throw new Error('Server error');
}
} catch (e) {
statusEl.textContent = '⚠️ فشل التحسين الذكي، نعرض النص الأصلي.';
updateCopyBtnVisibility();
}
}
}
// ─── Init ────────────────────────────────────────────────────────────────────