Update connection status indicator
This commit is contained in:
1 parent
2e603caeb6
commit
726a7fedc7
8 files changed
+254
-64
No files matched your search
@@ -285,23 +285,14 @@
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.status-dot::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -0.28rem;
|
||||
border-radius: inherit;
|
||||
opacity: 0;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
|
||||
.status-dot--online {
|
||||
background: #28a745;
|
||||
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.2);
|
||||
}
|
||||
|
||||
.status-dot--online::after {
|
||||
background: rgba(40, 167, 69, 0.32);
|
||||
animation: status-dot-pulse 1.8s ease-out infinite;
|
||||
.status-dot--idle {
|
||||
background: #0d6efd;
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.2);
|
||||
}
|
||||
|
||||
.status-dot--offline {
|
||||
@@ -314,28 +305,6 @@
|
||||
box-shadow: 0 0 0 0.2rem rgba(173, 181, 189, 0.18);
|
||||
}
|
||||
|
||||
.status-dot--unknown::after {
|
||||
background: rgba(173, 181, 189, 0.26);
|
||||
animation: status-dot-pulse 1.8s ease-out infinite;
|
||||
}
|
||||
|
||||
@keyframes status-dot-pulse {
|
||||
0% {
|
||||
opacity: 0.55;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
|
||||
70% {
|
||||
opacity: 0;
|
||||
transform: scale(1.75);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(1.75);
|
||||
}
|
||||
}
|
||||
|
||||
/* Account menu */
|
||||
|
||||
.user-menu-avatar {
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
(function () {
|
||||
function buildLivePlayerFeedLabel(connectedPlayersCount) {
|
||||
var count = Number(connectedPlayersCount || 0);
|
||||
if (count <= 0) {
|
||||
return 'Player feed online - no players connected';
|
||||
}
|
||||
var playerServiceName = 'Player';
|
||||
|
||||
return 'Live player feed - ' + count + ' player' + (count === 1 ? '' : 's') + ' connected';
|
||||
function buildConnectingLabel() {
|
||||
return playerServiceName === 'Bridge' ? 'Connecting to bridge' : 'Connecting to player service';
|
||||
}
|
||||
|
||||
function updateSidebarStatus(status, label) {
|
||||
function buildPlayerServiceLabel(connectedPlayersCount, serviceConnected) {
|
||||
if (!serviceConnected) {
|
||||
return 'No services connected';
|
||||
}
|
||||
|
||||
var count = Number(connectedPlayersCount || 0);
|
||||
if (count <= 0) {
|
||||
return playerServiceName + ' online - no players connected';
|
||||
}
|
||||
|
||||
return playerServiceName + ' online - ' + count + ' player' + (count === 1 ? '' : 's') + ' connected';
|
||||
}
|
||||
|
||||
function updateSidebarStatus(status, label, persist) {
|
||||
var dot = document.getElementById('sidebar-status-dot');
|
||||
var text = document.getElementById('sidebar-status-text');
|
||||
var pill = document.getElementById('sidebar-status-pill');
|
||||
@@ -16,18 +26,25 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var normalizedStatus = status === 'online' || status === 'offline' || status === 'unknown'
|
||||
var normalizedStatus = status === 'online' || status === 'idle' || status === 'offline' || status === 'unknown'
|
||||
? status
|
||||
: (status ? 'online' : 'offline');
|
||||
var statusLabel = normalizedStatus === 'online'
|
||||
? (label || 'Connected to player feed')
|
||||
: normalizedStatus === 'offline'
|
||||
? 'Disconnected from player feed'
|
||||
: (label || 'Connecting to player feed');
|
||||
var pillLabel = normalizedStatus === 'online' ? 'Connected' : normalizedStatus === 'offline' ? 'Disconnected' : 'Connecting';
|
||||
var statusLabel = label;
|
||||
if (!statusLabel) {
|
||||
if (normalizedStatus === 'online') {
|
||||
statusLabel = playerServiceName + ' online';
|
||||
} else if (normalizedStatus === 'idle') {
|
||||
statusLabel = playerServiceName + ' online - no players connected';
|
||||
} else if (normalizedStatus === 'offline') {
|
||||
statusLabel = 'No services connected';
|
||||
} else {
|
||||
statusLabel = buildConnectingLabel();
|
||||
}
|
||||
}
|
||||
var pillLabel = normalizedStatus === 'online' ? 'Connected' : normalizedStatus === 'idle' ? 'No players' : normalizedStatus === 'offline' ? 'Disconnected' : 'Connecting';
|
||||
|
||||
dot.classList.remove('status-dot--unknown', 'status-dot--online', 'status-dot--offline');
|
||||
dot.classList.add(normalizedStatus === 'online' ? 'status-dot--online' : normalizedStatus === 'offline' ? 'status-dot--offline' : 'status-dot--unknown');
|
||||
dot.classList.remove('status-dot--unknown', 'status-dot--online', 'status-dot--idle', 'status-dot--offline');
|
||||
dot.classList.add(normalizedStatus === 'online' ? 'status-dot--online' : normalizedStatus === 'idle' ? 'status-dot--idle' : normalizedStatus === 'offline' ? 'status-dot--offline' : 'status-dot--unknown');
|
||||
dot.setAttribute('aria-label', statusLabel);
|
||||
dot.setAttribute('title', statusLabel);
|
||||
|
||||
@@ -36,10 +53,41 @@
|
||||
}
|
||||
|
||||
if (pill) {
|
||||
pill.classList.remove('status-pill--unknown', 'status-pill--online', 'status-pill--offline');
|
||||
pill.classList.add(normalizedStatus === 'online' ? 'status-pill--online' : normalizedStatus === 'offline' ? 'status-pill--offline' : 'status-pill--unknown');
|
||||
pill.classList.remove('status-pill--unknown', 'status-pill--online', 'status-pill--idle', 'status-pill--offline');
|
||||
pill.classList.add(normalizedStatus === 'online' ? 'status-pill--online' : normalizedStatus === 'idle' ? 'status-pill--idle' : normalizedStatus === 'offline' ? 'status-pill--offline' : 'status-pill--unknown');
|
||||
pill.textContent = pillLabel;
|
||||
}
|
||||
|
||||
if (persist && window.sessionStorage) {
|
||||
try {
|
||||
window.sessionStorage.setItem('pulse-player-service-status-v2', JSON.stringify({ status: normalizedStatus, label: statusLabel, serviceName: playerServiceName }));
|
||||
} catch (_error) {
|
||||
// Storage may be unavailable in restricted browser contexts.
|
||||
}
|
||||
}
|
||||
if (persist) {
|
||||
hasCachedStatus = true;
|
||||
}
|
||||
}
|
||||
|
||||
var hasCachedStatus = false;
|
||||
if (window.sessionStorage) {
|
||||
try {
|
||||
var cachedStatus = JSON.parse(window.sessionStorage.getItem('pulse-player-service-status-v2') || 'null');
|
||||
if (cachedStatus && ['online', 'idle', 'offline', 'unknown'].indexOf(cachedStatus.status) !== -1 && typeof cachedStatus.label === 'string') {
|
||||
if (cachedStatus.serviceName === 'Player service') {
|
||||
cachedStatus.serviceName = 'Player';
|
||||
cachedStatus.label = cachedStatus.label.replace(/^Player service online(?= -|$)/, 'Player online');
|
||||
}
|
||||
if (cachedStatus.serviceName === 'Bridge' || cachedStatus.serviceName === 'Player') {
|
||||
playerServiceName = cachedStatus.serviceName;
|
||||
}
|
||||
updateSidebarStatus(cachedStatus.status, cachedStatus.status === 'offline' ? 'No services connected' : cachedStatus.label);
|
||||
hasCachedStatus = true;
|
||||
}
|
||||
} catch (_error) {
|
||||
// Ignore unavailable or malformed cached status.
|
||||
}
|
||||
}
|
||||
|
||||
function connectDashboardSocket() {
|
||||
@@ -68,7 +116,9 @@
|
||||
function connect() {
|
||||
var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
socket = new WebSocket(protocol + '//' + window.location.host + '/ws/dashboard');
|
||||
updateSidebarStatus('unknown', 'Connecting to player feed');
|
||||
if (!hasCachedStatus) {
|
||||
updateSidebarStatus('unknown', buildConnectingLabel());
|
||||
}
|
||||
|
||||
socket.onmessage = function (event) {
|
||||
try {
|
||||
@@ -77,11 +127,14 @@
|
||||
if (typeof window.webHandleDashboardState === 'function') {
|
||||
window.webHandleDashboardState(payload.state);
|
||||
}
|
||||
playerServiceName = payload.state && payload.state.playerServiceName === 'Bridge' ? 'Bridge' : 'Player';
|
||||
var screenCount = Array.isArray(payload.state && payload.state.screens) ? payload.state.screens.length : 0;
|
||||
if (!screenCount) {
|
||||
updateSidebarStatus('unknown', 'No screens configured');
|
||||
updateSidebarStatus('unknown', 'No screens configured', true);
|
||||
} else {
|
||||
updateSidebarStatus(Boolean(payload.state && payload.state.playerServiceConnected), buildLivePlayerFeedLabel(payload.state && payload.state.connectedPlayersCount));
|
||||
var playersConnected = Number(payload.state && payload.state.connectedPlayersCount || 0);
|
||||
var serviceConnected = Boolean(payload.state && payload.state.playerServiceConnected);
|
||||
updateSidebarStatus(serviceConnected ? (playersConnected > 0 ? 'online' : 'idle') : 'offline', buildPlayerServiceLabel(playersConnected, serviceConnected), true);
|
||||
}
|
||||
}
|
||||
} catch (_error) {
|
||||
@@ -104,7 +157,9 @@
|
||||
};
|
||||
|
||||
socket.onopen = function () {
|
||||
updateSidebarStatus('unknown', 'Connecting to player feed');
|
||||
if (!hasCachedStatus) {
|
||||
updateSidebarStatus('unknown', buildConnectingLabel());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user