Substitui o gráfico estático (últimos 120 samples + selectedIndex por
posição) por um modelo de viewport temporal que resolve os problemas de
qualidade em tempo real e abre zoom/pan nos 3 call sites (Captura,
Janela salva e Faixa customizada).
Adições:
- src/training/chartViewport.ts: funções puras (granularityForSpan,
formatTickLabel, buildChartViewport, applyZoomIn/Out, applyPan,
isLiveTailSnap, pickSampleAtTimestamp, xFromTimestampMs,
timestampMsFromX, tipos Viewport/ChartPin/Granularity).
- __tests__/chartViewport.test.ts: 34 testes cobrindo limites,
ordenação defensiva, snap zone, hit-test e granularidade adaptativa.
- src/components/TrainingChart.tsx: reescrito para consumir viewport.
- Pin por timestampMs (sobrevive a novas amostras em tempo real).
- Pinch (Gesture.Pinch) + Pan (Gesture.Pan) + Tap (Gesture.Tap) via
react-native-gesture-handler v3.
- Auto-follow: endMs estende com novos samples enquanto liveTail.
- Snap zone (5% da duração visível) reanexa o live ao final do pan.
- Eixo X com ticks adaptativos: minute/halfMinute/quarterMinute/
tenSeconds/second/halfSecond, conforme duração visível.
- Botões +/- (zoom 2x) e ↺ (reset) na lateral.
- Indicador 'dados mais novos disponíveis' quando !liveTail.
- Estado vazio preservado (samples < 2).
- jest.setup.js + jest.config.js: mocks de gesture-handler e
reanimated para o App.test rodar em Jest (módulos nativos não
disponíveis no host).
Modificações de setup (dependências aprovadas):
- package.json + package-lock.json: adiciona react-native-gesture-handler
^3.0.1, react-native-reanimated ^4.4.1, react-native-worklets ^0.9.2.
- index.js: import 'react-native-gesture-handler' no topo.
- App.tsx: <GestureHandlerRootView> envolvendo SafeAreaProvider.
- babel.config.js: plugin react-native-worklets/plugin.
Verificações:
- npm run typecheck: 0 errors.
- npm run lint: 0 errors, 0 warnings.
- npm test -- --runInBand: 55/55 passam.
- Build Android: não verificado nesta sessão (timeout); o usuário
valida localmente antes de distribuir.
Não comitado neste commit (mudanças pré-existentes não relacionadas):
- android/* (migração fightratern → healthtracking/fightrate, mipmaps)
- README.md
- app.json
48 lines
1.4 KiB
JSON
48 lines
1.4 KiB
JSON
{
|
|
"name": "FightRateRN",
|
|
"version": "0.0.1",
|
|
"private": true,
|
|
"scripts": {
|
|
"android": "react-native run-android",
|
|
"ios": "react-native run-ios",
|
|
"lint": "eslint .",
|
|
"start": "react-native start",
|
|
"test": "jest",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"lucide-react-native": "^1.17.0",
|
|
"react": "19.2.3",
|
|
"react-native": "0.86.0",
|
|
"react-native-gesture-handler": "^3.0.1",
|
|
"react-native-reanimated": "^4.4.1",
|
|
"react-native-safe-area-context": "^5.5.2",
|
|
"react-native-svg": "^15.15.5",
|
|
"react-native-worklets": "^0.9.2"
|
|
},
|
|
"devDependencies": {
|
|
"@babel/core": "^7.25.2",
|
|
"@babel/preset-env": "^7.25.3",
|
|
"@babel/runtime": "^7.25.0",
|
|
"@react-native-community/cli": "^20.1.3",
|
|
"@react-native-community/cli-platform-android": "^20.1.3",
|
|
"@react-native-community/cli-platform-ios": "^20.1.3",
|
|
"@react-native/babel-preset": "0.86.0",
|
|
"@react-native/eslint-config": "0.86.0",
|
|
"@react-native/jest-preset": "^0.86.0",
|
|
"@react-native/metro-config": "0.86.0",
|
|
"@react-native/typescript-config": "0.86.0",
|
|
"@types/jest": "^29.5.13",
|
|
"@types/react": "^19.2.0",
|
|
"@types/react-test-renderer": "^19.1.0",
|
|
"eslint": "^8.19.0",
|
|
"jest": "^29.6.3",
|
|
"prettier": "2.8.8",
|
|
"react-test-renderer": "19.2.3",
|
|
"typescript": "^5.8.3"
|
|
},
|
|
"engines": {
|
|
"node": ">= 22.11.0"
|
|
}
|
|
}
|