From 198ba573f9e41abe63b10c344b203aa7bd97f1fb Mon Sep 17 00:00:00 2001 From: Panfilov Konstantin Date: Fri, 23 Oct 2026 19:40:47 +0300 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=81?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BF=D0=B5=D1=80=D0=B2=D1=8B?= =?UTF-8?q?=D0=B9=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=20=D0=B8=20pending=20#1?= =?UTF-8?q?6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/browser-upload.php | 43 ++++++++++++++++++++++++++++++ components/form.php | 15 +++++++---- components/upload-picker-links.php | 2 +- messages/en/app.php | 4 +++ style.css | 36 ++++++++++++++++++++++++- style.min.c.css | 34 +++++++++++++++++++++++ style.min.css | 36 ++++++++++++++++++++++++- tests/check-index-copy.php | 25 +++++++++++++++++ 8 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 tests/check-index-copy.php diff --git a/components/browser-upload.php b/components/browser-upload.php index 26d9b92..d097b39 100644 --- a/components/browser-upload.php +++ b/components/browser-upload.php @@ -23,6 +23,19 @@ } output.textContent = '.'.repeat(dots); }, + setPending(form, pending) { + if (pending) form.dataset.uploadPending = 'true'; + else delete form.dataset.uploadPending; + const link = form.querySelector('[data-files-picker]'); + if (!link) return; + if (pending) { + link.setAttribute('aria-disabled', 'true'); + link.setAttribute('tabindex', '-1'); + } else { + link.removeAttribute('aria-disabled'); + link.removeAttribute('tabindex'); + } + }, bindPicker(form, mainInput, fullAccept, onFiles) { if (mobile) form.dataset.mobileUpload = '1'; const sync = () => { @@ -32,6 +45,36 @@ sync(); // Dropzone пересоздаёт input после каждого выбора: обновляем до native click. form.addEventListener('click', sync, true); + // svh не меняется при движении панелей браузера. На старых движках + // сохраняем минимальную высоту до смены ширины/ориентации. + const index = form.closest('.index-mobile-fit'); + if (index) { + const probe = document.createElement('span'); + probe.style.cssText = 'position:absolute;visibility:hidden;pointer-events:none;height:100vh;height:100svh;width:0'; + index.append(probe); + let lastWidth = 0, fallbackHeight = Infinity; + const fit = () => { + if (innerWidth !== lastWidth) fallbackHeight = Infinity; + lastWidth = innerWidth; + const height = probe.getBoundingClientRect().height; + fallbackHeight = Math.min(fallbackHeight, height); + const budget = window.CSS?.supports('height', '100svh') ? height : fallbackHeight; + index.style.setProperty('--index-small-height', budget + 'px'); + index.dataset.compactUpload = budget < 650 ? 'true' : 'false'; + const hero = index.querySelector('#image-compare'); + if (hero) hero.style.setProperty('--compare-width', hero.getBoundingClientRect().width + 'px'); + }; + fit(); + window.addEventListener('resize', fit); + if (window.ResizeObserver) new ResizeObserver(fit).observe(index); + } + if (mobile && form.dataset.photoLabel && !form.querySelector('[data-other-files][multiple]')) { + const label = form.querySelector('[data-upload-label]'); + if (label) { + label.textContent = form.dataset.photoLabel; + label.dataset.pickerLabel = form.dataset.photoLabel; + } + } if (!android) return; const link = form.querySelector('[data-files-picker]'); const other = form.querySelector('[data-other-files]'); diff --git a/components/form.php b/components/form.php index fe0fa71..080b1bb 100644 --- a/components/form.php +++ b/components/form.php @@ -14,13 +14,13 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a ?> -
+
-

+
:
@@ -35,7 +35,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a