mindmeld-streaminator / index.html
ruslan00290's picture
in react typescript write deepseek or chatgpt like text stream
7da8e16 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MindMeld Streaminator</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
500: '#6366f1',
},
secondary: {
500: '#8b5cf6',
}
}
}
}
}
</script>
<style>
.typing-cursor {
display: inline-block;
width: 8px;
height: 24px;
background-color: currentColor;
animation: blink 1s infinite;
vertical-align: middle;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.message-container {
max-height: 70vh;
overflow-y: auto;
scroll-behavior: smooth;
}
.gradient-bg {
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
}
</style>
</head>
<body class="bg-gray-50 dark:bg-gray-900 transition-colors duration-300">
<div class="min-h-screen flex flex-col">
<!-- Header -->
<header class="gradient-bg text-white p-4 shadow-lg">
<div class="container mx-auto flex items-center justify-between">
<div class="flex items-center space-x-2">
<i data-feather="cpu" class="w-6 h-6"></i>
<h1 class="text-xl font-bold">MindMeld Streaminator</h1>
</div>
<div class="flex items-center space-x-4">
<button id="themeToggle" class="p-2 rounded-full hover:bg-white/10 transition">
<i data-feather="moon" class="hidden dark:block w-5 h-5"></i>
<i data-feather="sun" class="block dark:hidden w-5 h-5"></i>
</button>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1 container mx-auto p-4 max-w-4xl">
<!-- Chat Display -->
<div id="messageContainer" class="message-container bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4 mb-4">
<div class="message response flex mb-4">
<div class="flex-shrink-0 mr-3">
<div class="gradient-bg text-white rounded-full w-8 h-8 flex items-center justify-center">
<i data-feather="cpu" class="w-4 h-4"></i>
</div>
</div>
<div class="flex-1">
<div class="text-sm text-gray-500 dark:text-gray-400 mb-1">MindMeld Streaminator</div>
<div class="text-gray-800 dark:text-gray-200">
<div id="streamedText" class="whitespace-pre-wrap">
<span class="typing-cursor"></span>
</div>
</div>
</div>
</div>
</div>
<!-- Input Area -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4">
<div class="flex items-start space-x-2">
<div class="flex-1">
<textarea id="userInput" placeholder="Ask me anything..." class="w-full p-3 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent resize-none" rows="3"></textarea>
</div>
<button id="sendButton" class="gradient-bg text-white p-3 rounded-lg hover:opacity-90 transition flex items-center justify-center">
<i data-feather="send" class="w-5 h-5"></i>
</button>
</div>
<div class="flex justify-between items-center mt-2 text-xs text-gray-500 dark:text-gray-400">
<div class="flex items-center space-x-2">
<button class="hover:text-primary-500 transition">
<i data-feather="mic" class="w-4 h-4"></i>
</button>
<button class="hover:text-primary-500 transition">
<i data-feather="image" class="w-4 h-4"></i>
</button>
</div>
<span>Press Shift+Enter for new line</span>
</div>
</div>
</main>
<!-- Footer -->
<footer class="gradient-bg text-white p-4 text-center text-sm">
<p>© 2023 MindMeld Streaminator - AI Text Streaming Interface</p>
</footer>
</div>
<script>
feather.replace();
// Theme toggle
const themeToggle = document.getElementById('themeToggle');
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
themeToggle.addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
localStorage.setItem('color-theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light');
});
// Simulate streaming text
const streamedText = document.getElementById('streamedText');
const sampleResponse = `Hello! I'm MindMeld Streaminator, your AI assistant.\n\nI can help you with:\n- Answering questions\n- Generating creative content\n- Analyzing data\n- And much more!\n\nWhat would you like to know today?`;
let currentIndex = 0;
const typingSpeed = 20; // milliseconds per character
function typeWriter() {
if (currentIndex < sampleResponse.length) {
const currentChar = sampleResponse.charAt(currentIndex);
if (currentChar === '\n') {
streamedText.innerHTML = streamedText.innerHTML.replace('<span class="typing-cursor"></span>', '<br><span class="typing-cursor"></span>');
} else {
streamedText.innerHTML = streamedText.innerHTML.replace('<span class="typing-cursor"></span>', currentChar + '<span class="typing-cursor"></span>');
}
currentIndex++;
setTimeout(typeWriter, typingSpeed);
// Auto-scroll to bottom
const container = document.getElementById('messageContainer');
container.scrollTop = container.scrollHeight;
}
}
// Start typing effect after page loads
setTimeout(typeWriter, 1000);
// Handle send button click
document.getElementById('sendButton').addEventListener('click', function() {
const userInput = document.getElementById('userInput').value.trim();
if (userInput) {
// Add user message to chat
const messageContainer = document.getElementById('messageContainer');
const userMessageDiv = document.createElement('div');
userMessageDiv.className = 'message user flex mb-4 justify-end';
userMessageDiv.innerHTML = `
<div class="flex-1 max-w-[90%]">
<div class="text-sm text-gray-500 dark:text-gray-400 mb-1 text-right">You</div>
<div class="bg-primary-500 text-white rounded-lg p-3 inline-block">
${userInput}
</div>
</div>
<div class="flex-shrink-0 ml-3">
<div class="bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-gray-200 rounded-full w-8 h-8 flex items-center justify-center">
<i data-feather="user" class="w-4 h-4"></i>
</div>
</div>
`;
messageContainer.appendChild(userMessageDiv);
// Clear input
document.getElementById('userInput').value = '';
// Scroll to bottom
messageContainer.scrollTop = messageContainer.scrollHeight;
// Simulate thinking
setTimeout(() => {
const thinkingDiv = document.createElement('div');
thinkingDiv.className = 'message response flex mb-4';
thinkingDiv.innerHTML = `
<div class="flex-shrink-0 mr-3">
<div class="gradient-bg text-white rounded-full w-8 h-8 flex items-center justify-center">
<i data-feather="cpu" class="w-4 h-4"></i>
</div>
</div>
<div class="flex-1">
<div class="text-sm text-gray-500 dark:text-gray-400 mb-1">MindMeld Streaminator</div>
<div class="text-gray-800 dark:text-gray-200">
<span id="newResponse" class="whitespace-pre-wrap"><span class="typing-cursor"></span></span>
</div>
</div>
`;
messageContainer.appendChild(thinkingDiv);
// Scroll to bottom
messageContainer.scrollTop = messageContainer.scrollHeight;
// Generate response
const responses = [
`I understand you're asking about "${userInput}". That's an interesting topic! Here's what I know...\n\nAI systems like me process information differently than humans, but we strive to provide accurate and helpful responses.`,
`Regarding "${userInput}", I can provide information based on my training data. Would you like me to go into more detail about any specific aspect?`,
`"${userInput}" - great question! My response would be that in an ever-changing technological landscape, adaptability is key to understanding complex topics.`,
`Let me analyze your query about "${userInput}". Based on patterns in my training data, I can offer several perspectives on this subject.`
];
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
let newIndex = 0;
const newResponse = document.getElementById('newResponse');
function typeNewResponse() {
if (newIndex < randomResponse.length) {
const currentChar = randomResponse.charAt(newIndex);
if (currentChar === '\n') {
newResponse.innerHTML = newResponse.innerHTML.replace('<span class="typing-cursor"></span>', '<br><span class="typing-cursor"></span>');
} else {
newResponse.innerHTML = newResponse.innerHTML.replace('<span class="typing-cursor"></span>', currentChar + '<span class="typing-cursor"></span>');
}
newIndex++;
setTimeout(typeNewResponse, typingSpeed);
// Auto-scroll to bottom
messageContainer.scrollTop = messageContainer.scrollHeight;
}
}
setTimeout(typeNewResponse, 500);
}, 800);
}
});
// Allow Shift+Enter for new line in textarea
document.getElementById('userInput').addEventListener('keydown', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
document.getElementById('sendButton').click();
}
});
// Initialize feather icons after dynamic content is added
setInterval(() => feather.replace(), 500);
</script>
</body>
</html>