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