From e66256cd2985c910b5e724ba3c4b464122368815 Mon Sep 17 00:00:00 2001 From: Stream Date: Wed, 6 May 2026 01:10:01 +0300 Subject: [PATCH] auto-sync: 2026-05-06 01:10:01 --- memory/2026-05-05.md | 87 ++++++++++++++++++++ tasks/enduro-trails/PROJECT.md | 1 + tasks/enduro-trails/prototype/static/app.css | 5 +- tasks/enduro-trails/prototype/static/app.js | 30 ++++++- 4 files changed, 117 insertions(+), 6 deletions(-) diff --git a/memory/2026-05-05.md b/memory/2026-05-05.md index 5cb98cc..89a3ae3 100644 --- a/memory/2026-05-05.md +++ b/memory/2026-05-05.md @@ -87,3 +87,90 @@ - Mouse drag: важно вешать mousemove/mouseup на `document`, а не на `list` — иначе drag ломается при выходе курсора за пределы элемента - OSRM бэкенд не возвращает `legs` — только общий `distance_m`. Сегменты считаем на фронте через snap к геометрии - `streaming.mode: "progress"` — лучший режим для Telegram: нет промежуточных сообщений, только финальный ответ +# 2026-05-05 — Дневник + +## Enduro Trails — работа над прототипом + +### Кнопка «Поделиться» → «Скачать GPX» +- Слава попросил убрать кастомный диалог «Поделиться» (Telegram/WhatsApp) +- Оставить только скачивание GPX через `downloadGPX()` +- Иконка заменена на download-стрелку (стрелка вниз + линия) в том же стиле что и другие кнопки header +- HTML уже обновлён: `onclick="downloadGPX()"`, иконка download +- Из app.js удалены функции: `shareRoute`, `closeShareDialog`, `shareTelegram`, `shareWhatsApp`, `shareNative` +- Из app.css удалены стили: `.share-dialog`, `.sd-*`, `#share-dialog` + +### Drag-and-drop для точек маршрута +- Слава попросил добавить иконку «перетаскивания» (grip) в каждый wl-item +- Дев-агент добавил grip SVG (6 кружков) и touch-drag логику +- Логика вынесена в `_initWaypointDragHandles(list)` с общими функциями `startDrag/moveDrag/endDrag` +- **Проблема:** на десктопе не работало — дев сделал только touch-события +- **Фикс:** добавлены mouse-события (mousedown/mousemove/mouseup) с `document`-level listeners для корректного завершения drag за пределами списка + +### Баг: «Добавить точку» не работала в баре маршрутов +- Причина: `addWaypointMode()` не устанавливала `routeMode = true` +- При закрытом/свайпнутом sheet `routeMode` мог быть `false` +- Клик на карте проверяет `if (!routeMode) return` — и игнорировал добавление +- Фикс: в `addWaypointMode()` добавить `routeMode = true` перед установкой `addingWaypoint = true` + +### Расстояние по маршруту между точками +- Слава попросил показывать расстояние по маршруту (не по прямой) для каждого сегмента +- Бэкенд не возвращает `legs` — только общий `distance_m` +- Решение: функция `getRouteSegmentDistances()` — snap waypoints к геометрии маршрута, суммировать haversine по точкам геометрии +- Проблема 1: сумма сегментов не совпадала с `route.distance_m` из-за неточного snap +- Решение: масштабировать сегменты пропорционально чтобы сумма = `route.distance_m` +- Проблема 2: при смене варианта маршрута расстояния не обновлялись +- Фикс: добавить `renderWaypointsList()` в `selectRoute()` и `selectMiniRoute()` + +### Дублированные сообщения в Telegram +- Слава заметил что от меня приходят дублированные сообщения +- Анализ: `streaming.mode: "partial"` шлёт промежуточные сообщения каждые 2 сек вместо edit +- Попробовали `progress` — тоже дублировало (маппится в partial на Telegram) +- Финальное решение: `streaming.mode: "off"` — только финальное сообщение, без превью +- Конфиг обновлён, hot-reload применился (лог: `config hot reload applied`) + +### Расстояние по маршруту — финальный фикс +- Корневая проблема: `renderWaypointsList()` вызывается ДО завершения `debounceBuildRoute()` (async) +- В момент рендера `routeResults` пустой → fallback на haversine по прямой (52 км вместо 104 км) +- Фикс: добавить `renderWaypointsList()` сразу после `drawRouteResults()` — когда маршрут уже построен +- Масштабирование сегментов оставлено: сумма сегментов = `route.distance_m` точно (diff=0 м) +- Форматирование приведено к `toFixed(1)` везде для визуального совпадения + +### voice-tts скилл — дублированные сообщения +- `send_voice.sh` пытался отправить через `openclaw message send` И через `MEDIA:` директиву одновременно +- Результат: в Telegram приходило сообщение с путём к файлу + голосовое +- Фикс: убрать блок `openclaw message send` из скрипта, оставить только генерацию OGG +- Доставка только через `MEDIA:` директиву в ответе ассистента + +### Фаза 5 — редизайн фронтенда (завершена) +- Убраны отладочные маркеры ✓/~ и console.log из app.js +- Задеплоена чистая версия: SFTP → docker restart → docker cp (правильный порядок) +- Документация обновлена: PROJECT.md, BRD_PHASE5.md + +### Поиск точек маршрута (новая фича) +- Слава попросил убрать верхний search bar и добавить поиск прямо в waypoints +- BRD создан: `tasks/enduro-trails/BRD_WAYPOINT_SEARCH.md` +- Dev реализовал: кнопка-лупа в каждом wl-item, inline Nominatim поиск, btn-theme перенесён в map-controls-r +- Задеплоено успешно + +### Онбординг маршрута + баги маркеров (Dev завершил) +- Баг: метки и линейка отображались в верхнем левом углу → фикс: `.maplibregl-marker { position: absolute !important }` +- Баг: подсказка «Тапни на карте» не видна → фикс: `#route-status { min-height: 20px }` +- Фича: онбординг при активации маршрута — поле «Откуда?» при 0 точках, «Куда?» при 1 точке +- Подсказка «или тапни на карте» видна в обоих состояниях + +### Новые замечания Славы (в работе у Dev) +1. Иконка колеса — заменить на нормальную мотокросс иконку +2. Флажок финиша — чёрно-белая шахматная раскраска (финишный флаг) +3. Спиннер в основном листе маршрута пока строится (как в мини-баре) +4. Тёмная карта при тёмной теме — **в бэклог** (нет `style-light.json` на сервере, нужна отдельная задача) +5. Автозум на маршрут после построения — плавный `fitBounds` +6. Мини-бар перекрывает кнопки справа — исправить позиционирование + +## Технические заметки +- Web Share API требует HTTPS — на HTTP молча падает, даже на Android Chrome +- Mouse drag: важно вешать mousemove/mouseup на `document`, а не на `list` +- OSRM бэкенд не возвращает `legs` — только общий `distance_m`. Сегменты считаем на фронте через snap к геометрии +- `streaming.mode: "off"` — только финальное сообщение в Telegram, без дублей +- `deploy_static.js` сломан (cp до рестарта) — использовать inline node скрипт: restart → sleep 8s → docker cp +- `style-light.json` отсутствует на сервере — тёмная тема карты требует отдельной задачи (MapLibre стиль) +- Деплой: SFTP → docker restart → docker cp (порядок критичен — образ перезаписывает статику при рестарте) diff --git a/tasks/enduro-trails/PROJECT.md b/tasks/enduro-trails/PROJECT.md index 66c4578..4495261 100644 --- a/tasks/enduro-trails/PROJECT.md +++ b/tasks/enduro-trails/PROJECT.md @@ -98,6 +98,7 @@ docker restart prototype-enduro-trails-1 | F-15 | "Народные треки" | OSM Traces, Wikiloc, Komoot, 4x4travel | ⏳ Бэклог | 8 | | F-16 | Тёмная тема + редизайн | Две темы (авто/светлая/тёмная), SunCalc, мобильный UI, drag-and-drop точек, расстояние по маршруту | ✅ Готово | 5 | | F-17 | PWA + офлайн | Service Worker, MBTiles, GPS-трекинг | ⏳ Бэклог | 7 | +| F-18 | Светлая карта | Создать `style-light.json` — светлый стиль карты для светлой темы. Сейчас при светлой теме карта остаётся тёмной (`style-light.json` отсутствует) | ⏳ Бэклог | 5.1 | --- diff --git a/tasks/enduro-trails/prototype/static/app.css b/tasks/enduro-trails/prototype/static/app.css index dcbc7bf..bceca60 100644 --- a/tasks/enduro-trails/prototype/static/app.css +++ b/tasks/enduro-trails/prototype/static/app.css @@ -126,7 +126,8 @@ html, body { #map-controls-r { position: fixed; right: 12px; bottom: calc(80px + env(safe-area-inset-bottom, 0px) + 12px); - display: flex; flex-direction: column; gap: 8px; z-index: 200; + display: flex; flex-direction: column; gap: 8px; z-index: 400; + transition: bottom 0.2s ease; } .map-btn { width: 48px; height: 48px; @@ -629,7 +630,7 @@ body.has-map-mode #sheet-backdrop.visible { pointer-events: none; } /* ── Mini Route Bar ───────────────────────── */ #sheet-route-mini { position: fixed; - bottom: 72px; left: 0; right: 56px; + bottom: 72px; left: 0; right: 0; height: 64px; background: var(--surface); border-top: 1px solid var(--border); diff --git a/tasks/enduro-trails/prototype/static/app.js b/tasks/enduro-trails/prototype/static/app.js index 95e0180..aabd64b 100644 --- a/tasks/enduro-trails/prototype/static/app.js +++ b/tasks/enduro-trails/prototype/static/app.js @@ -476,10 +476,26 @@ function createWaypointMarkerEl(index, total) { bg = '#0066ff'; label = String(index); } - el.innerHTML = ` - - ${label} - `; + if (label === 'F') { + const uid = Math.random().toString(36).slice(2); + el.innerHTML = ` + + + + + + + + + + F + `; + } else { + el.innerHTML = ` + + ${label} + `; + } return el; } @@ -2126,12 +2142,18 @@ function showMiniRouteSheet() { if (!routeResults || routeResults.length === 0) return; updateMiniRouteCard(); document.getElementById('sheet-route-mini').classList.add('visible'); + // Поднять кнопки карты над мини-баром (64px высота + 72px bottom + 8px отступ) + const ctrl = document.getElementById('map-controls-r'); + if (ctrl) ctrl.style.bottom = '148px'; initMiniRouteInteraction(); } function hideMiniRouteSheet() { const el = document.getElementById('sheet-route-mini'); if (el) el.classList.remove('visible'); + // Вернуть кнопки на место + const ctrl = document.getElementById('map-controls-r'); + if (ctrl) ctrl.style.bottom = ''; } function updateMiniRouteCard() {