GPS background recording: - Batched writes (10s flush) in native service - Polling lock prevents parallel processing - Track by timestamp instead of line count - Recovery idempotent via max DB timestamp - Seq numbers on live recorded points GPX export: - Button in session detail - SAF file picker on Android (ACTION_CREATE_DOCUMENT) - GPS config in metadata (accuracy, minSpeed, minDist) Charts: - Pinch zoom enabled at creation (Hammer.js registers handlers) - touch-action: pan-y blocks pinch in normal view (page scrolls) - Fullscreen: CSS-only expand (no canvas manipulation) - Downsampled to 500 points for smooth rendering - Back gesture collapses fullscreen before closing modal Build: --real flag finds first non-emulator device
43 lines
1.2 KiB
JavaScript
43 lines
1.2 KiB
JavaScript
const DAY_NAMES = ["вс", "пн", "вт", "ср", "чт", "пт", "сб"];
|
||
const MONTH_NAMES = [
|
||
"января", "февраля", "марта", "апреля", "мая", "июня",
|
||
"июля", "августа", "сентября", "октября", "ноября", "декабря",
|
||
];
|
||
|
||
// Format: "2026-04-05"
|
||
export function toIsoDate(date) {
|
||
const y = date.getFullYear();
|
||
const m = String(date.getMonth() + 1).padStart(2, "0");
|
||
const d = String(date.getDate()).padStart(2, "0");
|
||
return `${y}-${m}-${d}`;
|
||
}
|
||
|
||
// Format: "сб, 5 апреля"
|
||
export function toHumanDate(dateStr) {
|
||
const d = new Date(dateStr + "T00:00:00");
|
||
const day = DAY_NAMES[d.getDay()];
|
||
const num = d.getDate();
|
||
const month = MONTH_NAMES[d.getMonth()];
|
||
return `${day}, ${num} ${month}`;
|
||
}
|
||
|
||
export function today() {
|
||
return toIsoDate(new Date());
|
||
}
|
||
|
||
export function shiftDate(dateStr, days) {
|
||
const d = new Date(dateStr + "T00:00:00");
|
||
d.setDate(d.getDate() + days);
|
||
return toIsoDate(d);
|
||
}
|
||
|
||
export function currentTime() {
|
||
const now = new Date();
|
||
const h = String(now.getHours()).padStart(2, "0");
|
||
const m = String(now.getMinutes()).padStart(2, "0");
|
||
return `${h}:${m}`;
|
||
}
|
||
|
||
export function isToday(dateStr) {
|
||
return dateStr === today();
|
||
}
|