feat: Web Client — улучшенное подключение к WebSocket
Изменения: 1. Поле для ввода WebSocket адреса (вместо prompt) - wsUrlInput с значением по умолчанию - Сохраняется между перезагрузками 2. Кнопка CONNECT/DISCONNECT - Меняет текст и цвет при подключении - DISCONNECT красная кнопка - Работают обе кнопки (в шапке и в карточке) 3. Auto-connect - Чекбокс 'Auto-connect on load' - Автоматическое подключение при загрузке - Можно отключить 4. updateConnectButton() - Обновляет обе кнопки синхронно - 🔌 CONNECT / 🔌 DISCONNECT
This commit is contained in:
+89
-14
@@ -279,7 +279,7 @@
|
||||
|
||||
<div class="glass-panel">
|
||||
<!-- заголовок -->
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
|
||||
<div style="font-family: 'Orbitron'; font-weight: 700; font-size: 1.6rem; letter-spacing: 2px; background: linear-gradient(135deg, #aaffff, #3b8eff); -webkit-background-clip: text; background-clip: text; color: transparent;">
|
||||
⚡ Wyoming Droid Assistant ⚡
|
||||
</div>
|
||||
@@ -290,6 +290,25 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- WebSocket Connection Settings -->
|
||||
<div class="card" style="margin-bottom: 20px;">
|
||||
<div class="card-header">
|
||||
<span>🔌 WebSocket Connection</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
|
||||
<input type="text" id="wsUrlInput" value="ws://192.168.200.111:8675"
|
||||
style="flex: 1; min-width: 200px; padding: 8px 12px; background: rgba(0,0,0,0.3); border: 1px solid rgba(0,255,255,0.3); border-radius: 8px; color: #eee; font-size: 14px;"
|
||||
placeholder="ws://ip-address:8675">
|
||||
<button id="connectBtnCard" class="neo-btn" style="min-width: 120px;">
|
||||
🔌 CONNECT
|
||||
</button>
|
||||
<label class="checkbox-label" style="color: #aaa; cursor: pointer;">
|
||||
<input type="checkbox" id="autoConnect" checked style="margin-right: 5px;">
|
||||
Auto-connect on load
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard">
|
||||
<!-- ЛЕВАЯ КОЛОНКА: Аватар + Аудиовизуализация и Состояние -->
|
||||
<div class="card avatar-area">
|
||||
@@ -643,29 +662,49 @@
|
||||
|
||||
drawSatelliteVisualization();
|
||||
|
||||
// Подключение микрофона для визуализации (опционально) — УДАЛЕНО
|
||||
// Теперь используем RMS от satellite вместо локального микрофона
|
||||
// WebSocket подключение/отключение
|
||||
function toggleConnection() {
|
||||
const wsUrl = document.getElementById('wsUrlInput').value.trim();
|
||||
|
||||
if(!wsUrl) {
|
||||
addEventToLog('❌ Введите WebSocket URL');
|
||||
return;
|
||||
}
|
||||
|
||||
// Если уже подключены — отключаемся
|
||||
if(ws && ws.readyState === WebSocket.OPEN) {
|
||||
ws.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Подключаемся
|
||||
if(ws && ws.readyState === WebSocket.CONNECTING) {
|
||||
ws.close();
|
||||
return;
|
||||
}
|
||||
|
||||
ws = new WebSocket(wsUrl);
|
||||
|
||||
// WebSocket подключение
|
||||
function connectWebSocket() {
|
||||
const hostInput = prompt("Введите адрес LVA WebSocket (по умолчанию ws://192.168.200.111:8675):", "ws://192.168.200.111:8675");
|
||||
if(!hostInput) return;
|
||||
if(ws && ws.readyState === WebSocket.OPEN) ws.close();
|
||||
ws = new WebSocket(hostInput);
|
||||
ws.onopen = () => {
|
||||
isConnected = true;
|
||||
updateConnectButton();
|
||||
statusLed.classList.add('connected');
|
||||
statusLabel.innerText = 'connected';
|
||||
addEventToLog(`✅ Соединение установлено с ${hostInput}`);
|
||||
addEventToLog(`✅ Соединение установлено с ${wsUrl}`);
|
||||
stateText.innerText = 'ONLINE';
|
||||
orb.style.animation = 'pulse-glow 0.8s';
|
||||
setTimeout(()=> orb.style.animation='',700);
|
||||
// initMicVisualizer() — удалено, используем satellite RMS
|
||||
};
|
||||
|
||||
ws.onmessage = handleIncomingMessage;
|
||||
ws.onerror = (err) => { addEventToLog(`⚠️ WebSocket ошибка`); };
|
||||
|
||||
ws.onerror = (err) => {
|
||||
addEventToLog(`⚠️ WebSocket ошибка`);
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
isConnected = false;
|
||||
updateConnectButton();
|
||||
statusLed.classList.remove('connected');
|
||||
statusLabel.innerText = 'disconnected';
|
||||
addEventToLog(`🔌 Отключено`);
|
||||
@@ -674,8 +713,44 @@
|
||||
};
|
||||
}
|
||||
|
||||
// Кнопки управления
|
||||
document.getElementById('connectBtn').addEventListener('click', connectWebSocket);
|
||||
// Обновление кнопки подключения
|
||||
function updateConnectButton() {
|
||||
const btn = document.getElementById('connectBtn');
|
||||
const btnCard = document.getElementById('connectBtnCard');
|
||||
|
||||
if(ws && ws.readyState === WebSocket.OPEN) {
|
||||
if(btn) { btn.innerHTML = '🔌 DISCONNECT'; btn.classList.add('danger-btn'); }
|
||||
if(btnCard) { btnCard.innerHTML = '🔌 DISCONNECT'; btnCard.classList.add('danger-btn'); }
|
||||
} else {
|
||||
if(btn) { btn.innerHTML = '⟳ CONNECT'; btn.classList.remove('danger-btn'); }
|
||||
if(btnCard) { btnCard.innerHTML = '⟳ CONNECT'; btnCard.classList.remove('danger-btn'); }
|
||||
}
|
||||
}
|
||||
|
||||
// Кнопки подключения
|
||||
document.getElementById('connectBtn').addEventListener('click', toggleConnection);
|
||||
document.getElementById('connectBtnCard').addEventListener('click', toggleConnection);
|
||||
|
||||
// Auto-connect при загрузке
|
||||
window.addEventListener('load', () => {
|
||||
addEventToLog('🤖 Wyoming Droid Assistant • готов к подключению');
|
||||
|
||||
// Инициализация RMS элементов после загрузки DOM
|
||||
const rmsFillEl = document.getElementById('rmsFill');
|
||||
const rmsValueEl = document.getElementById('rmsValue');
|
||||
if (rmsFillEl && rmsValueEl) {
|
||||
console.log('RMS meter initialized');
|
||||
}
|
||||
|
||||
// Auto-connect если включена опция
|
||||
const autoConnect = document.getElementById('autoConnect');
|
||||
if(autoConnect && autoConnect.checked) {
|
||||
setTimeout(() => {
|
||||
addEventToLog('📡 Auto-connect...');
|
||||
toggleConnection();
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// Volume control
|
||||
document.getElementById('startListeningBtn').addEventListener('click', () => sendCommand('set_volume', { level: 1.0 }));
|
||||
|
||||
Reference in New Issue
Block a user