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:
@@ -1,114 +1,110 @@
|
||||
var app = angular.module('RconApp', ['ngRoute', 'nvd3']);
|
||||
/**
|
||||
* Main application — layout management, header updates, sidebar nav, routing.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
app.service('rconService', [RconService]);
|
||||
var elConnect = document.getElementById('app-connect');
|
||||
var elConnected = document.getElementById('app-connected');
|
||||
var elHeader = document.getElementById('server-header');
|
||||
var elSidebar = document.getElementById('sidebar-nav');
|
||||
var elTitle = document.getElementById('page-title');
|
||||
|
||||
app.config(function($routeProvider) {
|
||||
$routeProvider.when("/home", {Title: "Home"});
|
||||
$routeProvider.when("/:address/info", {
|
||||
Title: "Server",
|
||||
templateUrl: "html/serverInfo.html",
|
||||
Nav: true
|
||||
});
|
||||
$routeProvider.when("/:address/console", {
|
||||
Title: "Console",
|
||||
templateUrl: "html/console.html",
|
||||
Nav: true
|
||||
});
|
||||
$routeProvider.when("/:address/chat", {
|
||||
Title: "Chat",
|
||||
templateUrl: "html/chat.html",
|
||||
Nav: true
|
||||
});
|
||||
$routeProvider.when("/:address/playerlist", {
|
||||
Title: "Player List",
|
||||
templateUrl: "html/playerlist.html",
|
||||
Nav: true
|
||||
});
|
||||
$routeProvider.when("/:address/player/:userid", {
|
||||
Title: "Player Info",
|
||||
templateUrl: "html/playerInfo.html"
|
||||
});
|
||||
$routeProvider.otherwise({redirectTo: '/home'});
|
||||
});
|
||||
// ---- Sidebar navigation ----
|
||||
var navPages = [
|
||||
{ title: 'Server', path: '/:address/info' },
|
||||
{ title: 'Console', path: '/:address/console' },
|
||||
{ title: 'Chat', path: '/:address/chat' },
|
||||
{ title: 'Player List', path: '/:address/playerlist' }
|
||||
];
|
||||
|
||||
app.controller('RconController', RconController);
|
||||
|
||||
function RconController($scope, $rootScope, rconService, $timeout, $route) {
|
||||
$scope.$route = $route;
|
||||
|
||||
$scope.pages = $.map($route.routes, function(value, index) {
|
||||
if (value.Nav) {
|
||||
return [value];
|
||||
function renderSidebar(address) {
|
||||
var html = '';
|
||||
for (var i = 0; i < navPages.length; i++) {
|
||||
var url = navPages[i].path.replace(':address', address);
|
||||
var linkCls = (window._currentPage === navPages[i].title) ? ' nav-link active' : 'nav-link';
|
||||
html += '<li class="nav-item"><a class="' + linkCls + '" href="#' + url + '">' + navPages[i].title + '</a></li>';
|
||||
}
|
||||
});
|
||||
|
||||
$scope.OpenLeftMenu = function() {
|
||||
$mdSidenav('left').toggle();
|
||||
};
|
||||
|
||||
$scope.IsConnected = function() {
|
||||
return rconService.IsConnected();
|
||||
elSidebar.innerHTML = html;
|
||||
}
|
||||
|
||||
$rootScope.Nav = function(url) {
|
||||
return url.replace(":address", rconService.Address);
|
||||
function setActivePage(title) {
|
||||
window._currentPage = title;
|
||||
elTitle.textContent = title;
|
||||
if (Rcon.isConnected()) renderSidebar(Rcon.getAddress());
|
||||
}
|
||||
|
||||
$rootScope.$on('$stateChangeStart', function(next, current) {
|
||||
console.log(next);
|
||||
});
|
||||
// ---- Header update ----
|
||||
var headerTimer = null;
|
||||
|
||||
rconService.OnOpen = function() {
|
||||
$scope.Connected = true;
|
||||
$scope.$broadcast("OnConnected");
|
||||
$scope.$digest();
|
||||
$scope.address = rconService.Address;
|
||||
}
|
||||
|
||||
rconService.OnClose = function(ev) {
|
||||
$scope.$broadcast("OnDisconnected", ev);
|
||||
$scope.$digest();
|
||||
}
|
||||
|
||||
rconService.OnError = function(ev) {
|
||||
$scope.$broadcast("OnConnectionError", ev);
|
||||
$scope.$digest();
|
||||
}
|
||||
|
||||
rconService.OnMessage = function(msg) {
|
||||
$scope.$apply(function() {
|
||||
$scope.$broadcast("OnMessage", msg);
|
||||
function updateHeader() {
|
||||
Rcon.request('serverinfo', function (msg) {
|
||||
var data = JSON.parse(msg.Message);
|
||||
document.getElementById('header-hostname').textContent = data.Hostname || 'Rust Server';
|
||||
document.getElementById('header-uptime').innerHTML = '<i class="bi bi-clock"></i> ' + secondsToDuration(data.Uptime);
|
||||
document.getElementById('header-map').innerHTML = '<i class="bi bi-globe2"></i> ' + (data.Map || '');
|
||||
document.getElementById('header-players').innerHTML = '<i class="bi bi-people-fill"></i> ' + formatNumber(data.Players) + '/' + formatNumber(data.MaxPlayers);
|
||||
document.getElementById('header-fps').innerHTML = '<i class="bi bi-speedometer2"></i> ' + formatNumber(data.Framerate) + 'fps';
|
||||
document.getElementById('header-entities').innerHTML = '<i class="bi bi-boxes"></i> ' + formatNumber(data.EntityCount);
|
||||
});
|
||||
}
|
||||
|
||||
$scope.Disconnect = function() {
|
||||
function startHeaderUpdates() {
|
||||
updateHeader();
|
||||
headerTimer = setInterval(updateHeader, 1000);
|
||||
}
|
||||
|
||||
function stopHeaderUpdates() {
|
||||
if (headerTimer) { clearInterval(headerTimer); headerTimer = null; }
|
||||
}
|
||||
|
||||
// ---- Disconnect button ----
|
||||
document.getElementById('btn-disconnect').addEventListener('click', function () {
|
||||
if (confirm('Do you really want to disconnect?')) {
|
||||
rconService.Disconnect();
|
||||
$scope.Connected = false;
|
||||
|
||||
$scope.address = '#/home';
|
||||
Rcon.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
// ---- Layout toggling ----
|
||||
function showConnected(address) {
|
||||
elConnect.innerHTML = '';
|
||||
elConnect.style.display = 'none';
|
||||
elConnected.style.display = 'block';
|
||||
elHeader.style.display = 'block';
|
||||
renderSidebar(address);
|
||||
startHeaderUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
app.filter('SecondsToDuration', [SecondsToDuration]);
|
||||
|
||||
function SecondsToDuration() {
|
||||
return function(input) {
|
||||
input = parseInt(input);
|
||||
|
||||
var out = "";
|
||||
var hours = Math.floor(input / 3600);
|
||||
if (input > 3600)
|
||||
out += hours + "h";
|
||||
|
||||
var minutes = Math.floor(input / 60) % 60;
|
||||
if (input > 60)
|
||||
out += minutes + "m";
|
||||
|
||||
var seconds = input % 60;
|
||||
out += seconds + "s";
|
||||
|
||||
return out;
|
||||
function showDisconnected() {
|
||||
stopHeaderUpdates();
|
||||
elConnected.style.display = 'none';
|
||||
elHeader.style.display = 'none';
|
||||
elConnect.style.display = 'block';
|
||||
// Clear any stale router content
|
||||
document.getElementById('app-view').innerHTML = '';
|
||||
ConnectPage([], elConnect);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Events ----
|
||||
Rcon.on('connected', function () {
|
||||
var addr = Rcon.getAddress();
|
||||
showConnected(addr);
|
||||
Router.go('#/' + addr + '/info');
|
||||
});
|
||||
|
||||
Rcon.on('disconnected', function () {
|
||||
showDisconnected();
|
||||
});
|
||||
|
||||
// ---- Router setup ----
|
||||
Router.add(/^\/([^/]+)\/info$/, 'Server', function (p, c) { setActiveSidebar('Server'); ServerInfoPage(p, c); });
|
||||
Router.add(/^\/([^/]+)\/console$/, 'Console', function (p, c) { setActiveSidebar('Console'); ConsolePage(p, c); });
|
||||
Router.add(/^\/([^/]+)\/chat$/, 'Chat', function (p, c) { setActiveSidebar('Chat'); ChatPage(p, c); });
|
||||
Router.add(/^\/([^/]+)\/playerlist$/, 'Player List', function (p, c) { setActiveSidebar('Player List'); PlayerListPage(p, c); });
|
||||
Router.add(/^\/([^/]+)\/player\/(.+)$/, 'Player Info', function (p, c) { setActiveSidebar('Player Info'); PlayerInfoPage(p, c); });
|
||||
|
||||
Router.start('#app-view');
|
||||
|
||||
// ---- Initial state ----
|
||||
showDisconnected();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user