baldav/README.md
4aiman bf3c0e2534 Track detail de-jitter: fix overlay stacking, native dialogs, slow save
Fixes to the smoothing/routes UI reported on device:
- Blank detail after save/revert: showSessionDetail was called from inside the
  open detail modal, stacking a second overlay; querySelector("#sd-map") then
  hit the stale, already-initialized Leaflet map and threw, aborting the rest
  of the render (map + speed chart). New reopenDetail() closes the current
  detail (and its fullscreen-map child) and reopens fresh, like recalc/refine.
- Native confirm()/prompt() replaced with in-app appConfirm/appPrompt dialogs
  (winStack + history integrated, hardware back cancels). Used for smoothed
  save, route delete, route rename.
- Slow smoothed save: one UPDATE per point (4000+ IPC round-trips) replaced
  with a chunked CASE update — 18 statements for 4366 points, params kept
  under SQLite's 999 limit. Verified value-for-value on a copy DB.
- Closing the fullscreen map now also closes the smoothing panel (it is a
  fixed element that otherwise lingered over the collapsed map).
- "≈" button active state now reflects panel-open only, not session.smoothed
  (it looked permanently pressed after a save).

Docs: README + PROJECT_MAP updated for saved routes, de-jitter, accuracy_m,
routes table and new gps_points/gps_sessions columns. Version 0.1.393.
2026-07-31 23:51:20 +03:00

11 KiB
Raw Blame History

BalDav

Персональный трекер здоровья и физической активности.

Возможности

  • Дневник питания — 24400+ продуктов (Магнит, 5ка, Health-Diet.ru, Ашан, Макдоналдс, KFC, Додо Пицца, KDV, ИОН, Гриднев). 37 нутриентов (витамины, минералы, omega-3/6, вода, клетчатка). Рецепты с термообработкой. Формулы порций (4*30, 300+50).
  • GPS трекинг — запись маршрутов на велосипеде/пешком в фоне (foreground service, точки пишутся при выключенном экране; один файл на сессию с id сессии в имени gps_points_<ms>_s<id>.jsonl для однозначной привязки, переживает START_STICKY-перезапуск ОС; полный до-импорт нативных точек по timestamp при финализации — без потерь, даже если экран был выключен всю запись, а при пробуждении экрана точки видимо нарастают на карте по мере импорта). При живой записи нативный файл — источник истины для БД, watchPosition только рисует маркер (без дублей одного фикса с разными ts). Восстановление точек из файлов на устройстве — матч файла к сессии по id/дате, дозаполнение разрывов с дедупом по близости ±2.5с, безопасный пересчёт без удаления точек, чистка уже импортированных файлов. Оффлайн карты (Leaflet + IndexedDB кэш). Импорт GPX/FTB (FitoTrack). Экспорт GPX. Фильтр altitude outlier'ов и GPS-залипаний. Отбор точек по точности (жёсткий порог по настройке «Мин. точность» — рубит грубые сотовые фиксы ~800м, оставляет слабый но точный GPS; где сигнала нет — честный разрыв). Направление (bearing) каждой точки пишется в БД. Вращение карты по компасу (leaflet-rotate, EMA-сглаживание, gimbal lock компенсация) и course-up по GPS-курсу (в ландшафте карта доворачивается вместе с экраном — курс к физическому верху). Ландшафтный режим (CSS rotation + панель справа, 3 режима: off/auto/lock). Dead reckoning при потере GPS (гироскоп + акселерометр). Placeholder до GPS (пиксельарт). Карта проезженных дорог (дедупликация 2м, вело/пешие). Импорт тайлов по регионам (SQLite, роутер LAN).
  • BLE пульсометр — подключение к FitPro браслетам и стандартным HR датчикам (0x180D). ЧСС, SpO2, давление в реальном времени при записи трека.
  • Расчёт ккал — велосипед: НЕТТО-модель (суточный баланс уже учитывает BMR, поэтому активность считается сверх покоя). Кручение = max(физика мощности из gradient+Crr+CdA / КПД, эмпирический MET-нетто по скорости); накат (freewheel, power≤0 — «велик катился бы сам») = только базовый обмен. MET-таблица для ходьбы/бега и тренировок (приседания 6.0, скакалка 12.3, растяжки 2.3, бассейн 8.0). Набор высоты — кумулятивный гистерезис (устойчив на плотных треках, где per-point разница <1м). Пункт меню «Пересчитать высоту/калории» пересчитывает статистику всех треков без изменения точек. Профили велосипедов. BMR по Mifflin-St Jeor с коэффициентом активности.
  • Дистанция на разрывах GPS — на «слепых» участках (интервал между фиксами > gapThresholdSec) путь считается по скорости (speed×dt, с ограничением по макс. скорости), а не прямой хордой — иначе разрывы занижают/искажают длину. Телепорт-скачки без временного разрыва отбрасываются. Расчёт зависит только от времени и скорости, поэтому live-счётчик, «Стоп» и пересчёт дают одинаковую длину. Порог gapThresholdSec настраивается; при изменении и пересчёте применяется сразу.
  • Тренировки — приседания (подходы x повторения), скакалка, растяжки, бассейн (дистанция). Автоматический расчёт ккал по MET и весу.
  • Нутриенты — 37 микронутриентов (витамины, минералы, жирные кислоты, женьшень, ресвератрол, CoQ10). Нормы РСП/АУП (РФ/ЕС/США). Фармакокинетика — запасы в организме по полураспаду.
  • Трекинг жидкости — water_pct в продуктах, прогресс-бар, настраиваемая норма.
  • Графики — скорость, высота, ЧСС тренировки с зумом и pan. Тренд веса. Донат макронутриентов. Баланс ккал (приход/расход).
  • OTA обновления — проверка BUILD_NUMBER на роутере (LAN) или VPS, скачивание через браузер.
  • Ручные маршруты — рисование трека на карте тапами, elevation из прошлых треков или open-meteo API.
  • Сохранённые маршруты — импорт GPX-маршрутов, нарисованных заранее (например, в конструкторе Яндекс.Карт: формат <rtept>), выбор активного, наложение цветной линией поверх карты во время записи И на экране просмотра прошлого трека — для визуальной навигации. Управление на отдельной странице (импорт/переименование/цвет/удаление, один активный за раз), переключение линии кнопкой-тогглом. Цвета «проезженных дорог» настраиваются раздельно для вело/пеших/бега.
  • Де-джиттер трека — сглаживание дрожащего GPS-трека методом Савицкого-Голея (настраиваемое окно/число итераций, живое превью на карте детали трека). Хранится обратимо: оригинал и сглаженный вариант лежат раздельно, калории пересчитываются по сглаженным точкам, откат к оригиналу в один тап. Точность каждого фикса (accuracy_m) пишется в БД для будущего пересчёта с порогом точности.
  • Экспорт/импорт — свои продукты, рецепты и добавки одним файлом (JSON).
  • Вес, сон, добавки — логирование с историей.

Стек

  • Frontend: чистый JavaScript, HTML, CSS. Без React/Vue/bundler.
  • Backend: Rust (Tauri 2) — SQLite, IPC, seed import, BLE (btleplug на десктопе).
  • Android: Kotlin — foreground GPS service, BLE HR service, WakeLock, SAF.
  • Библиотеки: Leaflet 1.9.4 (карты), leaflet-rotate (компас), Chart.js (графики), Hammer.js (жесты), JSZip.

Сборка

# Зависимости: Rust, Node.js, Android SDK + NDK
./build.sh -d android       # debug APK
./build.sh android          # release APK
./build.sh -i android -d    # debug + установка на устройство
./build.sh -u android       # release + upload на роутер (LAN) и VPS (OTA)
./build.sh -d -i -u android # debug + install + upload

Структура

Подробно: PROJECT_MAP.md

frontend/
  js/main.js          — UI, навигация, модалки, компас, ландшафт (~5500 строк)
  js/db.js            — БД, миграции, CRUD (~1500)
  js/gps.js           — GPS, физика ккал, BLE HR polling (~1200)
  js/bmr.js           — BMR формула, РСП, полураспад нутриентов
  js/sync.js          — синхронизация между устройствами (LAN)
  js/tilecache.js     — оффлайн тайлы (IndexedDB)
  css/styles.css      — стили, тёмная тема, ландшафтный режим
  img/gps-placeholder.png — пиксельарт заглушка до GPS
  data/products_seed.db — 13480 продуктов
src-tauri/
  src/lib.rs          — Rust бэкенд, seed import
  src/ble.rs          — BLE HR (btleplug десктоп, file IPC Android)
  gen/android/        — Kotlin: MainActivity, GpsRecorderService, BleHrService
tools/
  5ka_scraper.user.js — Tampermonkey скрейпер 5ка
  magnit_scraper.user.js — Tampermonkey скрейпер Магнит
  ion_scraper.user.js — Tampermonkey скрейпер ИОН
smart/
  protocol.js         — FitPro BLE протокол (reverse-engineered)
  hr-reader.js        — Node.js прототип чтения ЧСС

Данные продуктов

Источник Продуктов Витамины/минералы
Health-Diet.ru 8090 да (37 нутриентов, omega-3/6, вода)
Магнит (SSR парсинг) 7690 нет
5ка (API скрейпер) 3354 нет
Ашан (HD) 2000 да
ИОН (web.ion.ru) 1079 да
KDV (SSR парсинг) 667 нет
Макдоналдс (HD) 619 да
KFC (HD) 361 да
Додо Пицца 258 КБЖУ
Гриднев (PDF) 217 да
Всего ~24400