feat: add changelog panel showing recent Nexus updates from git log
Some checks failed
CI / validate (pull_request) Failing after 19s
Some checks failed
CI / validate (pull_request) Failing after 19s
Adds a toggleable LOG panel (bottom-left) that fetches changelog.json and displays recent commits with date, author badge, and message. Includes CSS styling consistent with the dark space theme. Fixes #130
This commit is contained in:
59
app.js
59
app.js
@@ -187,6 +187,65 @@ function animate() {
|
||||
|
||||
animate();
|
||||
|
||||
// === CHANGELOG PANEL ===
|
||||
(function initChangelog() {
|
||||
const panel = document.getElementById('changelog-panel');
|
||||
const toggleBtn = document.getElementById('changelog-toggle');
|
||||
const closeBtn = document.getElementById('changelog-close');
|
||||
const list = document.getElementById('changelog-list');
|
||||
|
||||
/**
|
||||
* Renders changelog entries into the list element.
|
||||
* @param {Array<{hash: string, date: string, author: string, message: string}>} entries
|
||||
* @returns {void}
|
||||
*/
|
||||
function renderEntries(entries) {
|
||||
list.innerHTML = '';
|
||||
for (const entry of entries) {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'changelog-entry';
|
||||
|
||||
const authorClass = 'changelog-author author-' + entry.author;
|
||||
li.innerHTML =
|
||||
'<div class="changelog-meta">' +
|
||||
'<span class="changelog-date">' + entry.date + '</span>' +
|
||||
'<span class="' + authorClass + '">' + entry.author + '</span>' +
|
||||
'</div>' +
|
||||
'<div class="changelog-message">' + entry.message + '</div>';
|
||||
|
||||
list.appendChild(li);
|
||||
}
|
||||
}
|
||||
|
||||
fetch('changelog.json')
|
||||
.then((/** @type {Response} */ res) => res.json())
|
||||
.then((/** @type {Array<{hash: string, date: string, author: string, message: string}>} */ entries) => {
|
||||
renderEntries(entries);
|
||||
})
|
||||
.catch(() => {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'changelog-entry';
|
||||
li.innerHTML = '<div class="changelog-message" style="color:var(--color-text-muted)">No changelog available.</div>';
|
||||
list.appendChild(li);
|
||||
});
|
||||
|
||||
toggleBtn.addEventListener('click', () => {
|
||||
const isVisible = panel.classList.toggle('visible');
|
||||
toggleBtn.style.backgroundColor = isVisible
|
||||
? 'var(--color-primary)'
|
||||
: 'var(--color-secondary)';
|
||||
toggleBtn.style.color = isVisible
|
||||
? 'var(--color-bg)'
|
||||
: 'var(--color-text)';
|
||||
});
|
||||
|
||||
closeBtn.addEventListener('click', () => {
|
||||
panel.classList.remove('visible');
|
||||
toggleBtn.style.backgroundColor = 'var(--color-secondary)';
|
||||
toggleBtn.style.color = 'var(--color-text)';
|
||||
});
|
||||
}());
|
||||
|
||||
// === DEBUG MODE ===
|
||||
let debugMode = false;
|
||||
|
||||
|
||||
17
changelog.json
Normal file
17
changelog.json
Normal file
@@ -0,0 +1,17 @@
|
||||
[
|
||||
{"hash":"440e31e","date":"2026-03-24","author":"claude","message":"Add photo mode with camera controls and depth of field"},
|
||||
{"hash":"2ebd153","date":"2026-03-24","author":"claude","message":"Add test harness for scene validation"},
|
||||
{"hash":"4f853aa","date":"2026-03-24","author":"claude","message":"World map overview mode — press Tab for bird's-eye view"},
|
||||
{"hash":"316ce63","date":"2026-03-24","author":"claude","message":"Add JSDoc types to all function parameters"},
|
||||
{"hash":"7eca0fb","date":"2026-03-24","author":"groq","message":"Debug mode — visualize collision boxes and light sources"},
|
||||
{"hash":"3934a7b","date":"2026-03-24","author":"claude","message":"Constellation system — connect nearby stars with faint lines"},
|
||||
{"hash":"554a4a0","date":"2026-03-24","author":"groq","message":"WebSocket stub for future live multiplayer"},
|
||||
{"hash":"8767f2c","date":"2026-03-24","author":"groq","message":"Manifest.json for PWA install"},
|
||||
{"hash":"4c4b776","date":"2026-03-24","author":"groq","message":"Meta tags for SEO and social sharing"},
|
||||
{"hash":"b40b7d9","date":"2026-03-24","author":"groq","message":"Ambient sound toggle for the Nexus"},
|
||||
{"hash":"db354e8","date":"2026-03-24","author":"claude","message":"NIP-07 visitor identity in the workshop"},
|
||||
{"hash":"a377da0","date":"2026-03-24","author":"claude","message":"Agent idle behaviors in 3D world"},
|
||||
{"hash":"d0edfe8","date":"2026-03-24","author":"claude","message":"Portal system — entry points to other worlds"},
|
||||
{"hash":"e293fbf","date":"2026-03-24","author":"manus","message":"Sovereign Memory Vault — 3D Knowledge Store"},
|
||||
{"hash":"6587869","date":"2026-03-24","author":"manus","message":"Three.js scene foundation"}
|
||||
]
|
||||
12
index.html
12
index.html
@@ -33,9 +33,21 @@
|
||||
<button id="debug-toggle" class="chat-toggle-btn" aria-label="Toggle debug mode" style="background-color: var(--color-secondary); color: var(--color-bg); padding: 4px 8px; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
||||
🔍
|
||||
</button>
|
||||
<button id="changelog-toggle" class="chat-toggle-btn" aria-label="Toggle changelog" style="background-color: var(--color-secondary); color: var(--color-text); padding: 4px 8px; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
||||
LOG
|
||||
</button>
|
||||
<audio id="ambient-sound" src="ambient.mp3" loop></audio>
|
||||
</div>
|
||||
|
||||
<!-- Changelog Panel -->
|
||||
<div id="changelog-panel" aria-label="Recent Nexus updates">
|
||||
<div id="changelog-header">
|
||||
<span id="changelog-title">NEXUS CHANGELOG</span>
|
||||
<button id="changelog-close" aria-label="Close changelog">✕</button>
|
||||
</div>
|
||||
<ul id="changelog-list"></ul>
|
||||
</div>
|
||||
|
||||
<div id="overview-indicator">
|
||||
<span>MAP VIEW</span>
|
||||
<span class="overview-hint">[Tab] to exit</span>
|
||||
|
||||
117
style.css
117
style.css
@@ -106,3 +106,120 @@ canvas {
|
||||
0%, 100% { opacity: 0.7; }
|
||||
50% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* === CHANGELOG PANEL === */
|
||||
#changelog-panel {
|
||||
display: none;
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
left: 16px;
|
||||
width: 320px;
|
||||
max-height: 400px;
|
||||
background: rgba(0, 0, 8, 0.88);
|
||||
border: 1px solid var(--color-secondary);
|
||||
border-radius: 6px;
|
||||
z-index: 20;
|
||||
font-family: var(--font-body);
|
||||
font-size: 11px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 20px rgba(68, 136, 255, 0.15);
|
||||
}
|
||||
|
||||
#changelog-panel.visible {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#changelog-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid var(--color-secondary);
|
||||
background: rgba(51, 68, 136, 0.3);
|
||||
}
|
||||
|
||||
#changelog-title {
|
||||
color: var(--color-primary);
|
||||
letter-spacing: 0.15em;
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#changelog-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text-muted);
|
||||
cursor: pointer;
|
||||
font-family: var(--font-body);
|
||||
font-size: 12px;
|
||||
padding: 0 2px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#changelog-close:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
#changelog-list {
|
||||
list-style: none;
|
||||
overflow-y: auto;
|
||||
max-height: 340px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
#changelog-list::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
#changelog-list::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#changelog-list::-webkit-scrollbar-thumb {
|
||||
background: var(--color-secondary);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.changelog-entry {
|
||||
padding: 6px 12px;
|
||||
border-bottom: 1px solid rgba(51, 68, 136, 0.2);
|
||||
}
|
||||
|
||||
.changelog-entry:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.changelog-meta {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.changelog-date {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.changelog-author {
|
||||
font-size: 10px;
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
background: rgba(68, 136, 255, 0.15);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.changelog-author.author-groq {
|
||||
background: rgba(255, 136, 68, 0.15);
|
||||
color: #ff8844;
|
||||
}
|
||||
|
||||
.changelog-author.author-manus {
|
||||
background: rgba(136, 255, 68, 0.15);
|
||||
color: #88ff44;
|
||||
}
|
||||
|
||||
.changelog-message {
|
||||
color: var(--color-text);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user