17 KiB
17 KiB
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
Технические заметки
- Web Share API требует HTTPS — на HTTP молча падает, даже на Android Chrome
- Кастомные диалоги через DOM работают всегда, но Слава предпочёл простоту (только скачать)
- Mouse drag: важно вешать mousemove/mouseup на
document, а не наlist— иначе drag ломается при выходе курсора за пределы элемента
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:директиву в ответе ассистента
Технические заметки
- Web Share API требует HTTPS — на HTTP молча падает, даже на Android Chrome
- Кастомные диалоги через DOM работают всегда, но Слава предпочёл простоту (только скачать)
- 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)
- Иконка колеса — заменить на нормальную мотокросс иконку
- Флажок финиша — чёрно-белая шахматная раскраска (финишный флаг)
- Спиннер в основном листе маршрута пока строится (как в мини-баре)
- Тёмная карта при тёмной теме — в бэклог (нет
style-light.jsonна сервере, нужна отдельная задача) - Автозум на маршрут после построения — плавный
fitBounds - Мини-бар перекрывает кнопки справа — исправить позиционирование
Технические заметки
- 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 cpstyle-light.jsonотсутствует на сервере — тёмная тема карты требует отдельной задачи (MapLibre стиль)- Деплой: SFTP → docker restart → docker cp (порядок критичен — образ перезаписывает статику при рестарте)