Files
wiki/memory/2026-05-05.md
2026-05-06 01:10:01 +03:00

17 KiB
Raw Permalink Blame History

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)

  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 (порядок критичен — образ перезаписывает статику при рестарте)