Found in desktop testing: showSessionDetail() from the save/revert handlers pushed a second detail overlay whose map rendered blank. reopenDetail() collapses the stack and re-renders in place (the pattern recalc/refine already use). Session log updated with the desktop verification results.
6.4 KiB
Сессия 2026-09-10 — BRouter на телефоне: гэп-филл и планировщик
Контекст
Пользователь пожаловался на UX двух BRouter-фич на телефоне:
- Гэп-филл (🧩 на детали трека) рисовал ВЕСЬ трек целиком, было непонятно, что достроено, и не было сохранения/отмены.
- Планировщик маршрутов по точкам не находился: в меню пункт «Нарисовать маршрут» вёл на рисование ТРЕНИРОВКИ, а сам планировщик спрятан в «Сохранённые маршруты → Новый маршрут».
Работал по утверждённому плану: docs/plans/2026-09-10-brouter-ux-gapfill-planner.md.
Решения с пользователем: гэп-филл — обратимый патч на месте; планировщик — по-сегментный
роутинг (дорога по умолчанию, прямая где нет дороги, тап по отрезку переключает); пункт меню
переименовать.
Сделано
Часть A — гэп-филл:
GPS.fillGaps(gps.js) теперь возвращает{points, gaps}со статусами filled/skipped-long/skipped-noroute, интерполированными ts и флагомestimated.GapCtl(main.js, showSessionDetail): предпросмотр ТОЛЬКО достроенных пропусков (голубой с бело-чёрной оковкой; недостроенные — красный пунктир) + панель «Достроено N (+X км), M не удалось» с Сохранить/Отмена. Уже достроенный трек → кнопка «Убрать достройку».- БД (db.js): миграции
gps_points.estimated,gps_sessions.gap_filled;saveGapFill/revertGapFill(обратимо, seq = seq предыдущей реальной точки, оригинал цел); после сохранения/отката —GPS.recalculateSession(id,{noDelete:true}). - Отрисовка детали помечает достроенные участки голубым (видно после сохранения). CSS
.gap-panel.
Часть B — планировщик:
- Пункт меню «Нарисовать маршрут» → «Нарисовать тренировку» (он сохраняет сессию).
- Подсказка в пустом списке маршрутов зовёт планировать на телефоне («Новый маршрут»).
showRouteEditorпереписан на по-сегментную модель:legMode[]/legGeom[], дорога по умолчанию, тап по отрезку — дорога↔прямая, долгий тап — вставить точку, неудачный роутинг отрезка молча падает на прямую. Кнопка «🚲 По дорогам» задаёт режим сразу всем отрезкам.
Доки: README (редактор, гэп-филл), PROJECT_MAP (db/gps методы, колонки).
Проверка (десктоп, Xvfb :99 + домашний RouteServer)
- Синтаксис gps.js/db.js/main.js — OK (node --check). const в новых функциях — нет.
- Гэп-филл на сессии 1782115144011 (4 дропаута): 🧩 → предпросмотр ТОЛЬКО пропусков (голубой с оковкой) + панель «Достроено 4 (+1.75 км)» + Сохранить/Отмена. Сохранить → 88 estimated-точек в БД, gap_filled=1, петля замкнута по дорогам, деталь перерисовалась. «Убрать достройку» → estimated=0, gap_filled=0, исходный трек вернулся, карта отрисовалась.
- БАГ, найденный тестом:
showSessionDetail(id)в обработчиках ЗАТАЛКИВАЛ второй экран поверх → у него пустая карта. Исправлено наreopenDetail(id)(схлопывает стек, рендер на месте) — отдельным коммитом. Проверено: после save/revert карта рисуется. - Планировщик: 3 точки по региону → обе ноги легли ПО ДОРОГАМ (2.26 км). Глобальная кнопка «По дорогам» переключает все ноги на прямые (пунктир, 2.87 км) и обратно — рисование/пересчёт/ состояние кнопки ОК. По-сегментный тап по линии слепой мышью на headless не попал в 4px-линию (каждый промах добавлял точку — у Leaflet-вектора bubblingMouseEvents=false, т.е. попадание по линии точку бы не добавило); биндинг корректный, на тач-экране допуск больше — подтвердить на теле.
- Реальную стату десктоп-сессии, сдвинутую пересчётом при тесте, восстановил из старой копии БД.
Замечание к разбору (на будущее)
Дистанция сессии «плавает» при recalculateSession (сохранённая 16.24 → достройка 15.58 →
откат 18.25) — это поведение текущего computeStats (та же кнопка «Пересчитать» даёт то же),
но достройка ожидаемо должна УВЕЛИЧивать дистанцию. Стоит разобрать, как computeStats считает
дистанцию через (бывшие) гэпы, и сохранять исходные статы для точного отката.
Дальше
- На теле встроенным движком офлайн:
./build.sh install -d, докачать сегмент региона. Проверить гэп-филл (предпросмотр/сохранить/убрать) и планировщик (тап по отрезку — тач).