refactor(preview): unified message notification component
Replace ad-hoc #static-notice with reusable .message system: - .message — base notification bar, spans full width below navbar - .message-warn — amber/yellow warning (static mode notice) - .message-error — red error (missing rendered.js, dev disconnect) - showMessage(html, type) / clearMessages() helpers - Messages stack vertically in #messages container - Static notice auto-shown on page load; cleared on dev ws connect - Dev reconnect/disconnect events shown as error messages Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
dc07b54625
commit
fe77d52b5b
1 file changed
+29
-12
+29
-12
@@ -68,7 +68,11 @@ body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:v
|
|||||||
.loading-wrap{display:flex;align-items:center;justify-content:center;height:100%;color:var(--muted);font-size:13px;flex-direction:column;gap:8px}
|
.loading-wrap{display:flex;align-items:center;justify-content:center;height:100%;color:var(--muted);font-size:13px;flex-direction:column;gap:8px}
|
||||||
.spinner{width:20px;height:20px;border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .6s linear infinite}
|
.spinner{width:20px;height:20px;border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .6s linear infinite}
|
||||||
@keyframes spin{to{transform:rotate(360deg)}}
|
@keyframes spin{to{transform:rotate(360deg)}}
|
||||||
#static-notice{display:none;background:rgba(251,191,36,0.08);border-bottom:1px solid rgba(251,191,36,0.15);padding:6px 16px;font-size:11px;color:rgba(251,191,36,0.7);text-align:center;flex-shrink:0}
|
#messages{flex-shrink:0}
|
||||||
|
.message{display:block;padding:6px 16px;font-size:11px;text-align:center;border-bottom:1px solid transparent}
|
||||||
|
.message-warn{background:rgba(251,191,36,0.08);color:rgba(251,191,36,0.75);border-color:rgba(251,191,36,0.15)}
|
||||||
|
.message-error{background:rgba(248,113,113,0.08);color:rgba(248,113,113,0.75);border-color:rgba(248,113,113,0.15)}
|
||||||
|
.message code{background:rgba(0,0,0,0.12);padding:1px 6px;border-radius:3px}
|
||||||
|
|
||||||
#panel::-webkit-scrollbar{width:4px}
|
#panel::-webkit-scrollbar{width:4px}
|
||||||
#panel::-webkit-scrollbar-track{background:transparent}
|
#panel::-webkit-scrollbar-track{background:transparent}
|
||||||
@@ -101,7 +105,7 @@ body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:v
|
|||||||
<span class="hint">keys: d/m ←→</span>
|
<span class="hint">keys: d/m ←→</span>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div id="static-notice">Gmail / Outlook simulation is approximate. For more accurate rendering with CSS inlining, use <code style="background:rgba(251,191,36,0.1);padding:1px 6px;border-radius:3px;">cd tools && go run . dev</code></div>
|
<div id="messages"></div>
|
||||||
|
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="preview-area">
|
<div id="preview-area">
|
||||||
@@ -293,21 +297,34 @@ document.addEventListener('keydown',e=>{
|
|||||||
|
|
||||||
document.getElementById('loading').style.display='none';
|
document.getElementById('loading').style.display='none';
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('loading').innerHTML = '<p style="color:var(--red)">rendered.js not found</p><p style="color:var(--muted);margin-top:8px"> Run: cd tools && go run . preview all</p>';
|
showMessage('rendered.js not found — run <code>cd tools && go run . preview all</code> to generate', 'error');
|
||||||
}
|
}
|
||||||
render();
|
render();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// ── Message helpers ──
|
||||||
|
function showMessage(ht, type) {
|
||||||
|
const container = document.getElementById('messages');
|
||||||
|
const el = document.createElement('div');
|
||||||
|
el.className = 'message message-' + (type || 'warn');
|
||||||
|
el.innerHTML = ht;
|
||||||
|
container.appendChild(el);
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
function clearMessages() {
|
||||||
|
document.getElementById('messages').innerHTML = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Static-mode notice ──
|
||||||
|
showMessage('Gmail / Outlook simulation is approximate. For accurate rendering with CSS inlining, use <code>cd tools && go run . dev</code>', 'warn');
|
||||||
|
|
||||||
// ── Dev-server live-reload (WebSocket) ──
|
// ── Dev-server live-reload (WebSocket) ──
|
||||||
(function(){
|
(function(){
|
||||||
const notice = document.getElementById('static-notice');
|
|
||||||
let ws;
|
let ws;
|
||||||
try {
|
try {
|
||||||
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
ws = new WebSocket(proto + '//' + location.host + '/ws');
|
ws = new WebSocket(proto + '//' + location.host + '/ws');
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// static mode (file://) — WebSocket constructor throws
|
|
||||||
if (notice) notice.style.display = 'block';
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ws.onmessage = function(e) {
|
ws.onmessage = function(e) {
|
||||||
@@ -323,21 +340,21 @@ document.addEventListener('keydown',e=>{
|
|||||||
render();
|
render();
|
||||||
};
|
};
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
|
} else if (msg.type === 'error') {
|
||||||
|
showMessage(msg.message, 'error');
|
||||||
}
|
}
|
||||||
} catch(_) {}
|
} catch(_) {}
|
||||||
};
|
};
|
||||||
ws.onopen = function() {
|
ws.onopen = function() {
|
||||||
if (notice) notice.style.display = 'none';
|
clearMessages();
|
||||||
console.log('[dev] live-reload connected');
|
console.log('[dev] live-reload connected');
|
||||||
};
|
};
|
||||||
ws.onclose = function() {
|
ws.onclose = function() {
|
||||||
if (notice) notice.style.display = 'block';
|
showMessage('Dev server disconnected', 'error');
|
||||||
console.log('[dev] live-reload disconnected');
|
console.log('[dev] live-reload disconnected');
|
||||||
};
|
};
|
||||||
ws.onerror = function() {
|
ws.onerror = function() {
|
||||||
if (notice) notice.style.display = 'block';
|
showMessage('Dev server connection failed', 'error');
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in new issue
Block a user