feat: full de-Angularization with Bootstrap 5 migration
- Removed AngularJS 1.4.8 completely — no more framework dependency - Extracted core RCON logic into pure vanilla JS (js/rcon.js) - Added lightweight hash-based SPA router (js/router.js) - Rewrote all 6 pages as vanilla JS modules in js/pages/ - Migrated Bootstrap 3 → Bootstrap 5 (cards instead of panels, bootstrap-icons instead of glyphicons) - Removed jQuery dependency (Bootstrap 5 is vanilla JS) - Purged all Angular templates from html/ - Removed npm artifacts (package.json, node_modules) - Added nginx.example.conf for static hosting - Updated rcon.css dark theme for BS5 variables - Static file only — no Node.js backend required Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Chat page — live chat viewer with message sending.
|
||||
*/
|
||||
function ChatPage(params, container) {
|
||||
var address = Rcon.getAddress() || '';
|
||||
|
||||
var html =
|
||||
'<div id="ChatController">' +
|
||||
'<div id="chat-output" style="height:600px" class="Output scrollable"></div>' +
|
||||
'<form id="chat-form">' +
|
||||
'<input id="chat-input" class="form-control" style="width:100%" placeholder="Type a message...">' +
|
||||
'</form>' +
|
||||
'</div>';
|
||||
container.innerHTML = html;
|
||||
|
||||
var outputEl = document.getElementById('chat-output');
|
||||
var inputEl = document.getElementById('chat-input');
|
||||
|
||||
function addMessage(msg) {
|
||||
var div = document.createElement('div');
|
||||
var t = new Date((msg.Time || 0) * 1000);
|
||||
var timeStr = t.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
|
||||
var ts = document.createElement('span');
|
||||
ts.style.cssText = 'min-width:60px;display:inline-block;';
|
||||
ts.textContent = timeStr;
|
||||
div.appendChild(ts);
|
||||
|
||||
var ns = document.createElement('span');
|
||||
ns.style.cssText = 'min-width:130px;display:inline-block;text-align:right;';
|
||||
var a = document.createElement('a');
|
||||
a.href = '#/' + address + '/player/' + (msg.UserId || '');
|
||||
a.textContent = stripHtml(msg.Username || '') + ' :';
|
||||
ns.appendChild(a);
|
||||
div.appendChild(ns);
|
||||
|
||||
var ms = document.createElement('span');
|
||||
ms.style.display = 'inline-block';
|
||||
ms.textContent = stripHtml(msg.Message || '');
|
||||
div.appendChild(ms);
|
||||
|
||||
outputEl.appendChild(div);
|
||||
if (isScrolledToBottom(outputEl)) outputEl.scrollTop = outputEl.scrollHeight;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
var cmd = inputEl.value.trim();
|
||||
if (!cmd) return;
|
||||
Rcon.command('say ' + cmd, 1);
|
||||
inputEl.value = '';
|
||||
}
|
||||
|
||||
function onMessage(msg) {
|
||||
if (msg.Type !== 'Chat') return;
|
||||
addMessage(JSON.parse(msg.Message));
|
||||
}
|
||||
|
||||
function fetchHistory() {
|
||||
Rcon.request('chat.tail 512', function (response) {
|
||||
var messages = JSON.parse(response.Message);
|
||||
for (var i = 0; i < messages.length; i++) addMessage(messages[i]);
|
||||
outputEl.scrollTop = outputEl.scrollHeight;
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('chat-form').addEventListener('submit', function (e) { e.preventDefault(); onSubmit(); });
|
||||
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); };
|
||||
}
|
||||
Reference in New Issue
Block a user