feat: Add configurable tooltips to status icons

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
Chris Frankland-Wright 2025-08-08 00:04:52 +01:00
parent 0baf7588da
commit e419cd506e
2 changed files with 23 additions and 23 deletions

View file

@ -1,25 +1,25 @@
// In this file, you can define the paths to your local icon image files. // In this file, you can define the paths to your local icon image files.
const iconMap = { const iconMap = {
ltcStatus: { ltcStatus: {
'LOCK': 'assets/timeturner_ltc_green.png', 'LOCK': { src: 'assets/timeturner_ltc_green.png', tooltip: 'LTC signal is locked and stable.' },
'FREE': 'assets/timeturner_ltc_orange.png', 'FREE': { src: 'assets/timeturner_ltc_orange.png', tooltip: 'LTC signal is in freewheel mode.' },
'default': 'assets/timeturner_ltc_red.png' 'default': { src: 'assets/timeturner_ltc_red.png', tooltip: 'LTC signal is not detected.' }
}, },
ntpActive: { ntpActive: {
true: 'assets/timeturner_ntp_green.png', true: { src: 'assets/timeturner_ntp_green.png', tooltip: 'NTP service is active.' },
false: 'assets/timeturner_ntp_red.png' false: { src: 'assets/timeturner_ntp_red.png', tooltip: 'NTP service is inactive.' }
}, },
syncStatus: { syncStatus: {
'IN SYNC': 'assets/timeturner_sync_green.png', 'IN SYNC': { src: 'assets/timeturner_sync_green.png', tooltip: 'System clock is in sync with LTC source.' },
'CLOCK AHEAD': 'assets/timeturner_sync_orange.png', 'CLOCK AHEAD': { src: 'assets/timeturner_sync_orange.png', tooltip: 'System clock is ahead of the LTC source.' },
'CLOCK BEHIND': 'assets/timeturner_sync_orange.png', 'CLOCK BEHIND': { src: 'assets/timeturner_sync_orange.png', tooltip: 'System clock is behind the LTC source.' },
'TIMETURNING': 'assets/timeturner_timeturning.png', 'TIMETURNING': { src: 'assets/timeturner_timeturning.png', tooltip: 'Timeturner offset is active.' },
'default': 'assets/timeturner_sync_red.png' 'default': { src: 'assets/timeturner_sync_red.png', tooltip: 'Sync status is unknown.' }
}, },
jitterStatus: { jitterStatus: {
'GOOD': 'assets/timeturner_jitter_green.png', 'GOOD': { src: 'assets/timeturner_jitter_green.png', tooltip: 'Clock jitter is within acceptable limits.' },
'AVERAGE': 'assets/timeturner_jitter_orange.png', 'AVERAGE': { src: 'assets/timeturner_jitter_orange.png', tooltip: 'Clock jitter is moderate.' },
'BAD': 'assets/timeturner_jitter_red.png', 'BAD': { src: 'assets/timeturner_jitter_red.png', tooltip: 'Clock jitter is high and may affect accuracy.' },
'default': 'assets/timeturner_jitter_red.png' 'default': { src: 'assets/timeturner_jitter_red.png', tooltip: 'Jitter status is unknown.' }
} }
}; };

View file

@ -76,8 +76,8 @@ document.addEventListener('DOMContentLoaded', () => {
function updateStatus(data) { function updateStatus(data) {
const ltcStatus = data.ltc_status || 'UNKNOWN'; const ltcStatus = data.ltc_status || 'UNKNOWN';
const ltcIconSrc = iconMap.ltcStatus[ltcStatus] || iconMap.ltcStatus.default; const ltcIconInfo = iconMap.ltcStatus[ltcStatus] || iconMap.ltcStatus.default;
statusElements.ltcStatus.innerHTML = `<img src="${ltcIconSrc}" class="status-icon" alt=""><span>${ltcStatus}</span>`; statusElements.ltcStatus.innerHTML = `<img src="${ltcIconInfo.src}" class="status-icon" alt="" title="${ltcIconInfo.tooltip}"><span>${ltcStatus}</span>`;
statusElements.ltcStatus.className = ltcStatus.toLowerCase(); statusElements.ltcStatus.className = ltcStatus.toLowerCase();
statusElements.ltcTimecode.textContent = data.ltc_timecode; statusElements.ltcTimecode.textContent = data.ltc_timecode;
statusElements.frameRate.textContent = data.frame_rate; statusElements.frameRate.textContent = data.frame_rate;
@ -85,26 +85,26 @@ document.addEventListener('DOMContentLoaded', () => {
statusElements.systemClock.textContent = data.system_clock; statusElements.systemClock.textContent = data.system_clock;
statusElements.systemDate.textContent = data.system_date; statusElements.systemDate.textContent = data.system_date;
const ntpIconSrc = iconMap.ntpActive[data.ntp_active]; const ntpIconInfo = iconMap.ntpActive[!!data.ntp_active];
if (data.ntp_active) { if (data.ntp_active) {
statusElements.ntpActive.innerHTML = `<img src="${ntpIconSrc}" class="status-icon" alt=""><span>Active</span>`; statusElements.ntpActive.innerHTML = `<img src="${ntpIconInfo.src}" class="status-icon" alt="" title="${ntpIconInfo.tooltip}"><span>Active</span>`;
statusElements.ntpActive.className = 'active'; statusElements.ntpActive.className = 'active';
} else { } else {
statusElements.ntpActive.innerHTML = `<img src="${ntpIconSrc}" class="status-icon" alt=""><span>Inactive</span>`; statusElements.ntpActive.innerHTML = `<img src="${ntpIconInfo.src}" class="status-icon" alt="" title="${ntpIconInfo.tooltip}"><span>Inactive</span>`;
statusElements.ntpActive.className = 'inactive'; statusElements.ntpActive.className = 'inactive';
} }
const syncStatus = data.sync_status || 'UNKNOWN'; const syncStatus = data.sync_status || 'UNKNOWN';
const syncIconSrc = iconMap.syncStatus[syncStatus] || iconMap.syncStatus.default; const syncIconInfo = iconMap.syncStatus[syncStatus] || iconMap.syncStatus.default;
statusElements.syncStatus.innerHTML = `<img src="${syncIconSrc}" class="status-icon" alt=""><span>${syncStatus}</span>`; 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.syncStatus.className = syncStatus.replace(/\s+/g, '-').toLowerCase();
statusElements.deltaMs.textContent = data.timecode_delta_ms; statusElements.deltaMs.textContent = data.timecode_delta_ms;
statusElements.deltaFrames.textContent = data.timecode_delta_frames; statusElements.deltaFrames.textContent = data.timecode_delta_frames;
const jitterStatus = data.jitter_status || 'UNKNOWN'; const jitterStatus = data.jitter_status || 'UNKNOWN';
const jitterIconSrc = iconMap.jitterStatus[jitterStatus] || iconMap.jitterStatus.default; const jitterIconInfo = iconMap.jitterStatus[jitterStatus] || iconMap.jitterStatus.default;
statusElements.jitterStatus.innerHTML = `<img src="${jitterIconSrc}" class="status-icon" alt=""><span>${jitterStatus}</span>`; statusElements.jitterStatus.innerHTML = `<img src="${jitterIconInfo.src}" class="status-icon" alt="" title="${jitterIconInfo.tooltip}"><span>${jitterStatus}</span>`;
statusElements.jitterStatus.className = jitterStatus.toLowerCase(); statusElements.jitterStatus.className = jitterStatus.toLowerCase();
statusElements.interfaces.innerHTML = ''; statusElements.interfaces.innerHTML = '';