Spaces:
Running
Running
Update index.html
Browse files- index.html +188 -23
index.html
CHANGED
|
@@ -162,6 +162,42 @@
|
|
| 162 |
border-left: none;
|
| 163 |
border-top: none;
|
| 164 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
</style>
|
| 166 |
</head>
|
| 167 |
<body class="scanlines min-h-screen">
|
|
@@ -195,7 +231,7 @@
|
|
| 195 |
</div>
|
| 196 |
|
| 197 |
<!-- Terminal Content -->
|
| 198 |
-
<div class="p-4 h-96 overflow-y-auto terminal-font text-green-200">
|
| 199 |
<div class="mb-4">
|
| 200 |
<span class="neon-purple">user@vibecode:~$</span> <span class="neon-green">welcome to Vibecode</span>
|
| 201 |
</div>
|
|
@@ -285,7 +321,7 @@
|
|
| 285 |
<a href="#" class="mx-2 hover:text-neon-green transition-all">Discord</a>
|
| 286 |
<a href="#" class="mx-2 hover:text-neon-green transition-all">GitHub</a>
|
| 287 |
</div>
|
| 288 |
-
<p>Vibecode ©
|
| 289 |
</footer>
|
| 290 |
</div>
|
| 291 |
|
|
@@ -294,6 +330,11 @@
|
|
| 294 |
const userInput = document.getElementById('user-input');
|
| 295 |
const sendBtn = document.getElementById('send-btn');
|
| 296 |
const chatMessages = document.getElementById('chat-messages');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 297 |
|
| 298 |
// Typing animation for the terminal prompt
|
| 299 |
const typingElement = document.querySelector('.typing');
|
|
@@ -340,14 +381,29 @@
|
|
| 340 |
// Add user message
|
| 341 |
addMessage(message, 'user');
|
| 342 |
|
| 343 |
-
//
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 351 |
|
| 352 |
// Clear input
|
| 353 |
userInput.value = '';
|
|
@@ -364,26 +420,135 @@
|
|
| 364 |
? 'bg-neon-green/10 border border-neon-green/30 text-neon-green'
|
| 365 |
: 'bg-gray-800/50 border border-neon-purple/30 text-gray-300'
|
| 366 |
}`;
|
| 367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
|
| 369 |
messageDiv.appendChild(bubble);
|
| 370 |
chatMessages.appendChild(messageDiv);
|
| 371 |
|
| 372 |
// Scroll to bottom
|
| 373 |
-
|
| 374 |
}
|
| 375 |
|
| 376 |
-
function
|
| 377 |
-
|
| 378 |
-
const
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
|
| 386 |
-
return
|
| 387 |
}
|
| 388 |
|
| 389 |
// Event listeners
|
|
@@ -395,5 +560,5 @@
|
|
| 395 |
});
|
| 396 |
});
|
| 397 |
</script>
|
| 398 |
-
|
| 399 |
</html>
|
|
|
|
| 162 |
border-left: none;
|
| 163 |
border-top: none;
|
| 164 |
}
|
| 165 |
+
|
| 166 |
+
.loading-dots:after {
|
| 167 |
+
content: '...';
|
| 168 |
+
animation: dots 1.5s steps(5, end) infinite;
|
| 169 |
+
display: inline-block;
|
| 170 |
+
width: 0;
|
| 171 |
+
overflow: hidden;
|
| 172 |
+
vertical-align: bottom;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
@keyframes dots {
|
| 176 |
+
0%, 20% { width: 0; }
|
| 177 |
+
40% { width: 0.2em; }
|
| 178 |
+
60% { width: 0.4em; }
|
| 179 |
+
80% { width: 0.6em; }
|
| 180 |
+
100% { width: 0; }
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
/* Code syntax highlighting */
|
| 184 |
+
.code-snippet {
|
| 185 |
+
background-color: rgba(0,0,0,0.4);
|
| 186 |
+
padding: 12px;
|
| 187 |
+
border-radius: 4px;
|
| 188 |
+
border-left: 3px solid var(--neon-green);
|
| 189 |
+
font-family: 'IBM Plex Mono', monospace;
|
| 190 |
+
font-size: 0.9em;
|
| 191 |
+
overflow-x: auto;
|
| 192 |
+
margin: 10px 0;
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
.code-keyword { color: #ff79c6; }
|
| 196 |
+
.code-string { color: #f1fa8c; }
|
| 197 |
+
.code-comment { color: #6272a4; }
|
| 198 |
+
.code-function { color: #50fa7b; }
|
| 199 |
+
.code-variable { color: #8be9fd; }
|
| 200 |
+
.code-number { color: #bd93f9; }
|
| 201 |
</style>
|
| 202 |
</head>
|
| 203 |
<body class="scanlines min-h-screen">
|
|
|
|
| 231 |
</div>
|
| 232 |
|
| 233 |
<!-- Terminal Content -->
|
| 234 |
+
<div class="p-4 h-96 overflow-y-auto terminal-font text-green-200" id="terminal-content">
|
| 235 |
<div class="mb-4">
|
| 236 |
<span class="neon-purple">user@vibecode:~$</span> <span class="neon-green">welcome to Vibecode</span>
|
| 237 |
</div>
|
|
|
|
| 321 |
<a href="#" class="mx-2 hover:text-neon-green transition-all">Discord</a>
|
| 322 |
<a href="#" class="mx-2 hover:text-neon-green transition-all">GitHub</a>
|
| 323 |
</div>
|
| 324 |
+
<p>Vibecode © 2025 | Onchain Replit with Vibes</p>
|
| 325 |
</footer>
|
| 326 |
</div>
|
| 327 |
|
|
|
|
| 330 |
const userInput = document.getElementById('user-input');
|
| 331 |
const sendBtn = document.getElementById('send-btn');
|
| 332 |
const chatMessages = document.getElementById('chat-messages');
|
| 333 |
+
const terminalContent = document.getElementById('terminal-content');
|
| 334 |
+
|
| 335 |
+
// Gemini API Key
|
| 336 |
+
const GEMINI_API_KEY = "AIzaSyAX_-SVl0NpZ8Iv8mlkJ3olLbgxs_fTyGw";
|
| 337 |
+
const GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent";
|
| 338 |
|
| 339 |
// Typing animation for the terminal prompt
|
| 340 |
const typingElement = document.querySelector('.typing');
|
|
|
|
| 381 |
// Add user message
|
| 382 |
addMessage(message, 'user');
|
| 383 |
|
| 384 |
+
// Add loading indicator
|
| 385 |
+
const loadingId = addLoadingIndicator();
|
| 386 |
+
|
| 387 |
+
// Call Gemini API
|
| 388 |
+
callGeminiAPI(message)
|
| 389 |
+
.then(response => {
|
| 390 |
+
// Remove loading indicator
|
| 391 |
+
removeLoadingIndicator(loadingId);
|
| 392 |
+
|
| 393 |
+
// Add AI response
|
| 394 |
+
addMessage(formatResponse(response, message), 'ai');
|
| 395 |
+
|
| 396 |
+
// Scroll to bottom
|
| 397 |
+
terminalContent.scrollTop = terminalContent.scrollHeight;
|
| 398 |
+
})
|
| 399 |
+
.catch(error => {
|
| 400 |
+
// Remove loading indicator
|
| 401 |
+
removeLoadingIndicator(loadingId);
|
| 402 |
+
|
| 403 |
+
// Add error message
|
| 404 |
+
addMessage("Error processing your request. Please try again.", 'ai');
|
| 405 |
+
console.error("Gemini API Error:", error);
|
| 406 |
+
});
|
| 407 |
|
| 408 |
// Clear input
|
| 409 |
userInput.value = '';
|
|
|
|
| 420 |
? 'bg-neon-green/10 border border-neon-green/30 text-neon-green'
|
| 421 |
: 'bg-gray-800/50 border border-neon-purple/30 text-gray-300'
|
| 422 |
}`;
|
| 423 |
+
|
| 424 |
+
// Format the response with code highlighting if it contains code
|
| 425 |
+
if (sender === 'ai' && text.includes('```')) {
|
| 426 |
+
const formattedText = formatCodeBlocks(text);
|
| 427 |
+
bubble.innerHTML = formattedText;
|
| 428 |
+
} else {
|
| 429 |
+
bubble.textContent = text;
|
| 430 |
+
}
|
| 431 |
|
| 432 |
messageDiv.appendChild(bubble);
|
| 433 |
chatMessages.appendChild(messageDiv);
|
| 434 |
|
| 435 |
// Scroll to bottom
|
| 436 |
+
terminalContent.scrollTop = terminalContent.scrollHeight;
|
| 437 |
}
|
| 438 |
|
| 439 |
+
function addLoadingIndicator() {
|
| 440 |
+
const loadingId = 'loading-' + Date.now();
|
| 441 |
+
const loadingDiv = document.createElement('div');
|
| 442 |
+
loadingDiv.id = loadingId;
|
| 443 |
+
loadingDiv.className = 'flex justify-start';
|
| 444 |
+
|
| 445 |
+
const loadingBubble = document.createElement('div');
|
| 446 |
+
loadingBubble.className = 'terminal-font rounded px-4 py-2 bg-gray-800/50 border border-neon-purple/30 text-gray-300';
|
| 447 |
+
|
| 448 |
+
const loadingText = document.createElement('span');
|
| 449 |
+
loadingText.className = 'loading-dots';
|
| 450 |
+
loadingText.textContent = 'Generating smart contract';
|
| 451 |
+
|
| 452 |
+
loadingBubble.appendChild(loadingText);
|
| 453 |
+
loadingDiv.appendChild(loadingBubble);
|
| 454 |
+
chatMessages.appendChild(loadingDiv);
|
| 455 |
+
|
| 456 |
+
// Scroll to bottom
|
| 457 |
+
terminalContent.scrollTop = terminalContent.scrollHeight;
|
| 458 |
+
|
| 459 |
+
return loadingId;
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
function removeLoadingIndicator(loadingId) {
|
| 463 |
+
const loadingElement = document.getElementById(loadingId);
|
| 464 |
+
if (loadingElement) {
|
| 465 |
+
loadingElement.remove();
|
| 466 |
+
}
|
| 467 |
+
}
|
| 468 |
+
|
| 469 |
+
async function callGeminiAPI(message) {
|
| 470 |
+
// Construct prompt for blockchain context
|
| 471 |
+
const blockchainPrompt = `You are Vibecode AI, an expert in blockchain development and smart contract creation.
|
| 472 |
+
The user will give you a request related to creating tokens, NFTs, DAOs, or other blockchain applications.
|
| 473 |
+
|
| 474 |
+
Please respond with:
|
| 475 |
+
1. An explanation of what you'll create based on their request
|
| 476 |
+
2. The appropriate smart contract code (Solidity) to implement their request
|
| 477 |
+
3. Clear deployment instructions
|
| 478 |
+
|
| 479 |
+
Current user request: "${message}"`;
|
| 480 |
+
|
| 481 |
+
try {
|
| 482 |
+
const response = await fetch(`${GEMINI_API_URL}?key=${GEMINI_API_KEY}`, {
|
| 483 |
+
method: 'POST',
|
| 484 |
+
headers: {
|
| 485 |
+
'Content-Type': 'application/json'
|
| 486 |
+
},
|
| 487 |
+
body: JSON.stringify({
|
| 488 |
+
contents: [{
|
| 489 |
+
parts: [{
|
| 490 |
+
text: blockchainPrompt
|
| 491 |
+
}]
|
| 492 |
+
}]
|
| 493 |
+
})
|
| 494 |
+
});
|
| 495 |
+
|
| 496 |
+
if (!response.ok) {
|
| 497 |
+
throw new Error(`HTTP error! status: ${response.status}`);
|
| 498 |
+
}
|
| 499 |
+
|
| 500 |
+
const data = await response.json();
|
| 501 |
+
|
| 502 |
+
// Extract the text from the response
|
| 503 |
+
if (data.candidates &&
|
| 504 |
+
data.candidates[0] &&
|
| 505 |
+
data.candidates[0].content &&
|
| 506 |
+
data.candidates[0].content.parts &&
|
| 507 |
+
data.candidates[0].content.parts[0]) {
|
| 508 |
+
return data.candidates[0].content.parts[0].text;
|
| 509 |
+
} else {
|
| 510 |
+
throw new Error("Unexpected response format from Gemini API");
|
| 511 |
+
}
|
| 512 |
+
} catch (error) {
|
| 513 |
+
console.error("Error calling Gemini API:", error);
|
| 514 |
+
throw error;
|
| 515 |
+
}
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
function formatResponse(response, userRequest) {
|
| 519 |
+
// You can customize the formatting of the AI response here
|
| 520 |
+
return response;
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
function formatCodeBlocks(text) {
|
| 524 |
+
// Split the text by code blocks
|
| 525 |
+
const parts = text.split('```');
|
| 526 |
+
let result = '';
|
| 527 |
+
|
| 528 |
+
for (let i = 0; i < parts.length; i++) {
|
| 529 |
+
if (i % 2 === 0) {
|
| 530 |
+
// Regular text
|
| 531 |
+
result += parts[i];
|
| 532 |
+
} else {
|
| 533 |
+
// Code block
|
| 534 |
+
const codeLines = parts[i].split('\n');
|
| 535 |
+
const language = codeLines[0] || '';
|
| 536 |
+
const code = codeLines.slice(1).join('\n');
|
| 537 |
+
|
| 538 |
+
// Basic syntax highlighting for Solidity
|
| 539 |
+
let highlightedCode = code
|
| 540 |
+
.replace(/\b(contract|function|address|uint|string|bytes|mapping|struct|enum|bool|public|private|internal|external|view|pure|returns|memory|storage|calldata)\b/g, '<span class="code-keyword">$1</span>')
|
| 541 |
+
.replace(/(\/\/.*)/g, '<span class="code-comment">$1</span>')
|
| 542 |
+
.replace(/"([^"]*)"/g, '<span class="code-string">"$1"</span>')
|
| 543 |
+
.replace(/\b(\d+)\b/g, '<span class="code-number">$1</span>')
|
| 544 |
+
.replace(/\b(constructor|require|assert|emit)\b/g, '<span class="code-function">$1</span>')
|
| 545 |
+
.replace(/\b(msg|block|tx|address)\b/g, '<span class="code-variable">$1</span>');
|
| 546 |
+
|
| 547 |
+
result += `<div class="code-snippet">${highlightedCode}</div>`;
|
| 548 |
+
}
|
| 549 |
+
}
|
| 550 |
|
| 551 |
+
return result;
|
| 552 |
}
|
| 553 |
|
| 554 |
// Event listeners
|
|
|
|
| 560 |
});
|
| 561 |
});
|
| 562 |
</script>
|
| 563 |
+
</body>
|
| 564 |
</html>
|