Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Modern AI Chat</title> | |
<style> | |
/* Import Fonts */ | |
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;600&family=Poppins:wght@400;600&display=swap'); | |
/* Highlight Title Styling for AI Response */ | |
.highlight-title { | |
font-size: 1.2rem; /* Larger font size */ | |
font-weight: 700; /* Extra bold */ | |
color: #000; /* Black text */ | |
display: inline-block; /* Ensure inline styling behaves properly */ | |
margin: 5px 0; /* Add some spacing if needed */ | |
} | |
/* Code Block Styling */ | |
.code-block { | |
position: relative; | |
margin: 10px 0; | |
background: #f5f5f5; | |
border-radius: 5px; | |
padding: 10px; | |
overflow-x: auto; | |
} | |
.code-block pre { | |
margin: 0; | |
font-family: 'Courier New', Courier, monospace; | |
font-size: 0.9rem; | |
} | |
/* Copy Button Styling */ | |
.copy-btn { | |
position: absolute; | |
top: 10px; | |
right: 10px; | |
padding: 5px 10px; | |
font-size: 0.8rem; | |
font-family: 'Poppins', sans-serif; | |
background: #6200ea; | |
color: #fff; | |
border: none; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background 0.3s ease; | |
} | |
.copy-btn:hover { | |
background: #3700b3; | |
} | |
.copy-btn:active { | |
background: #311b92; | |
} | |
pre { | |
background: #f5f5f5; | |
padding: 10px; | |
border-radius: 5px; | |
font-family: 'Courier New', Courier, monospace; | |
font-size: 0.9rem; | |
overflow-x: auto; /* Enable horizontal scrolling for long code */ | |
} | |
code { | |
background: #f5f5f5; | |
padding: 2px 4px; | |
border-radius: 3px; | |
font-family: 'Courier New', Courier, monospace; | |
font-size: 0.9rem; | |
} | |
/* Other styles for chat system */ | |
body { | |
margin: 0; | |
padding: 0; | |
font-family: 'Poppins', sans-serif; | |
background: linear-gradient(135deg, #6E45E2, #88D3CE); | |
min-height: 100vh; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
overflow: hidden; | |
} | |
/* Animation Background */ | |
body::before { | |
content: ''; | |
position: absolute; | |
top: -50%; | |
left: -50%; | |
width: 200%; | |
height: 200%; | |
background: radial-gradient(circle, rgba(98, 0, 234, 0.6), transparent); | |
animation: backgroundAnimation 6s infinite linear alternate; | |
z-index: 0; | |
} | |
@keyframes backgroundAnimation { | |
to { | |
transform: rotate(360deg); | |
} | |
} | |
.chat-container { | |
position: relative; | |
z-index: 1; | |
width: 100%; | |
max-width: 500px; | |
margin: 0 auto; | |
background: #ffffff; | |
border-radius: 15px; | |
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); | |
display: flex; | |
flex-direction: column; | |
overflow: hidden; | |
} | |
@keyframes fadeIn { | |
from { | |
opacity: 0; | |
transform: translateY(30px); | |
} | |
to { | |
opacity: 1; | |
transform: translateY(0); | |
} | |
} | |
/* Header */ | |
.chat-header { | |
background: linear-gradient(135deg, #6200ea, #3700b3); | |
color: #fff; | |
padding: 20px; | |
text-align: center; | |
font-size: 1.5rem; | |
font-weight: bold; | |
font-family: 'Cairo', sans-serif; | |
} | |
/* Chat Box */ | |
.chat-box { | |
flex: 1; | |
padding: 20px; | |
overflow-y: auto; /* Enable vertical scrolling */ | |
max-height: 400px; /* Restrict the height to make the scrolling work */ | |
border-bottom: 1px solid #ddd; | |
display: flex; | |
flex-direction: column; | |
} | |
.chat-box .message { | |
margin-bottom: 15px; | |
font-size: 1rem; | |
padding: 10px 15px; | |
border-radius: 20px; | |
max-width: 75%; | |
animation: slideIn 0.3s ease-in-out; | |
word-wrap: break-word; | |
font-family: 'Cairo', 'Poppins', sans-serif; | |
} | |
@keyframes slideIn { | |
from { | |
transform: translateY(10px); | |
opacity: 0; | |
} | |
to { | |
transform: translateY(0); | |
opacity: 1; | |
} | |
} | |
.chat-box .message.user { | |
margin-left: auto; | |
background: #e3f2fd; | |
color: #0D47A1; | |
text-align: right; | |
} | |
.chat-box .message.ai { | |
margin-right: auto; | |
background: #e8f5e9; | |
color: #1B5E20; | |
text-align: left; | |
} | |
/* Typing Animation */ | |
.typing-animation { | |
display: flex; | |
margin: 10px 0; | |
justify-content: left; | |
align-items: center; | |
} | |
.typing-animation span { | |
display: inline-block; | |
width: 8px; | |
height: 8px; | |
margin: 0 3px; | |
background: #1B5E20; | |
border-radius: 50%; | |
animation: typing 1.3s infinite; | |
} | |
.typing-animation span:nth-child(2) { | |
animation-delay: 0.2s; | |
} | |
.typing-animation span:nth-child(3) { | |
animation-delay: 0.4s; | |
} | |
@keyframes typing { | |
0%, 80% { | |
transform: scale(0); | |
} | |
40% { | |
transform: scale(1); | |
} | |
} | |
/* Chat Input */ | |
.chat-input { | |
display: flex; | |
align-items: center; | |
padding: 15px; | |
background: #f9f9f9; | |
border-top: 1px solid #ddd; | |
} | |
.chat-input input { | |
flex: 1; | |
padding: 15px; | |
border: 1px solid #ddd; | |
border-radius: 30px; | |
margin-right: 10px; | |
font-size: 1rem; | |
font-family: 'Poppins', 'Cairo', sans-serif; | |
outline: none; | |
transition: all 0.3s ease; | |
} | |
.chat-input input:focus { | |
border-color: #6200ea; | |
box-shadow: 0 0 5px rgba(98, 0, 234, 0.5); | |
} | |
.chat-input button { | |
padding: 12px 18px; | |
background: linear-gradient(135deg, #6200ea, #3700b3); | |
border: none; | |
color: white; | |
border-radius: 20px; | |
cursor: pointer; | |
font-weight: bold; | |
font-size: 1rem; | |
font-family: 'Poppins', 'Cairo', sans-serif; | |
transition: all 0.3s ease; | |
} | |
.chat-input button:hover { | |
background: #5e35b1; | |
box-shadow: 0 5px 15px rgba(98, 0, 234, 0.4); | |
} | |
</style> | |
</head> | |
<body> | |
<div class="chat-container"> | |
<div class="chat-header"> | |
AI Chat with Omar's Smart Model | |
</div> | |
<div class="chat-box" id="chat-box"> | |
<!-- Chat messages will populate here --> | |
</div> | |
<div class="chat-input"> | |
<input type="text" id="user-input" placeholder="Type a message..." autocomplete="off"> | |
<button id="send-btn">Send</button> | |
<button id="voice-btn">🎤</button> | |
</div> | |
</div> | |
<script> | |
const apiUrl = "https://dooratre-test-flask-space.hf.space/chat"; | |
const chatBox = document.getElementById("chat-box"); | |
const userInput = document.getElementById("user-input"); | |
const sendBtn = document.getElementById("send-btn"); | |
// Initialize conversation history | |
let conversationHistory = [ | |
{ "role": "system", "content": "you are AI model created and developed By MR Omar Nuwara In CORVO AI Company you are model name ALEX-9 you can chat and help user you are best model for now\n\n you will chat Omar's Freind Hussein Shkikel He is Libyan So chat with Libyan arabic accent 😂😂😂 make it fun with smart libyan brain 😂 Hussein now in the work he is working in الاستخبارات😂😂" } | |
]; | |
function formatResponse(content) { | |
// Replace multi-line code blocks with copy buttons | |
content = content.replace(/```(.*?)\n([\s\S]*?)```/g, (match, lang, code) => { | |
return ` | |
<div class="code-block"> | |
<button class="copy-btn" onclick="copyToClipboard(this)">Copy</button> | |
<pre><code>${code.trim()}</code></pre> | |
</div> | |
`; | |
}); | |
// Replace inline code using ` for single-line code | |
content = content.replace(/`(.*?)`/g, '<code>$1</code>'); | |
// Replace \n with <br> for line breaks (outside code blocks) | |
content = content.replace(/\n/g, '<br>'); | |
// Replace **{title}** with <strong class="highlight-title">{title}</strong> for bold styled text | |
content = content.replace(/\*\*(.*?)\*\*/g, '<strong class="highlight-title">$1</strong>'); | |
return content; | |
} | |
function copyToClipboard(button) { | |
// Find the <code> block by traversing the DOM | |
const codeBlock = button.parentNode.querySelector("code"); // Get the <code> block inside the same parent | |
const codeText = codeBlock.innerText; // Retrieve the text content of the <code> block | |
// Copy the text to the clipboard using the Clipboard API | |
navigator.clipboard.writeText(codeText).then(() => { | |
// Temporarily show "Copied!" message on the button | |
button.textContent = "Copied!"; | |
setTimeout(() => { | |
button.textContent = "Copy"; // Reset button text after 2 seconds | |
}, 2000); | |
}).catch(err => { | |
console.error("Failed to copy the code:", err); | |
alert("Failed to copy the code. Please try again!"); | |
}); | |
} | |
// Function to add a message to the chat box | |
function addMessage(role, content) { | |
const messageDiv = document.createElement("div"); | |
messageDiv.classList.add("message", role); | |
// Format content for AI messages | |
if (role === "ai") { | |
content = formatResponse(content); | |
} | |
messageDiv.innerHTML = content; // Use innerHTML to render formatted text | |
chatBox.appendChild(messageDiv); | |
// Ensure smooth scroll to the bottom | |
setTimeout(() => { | |
chatBox.scrollTop = chatBox.scrollHeight; // Auto-scroll to the bottom after rendering | |
}, 100); | |
} | |
// Function to show typing animation | |
function showTyping() { | |
const typingDiv = document.createElement("div"); | |
typingDiv.classList.add("typing-animation"); | |
typingDiv.innerHTML = ` | |
<span></span> | |
<span></span> | |
<span></span> | |
`; | |
chatBox.appendChild(typingDiv); | |
// Ensure smooth scroll to include typing animation | |
setTimeout(() => { | |
chatBox.scrollTop = chatBox.scrollHeight; | |
}, 100); | |
return typingDiv; // Return the typing div to remove it later | |
} | |
// Function to play TTS for AI response | |
function playTTS(text) { | |
var tts_xhr = new XMLHttpRequest(); | |
tts_xhr.open("POST", "https://api.braininc.net/be/vectordb/tts", true); | |
tts_xhr.setRequestHeader("Authorization", "token 72ec00483379076f580eb8126f29da802a5140c3"); | |
tts_xhr.setRequestHeader("Content-Type", "application/json"); | |
tts_xhr.responseType = 'blob'; | |
tts_xhr.onreadystatechange = function() { | |
if (tts_xhr.readyState === 4 && tts_xhr.status === 200) { | |
var blob = tts_xhr.response; | |
var audio_url = URL.createObjectURL(blob); | |
// Create an audio element and play the audio | |
var audio = new Audio(audio_url); | |
audio.play(); | |
} | |
}; | |
var tts_payload = { | |
"pubsub_topic": "/studios/516104/wsuid_new-edge-67_nodeid_editor-66/customApi/1719909878183", | |
"text": text | |
}; | |
tts_xhr.send(JSON.stringify(tts_payload)); | |
} | |
// Function to send a message | |
async function sendMessage() { | |
const userMessage = userInput.value.trim(); | |
if (!userMessage) return; | |
// Add user's message to the chat UI | |
addMessage("user", userMessage); | |
// Append user message to conversation history | |
conversationHistory.push({ "role": "user", "content": userMessage }); | |
// Show typing animation | |
const typingDiv = showTyping(); | |
// Prepare data for the API | |
const data = { message: conversationHistory }; | |
try { | |
// Send message to AI using fetch | |
const response = await fetch(apiUrl, { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json" | |
}, | |
body: JSON.stringify(data) | |
}); | |
if (response.ok) { | |
const aiResponse = await response.text(); | |
// Remove typing animation | |
chatBox.removeChild(typingDiv); | |
// Add AI's response to the chat UI (with line breaks and bold formatting handled) | |
addMessage("ai", aiResponse); | |
// Append AI response to conversation history | |
conversationHistory.push({ "role": "assistant", "content": aiResponse }); | |
// Play TTS for AI's response | |
playTTS(aiResponse); | |
} else { | |
throw new Error(`Error: ${response.status}`); | |
} | |
} catch (error) { | |
console.error("Error:", error); | |
chatBox.removeChild(typingDiv); // Remove typing animation | |
addMessage("ai", "AI: Sorry, something went wrong!"); | |
} | |
// Clear input field | |
userInput.value = ""; | |
} | |
// Attach event listeners | |
sendBtn.addEventListener("click", sendMessage); | |
userInput.addEventListener("keypress", (e) => { | |
if (e.key === "Enter") sendMessage(); | |
}); | |
// Initialize Speech Recognition | |
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; | |
const recognition = new SpeechRecognition(); | |
recognition.lang = 'ar-LY'; // Set language to Arabic (Libya) | |
recognition.onstart = function() { | |
console.log('Voice recognition started. Speak now.'); | |
}; | |
recognition.onresult = function(event) { | |
const transcript = event.results[0][0].transcript; // Get the recognized text | |
userInput.value = transcript; // Set the input field to the recognized text | |
sendMessage(); // Send the message | |
}; | |
recognition.onerror = function(event) { | |
console.error('Error occurred in recognition: ' + event.error); | |
}; | |
// Attach event listener for the voice button | |
document.getElementById("voice-btn").addEventListener("click", () => { | |
recognition.start(); // Start voice recognition | |
}); | |
</script> | |
</body> | |
</html> |