/** * Console page — live console output with command input and history. */ function ConsolePage(params, container) { var html = '
' + '
Loading…
' + '
' + '' + '
' + '
'; container.innerHTML = html; var outputEl = document.getElementById('console-output'); var inputEl = document.getElementById('console-input'); var commandHistory = []; var historyIndex = 0; var firstOutput = true; function addOutput(msg) { if (firstOutput) { outputEl.innerHTML = ''; outputEl.classList.remove('text-white-50'); firstOutput = false; } var div = document.createElement('div'); div.className = msg.Type; div.textContent = stripHtml(msg.Message); outputEl.appendChild(div); if (isScrolledToBottom(outputEl)) outputEl.scrollTop = outputEl.scrollHeight; } function onSubmit() { var cmd = inputEl.value.trim(); if (!cmd) return; addOutput({ Message: cmd, Type: 'Command' }); commandHistory.push(cmd); historyIndex = commandHistory.length; Rcon.command(cmd, 1); inputEl.value = ''; } function onKeyDown(e) { if (commandHistory.length === 0) return; if (e.keyCode === 38) { // Up historyIndex--; if (historyIndex < 0) historyIndex = commandHistory.length - 1; inputEl.value = commandHistory[historyIndex] || ''; e.preventDefault(); } else if (e.keyCode === 40) { // Down historyIndex++; if (historyIndex >= commandHistory.length) historyIndex = 0; inputEl.value = commandHistory[historyIndex] || ''; e.preventDefault(); } else { historyIndex = commandHistory.length; } } function onMessage(msg) { if (msg.Message && msg.Message.indexOf('[rcon] ') === 0) return; switch (msg.Type) { case 'Generic': case 'Log': case 'Error': case 'Warning': addOutput(msg); break; } } function fetchHistory() { Rcon.request('console.tail 128', function (response) { var messages = JSON.parse(response.Message); for (var i = 0; i < messages.length; i++) onMessage(messages[i]); outputEl.scrollTop = outputEl.scrollHeight; }); } document.getElementById('console-form').addEventListener('submit', function (e) { e.preventDefault(); onSubmit(); }); inputEl.addEventListener('keydown', onKeyDown); Rcon.on('message', onMessage); if (Rcon.isConnected()) fetchHistory(); else { var _c = function () { fetchHistory(); Rcon.off('connected', _c); }; Rcon.on('connected', _c); } return function cleanup() { Rcon.off('message', onMessage); }; }