Auto-deploy: 2026-06-02 19:04:20
This commit is contained in:
77
popup.js
77
popup.js
@@ -264,8 +264,6 @@ document.getElementById('autofill-btn').addEventListener('click', async () => {
|
||||
|
||||
// ─── Voice Dictation ───────────────────────────────────────────────────────────
|
||||
|
||||
// ─── Voice Dictation ───────────────────────────────────────────────────────────
|
||||
|
||||
function initDictation() {
|
||||
const statusEl = document.getElementById('dictation-status');
|
||||
const micBtn = document.getElementById('dictation-mic-btn');
|
||||
@@ -276,6 +274,16 @@ function initDictation() {
|
||||
let finalTranscript = '';
|
||||
let interimTranscript = '';
|
||||
|
||||
function updateCopyBtnVisibility() {
|
||||
if (resultArea.value.trim()) {
|
||||
copyBtn.style.display = 'inline-flex';
|
||||
} else {
|
||||
copyBtn.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
resultArea.addEventListener('input', updateCopyBtnVisibility);
|
||||
|
||||
function stopRecording(process = true) {
|
||||
if (!isRecording) return;
|
||||
isRecording = false;
|
||||
@@ -283,6 +291,8 @@ function initDictation() {
|
||||
micBtn.style.background = 'linear-gradient(135deg, var(--accent), #9b5de5)';
|
||||
micBtn.innerHTML = '🎤';
|
||||
|
||||
updateCopyBtnVisibility();
|
||||
|
||||
const textToProcess = resultArea.value.trim();
|
||||
if (textToProcess && process) {
|
||||
statusEl.textContent = '✨ جارٍ التحسين بواسطة الذكاء الاصطناعي...';
|
||||
@@ -305,6 +315,7 @@ function initDictation() {
|
||||
interimTranscript = message.payload.interimText || '';
|
||||
finalTranscript = message.payload.finalText || '';
|
||||
resultArea.value = (finalTranscript + interimTranscript).trim();
|
||||
updateCopyBtnVisibility();
|
||||
} else if (message.type === 'SPEECH_ERROR') {
|
||||
console.error('Speech recognition error', message.payload.error);
|
||||
if (message.payload.error === 'not-allowed') {
|
||||
@@ -352,6 +363,9 @@ function initDictation() {
|
||||
return;
|
||||
}
|
||||
window.__ljaDictationActive = true;
|
||||
window.__ljaSpeechUserStopped = false;
|
||||
window.__ljaSpeechAccumulatedText = '';
|
||||
window.__ljaSpeechCurrentSessionFinalText = '';
|
||||
|
||||
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||
if (!SpeechRecognition) {
|
||||
@@ -360,7 +374,12 @@ function initDictation() {
|
||||
return;
|
||||
}
|
||||
|
||||
const recognition = new SpeechRecognition();
|
||||
let recognition;
|
||||
|
||||
function startRecognition() {
|
||||
if (window.__ljaSpeechUserStopped) return;
|
||||
|
||||
recognition = new SpeechRecognition();
|
||||
recognition.lang = lang;
|
||||
recognition.continuous = true;
|
||||
recognition.interimResults = true;
|
||||
@@ -372,37 +391,70 @@ function initDictation() {
|
||||
|
||||
recognition.onresult = (event) => {
|
||||
let interimText = '';
|
||||
let finalText = '';
|
||||
let sessionFinalText = '';
|
||||
|
||||
for (let i = 0; i < event.results.length; i++) {
|
||||
const result = event.results[i];
|
||||
if (result.isFinal) {
|
||||
finalText += result[0].transcript + ' ';
|
||||
sessionFinalText += result[0].transcript + ' ';
|
||||
} else {
|
||||
interimText += result[0].transcript;
|
||||
}
|
||||
}
|
||||
|
||||
window.__ljaSpeechCurrentSessionFinalText = sessionFinalText;
|
||||
|
||||
const fullFinalText = window.__ljaSpeechAccumulatedText + sessionFinalText;
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
type: 'SPEECH_RESULT',
|
||||
payload: { interimText, finalText }
|
||||
payload: {
|
||||
interimText: interimText,
|
||||
finalText: fullFinalText
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
recognition.onerror = (event) => {
|
||||
console.error('[LJA Dictation] Error:', event.error);
|
||||
if (event.error === 'not-allowed') {
|
||||
chrome.runtime.sendMessage({ type: 'SPEECH_ERROR', payload: { error: event.error } });
|
||||
window.__ljaDictationActive = false;
|
||||
} else {
|
||||
console.warn('[LJA Dictation] Recoverable error:', event.error);
|
||||
}
|
||||
};
|
||||
|
||||
recognition.onend = () => {
|
||||
if (window.__ljaSpeechUserStopped) {
|
||||
// User explicitly stopped
|
||||
chrome.runtime.sendMessage({ type: 'SPEECH_END' });
|
||||
window.__ljaDictationActive = false;
|
||||
} else {
|
||||
// Ended due to browser timeout / silence, restart it
|
||||
window.__ljaSpeechAccumulatedText += window.__ljaSpeechCurrentSessionFinalText;
|
||||
window.__ljaSpeechCurrentSessionFinalText = '';
|
||||
console.log('[LJA Dictation] Silence/timeout. Restarting recognition...');
|
||||
setTimeout(() => {
|
||||
if (!window.__ljaSpeechUserStopped) {
|
||||
startRecognition();
|
||||
}
|
||||
}, 150);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
recognition.start();
|
||||
} catch (e) {
|
||||
chrome.runtime.sendMessage({ type: 'SPEECH_ERROR', payload: { error: e.message } });
|
||||
window.__ljaDictationActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for STOP message from popup
|
||||
const stopListener = (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);
|
||||
@@ -411,12 +463,7 @@ function initDictation() {
|
||||
};
|
||||
chrome.runtime.onMessage.addListener(stopListener);
|
||||
|
||||
try {
|
||||
recognition.start();
|
||||
} catch (e) {
|
||||
chrome.runtime.sendMessage({ type: 'SPEECH_ERROR', payload: { error: e.message } });
|
||||
window.__ljaDictationActive = false;
|
||||
}
|
||||
startRecognition();
|
||||
},
|
||||
args: ['ar-SA']
|
||||
}).catch(err => {
|
||||
@@ -440,7 +487,7 @@ function initDictation() {
|
||||
const apiKey = document.getElementById('api-key-input').value.trim();
|
||||
if (!apiKey) {
|
||||
statusEl.textContent = '⚠️ الرجاء إدخال مفتاح Gemini لتحسين النص';
|
||||
copyBtn.style.display = 'inline-flex';
|
||||
updateCopyBtnVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -481,13 +528,13 @@ CORRECTED TEXT:`;
|
||||
|
||||
resultArea.value = processedText.trim();
|
||||
statusEl.textContent = '✅ تم التحسين بنجاح! يمكنك النسخ الآن.';
|
||||
copyBtn.style.display = 'inline-flex';
|
||||
updateCopyBtnVisibility();
|
||||
} else {
|
||||
throw new Error('Server error');
|
||||
}
|
||||
} catch (e) {
|
||||
statusEl.textContent = '⚠️ فشل التحسين الذكي، نعرض النص الأصلي.';
|
||||
copyBtn.style.display = 'inline-flex';
|
||||
updateCopyBtnVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user