- Nouveau composant EditNameBottomSheet (gorhom BottomSheet +
BottomSheetTextInput + BottomSheetScrollView) avec snap 92%, topInset
safe-area, keyboardBehavior interactive, autoFocus
- Mounted conditionnellement (state editingName) pour éviter que l'autoFocus
ouvre le clavier dès l'arrivée sur ScanDetail
- Boutons Annuler / Enregistrer avec icônes X / Check, ghost grisé bordé +
primary shadow, alignés en row via inner View, isDirty disable du Save si
le nom n'a pas changé
- ScanDetailScreen : bouton Pencil flottant à côté du favori, heroTitle
utilise customName en priorité
- useScanDetail : nouvelle méthode renameScan(newName) avec persist storage
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comportement 2-clicks sur la liste des scans :
- 1er clic : map zoom sur le scan + sheet snap au plus bas + tile preview
unique avec hint 'Appuyez à nouveau pour voir les détails'
- 2e clic même scan : navigate vers ScanDetail
- Clic autre scan en preview : switch preview + zoom
Rename inline dans le BottomSheet existant (plus de 2e sheet superposé) :
- Bouton retour (ChevronLeft) au lieu de croix
- Form (BottomSheetTextInput) avec keyboardBehavior='interactive' +
android_keyboardInputMode='adjustResize' pour ne pas masquer l'input
- Boutons Annuler/Enregistrer avec icônes (X / Check), border 1.5px primary,
shadow primary[900] sur le Save, minHeight 56px
- snapToIndex(2) à l'ouverture du form (85%) puis snapToIndex(0) après
save/cancel pour redonner la map à voir
- containerStyle { zIndex:100, elevation:100 } pour passer au-dessus des
FloatingActions quand le sheet s'expand
FloatingActions : couleur d'icône via prop color (className n'est pas
supporté pour la couleur sur lucide-react-native sans cssInterop).
actionsSlot : zIndex/elevation 1 pour passer derrière le sheet expanded.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Refonte HomeScreen :
- 'Commencer votre collection' (HomeCta) → conditionnellement remplacé par
les 3 derniers scans en mode \"grouped card\" via le nouveau composant
RecentScans (fallback HomeCta si historique vide)
- 'Maladies fréquentes' → SmallDiseaseCard remplacé par LargeDiseaseCard
en mode compact, en scroll horizontal (FrequentDiseasesHorizontal)
- Comment temporairement <SeasonAlert /> en attendant la page Notifications
LargeDiseaseCard : nouvelle prop compact qui réduit hauteur (260→220),
padding, font-sizes et lignes de description (3→2). Border + radius +
shadow Android forcés en style inline pour clip elevation correctement.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aligne le rendu des date groups sur le pattern PracticalGuides : items
encapsulés dans une card blanche rounded-16, séparés par une ligne grise
indentée.
- ScanListItem : nouvelles props grouped + showSeparator → désactive
borderRadius/margins/border individuels et active la ligne séparatrice
alignée sous le texte
- DateGroupAccordion : wrappe les ScanListItem dans une View card avec
shadow iOS / elevation Android
Le même pattern est réutilisé par RecentScans (Home) — voir commit suivant.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extrait la barre de recherche en composant partagé
(components/shared/SearchBar.tsx) avec props placeholder/value/onChangeText/
showFilter.
- Home (SearchSection) : utilise le composant partagé
- Map (FloatingSearch) : remplace l'input custom + ajuste les chips (border
primary, font-size 15→12, MapPin couleur primary)
- MyPlants : remplace l'input custom + son bouton clear
Bonus : SearchBar gère proprement le clavier Android via numberOfLines={1},
multiline={false}, scrollEnabled={false}, lineHeight 20 + textAlignVertical
center + includeFontPadding false → le placeholder ne wrappe plus sur 2 lignes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Commente (sans supprimer) les liens et imports de NotificationsScreen :
- HeaderActionButtons : bouton cloche commenté → seul Settings reste
- RootNavigator : import + Stack.Screen commentés
- linking : deep-link 'notifications' commenté
- types/navigation : route param 'Notifications' commenté
À réactiver via la recherche de \"// TODO: réactiver quand la page Notifications\".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ConfidenceTile multipliait par 100 une valeur déjà 0-100 (résultat 7000%).
Aligne le composant sur la convention 0-100 utilisée partout dans le projet
(useGameProgress, ScanCard, ScanDetail, ResultScreen, model.ts).
Corrige aussi mockSeed (0.94 → 94, etc.) pour matcher la convention.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contexte
- Build Android C++ instable sur Windows (CMake/Ninja path too long, Nitro
headers manquants au clean). Modèle .tflite final pas encore prêt.
- Désinstall temporaire des deux libs natives, le mock JS dans model.ts
continue de servir les détections simulées pondérées.
Changements
- package.json : retire react-native-fast-tflite (3.0.1)
- pnpm-lock.yaml : régénéré, -72 packages dont nitro-modules
- src/services/tflite/model.ts : refactor pur mock, interface publique
inchangée (loadModel + runInference), procédure de réintégration
documentée en tête du fichier
- plugins/withCmakeFix.js : plugin Expo config qui injecte les flags
CMake (response files + ninja 1.12.1 + OBJECT_PATH_MAX) à chaque
prebuild — dormant tant que fast-tflite n'est pas réintégré
- app.json : référence le plugin
- CLAUDE.md + .claude/notes/android-build : doc de l'état actuel et
des étapes de réintégration (idéalement via EAS Build)
Reste
- src/assets/models/grapevine_v1.tflite conservé pour la réintégration
- metro.config.js continue de déclarer .tflite dans assetExts
- TypeScript check: 1 erreur préexistante (homeheader.tsx, palette[50]),
non liée à ce changement
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a "Add mock plants" entry under a new Developer section in the
Settings screen, gated by __DEV__ so it never ships in release. It
calls useHistory.seedTestData() which prepends 5 fake ScanRecords
spread across Bordeaux / Bourgogne / Champagne so all the map
features (region chips, markers, rename) can be exercised without
having to actually walk into a vineyard.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the Google-Maps-backed react-native-maps screen with a self-
contained WebView running Leaflet + Carto/OSM tiles. No API key, no
native compilation surface. The map is now driven by the real scan
history (useHistory) instead of mock parcels.
What's on the screen now:
- Markers for every ScanRecord that carries lat/lng, colored by
status (healthy / infected / uncertain) derived from diseaseClass.
- Tapping a marker animates the camera and opens ScanDetail.
- Bottom sheet lists the same located scans with rename support: a
pencil opens a modal-input that calls renameScan() to set
ScanRecord.customName (empty value clears it). When the history is
empty the sheet auto-snaps higher and shows a CTA to the Scanner.
- Region chips (Bordeaux/Bourgogne/Champagne) animate the camera and
draw the actual department polygon as a dashed green outline. The
GeoJSON is fetched on the React Native side (avoids the opaque
origin CORS issue inside `source={{ html }}`) and cached in a
useRef Map.
- "Ma position" filter + Locate FAB drop a circular green pin with a
smiley SVG and a pulse halo at the user's GPS coords.
- FloatingActions and FloatingSearch tags restyled to match the
Apple-inspired Bento spec (rounded-full FABs, 56x56, soft shadows,
primary[900] active state).
VineyardMarker (orphan since markers are SVG inside the WebView) and
the data/mockScans.ts file were removed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Capture the user's location in parallel with TFLite inference so saving
the scan doesn't slow down the camera flow. Permission is requested
just-in-time on the first capture (not at app boot) and refusals are
surfaced once via toast — repeat refusals stay silent (flag persisted
in AsyncStorage under @vineye:location-permission-asked).
- ScanRecord gains optional latitude / longitude / locationCapturedAt
(plus customName + getScanStatus helper used by the Map screen).
All fields optional so older scans keep working unchanged.
- New useScanLocation hook: requestForegroundPermissionsAsync +
getCurrentPositionAsync(Balanced) with a 5s timeout. On any failure
returns null so the scan still saves without coordinates.
- ScannerScreen runs analyze() and requestAndGetLocation() through
Promise.all so GPS acquisition does not block inference.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add VinEye/.npmrc with node-linker=hoisted to avoid Windows MAX_PATH
crashes with .pnpm/<hash>/ deep paths during native compilation
- Replace react-native-maps (Google Maps SDK requires API key) with
react-native-webview (renders Leaflet + OSM tiles, no key needed)
- Add expo-location for GPS capture during scans
- Add expo-dev-client for proper HMR + deep-link launch in dev builds
- Configure expo-location plugin in app.json with FR permission strings
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New screens: Guides, Library, Map, Notifications, Settings.
Home refactored with modular components (SearchHeader, HomeCta, FrequentDiseases, SeasonAlert, PracticalGuides).
Replaced hardcoded colors with theme tokens in SeasonAlert and HomeCta.
Updated navigation, i18n, and CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace floating pill tab bar with classic anchored bottom bar (Home | FAB Scan | Map)
- Add central FAB button (green, elevated) for Scanner
- Move History → Notifications and Profile → Settings (accessible via header icons)
- Add SearchHeader with bell (notifications) and settings icons
- Add MapScreen placeholder
- Extract SearchHeader component from HomeScreen
- Switch to lucide-react-native icons for bottom tab bar
- Fix react-dom version mismatch (19.2.4 → 19.1.0)
- Clean up unused imports in homeheader.tsx
- Update navigation types, deep links, and i18n keys
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>