feat: Add dynamic icon for clock delta based on offset value

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
Chris Frankland-Wright 2025-08-08 00:07:43 +01:00
parent e419cd506e
commit 7e7ca42220
4 changed files with 21 additions and 6 deletions

View file

@ -21,5 +21,10 @@ const iconMap = {
'AVERAGE': { src: 'assets/timeturner_jitter_orange.png', tooltip: 'Clock jitter is moderate.' },
'BAD': { src: 'assets/timeturner_jitter_red.png', tooltip: 'Clock jitter is high and may affect accuracy.' },
'default': { src: 'assets/timeturner_jitter_red.png', tooltip: 'Jitter status is unknown.' }
},
deltaStatus: {
'good': { src: 'assets/timeturner_delta_green.png', tooltip: 'Clock delta is low (<= 40ms).' },
'average': { src: 'assets/timeturner_delta_orange.png', tooltip: 'Clock delta is moderate (<= 100ms).' },
'bad': { src: 'assets/timeturner_delta_red.png', tooltip: 'Clock delta is high (> 100ms).' }
}
};

View file

@ -41,7 +41,7 @@
<!-- Delta & Jitter -->
<div class="card">
<h2>Clock Offset</h2>
<p>Delta: <span id="delta-ms">--</span> ms (<span id="delta-frames">--</span> frames)</p>
<p>Delta: <span id="delta-status">-- ms (-- frames)</span></p>
<p>Jitter: <span id="jitter-status">--</span></p>
</div>

View file

@ -16,8 +16,7 @@ document.addEventListener('DOMContentLoaded', () => {
systemDate: document.getElementById('system-date'),
ntpActive: document.getElementById('ntp-active'),
syncStatus: document.getElementById('sync-status'),
deltaMs: document.getElementById('delta-ms'),
deltaFrames: document.getElementById('delta-frames'),
deltaStatus: document.getElementById('delta-status'),
jitterStatus: document.getElementById('jitter-status'),
interfaces: document.getElementById('interfaces'),
logs: document.getElementById('logs'),
@ -99,8 +98,19 @@ document.addEventListener('DOMContentLoaded', () => {
statusElements.syncStatus.innerHTML = `<img src="${syncIconInfo.src}" class="status-icon" alt="" title="${syncIconInfo.tooltip}"><span>${syncStatus}</span>`;
statusElements.syncStatus.className = syncStatus.replace(/\s+/g, '-').toLowerCase();
statusElements.deltaMs.textContent = data.timecode_delta_ms;
statusElements.deltaFrames.textContent = data.timecode_delta_frames;
// Delta Status
const deltaMs = data.timecode_delta_ms;
let deltaCategory;
if (Math.abs(deltaMs) <= 40) { // ~1 frame at 25fps
deltaCategory = 'good';
} else if (Math.abs(deltaMs) <= 100) {
deltaCategory = 'average';
} else {
deltaCategory = 'bad';
}
const deltaIconInfo = iconMap.deltaStatus[deltaCategory];
const deltaText = `${data.timecode_delta_ms} ms (${data.timecode_delta_frames} frames)`;
statusElements.deltaStatus.innerHTML = `<img src="${deltaIconInfo.src}" class="status-icon" alt="" title="${deltaIconInfo.tooltip}"><span>${deltaText}</span>`;
const jitterStatus = data.jitter_status || 'UNKNOWN';
const jitterIconInfo = iconMap.jitterStatus[jitterStatus] || iconMap.jitterStatus.default;

View file

@ -99,7 +99,7 @@ button:hover {
color: #555;
}
#ltc-status, #ntp-active, #sync-status, #jitter-status {
#ltc-status, #ntp-active, #sync-status, #jitter-status, #delta-status {
display: inline-flex;
align-items: center;
gap: 0.5em;