- docs/settings-cheatsheet.md — полный справочник всех CLI флагов - Обновлён docs/README.md — добавлена ссылка на cheat sheet Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
179 lines
6.2 KiB
HTML
179 lines
6.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Wyoming Satellite WebSocket</title>
|
|
<style>
|
|
* { box-sizing: border-box; }
|
|
body {
|
|
font-family: 'Courier New', monospace;
|
|
padding: 20px;
|
|
background: #1a1a2e;
|
|
color: #eee;
|
|
margin: 0;
|
|
}
|
|
h1 { color: #00d9ff; margin-bottom: 10px; }
|
|
#status {
|
|
padding: 8px 12px;
|
|
border-radius: 4px;
|
|
display: inline-block;
|
|
margin-bottom: 15px;
|
|
font-weight: bold;
|
|
}
|
|
#status.connected { background: #2d5a3d; color: #7fff7f; }
|
|
#status.disconnected { background: #5a2d2d; color: #ff7f7f; }
|
|
#status.connecting { background: #5a5a2d; color: #ffff7f; }
|
|
#log {
|
|
background: #0f0f1a;
|
|
border: 1px solid #333;
|
|
border-radius: 4px;
|
|
padding: 15px;
|
|
height: calc(100vh - 180px);
|
|
overflow-y: auto;
|
|
white-space: pre-wrap;
|
|
word-break: break-all;
|
|
}
|
|
.event {
|
|
border-left: 3px solid #00d9ff;
|
|
padding-left: 10px;
|
|
margin: 10px 0;
|
|
background: rgba(0, 217, 255, 0.05);
|
|
padding: 10px;
|
|
border-radius: 0 4px 4px 0;
|
|
}
|
|
.event-type { color: #00d9ff; font-weight: bold; }
|
|
.event-data { color: #aaa; }
|
|
.clear-btn {
|
|
background: #00d9ff;
|
|
color: #1a1a2e;
|
|
border: none;
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-weight: bold;
|
|
margin-left: 10px;
|
|
}
|
|
.clear-btn:hover { background: #00b8d9; }
|
|
.header { display: flex; align-items: center; justify-content: space-between; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<div>
|
|
<h1>🛰️ Wyoming Satellite WebSocket</h1>
|
|
<div id="status" class="connecting">Connecting...</div>
|
|
</div>
|
|
<div>
|
|
<button class="clear-btn" onclick="toggleSettings()">⚙️ Settings</button>
|
|
<button class="clear-btn" onclick="clearLog()">Clear Log</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="settings" style="display:none; background:#0f0f1a; padding:15px; border-radius:4px; margin-bottom:15px;">
|
|
<label for="wsUrl" style="color:#00d9ff; font-weight:bold;">WebSocket URL:</label>
|
|
<input type="text" id="wsUrl" value="ws://localhost:8675"
|
|
style="width:100%; padding:8px; margin:5px 0; background:#1a1a2e; color:#eee; border:1px solid #333; border-radius:4px;">
|
|
<button class="clear-btn" onclick="connect()">Connect</button>
|
|
<label style="margin-left:10px; color:#aaa;">
|
|
<input type="checkbox" id="autoReconnect" checked> Auto-reconnect
|
|
</label>
|
|
</div>
|
|
|
|
<div id="log"></div>
|
|
|
|
<script>
|
|
const log = document.getElementById('log');
|
|
const status = document.getElementById('status');
|
|
const settingsPanel = document.getElementById('settings');
|
|
const wsUrlInput = document.getElementById('wsUrl');
|
|
const autoReconnectCheckbox = document.getElementById('autoReconnect');
|
|
let eventCount = 0;
|
|
let ws = null;
|
|
let autoReconnect = true;
|
|
|
|
function toggleSettings() {
|
|
settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none';
|
|
}
|
|
|
|
function connect() {
|
|
const wsUrl = wsUrlInput.value.trim();
|
|
if (!wsUrl) {
|
|
addEvent('SYSTEM', { error: 'Please enter a WebSocket URL' });
|
|
return;
|
|
}
|
|
|
|
// Close existing connection
|
|
if (ws) {
|
|
ws.close();
|
|
}
|
|
|
|
ws = new WebSocket(wsUrl);
|
|
|
|
ws.onopen = () => {
|
|
status.textContent = 'Connected to ' + wsUrl;
|
|
status.className = 'connected';
|
|
addEvent('SYSTEM', { status: 'Connected to ' + wsUrl });
|
|
};
|
|
|
|
ws.onmessage = (event) => {
|
|
try {
|
|
const data = JSON.parse(event.data);
|
|
addEvent(data.type, data.data);
|
|
} catch (e) {
|
|
addEvent('RAW', { raw: event.data });
|
|
}
|
|
};
|
|
|
|
ws.onclose = () => {
|
|
status.textContent = 'Disconnected';
|
|
status.className = 'disconnected';
|
|
addEvent('SYSTEM', { status: 'Connection closed' });
|
|
|
|
// Auto-reconnect
|
|
if (autoReconnectCheckbox.checked) {
|
|
setTimeout(() => {
|
|
addEvent('SYSTEM', { status: 'Attempting to reconnect...' });
|
|
connect();
|
|
}, 3000);
|
|
}
|
|
};
|
|
|
|
ws.onerror = (err) => {
|
|
status.textContent = 'Error';
|
|
status.className = 'disconnected';
|
|
addEvent('SYSTEM', { error: 'WebSocket error', details: err.toString() });
|
|
};
|
|
}
|
|
|
|
// Auto-detect WebSocket URL from current page location on first load
|
|
window.addEventListener('load', () => {
|
|
const detectedUrl = `ws://${window.location.hostname}:8675`;
|
|
wsUrlInput.value = detectedUrl;
|
|
connect();
|
|
});
|
|
|
|
function addEvent(type, data) {
|
|
eventCount++;
|
|
const time = new Date().toLocaleTimeString();
|
|
const div = document.createElement('div');
|
|
div.className = 'event';
|
|
div.innerHTML = `<span class="event-type">[${time}] #${eventCount} ${escapeHtml(type)}</span>\n<span class="event-data">${escapeHtml(JSON.stringify(data, null, 2))}</span>`;
|
|
log.appendChild(div);
|
|
log.scrollTop = log.scrollHeight;
|
|
}
|
|
|
|
function escapeHtml(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
function clearLog() {
|
|
log.innerHTML = '';
|
|
eventCount = 0;
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|