Streamline calibration modal: inline controls, dynamic aspect ratio, offset fix
Some checks failed
Validate / validate (push) Failing after 8s
Some checks failed
Validate / validate (push) Failing after 8s
- Move total LEDs counter, direction toggle, and offset input into the screen area of the calibration preview - Remove description paragraph, standalone offset form, and total LEDs banner - Add mismatch warning (yellow + ⚠) when configured LEDs ≠ device count - Use actual display aspect ratio for calibration preview - Fix offset not updating tick labels (buildSegments now starts at offset) - Remove max-width constraint on preview, add padding for breathing room - Clean up unused i18n keys from both locale files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -980,10 +980,11 @@ function closeConfirmModal(result) {
|
||||
// Calibration functions
|
||||
async function showCalibration(deviceId) {
|
||||
try {
|
||||
// Fetch current device data
|
||||
const response = await fetch(`${API_BASE}/devices/${deviceId}`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
// Fetch device data and displays in parallel
|
||||
const [response, displaysResponse] = await Promise.all([
|
||||
fetch(`${API_BASE}/devices/${deviceId}`, { headers: getHeaders() }),
|
||||
fetch(`${API_BASE}/config/displays`, { headers: getHeaders() }),
|
||||
]);
|
||||
|
||||
if (response.status === 401) {
|
||||
handle401Error();
|
||||
@@ -998,9 +999,24 @@ async function showCalibration(deviceId) {
|
||||
const device = await response.json();
|
||||
const calibration = device.calibration;
|
||||
|
||||
// Set aspect ratio from device's display
|
||||
const preview = document.querySelector('.calibration-preview');
|
||||
if (displaysResponse.ok) {
|
||||
const displaysData = await displaysResponse.json();
|
||||
const displayIndex = device.settings?.display_index ?? 0;
|
||||
const display = (displaysData.displays || []).find(d => d.index === displayIndex);
|
||||
if (display && display.width && display.height) {
|
||||
preview.style.aspectRatio = `${display.width} / ${display.height}`;
|
||||
} else {
|
||||
preview.style.aspectRatio = '';
|
||||
}
|
||||
} else {
|
||||
preview.style.aspectRatio = '';
|
||||
}
|
||||
|
||||
// Store device ID and LED count
|
||||
document.getElementById('calibration-device-id').value = device.id;
|
||||
document.getElementById('cal-device-led-count').textContent = device.led_count;
|
||||
document.getElementById('cal-device-led-count-inline').textContent = device.led_count;
|
||||
|
||||
// Set layout
|
||||
document.getElementById('cal-start-position').value = calibration.start_position;
|
||||
@@ -1083,7 +1099,14 @@ function updateCalibrationPreview() {
|
||||
parseInt(document.getElementById('cal-right-leds').value || 0) +
|
||||
parseInt(document.getElementById('cal-bottom-leds').value || 0) +
|
||||
parseInt(document.getElementById('cal-left-leds').value || 0);
|
||||
document.getElementById('cal-total-leds').textContent = total;
|
||||
// Warning if total doesn't match device LED count
|
||||
const totalEl = document.querySelector('.preview-screen-total');
|
||||
const deviceCount = parseInt(document.getElementById('cal-device-led-count-inline').textContent || 0);
|
||||
const mismatch = total !== deviceCount;
|
||||
document.getElementById('cal-total-leds-inline').textContent = (mismatch ? '\u26A0 ' : '') + total;
|
||||
if (totalEl) {
|
||||
totalEl.classList.toggle('mismatch', mismatch);
|
||||
}
|
||||
|
||||
// Update corner dot highlights for start position
|
||||
const startPos = document.getElementById('cal-start-position').value;
|
||||
@@ -1174,11 +1197,9 @@ function renderCalibrationCanvas() {
|
||||
const segments = buildSegments(calibration);
|
||||
if (segments.length === 0) return;
|
||||
|
||||
// Edge bar geometry (matches CSS: corner zones 56px × 36px proportional)
|
||||
const cornerFracW = 56 / 500;
|
||||
const cornerFracH = 36 / 312.5;
|
||||
const cw = cornerFracW * cW;
|
||||
const ch = cornerFracH * cH;
|
||||
// Edge bar geometry (matches CSS: corner zones 56px × 36px fixed)
|
||||
const cw = 56;
|
||||
const ch = 36;
|
||||
|
||||
// Edge midlines (center of each edge bar) - in canvas coords
|
||||
const edgeGeometry = {
|
||||
@@ -1371,7 +1392,7 @@ async function clearTestMode(deviceId) {
|
||||
|
||||
async function saveCalibration() {
|
||||
const deviceId = document.getElementById('calibration-device-id').value;
|
||||
const deviceLedCount = parseInt(document.getElementById('cal-device-led-count').textContent);
|
||||
const deviceLedCount = parseInt(document.getElementById('cal-device-led-count-inline').textContent);
|
||||
const error = document.getElementById('calibration-error');
|
||||
|
||||
// Clear test mode before saving
|
||||
@@ -1476,7 +1497,7 @@ function buildSegments(calibration) {
|
||||
};
|
||||
|
||||
const segments = [];
|
||||
let ledStart = 0;
|
||||
let ledStart = calibration.offset || 0;
|
||||
|
||||
edgeOrder.forEach(edge => {
|
||||
const count = edgeCounts[edge];
|
||||
|
||||
Reference in New Issue
Block a user