Files
Kao/index.html
Spencer Grimes 11896919e4 Initial commit: Sentry-Emote system monitor
- Aggregator: Flask-based event broker with priority queue
- Frontend: OLED-optimized UI with animations
- Detectors: disk, cpu, memory, service, network
- Unified entry point (sentry.py) with process management
- Heartbeat TTL system for auto-clearing stale events

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:04:02 -06:00

123 lines
3.3 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Sentry-Emote</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #000000;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-family: monospace;
overflow: hidden;
}
#emote {
font-size: 18vw;
font-weight: bold;
text-align: center;
transition: color 0.3s ease;
}
#message {
font-size: 4vw;
margin-top: 2vh;
opacity: 0.7;
text-align: center;
}
/* Breathing animation - slow pulse */
.breathing {
animation: breathe 3s ease-in-out infinite;
}
@keyframes breathe {
0%, 100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.7;
transform: scale(0.98);
}
}
/* Shaking animation - rapid jitter for Critical */
.shaking {
animation: shake 0.15s linear infinite;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-5px); }
75% { transform: translateX(5px); }
}
/* Popping animation - scale up for Notifications */
.popping {
animation: pop 1s ease-in-out infinite;
}
@keyframes pop {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.08);
}
}
</style>
</head>
<body>
<div id="emote" class="breathing">( ^_^)</div>
<div id="message">Loading...</div>
<script>
const emoteEl = document.getElementById('emote');
const messageEl = document.getElementById('message');
const POLL_INTERVAL = 2000;
async function fetchStatus() {
try {
const response = await fetch('/status');
if (!response.ok) throw new Error('Failed to fetch');
const data = await response.json();
updateDisplay(data);
} catch (err) {
messageEl.textContent = 'Connection lost...';
}
}
function updateDisplay(data) {
emoteEl.textContent = data.active_emote;
emoteEl.style.color = data.color;
messageEl.style.color = data.color;
// Show event message if available, otherwise show state
const topEvent = data.active_events && data.active_events[0];
messageEl.textContent = (topEvent && topEvent.message) || data.message;
// Update animation class
emoteEl.className = '';
if (data.animation) {
emoteEl.classList.add(data.animation);
}
}
// Initial fetch and start polling
fetchStatus();
setInterval(fetchStatus, POLL_INTERVAL);
</script>
</body>
</html>