From 9afd38e50e17255a4b6d8662ecf28d4d85a6f120 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Tue, 28 Apr 2026 18:52:20 +0300 Subject: [PATCH] fix(redesign): contain modal scroll chaining and smooth Telegram chat refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add overscroll-behavior: contain to all in-modal/popup scroll containers (Modal body, EntitySelect, MultiEntitySelect, IconPicker, IconGridSelect, SearchPalette, TimezoneSelector) so reaching the inner scroll boundary no longer scrolls the page underneath. - Telegram bot Discover Chats no longer collapses the existing chat list into a "Loading…" placeholder. Split chatsLoading (initial) from chatsRefreshing (Discover); rows are keyed by chat.id with flip+fade animations; the list dims with a sweeping shimmer bar while the Discover button shows a spinning icon and "Discovering chats…" label. Honors prefers-reduced-motion. --- .../src/lib/components/EntitySelect.svelte | 1 + .../src/lib/components/IconGridSelect.svelte | 1 + frontend/src/lib/components/IconPicker.svelte | 1 + frontend/src/lib/components/Modal.svelte | 1 + .../lib/components/MultiEntitySelect.svelte | 1 + .../src/lib/components/SearchPalette.svelte | 1 + .../lib/components/TimezoneSelector.svelte | 1 + frontend/src/lib/i18n/en.json | 1 + frontend/src/lib/i18n/ru.json | 1 + .../src/routes/bots/TelegramBotTab.svelte | 201 +++++++++++++----- 10 files changed, 154 insertions(+), 56 deletions(-) diff --git a/frontend/src/lib/components/EntitySelect.svelte b/frontend/src/lib/components/EntitySelect.svelte index 08f2272..9a3a0f3 100644 --- a/frontend/src/lib/components/EntitySelect.svelte +++ b/frontend/src/lib/components/EntitySelect.svelte @@ -304,6 +304,7 @@ /* List */ .ep-list { overflow-y: auto; + overscroll-behavior: contain; scrollbar-width: thin; padding: 0.35rem; position: relative; diff --git a/frontend/src/lib/components/IconGridSelect.svelte b/frontend/src/lib/components/IconGridSelect.svelte index e0417c4..ccba7d3 100644 --- a/frontend/src/lib/components/IconGridSelect.svelte +++ b/frontend/src/lib/components/IconGridSelect.svelte @@ -195,6 +195,7 @@ padding: 0.5rem; max-height: 320px; overflow-y: auto; + overscroll-behavior: contain; scrollbar-width: thin; } :global([data-theme="light"]) .icon-grid-popup { --igs-solid-bg: #fafafe; } diff --git a/frontend/src/lib/components/IconPicker.svelte b/frontend/src/lib/components/IconPicker.svelte index ad41efe..2e7fe27 100644 --- a/frontend/src/lib/components/IconPicker.svelte +++ b/frontend/src/lib/components/IconPicker.svelte @@ -188,6 +188,7 @@ max-height: 14rem; overflow-y: auto; overflow-x: hidden; + overscroll-behavior: contain; scrollbar-width: thin; position: relative; z-index: 1; diff --git a/frontend/src/lib/components/Modal.svelte b/frontend/src/lib/components/Modal.svelte index 9f7d510..5839d03 100644 --- a/frontend/src/lib/components/Modal.svelte +++ b/frontend/src/lib/components/Modal.svelte @@ -192,6 +192,7 @@ z-index: 1; padding: 0 1.5rem 1.5rem; overflow-y: auto; + overscroll-behavior: contain; } .modal-close { diff --git a/frontend/src/lib/components/MultiEntitySelect.svelte b/frontend/src/lib/components/MultiEntitySelect.svelte index 15225c3..02a9e01 100644 --- a/frontend/src/lib/components/MultiEntitySelect.svelte +++ b/frontend/src/lib/components/MultiEntitySelect.svelte @@ -307,6 +307,7 @@ .mes-list { overflow-y: auto; + overscroll-behavior: contain; scrollbar-width: thin; padding: 0.25rem 0; } diff --git a/frontend/src/lib/components/SearchPalette.svelte b/frontend/src/lib/components/SearchPalette.svelte index 36e0c4f..9769dca 100644 --- a/frontend/src/lib/components/SearchPalette.svelte +++ b/frontend/src/lib/components/SearchPalette.svelte @@ -342,6 +342,7 @@ .sp-results { max-height: 52vh; overflow-y: auto; + overscroll-behavior: contain; scrollbar-width: thin; padding: 0.35rem; position: relative; diff --git a/frontend/src/lib/components/TimezoneSelector.svelte b/frontend/src/lib/components/TimezoneSelector.svelte index 8d3e835..39ded2c 100644 --- a/frontend/src/lib/components/TimezoneSelector.svelte +++ b/frontend/src/lib/components/TimezoneSelector.svelte @@ -530,6 +530,7 @@ .tz-list { overflow-y: auto; + overscroll-behavior: contain; /* No top padding — the sticky group head is at top:0 of the scroll container, so any padding-top would let scrolling items leak into the gap above the sticky header. */ diff --git a/frontend/src/lib/i18n/en.json b/frontend/src/lib/i18n/en.json index c3de137..5c0bc64 100644 --- a/frontend/src/lib/i18n/en.json +++ b/frontend/src/lib/i18n/en.json @@ -475,6 +475,7 @@ "noCommandsForProvider": "This provider type does not support bot commands.", "syncCommands": "Sync Commands", "discoverChats": "Discover chats from Telegram", + "discoveringChats": "Discovering chats…", "clickToCopy": "Click to copy chat ID", "chatsDiscovered": "Chats discovered", "chatDeleted": "Chat removed", diff --git a/frontend/src/lib/i18n/ru.json b/frontend/src/lib/i18n/ru.json index 40b9b61..6fa2926 100644 --- a/frontend/src/lib/i18n/ru.json +++ b/frontend/src/lib/i18n/ru.json @@ -475,6 +475,7 @@ "noCommandsForProvider": "Этот тип провайдера не поддерживает команды бота.", "syncCommands": "Синхр. команды", "discoverChats": "Обнаружить чаты из Telegram", + "discoveringChats": "Поиск чатов…", "clickToCopy": "Нажмите, чтобы скопировать ID чата", "chatsDiscovered": "Чаты обнаружены", "chatDeleted": "Чат удалён", diff --git a/frontend/src/routes/bots/TelegramBotTab.svelte b/frontend/src/routes/bots/TelegramBotTab.svelte index 2d720cc..a7d0253 100644 --- a/frontend/src/routes/bots/TelegramBotTab.svelte +++ b/frontend/src/routes/bots/TelegramBotTab.svelte @@ -1,5 +1,6 @@