From ceee0a48eb5274bc17d43f68c8b3fe7e240ffffd Mon Sep 17 00:00:00 2001 From: 4aiman Date: Thu, 10 Sep 2026 15:51:34 +0300 Subject: [PATCH] gap-fill: reload detail via reopenDetail (in-place), not a stacked screen 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. --- .../2026-09-10_brouter-ux-gapfill-planner.md | 30 ++++++++++++++----- frontend/js/main.js | 4 +-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/docs/session-logs/2026-09-10_brouter-ux-gapfill-planner.md b/docs/session-logs/2026-09-10_brouter-ux-gapfill-planner.md index ccc8775..3f234db 100644 --- a/docs/session-logs/2026-09-10_brouter-ux-gapfill-planner.md +++ b/docs/session-logs/2026-09-10_brouter-ux-gapfill-planner.md @@ -33,12 +33,28 @@ Доки: README (редактор, гэп-филл), PROJECT_MAP (db/gps методы, колонки). -## Проверка -- Синтаксис gps.js/db.js/main.js — OK (node --check). const в новых функциях — нет (правило проекта). -- ДЕСКТОП-ТЕСТ на Xvfb со скринами — СЛЕДУЮЩИЙ шаг (ещё не гонял на момент записи). -- На устройстве встроенным движком — после `./build.sh install -d`. +## Проверка (десктоп, 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 считает +дистанцию через (бывшие) гэпы, и сохранять исходные статы для точного отката. ## Дальше -- Прогнать на Xvfb: гэп-филл на треке с дропаутом (сессия 1782115144011) — предпросмотр только - пропусков, Сохранить, Убрать; планировщик — 3 точки, тап по отрезку переключает дорога/прямая. -- Затем сборка и проверка на теле офлайн. +- На теле встроенным движком офлайн: `./build.sh install -d`, докачать сегмент региона. + Проверить гэп-филл (предпросмотр/сохранить/убрать) и планировщик (тап по отрезку — тач). diff --git a/frontend/js/main.js b/frontend/js/main.js index 7002c14..abfb87f 100644 --- a/frontend/js/main.js +++ b/frontend/js/main.js @@ -4873,7 +4873,7 @@ async function showSessionDetail(sessionId) { await DB.revertGapFill(sessionId); await GPS.recalculateSession(sessionId, { noDelete: true }); showToast("Достройка убрана"); - clearGapPreview(); showSessionDetail(sessionId); + clearGapPreview(); reopenDetail(sessionId); } catch (e) { showToast("Откат: " + (e.message || e)); rb.disabled = false; rb.textContent = "Убрать достройку"; } }; return; @@ -4898,7 +4898,7 @@ async function showSessionDetail(sessionId) { await DB.saveGapFill(sessionId, gapCache.points); await GPS.recalculateSession(sessionId, { noDelete: true }); showToast("Пропуски достроены"); - clearGapPreview(); showSessionDetail(sessionId); + clearGapPreview(); reopenDetail(sessionId); } catch (e) { showToast("Сохранение: " + (e.message || e)); sv.disabled = false; sv.textContent = "Сохранить"; } }; } catch (e) { showToast("Пропуски: " + (e.message || e)); clearGapPreview(); }