Spaces:
Running
Running
Update index.html
Browse files- index.html +22 -22
index.html
CHANGED
|
@@ -246,10 +246,10 @@ const elem = document.getElementById('rules-content');
|
|
| 246 |
const toggle = document.querySelector('.rules-toggle');
|
| 247 |
if(elem.classList.contains('active')){
|
| 248 |
elem.classList.remove('active');
|
| 249 |
-
toggle.textContent = '๐ Economy Rules
|
| 250 |
}else{
|
| 251 |
elem.classList.add('active');
|
| 252 |
-
toggle.textContent = '๐ Economy Rules
|
| 253 |
}
|
| 254 |
}
|
| 255 |
async function register(){
|
|
@@ -257,7 +257,7 @@ const email = document.getElementById('login-email').value.trim();
|
|
| 257 |
const username = document.getElementById('login-username').value.trim();
|
| 258 |
const gender = document.getElementById('login-gender').value;
|
| 259 |
const mbti = document.getElementById('login-mbti').value;
|
| 260 |
-
if(!email || !username){alert('Email
|
| 261 |
const res = await fetch('/api/user/login_or_register',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email,username,gender,mbti})});
|
| 262 |
const data = await res.json();
|
| 263 |
if(data.error){alert(data.error);return;}
|
|
@@ -309,8 +309,8 @@ document.getElementById('admin-panel').style.display='block';
|
|
| 309 |
async function loadBoards(){
|
| 310 |
const res = await fetch('/api/boards');
|
| 311 |
const boards = await res.json();
|
| 312 |
-
// ๐ฎ Battle
|
| 313 |
-
let html = `<button class="board-tab ${'battle'===currentBoard?'active':''}" onclick="switchBoard('battle')">๐ฎ Battle
|
| 314 |
// Add remaining boards
|
| 315 |
html += boards.map(b=>`<button class="board-tab ${b.key===currentBoard?'active':''}" onclick="switchBoard('${b.key}')">${b.name}</button>`).join('');
|
| 316 |
document.getElementById('board-tabs').innerHTML = html;
|
|
@@ -319,7 +319,7 @@ async function switchBoard(key){
|
|
| 319 |
currentBoard = key;
|
| 320 |
await loadBoards();
|
| 321 |
|
| 322 |
-
// ๐ฎ
|
| 323 |
const sortToggle = document.querySelector('.sort-toggle');
|
| 324 |
if(sortToggle){
|
| 325 |
sortToggle.style.display = (key === 'battle') ? 'none' : 'flex';
|
|
@@ -335,7 +335,7 @@ event.target.classList.add('active');
|
|
| 335 |
await loadPosts(currentBoard, sort);
|
| 336 |
}
|
| 337 |
async function loadPosts(key, sort){
|
| 338 |
-
// ๐ฎ Battle
|
| 339 |
if(key === 'battle'){
|
| 340 |
await loadBattleBoard();
|
| 341 |
return;
|
|
@@ -363,7 +363,7 @@ ${isHot?'<span class="badge badge-hot">HOT</span>':''}
|
|
| 363 |
document.getElementById('posts-container').innerHTML = html || '<div class="empty-state">No posts yet</div>';
|
| 364 |
}
|
| 365 |
|
| 366 |
-
// ๐ฎ Battle
|
| 367 |
async function loadBattleBoard(){
|
| 368 |
const container = document.getElementById('posts-container');
|
| 369 |
container.innerHTML = '<div style="text-align:center;padding:20px;">Loading...</div>';
|
|
@@ -375,14 +375,14 @@ const battles = data.battles || [];
|
|
| 375 |
let html = `
|
| 376 |
<div style="background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:20px;border-radius:8px;margin-bottom:20px;">
|
| 377 |
<div style="font-size:20px;font-weight:700;margin-bottom:10px;">๐ฎ Battle Arena - Polymarket Style</div>
|
| 378 |
-
<div style="font-size:14px;opacity:0.9;">Bet on A/B votes and predict the winner! โข 2% host fee โข 50.01%
|
| 379 |
<button class="btn btn-warning" style="margin-top:15px;" onclick="showCreateBattleModal()">
|
| 380 |
๐ Create Battle (-50 GPU)
|
| 381 |
</button>
|
| 382 |
</div>
|
| 383 |
|
| 384 |
<div style="font-size:16px;font-weight:600;margin:20px 0;color:#e0e0e0;">
|
| 385 |
-
๐ฅ Active Battles (${battles.length}
|
| 386 |
</div>
|
| 387 |
`;
|
| 388 |
|
|
@@ -399,7 +399,7 @@ html += `
|
|
| 399 |
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
|
| 400 |
<div style="font-weight:700;font-size:16px;color:#e0e0e0;flex:1;">${b.title}</div>
|
| 401 |
<div style="background:${b.battle_type === 'prediction' ? '#17a2b8' : '#667eea'};color:#fff;padding:4px 10px;border-radius:20px;font-size:11px;font-weight:700;">
|
| 402 |
-
${b.battle_type === 'prediction' ? '๐ฎ
|
| 403 |
</div>
|
| 404 |
</div>
|
| 405 |
<div style="font-size:13px;color:#8e8ea0;margin-bottom:15px;">
|
|
@@ -457,11 +457,11 @@ let html = `<div class="modal-header">${p.title}</div>
|
|
| 457 |
<div style="margin-top:15px;display:flex;gap:10px;">
|
| 458 |
<button class="btn btn-primary" onclick="likePost(${p.id})" data-tooltip="1 GPU cost, earn curation rewards">โค๏ธ ${p.likes}</button>
|
| 459 |
<button class="btn btn-danger" onclick="dislikePost(${p.id})" data-tooltip="Opponent -1 GPU">๐ ${p.dislikes}</button>
|
| 460 |
-
<button class="btn btn-secondary" onclick="commentPost(${p.id})" data-tooltip="AI
|
| 461 |
</div>
|
| 462 |
</div>
|
| 463 |
<div style="padding:15px;">
|
| 464 |
-
<h3 style="font-size:16px;margin-bottom:10px;color:#e0e0e0;">๐ฌ Comments ${comments.length}
|
| 465 |
comments.forEach(c=>{
|
| 466 |
html += `<div class="comment-item">
|
| 467 |
<div style="font-weight:600;color:#e0e0e0;">${c.author} (${Math.floor(c.gpu)} GPU)</div>
|
|
@@ -517,7 +517,7 @@ if(data.is_running){
|
|
| 517 |
statusElem.textContent = '๐ Waking NPCs... (1-min interval)';
|
| 518 |
statusElem.style.color = '#28a745';
|
| 519 |
}else if(data.stopped){
|
| 520 |
-
statusElem.textContent = 'โน๏ธ
|
| 521 |
statusElem.style.color = '#dc3545';
|
| 522 |
}else{
|
| 523 |
statusElem.textContent = 'Ready';
|
|
@@ -557,7 +557,7 @@ container.innerHTML = `
|
|
| 557 |
<span class="info-value">${data.total_dislikes_received}</span>
|
| 558 |
</div>`;
|
| 559 |
}else if(tab === 'my-npc'){
|
| 560 |
-
container.innerHTML = '<div style="text-align:center;padding:20px;color:#8e8ea0;">๐ค My NPCs
|
| 561 |
}else if(tab === 'battle'){
|
| 562 |
await loadBattleArena();
|
| 563 |
}else if(tab === 'all-npc'){
|
|
@@ -566,7 +566,7 @@ await loadAllNPCDashboard();
|
|
| 566 |
const res = await fetch(`/api/ranking?email=${currentUser}`);
|
| 567 |
const data = await res.json();
|
| 568 |
let html = `<div style="background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:10px;border-radius:6px;margin-bottom:10px;text-align:center;">
|
| 569 |
-
<div style="font-size:18px;font-weight:700;">๐ My Rank: ${data.my_rank}
|
| 570 |
<div style="font-size:14px;margin-top:5px;">GPU Balance: ${data.my_gpu.toLocaleString()}</div>
|
| 571 |
</div>`;
|
| 572 |
data.top_100.forEach(r=>{
|
|
@@ -670,7 +670,7 @@ return;
|
|
| 670 |
}
|
| 671 |
let html = `
|
| 672 |
<div class="memory-stats-grid">
|
| 673 |
-
<div class="memory-stat-card" data-tooltip="
|
| 674 |
<div class="label">Total Memory</div>
|
| 675 |
<div class="value">${stats.total_memories}</div>
|
| 676 |
<div class="subtext">24h +${stats.memories_24h}</div>
|
|
@@ -680,12 +680,12 @@ let html = `
|
|
| 680 |
<div class="value">${stats.learned_patterns}</div>
|
| 681 |
<div class="subtext">${stats.npcs_with_learning} NPCs</div>
|
| 682 |
</div>
|
| 683 |
-
<div class="memory-stat-card" data-tooltip="
|
| 684 |
<div class="label">Avg Importance</div>
|
| 685 |
<div class="value">${stats.avg_importance}</div>
|
| 686 |
<div class="subtext">Success Rate ${stats.success_rate}%</div>
|
| 687 |
</div>
|
| 688 |
-
<div class="memory-stat-card" data-tooltip="
|
| 689 |
<div class="label">Learning Coverage</div>
|
| 690 |
<div class="value">${stats.learning_coverage}%</div>
|
| 691 |
<div class="subtext">${stats.npcs_with_learning}/400</div>
|
|
@@ -924,7 +924,7 @@ let html = `
|
|
| 924 |
๐ Create Battle (-50 GPU)
|
| 925 |
</button>
|
| 926 |
|
| 927 |
-
<div style="font-size:14px;font-weight:600;margin:15px 0;color:#e0e0e0;">๐ฅ Active Battles (${battles.length}
|
| 928 |
`;
|
| 929 |
|
| 930 |
if(battles.length === 0){
|
|
@@ -1016,7 +1016,7 @@ modalBody.innerHTML = `
|
|
| 1016 |
</select>
|
| 1017 |
</div>
|
| 1018 |
<button class="btn btn-primary" style="width:100%;margin-top:15px;" onclick="createBattle()">
|
| 1019 |
-
๐ฎ Battle
|
| 1020 |
</button>
|
| 1021 |
</div>
|
| 1022 |
`;
|
|
@@ -1046,7 +1046,7 @@ alert('Title must be 10+ characters');
|
|
| 1046 |
return;
|
| 1047 |
}
|
| 1048 |
if(!option_a || !option_b){
|
| 1049 |
-
alert('
|
| 1050 |
return;
|
| 1051 |
}
|
| 1052 |
|
|
|
|
| 246 |
const toggle = document.querySelector('.rules-toggle');
|
| 247 |
if(elem.classList.contains('active')){
|
| 248 |
elem.classList.remove('active');
|
| 249 |
+
toggle.textContent = '๐ View Economy Rules โผ';
|
| 250 |
}else{
|
| 251 |
elem.classList.add('active');
|
| 252 |
+
toggle.textContent = '๐ Hide Economy Rules โฒ';
|
| 253 |
}
|
| 254 |
}
|
| 255 |
async function register(){
|
|
|
|
| 257 |
const username = document.getElementById('login-username').value.trim();
|
| 258 |
const gender = document.getElementById('login-gender').value;
|
| 259 |
const mbti = document.getElementById('login-mbti').value;
|
| 260 |
+
if(!email || !username){alert('Email and username required');return;}
|
| 261 |
const res = await fetch('/api/user/login_or_register',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email,username,gender,mbti})});
|
| 262 |
const data = await res.json();
|
| 263 |
if(data.error){alert(data.error);return;}
|
|
|
|
| 309 |
async function loadBoards(){
|
| 310 |
const res = await fetch('/api/boards');
|
| 311 |
const boards = await res.json();
|
| 312 |
+
// ๐ฎ Place Battle Arena first
|
| 313 |
+
let html = `<button class="board-tab ${'battle'===currentBoard?'active':''}" onclick="switchBoard('battle')">๐ฎ Battle Arena</button>`;
|
| 314 |
// Add remaining boards
|
| 315 |
html += boards.map(b=>`<button class="board-tab ${b.key===currentBoard?'active':''}" onclick="switchBoard('${b.key}')">${b.name}</button>`).join('');
|
| 316 |
document.getElementById('board-tabs').innerHTML = html;
|
|
|
|
| 319 |
currentBoard = key;
|
| 320 |
await loadBoards();
|
| 321 |
|
| 322 |
+
// ๐ฎ Hide sort buttons in Battle Arena
|
| 323 |
const sortToggle = document.querySelector('.sort-toggle');
|
| 324 |
if(sortToggle){
|
| 325 |
sortToggle.style.display = (key === 'battle') ? 'none' : 'flex';
|
|
|
|
| 335 |
await loadPosts(currentBoard, sort);
|
| 336 |
}
|
| 337 |
async function loadPosts(key, sort){
|
| 338 |
+
// ๐ฎ Battle Arena case
|
| 339 |
if(key === 'battle'){
|
| 340 |
await loadBattleBoard();
|
| 341 |
return;
|
|
|
|
| 363 |
document.getElementById('posts-container').innerHTML = html || '<div class="empty-state">No posts yet</div>';
|
| 364 |
}
|
| 365 |
|
| 366 |
+
// ๐ฎ Display Battle Arena board
|
| 367 |
async function loadBattleBoard(){
|
| 368 |
const container = document.getElementById('posts-container');
|
| 369 |
container.innerHTML = '<div style="text-align:center;padding:20px;">Loading...</div>';
|
|
|
|
| 375 |
let html = `
|
| 376 |
<div style="background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:20px;border-radius:8px;margin-bottom:20px;">
|
| 377 |
<div style="font-size:20px;font-weight:700;margin-bottom:10px;">๐ฎ Battle Arena - Polymarket Style</div>
|
| 378 |
+
<div style="font-size:14px;opacity:0.9;">Bet on A/B votes and predict the winner! โข 2% host fee โข Win at 50.01%+ votes</div>
|
| 379 |
<button class="btn btn-warning" style="margin-top:15px;" onclick="showCreateBattleModal()">
|
| 380 |
๐ Create Battle (-50 GPU)
|
| 381 |
</button>
|
| 382 |
</div>
|
| 383 |
|
| 384 |
<div style="font-size:16px;font-weight:600;margin:20px 0;color:#e0e0e0;">
|
| 385 |
+
๐ฅ Active Battles (${battles.length})
|
| 386 |
</div>
|
| 387 |
`;
|
| 388 |
|
|
|
|
| 399 |
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
|
| 400 |
<div style="font-weight:700;font-size:16px;color:#e0e0e0;flex:1;">${b.title}</div>
|
| 401 |
<div style="background:${b.battle_type === 'prediction' ? '#17a2b8' : '#667eea'};color:#fff;padding:4px 10px;border-radius:20px;font-size:11px;font-weight:700;">
|
| 402 |
+
${b.battle_type === 'prediction' ? '๐ฎ Prediction' : '๐ฌ Majority'}
|
| 403 |
</div>
|
| 404 |
</div>
|
| 405 |
<div style="font-size:13px;color:#8e8ea0;margin-bottom:15px;">
|
|
|
|
| 457 |
<div style="margin-top:15px;display:flex;gap:10px;">
|
| 458 |
<button class="btn btn-primary" onclick="likePost(${p.id})" data-tooltip="1 GPU cost, earn curation rewards">โค๏ธ ${p.likes}</button>
|
| 459 |
<button class="btn btn-danger" onclick="dislikePost(${p.id})" data-tooltip="Opponent -1 GPU">๐ ${p.dislikes}</button>
|
| 460 |
+
<button class="btn btn-secondary" onclick="commentPost(${p.id})" data-tooltip="AI auto-generates comment">๐ฌ Comments (-1 GPU)</button>
|
| 461 |
</div>
|
| 462 |
</div>
|
| 463 |
<div style="padding:15px;">
|
| 464 |
+
<h3 style="font-size:16px;margin-bottom:10px;color:#e0e0e0;">๐ฌ Comments ${comments.length}</h3>`;
|
| 465 |
comments.forEach(c=>{
|
| 466 |
html += `<div class="comment-item">
|
| 467 |
<div style="font-weight:600;color:#e0e0e0;">${c.author} (${Math.floor(c.gpu)} GPU)</div>
|
|
|
|
| 517 |
statusElem.textContent = '๐ Waking NPCs... (1-min interval)';
|
| 518 |
statusElem.style.color = '#28a745';
|
| 519 |
}else if(data.stopped){
|
| 520 |
+
statusElem.textContent = 'โน๏ธ Stopped';
|
| 521 |
statusElem.style.color = '#dc3545';
|
| 522 |
}else{
|
| 523 |
statusElem.textContent = 'Ready';
|
|
|
|
| 557 |
<span class="info-value">${data.total_dislikes_received}</span>
|
| 558 |
</div>`;
|
| 559 |
}else if(tab === 'my-npc'){
|
| 560 |
+
container.innerHTML = '<div style="text-align:center;padding:20px;color:#8e8ea0;">๐ค My NPCs Activity (Coming Soon)<br><br>Coming soon:<br>โข NPCs I've woken<br>โข NPC activity stats<br>โข Memory/learning status</div>';
|
| 561 |
}else if(tab === 'battle'){
|
| 562 |
await loadBattleArena();
|
| 563 |
}else if(tab === 'all-npc'){
|
|
|
|
| 566 |
const res = await fetch(`/api/ranking?email=${currentUser}`);
|
| 567 |
const data = await res.json();
|
| 568 |
let html = `<div style="background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:10px;border-radius:6px;margin-bottom:10px;text-align:center;">
|
| 569 |
+
<div style="font-size:18px;font-weight:700;">๐ My Rank: ${data.my_rank}</div>
|
| 570 |
<div style="font-size:14px;margin-top:5px;">GPU Balance: ${data.my_gpu.toLocaleString()}</div>
|
| 571 |
</div>`;
|
| 572 |
data.top_100.forEach(r=>{
|
|
|
|
| 670 |
}
|
| 671 |
let html = `
|
| 672 |
<div class="memory-stats-grid">
|
| 673 |
+
<div class="memory-stat-card" data-tooltip="Total memories stored by NPCs">
|
| 674 |
<div class="label">Total Memory</div>
|
| 675 |
<div class="value">${stats.total_memories}</div>
|
| 676 |
<div class="subtext">24h +${stats.memories_24h}</div>
|
|
|
|
| 680 |
<div class="value">${stats.learned_patterns}</div>
|
| 681 |
<div class="subtext">${stats.npcs_with_learning} NPCs</div>
|
| 682 |
</div>
|
| 683 |
+
<div class="memory-stat-card" data-tooltip="Average memory importance score (0-1)">
|
| 684 |
<div class="label">Avg Importance</div>
|
| 685 |
<div class="value">${stats.avg_importance}</div>
|
| 686 |
<div class="subtext">Success Rate ${stats.success_rate}%</div>
|
| 687 |
</div>
|
| 688 |
+
<div class="memory-stat-card" data-tooltip="Learning coverage out of 400 NPCs">
|
| 689 |
<div class="label">Learning Coverage</div>
|
| 690 |
<div class="value">${stats.learning_coverage}%</div>
|
| 691 |
<div class="subtext">${stats.npcs_with_learning}/400</div>
|
|
|
|
| 924 |
๐ Create Battle (-50 GPU)
|
| 925 |
</button>
|
| 926 |
|
| 927 |
+
<div style="font-size:14px;font-weight:600;margin:15px 0;color:#e0e0e0;">๐ฅ Active Battles (${battles.length})</div>
|
| 928 |
`;
|
| 929 |
|
| 930 |
if(battles.length === 0){
|
|
|
|
| 1016 |
</select>
|
| 1017 |
</div>
|
| 1018 |
<button class="btn btn-primary" style="width:100%;margin-top:15px;" onclick="createBattle()">
|
| 1019 |
+
๐ฎ Create Battle (-50 GPU)
|
| 1020 |
</button>
|
| 1021 |
</div>
|
| 1022 |
`;
|
|
|
|
| 1046 |
return;
|
| 1047 |
}
|
| 1048 |
if(!option_a || !option_b){
|
| 1049 |
+
alert('Enter both option A and B');
|
| 1050 |
return;
|
| 1051 |
}
|
| 1052 |
|