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