|
|
<!DOCTYPE html> |
|
|
<html lang="ar" dir="rtl"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>لهجة AI - مساعد باللهجة النجدية</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap'); |
|
|
|
|
|
body { |
|
|
font-family: 'Tajawal', sans-serif; |
|
|
background-color: #f8f4e8; |
|
|
} |
|
|
|
|
|
.header-bg { |
|
|
background: linear-gradient(135deg, #8B0000 0%, #A52A2A 100%); |
|
|
} |
|
|
|
|
|
.chat-bubble { |
|
|
border-radius: 20px 20px 5px 20px; |
|
|
background-color: #f0f0f0; |
|
|
} |
|
|
|
|
|
.user-bubble { |
|
|
border-radius: 20px 20px 20px 5px; |
|
|
background-color: #e3f2fd; |
|
|
} |
|
|
|
|
|
.audio-player { |
|
|
transition: all 0.3s ease; |
|
|
background-color: #fff; |
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
|
|
} |
|
|
|
|
|
.audio-player:hover { |
|
|
transform: translateY(-2px); |
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15); |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="min-h-screen flex flex-col"> |
|
|
|
|
|
<header class="header-bg text-white py-6 shadow-lg"> |
|
|
<div class="container mx-auto px-4 text-center"> |
|
|
<div class="flex items-center justify-center space-x-3"> |
|
|
<i class="fas fa-comments text-2xl"></i> |
|
|
<h1 class="text-2xl font-bold">لهجة AI</h1> |
|
|
</div> |
|
|
<p class="mt-2 text-sm opacity-90"> |
|
|
مساعد ذكي باللهجة النجدية | مطور من قبل أسس الذكاء الرقمي |
|
|
</p> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
|
|
|
<main class="flex-grow container mx-auto px-4 py-8"> |
|
|
<div class="max-w-4xl mx-auto"> |
|
|
|
|
|
<div class="bg-white rounded-xl shadow-lg overflow-hidden"> |
|
|
|
|
|
<div id="chatContainer" class="h-96 p-4 overflow-y-auto space-y-4"> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="p-4 border-t border-gray-200 bg-gray-50"> |
|
|
<div class="flex flex-col space-y-4"> |
|
|
<textarea id="userInput" |
|
|
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-red-600 focus:border-red-600 outline-none transition duration-200 resize-none" |
|
|
placeholder="💬 اكتب رسالتك هنا..." |
|
|
rows="3"></textarea> |
|
|
|
|
|
<div class="flex flex-col sm:flex-row items-center justify-between space-y-3 sm:space-y-0"> |
|
|
<div class="flex items-center space-x-3"> |
|
|
<div class="flex items-center"> |
|
|
<label for="voiceSelect" class="ml-2 text-sm font-medium text-gray-700">الصوت:</label> |
|
|
<select id="voiceSelect" class="border border-gray-300 rounded-md px-3 py-1 text-sm focus:ring-red-600 focus:border-red-600 outline-none"> |
|
|
<option value="alloy">عادي</option> |
|
|
<option value="echo">صدى</option> |
|
|
<option value="nova">نوفا</option> |
|
|
<option value="shimmer">شيمر</option> |
|
|
</select> |
|
|
</div> |
|
|
<div class="flex items-center"> |
|
|
<label for="speedSelect" class="ml-2 text-sm font-medium text-gray-700">السرعة:</label> |
|
|
<select id="speedSelect" class="border border-gray-300 rounded-md px-3 py-1 text-sm focus:ring-red-600 focus:border-red-600 outline-none"> |
|
|
<option value="0.8">بطيئة</option> |
|
|
<option value="1.0" selected>عادية</option> |
|
|
<option value="1.2">سريعة</option> |
|
|
</select> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<button id="sendBtn" class="bg-red-700 hover:bg-red-800 text-white font-medium py-2 px-6 rounded-lg shadow transition duration-200 flex items-center"> |
|
|
<i class="fas fa-paper-plane mr-2"></i> |
|
|
إرسال |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="audioSection" class="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4"> |
|
|
<div class="audio-player p-4 rounded-xl"> |
|
|
<h3 class="font-medium text-gray-800 mb-2">صوت السؤال</h3> |
|
|
<audio id="questionAudio" controls class="w-full"></audio> |
|
|
</div> |
|
|
<div class="audio-player p-4 rounded-xl"> |
|
|
<h3 class="font-medium text-gray-800 mb-2">صوت الجواب</h3> |
|
|
<audio id="answerAudio" controls class="w-full"></audio> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</main> |
|
|
|
|
|
|
|
|
<footer class="bg-gray-100 py-4 border-t border-gray-200 mt-auto"> |
|
|
<div class="container mx-auto px-4 text-center"> |
|
|
<p class="text-gray-600 text-sm"> |
|
|
© 2025 لهجة AI. جميع الحقوق محفوظة لشركة أسس الذكاء الرقمي. |
|
|
</p> |
|
|
</div> |
|
|
</footer> |
|
|
</div> |
|
|
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> |
|
|
<script> |
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
const chatContainer = document.getElementById('chatContainer'); |
|
|
const userInput = document.getElementById('userInput'); |
|
|
const sendBtn = document.getElementById('sendBtn'); |
|
|
const voiceSelect = document.getElementById('voiceSelect'); |
|
|
const speedSelect = document.getElementById('speedSelect'); |
|
|
const questionAudio = document.getElementById('questionAudio'); |
|
|
const answerAudio = document.getElementById('answerAudio'); |
|
|
const audioSection = document.getElementById('audioSection'); |
|
|
const API_ENDPOINT = "https://your-gradio-app-url.com/api/predict"; |
|
|
const API_KEY = "YOUR_API_KEY_HERE"; |
|
|
|
|
|
|
|
|
function addMessage(text, isUser) { |
|
|
const messageDiv = document.createElement('div'); |
|
|
messageDiv.className = `flex ${isUser ? 'justify-start' : 'justify-end'}`; |
|
|
|
|
|
const bubble = document.createElement('div'); |
|
|
bubble.className = isUser ? 'user-bubble p-4 max-w-xs md:max-w-md' : 'chat-bubble p-4 max-w-xs md:max-w-md'; |
|
|
bubble.textContent = text; |
|
|
|
|
|
messageDiv.appendChild(bubble); |
|
|
chatContainer.appendChild(messageDiv); |
|
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
|
} |
|
|
|
|
|
|
|
|
sendBtn.addEventListener('click', async function() { |
|
|
const message = userInput.value.trim(); |
|
|
if (!message) return; |
|
|
|
|
|
|
|
|
addMessage(message, true); |
|
|
userInput.value = ''; |
|
|
|
|
|
|
|
|
const loadingDiv = document.createElement('div'); |
|
|
loadingDiv.className = 'flex justify-end'; |
|
|
const loadingBubble = document.createElement('div'); |
|
|
loadingBubble.className = 'chat-bubble p-4 max-w-xs'; |
|
|
loadingBubble.innerHTML = '<i class="fas fa-spinner fa-spin"></i> جاري الرد...'; |
|
|
loadingDiv.appendChild(loadingBubble); |
|
|
chatContainer.appendChild(loadingDiv); |
|
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
|
|
|
|
try { |
|
|
|
|
|
const response = await fetch("https://your-gradio-app-url.com/api/predict", { |
|
|
method: "POST", |
|
|
headers: { |
|
|
"Content-Type": "application/json", |
|
|
}, |
|
|
body: JSON.stringify({ |
|
|
data: [ |
|
|
message, |
|
|
voiceSelect.value, |
|
|
parseFloat(speedSelect.value), |
|
|
[], |
|
|
API_KEY |
|
|
] |
|
|
}) |
|
|
}); |
|
|
|
|
|
const result = await response.json(); |
|
|
const [history, q_audio, a_audio] = result.data; |
|
|
|
|
|
|
|
|
chatContainer.removeChild(loadingDiv); |
|
|
|
|
|
|
|
|
const reply = history[history.length-1][1]; |
|
|
addMessage(reply, false); |
|
|
|
|
|
|
|
|
questionAudio.src = q_audio; |
|
|
answerAudio.src = a_audio; |
|
|
audioSection.classList.remove('hidden'); |
|
|
|
|
|
} catch (error) { |
|
|
console.error("Error:", error); |
|
|
chatContainer.removeChild(loadingDiv); |
|
|
addMessage("حدث خطأ أثناء محاولة الاتصال بالخادم. الرجاء المحاولة لاحقاً.", false); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
userInput.addEventListener('keypress', function(e) { |
|
|
if (e.key === 'Enter' && !e.shiftKey) { |
|
|
e.preventDefault(); |
|
|
sendBtn.click(); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |