| | <!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> |