From 767c2d78aa2e763ec8f248b92818ffea2483ad1b Mon Sep 17 00:00:00 2001 From: Davide Scaini Date: Wed, 3 Jun 2026 00:13:35 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20section=201=20=E2=80=94=20keep-awake=20?= =?UTF-8?q?toggle,=20sensor=20button,=20GPS=20pause,=20track=20view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Keep-awake now conditional: activates only when recording + toggle on - Sensor button overlaid on map area navigates to SensorPairing modal - Pause/resume now start/stop the GPS background task, not just store state - TrackView renders lat/lon polyline via react-native-svg (no tile server) - react-native-svg added as dependency --- CLAUDE.md | 20 +++--- src/screens/RecordingScreen.tsx | 107 +++++++++++++++++++++++++++----- 2 files changed, 105 insertions(+), 22 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7e24911..1a94d6a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -99,11 +99,12 @@ Files saved to a user-accessible location (iOS Files app / Android shared storag Scaffold is done (all screens, navigation, store, services, GPX, DB, upload). Items below are what remains before v1 is shippable. -### 1 — Quick fixes (each < 30 min) +### 1 — Quick fixes ✅ -- [ ] **Keep-awake toggle** — `useKeepAwake()` in `RecordingScreen` is unconditional; wire it to `keepAwake` from the store so the toggle actually works -- [ ] **Sensor button on Recording screen** — no entry point to the SensorPairing modal; add a BLE icon button in the header or stats area that calls `nav.navigate('SensorPairing')` -- [ ] **GPS pause/resume** — `pause()` / `resume()` only change store state; also call `stopGpsRecording()` / `startGpsRecording()` so the background task actually pauses +- [x] **Keep-awake toggle** — wired to `keepAwake` store state via `activateKeepAwakeAsync` / `deactivateKeepAwake`; toggle button visible in controls bar +- [x] **Sensor button on Recording screen** — "⚡ Sensors" button overlaid on map area navigates to SensorPairing modal +- [x] **GPS pause/resume** — `handlePause` calls `stopGpsRecording()`, `handleResume` calls `startGpsRecording()` +- [x] **Track view** — `TrackView` component renders recorded lat/lon points as a scaled SVG polyline on a dark background (no tile server needed); replaces the grey placeholder ### 2 — BLE (half day) @@ -120,8 +121,11 @@ Items below are what remains before v1 is shippable. - [ ] On first launch, detect if the app is affected by battery optimization (`expo-intent-launcher`) and show a one-time prompt directing the user to whitelist bincio-rec; persist dismissal in AsyncStorage so it only shows once -### 5 — Map (1–2 days) +### 5 — Map (optional upgrade) -- [ ] **Initialize MapLibre** — call `MapLibreGL.setAccessToken(null)` at app start (or configure a tile provider in Settings); add a tile source (e.g. OpenFreeMap / self-hosted) -- [ ] **Replace placeholder** — swap the grey `` in `RecordingScreen` with a `` + `` that follows current location -- [ ] **Live track polyline** — subscribe to `trackPoints` from the store and render a `` + `` that updates as points arrive +The track view from section 1 already shows the GPX polyline scaled to fit the screen. +MapLibre can be added later for a real basemap (streets/terrain), but is not required for v1. + +- [ ] **MapLibre basemap** — replace `TrackView` SVG with `` + a tile source (e.g. OpenFreeMap); call `MapLibreGL.setAccessToken(null)` for raster-free usage +- [ ] **Camera follow** — add `` that follows `trackPoints[last]` during recording +- [ ] **Line layer** — replace SVG polyline with `` + `` diff --git a/src/screens/RecordingScreen.tsx b/src/screens/RecordingScreen.tsx index bb62e6e..5e99d5a 100644 --- a/src/screens/RecordingScreen.tsx +++ b/src/screens/RecordingScreen.tsx @@ -1,27 +1,35 @@ import React, { useEffect, useRef, useState } from 'react'; -import { View, Text, StyleSheet, TouchableOpacity, Alert } from 'react-native'; +import { View, Text, StyleSheet, TouchableOpacity, Alert, LayoutChangeEvent } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; -import { useKeepAwake } from 'expo-keep-awake'; +import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake'; +import Svg, { Polyline } from 'react-native-svg'; import { useRecordingStore } from '../store/recording'; import { startGpsRecording, stopGpsRecording, requestLocationPermissions } from '../services/gps'; -import { RootStackParamList } from '../types'; +import { RootStackParamList, TrackPoint } from '../types'; type Nav = NativeStackNavigationProp; export function RecordingScreen() { const nav = useNavigation