i3-Series / index.html
FlameF0X's picture
Update index.html
3f2d92c verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>i3 Model Series</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
<style>
/* Global Styles */
body { margin: 0; font-family: 'Inter', sans-serif; background: #fff; color: #333; }
/* Navigation Bar */
nav {
background: #ffffff;
border-bottom: 1px solid #eee;
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
z-index: 1000;
}
.nav-logo { font-weight: 700; font-size: 1.2rem; color: #111; text-decoration: none; cursor: pointer;}
.nav-links a {
margin-left: 20px;
text-decoration: none;
color: #666;
font-size: 0.9rem;
transition: color 0.2s;
cursor: pointer;
}
.nav-links a:hover, .nav-links a.active { color: #007bff; }
/* Content Container */
#app-content {
padding: 40px 20px;
display: flex;
flex-direction: column;
align-items: center;
min-height: 80vh;
}
</style>
</head>
<body>
<nav>
<a class="nav-logo" onclick="route('home')">i3 Series</a>
<div class="nav-links">
<a onclick="route('home')" id="nav-home">Home</a>
<a onclick="route('timeline')" id="nav-timeline">Timeline</a>
<a onclick="route('chat')" id="nav-chat">Chat <i class="fas fa-sparkles" style="font-size: 0.7em; color: #007bff;"></i></a>
<a onclick="route('about')" id="nav-about">About</a>
</div>
</nav>
<div id="app-content"></div>
<footer style="text-align: center; padding: 20px; color: #999; font-size: 0.9rem; border-top: 1px solid #eee;">
<p>i3 Model Series &copy; 2025</p>
</footer>
<script type="module">
// 1. UPDATE: Import the 'Client' class from the latest version
import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client@latest/dist/index.min.js";
// --- MODEL CONFIGURATION ---
const MODEL_CONFIG = {
'200m': {
// 2. UPDATE: Use the simple Space ID with the new client
spaceId: "FlameF0X/i3-200m",
endpoint: "/predict",
name: "i3-200m"
},
'80m': {
spaceId: "FlameF0X/i3-80m-with-streaming",
endpoint: "/generate_text",
name: "i3-80m"
}
};
const routes = {
'home': 'pages/home.html',
'timeline': 'pages/timeline.html',
'chat': 'pages/chat.html',
'about': 'pages/about.html'
};
// Make route global
window.route = async function(pageName) {
document.querySelectorAll('.nav-links a').forEach(el => el.classList.remove('active'));
const activeLink = document.getElementById(`nav-${pageName}`);
if(activeLink) activeLink.classList.add('active');
const contentDiv = document.getElementById('app-content');
try {
const response = await fetch(routes[pageName]);
if (!response.ok) throw new Error('Page not found');
const html = await response.text();
contentDiv.innerHTML = html;
if(pageName === 'timeline') initTimelineAnimations();
if(pageName === 'chat') initChatInterface();
const newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?page=' + pageName;
window.history.pushState({ path: newUrl }, '', newUrl);
} catch (error) {
console.error(error);
contentDiv.innerHTML = "<h2 style='text-align:center; color:#999;'>404 - Page not found</h2>";
}
}
// --- TIMELINE LOGIC ---
function initTimelineAnimations() {
const spaceBtn = document.getElementById('i3SpaceBtn');
if(spaceBtn) {
spaceBtn.addEventListener('click', () => window.open('https://huggingface.co/spaces/FlameF0X/i3-200m', '_blank'));
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = 1;
entry.target.style.transform = 'translateY(0)';
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.timeline-item').forEach(item => {
item.style.opacity = 0;
item.style.transform = 'translateY(20px)';
item.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
observer.observe(item);
});
}
// --- CHAT LOGIC ---
function initChatInterface() {
const input = document.getElementById('user-input');
const btn = document.getElementById('send-btn');
const container = document.getElementById('messages-container');
const modelSelector = document.getElementById('model-selector');
function addMessage(text, sender, modelName = 'i3') {
const div = document.createElement('div');
div.className = `message ${sender}`;
div.innerHTML = sender === 'bot' ? `<strong>${modelName}:</strong> ${text}` : text;
container.appendChild(div);
container.scrollTop = container.scrollHeight;
return div;
}
async function handleSend() {
const prompt = input.value.trim();
if(!prompt) return;
const selectedKey = modelSelector.value;
const modelConfig = MODEL_CONFIG[selectedKey];
addMessage(prompt, 'user');
input.value = '';
input.disabled = true;
btn.disabled = true;
const loadingBubble = addMessage('<i class="fas fa-circle-notch fa-spin"></i> Thinking...', 'bot', modelConfig.name);
try {
const maxTokens = parseInt(document.getElementById('param-tokens').value);
const temp = parseFloat(document.getElementById('param-temp').value);
const topK = parseInt(document.getElementById('param-topk').value);
console.log(`Connecting to ${modelConfig.spaceId}...`);
// 3. UPDATE: Use Client.connect() syntax
const app = await Client.connect(modelConfig.spaceId);
const result = await app.predict(modelConfig.endpoint, {
param_0: prompt,
param_1: maxTokens,
param_2: temp,
param_3: topK
});
loadingBubble.innerHTML = `<strong>${modelConfig.name}:</strong> ${result.data[0]}`;
} catch (error) {
console.error("API Error:", error);
loadingBubble.innerHTML = `<strong>Error:</strong> Failed to connect.<br><small>${error.message}</small>`;
loadingBubble.style.background = "#fff0f0";
loadingBubble.style.color = "#d00";
} finally {
input.disabled = false;
btn.disabled = false;
input.focus();
container.scrollTop = container.scrollHeight;
}
}
btn.onclick = handleSend;
input.onkeypress = (e) => {
if(e.key === 'Enter') handleSend();
};
}
const urlParams = new URLSearchParams(window.location.search);
const currentPage = urlParams.get('page') || 'home';
window.route(currentPage);
</script>
</body>
</html>