Live KC test WS, sync clock fix, device card perf, camera icons, tab indicator
Key Colors test: - New WS endpoint for live KC target test streaming (replaces REST polling) - Auto-connect on lightbox open, auto-disconnect on close - Uses same FPS/preview_width as CSS source test (no separate controls) - Removed FPS selector, start/stop toggle, and updateAutoRefreshButton Device cards: - Fix full re-render on every poll caused by relative "Last seen" time in HTML - Last seen label now patched in-place via data attribute (like FPS metrics) - Remove overlay visualization button from LED target cards Sync clocks: - Fix card not updating start/stop icon: invalidate cache before reload Other: - Tab indicator respects bg-anim toggle (hidden when dynamic background off) - Camera backend icon grid uses SVG icons instead of emoji - Frontend context rule: no emoji in IconSelect items Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ import { API_BASE, getHeaders, fetchWithAuth, escapeHtml, isOpenrgbDevice } from
|
||||
import { t } from '../core/i18n.js';
|
||||
import { showToast, showConfirm, formatUptime, formatCompact, setTabRefreshing, desktopFocus } from '../core/ui.js';
|
||||
import { Modal } from '../core/modal.js';
|
||||
import { createDeviceCard, attachDeviceListeners, fetchDeviceBrightness, enrichOpenrgbZoneBadges, _computeMaxFps, getZoneCountCache } from './devices.js';
|
||||
import { createDeviceCard, attachDeviceListeners, fetchDeviceBrightness, enrichOpenrgbZoneBadges, _computeMaxFps, getZoneCountCache, formatRelativeTime } from './devices.js';
|
||||
import { _splitOpenrgbZone } from './device-discovery.js';
|
||||
import { createKCTargetCard, patchKCTargetMetrics, connectKCWebSocket, disconnectKCWebSocket } from './kc-targets.js';
|
||||
import {
|
||||
@@ -727,6 +727,17 @@ export async function loadTargetsTab() {
|
||||
}
|
||||
});
|
||||
|
||||
// Patch "Last seen" labels in-place (avoids full card re-render on relative time changes)
|
||||
for (const device of devicesWithState) {
|
||||
const el = container.querySelector(`[data-last-seen="${device.id}"]`);
|
||||
if (el) {
|
||||
const ts = device.state?.device_last_checked;
|
||||
const label = ts ? formatRelativeTime(ts) : null;
|
||||
el.textContent = label ? `\u23F1 ${t('device.last_seen.label')}: ${label}` : '';
|
||||
if (ts) el.title = ts;
|
||||
}
|
||||
}
|
||||
|
||||
// Manage KC WebSockets: connect for processing, disconnect for stopped
|
||||
const processingKCIds = new Set();
|
||||
kcTargets.forEach(target => {
|
||||
@@ -1021,15 +1032,7 @@ export function createTargetCard(target, deviceMap, colorStripSourceMap, valueSo
|
||||
<button class="btn btn-icon btn-secondary" onclick="showTargetEditor('${target.id}')" title="${t('common.edit')}">
|
||||
${ICON_EDIT}
|
||||
</button>
|
||||
${overlayAvailable ? (state.overlay_active ? `
|
||||
<button class="btn btn-icon btn-warning" onclick="stopTargetOverlay('${target.id}')" title="${t('overlay.button.hide')}">
|
||||
${ICON_OVERLAY}
|
||||
</button>
|
||||
` : `
|
||||
<button class="btn btn-icon btn-secondary" onclick="startTargetOverlay('${target.id}')" title="${t('overlay.button.show')}">
|
||||
${ICON_OVERLAY}
|
||||
</button>
|
||||
`) : ''}`,
|
||||
`,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user