|
|
|
|
@ -1431,7 +1431,9 @@ HTML = """<!doctype html>
|
|
|
|
|
body[data-motion="expressive"] .settings-panel, body[data-motion="expressive"] .model-panel, body[data-motion="expressive"] .archive-panel { animation-duration: .62s; }
|
|
|
|
|
.video, .settings-panel, .model-panel, .archive-panel { width: 100%; max-width: none; }
|
|
|
|
|
.config-canvas > .config-block.settings-group { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
|
|
|
|
|
.config-block .control-fields { display: grid; grid-column: 1 / -1; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 6px 8px; min-width: 0; }
|
|
|
|
|
.config-block > .wide, .config-block > .control-fields, .config-block > .packet-builder { grid-column: 1 / -1 !important; width: 100%; min-width: 0; }
|
|
|
|
|
.config-block > .wide > input, .config-block > .wide > select, .config-block > .wide > textarea { width: 100%; }
|
|
|
|
|
.config-block .control-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 6px 8px; }
|
|
|
|
|
.config-block .control-fields[hidden] { display: none !important; }
|
|
|
|
|
.config-block .control-fields > .wide, .config-block .control-fields > .drop-zone, .config-block .control-fields > .upload-progress { grid-column: 1 / -1; }
|
|
|
|
|
.config-block .control-fields > label, .config-block .control-fields > button, .config-block .control-fields > .file-picked { min-width: 0; width: 100%; }
|
|
|
|
|
@ -2025,6 +2027,19 @@ HTML = """<!doctype html>
|
|
|
|
|
}, 0);
|
|
|
|
|
configCanvas.style.minHeight = `${Math.max(window.innerWidth <= 760 ? 900 : 760, bottom + 28)}px`;
|
|
|
|
|
}
|
|
|
|
|
function fitConfigBlockContent(block) {
|
|
|
|
|
if (!block || configBlockState(block) || block._configManualHeight) return false;
|
|
|
|
|
const contentHeight = block.scrollHeight;
|
|
|
|
|
if (!contentHeight || block.offsetHeight <= contentHeight + 120) return false;
|
|
|
|
|
block.style.height = 'auto';
|
|
|
|
|
const entry = configLayout[block.dataset.section];
|
|
|
|
|
if (entry && Object.prototype.hasOwnProperty.call(entry, 'height')) {
|
|
|
|
|
delete entry.height;
|
|
|
|
|
delete entry.manualHeight;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
function captureConfigLayout(block) {
|
|
|
|
|
const key = block.dataset.section;
|
|
|
|
|
if (!key) return;
|
|
|
|
|
@ -2032,7 +2047,7 @@ HTML = """<!doctype html>
|
|
|
|
|
entry.left = Math.round(parseFloat(block.style.left) || block.offsetLeft || 0);
|
|
|
|
|
entry.top = Math.round(parseFloat(block.style.top) || block.offsetTop || 0);
|
|
|
|
|
entry.width = Math.round(block.offsetWidth);
|
|
|
|
|
if (block.style.height) entry.height = Math.round(block.offsetHeight);
|
|
|
|
|
if (block.style.height && block.style.height !== 'auto') entry.height = Math.round(block.offsetHeight);
|
|
|
|
|
else delete entry.height;
|
|
|
|
|
if (block.style.zIndex) entry.z = Number(block.style.zIndex);
|
|
|
|
|
configLayout[key] = entry;
|
|
|
|
|
@ -2113,6 +2128,9 @@ HTML = """<!doctype html>
|
|
|
|
|
if (Number.isFinite(Number(entry.height))) block.style.height = `${Math.max(110, Number(entry.height))}px`;
|
|
|
|
|
if (Number.isFinite(Number(entry.z))) { block.style.zIndex = String(Math.max(1, Number(entry.z))); configZIndex = Math.max(configZIndex, Number(entry.z)); }
|
|
|
|
|
});
|
|
|
|
|
let fitted = false;
|
|
|
|
|
configBlocks.forEach(block => { fitted = fitConfigBlockContent(block) || fitted; });
|
|
|
|
|
if (fitted) saveConfigLayout();
|
|
|
|
|
updateConfigCanvasHeight();
|
|
|
|
|
}
|
|
|
|
|
function setConfigBlockState(block, state) {
|
|
|
|
|
@ -2356,6 +2374,7 @@ HTML = """<!doctype html>
|
|
|
|
|
const startWidth = block.offsetWidth;
|
|
|
|
|
const startHeight = block.offsetHeight;
|
|
|
|
|
block.classList.add('is-resizing');
|
|
|
|
|
block._configManualHeight = true;
|
|
|
|
|
block.setPointerCapture?.(event.pointerId);
|
|
|
|
|
const move = moveEvent => {
|
|
|
|
|
const dx = moveEvent.clientX - startX;
|
|
|
|
|
@ -2785,6 +2804,12 @@ HTML = """<!doctype html>
|
|
|
|
|
setText('filePathLabel', dumpFile ? 'Путь к UDP-логу' : 'Путь к видео');
|
|
|
|
|
setText('dropZone', dumpFile ? 'перетащите UDP-лог сюда' : 'перетащите видео сюда');
|
|
|
|
|
setText('uploadRunVideo', dumpFile ? 'загрузить выбранный UDP-дамп' : 'загрузить выбранное видео');
|
|
|
|
|
if (configCanvas) window.requestAnimationFrame(() => {
|
|
|
|
|
let fitted = false;
|
|
|
|
|
configBlocks.forEach(block => { fitted = fitConfigBlockContent(block) || fitted; });
|
|
|
|
|
if (fitted) saveConfigLayout();
|
|
|
|
|
updateConfigCanvasHeight();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
function collectControl() {
|
|
|
|
|
return {
|
|
|
|
|
|