diff --git a/ui_server.py b/ui_server.py index 580cb15..06f72bd 100644 --- a/ui_server.py +++ b/ui_server.py @@ -1431,7 +1431,9 @@ 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 = """ }, 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 = """ 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 = """ 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 = """ 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 = """ 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 {