Fix album scroll loading, lift 9-photo limit, badge import & mobile UX

Four user-reported fixes:

1. Albums infinite scroll: after a successful page load the
   IntersectionObserver wouldn't refire when the sentinel stayed in
   view (small thumbnails or large viewport), so subsequent pages
   needed a manual refresh. Re-check sentinel position after each
   load and add a scroll-event fallback for older mobile browsers.

2. 9-photo limit: add a "Больше 9 фото" toggle next to the photo
   source buttons. When checked, the cap lifts to 99 (covers Telegram
   auto-album splitting). VK still has its 9-attachment limit — if
   posting to VK with more selected, prompt a confirm and truncate
   the VK media payload to the first 9 client-side. Counters and
   notifications all read the dynamic max.

3. Badge tab: gallery selections now auto-import into the badge list
   on tab activation, so the photos appear right away with the first
   one opened in the editor. The "Выбранные в галерее Flickr" button
   reuses the same path for clarity.

4. Mobile UX: main navigation now scrolls horizontally on screens
   ≤720px instead of breaking into a tall stack — tabs stay on one
   row, scroll-snap on. In the badge editor the canvas wrapper is
   `position: sticky; top: 0` on screens ≤800px so the photo stays
   visible while scrolling through the controls below it; canvas
   also shrinks to ~62vw on phones.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
zuevav
2026-05-14 23:16:23 +03:00
parent 8434a6888f
commit 91be1b1751
3 changed files with 211 additions and 32 deletions
+54
View File
@@ -212,6 +212,30 @@ body {
flex-wrap: wrap;
}
/* On narrow screens, switch to horizontal scrolling so 5+ tabs stay
on one row instead of breaking into a tall stack. */
@media (max-width: 720px) {
.main-nav {
flex-wrap: nowrap;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x proximity;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
.main-nav::-webkit-scrollbar {
display: none;
}
.nav-btn {
flex: 0 0 auto;
min-width: auto;
white-space: nowrap;
scroll-snap-align: start;
padding: 10px 16px;
font-size: 0.9rem;
}
}
.nav-btn {
flex: 1;
min-width: 120px;
@@ -4127,6 +4151,36 @@ select {
@media (max-width: 800px) {
.badge-editor-layout {
grid-template-columns: 1fr;
gap: 12px;
}
/* Keep the canvas visible while the user scrolls down through the
controls — sticky to the top of the viewport. The thumbnail shrinks
to ~62vw so the controls below have room to breathe. */
.badge-canvas-wrapper {
position: sticky;
top: 0;
z-index: 20;
background: var(--bg-secondary);
padding: 8px 0 6px;
margin: 0 -8px;
border-bottom: 1px solid var(--border-color);
}
#badge-canvas {
max-width: min(62vw, 320px);
}
.badge-canvas-hint {
font-size: 0.78em;
}
.badge-controls {
padding-top: 4px;
}
/* Stack form rows tightly on phones. */
.badge-color-row {
gap: 6px;
}
.badge-color-swatch {
width: 32px;
height: 32px;
}
}