Compare commits

...
4 changed files with 31 additions and 2 deletions
@@ -248,6 +248,7 @@ class AnalysisProvider extends ChangeNotifier {
String? sessionId, String? sessionId,
int? distance, int? distance,
String? caliber, String? caliber,
int? expectedShots,
}) async { }) async {
if (_imagePath == null || _targetType == null) { if (_imagePath == null || _targetType == null) {
_errorMessage = "Impossible d'exporter : image ou type de cible manquant."; _errorMessage = "Impossible d'exporter : image ou type de cible manquant.";
@@ -273,6 +274,7 @@ class AnalysisProvider extends ChangeNotifier {
shots: _shots, shots: _shots,
distanceMeters: distance ?? 25, distanceMeters: distance ?? 25,
caliber: caliber ?? 'unknown', caliber: caliber ?? 'unknown',
expectedShots: expectedShots,
); );
_state = AnalysisState.success; _state = AnalysisState.success;
+6 -1
View File
@@ -784,7 +784,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
// qu'elle ressorte sur le bouton. // qu'elle ressorte sur le bouton.
color: Colors.white, color: Colors.white,
), ),
label: 'TERMINER TOUT ET EXPORTER', label: 'TERMINER ET CONTRIBUER À L\'IA',
color: AppTheme.warningColor, color: AppTheme.warningColor,
onPressed: () => onPressed: () =>
_finishSession(context, provider, export: true), _finishSession(context, provider, export: true),
@@ -943,6 +943,11 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
sessionId: sessionProvider.activeSessionId, sessionId: sessionProvider.activeSessionId,
distance: sessionProvider.distance, distance: sessionProvider.distance,
caliber: sessionProvider.currentWeaponCaliber, caliber: sessionProvider.currentWeaponCaliber,
// Hors session, shotsPerTarget vaut sa valeur par defaut : mieux
// vaut ne rien annoncer qu'annoncer un nombre faux.
expectedShots: sessionProvider.isSessionActive
? sessionProvider.shotsPerTarget
: null,
); );
messenger.hideCurrentSnackBar(); messenger.hideCurrentSnackBar();
} }
+17 -1
View File
@@ -462,7 +462,23 @@ class _SettingsScreenState extends State<SettingsScreen> {
), ),
const SizedBox(height: 14), const SizedBox(height: 14),
const Text( const Text(
'🔒 Anonymat Garanti : L\'envoi est totalement anonymisé. Votre identité est remplacée par un hash cryptographique.', '📤 Ce qui est envoyé : la photo de la cible, la position des '
'impacts que vous avez placés, la distance de tir, le calibre et '
'le nombre de coups prévus.',
style: TextStyle(fontSize: 13),
),
const SizedBox(height: 10),
const Text(
'🚫 Ce qui ne l\'est pas : la géolocalisation de la photo (retirée '
'avant l\'envoi), le nom de votre arme, et le modèle de votre appareil.',
style: TextStyle(fontSize: 13),
),
const SizedBox(height: 10),
const Text(
'🔒 Pseudonymat : votre identité est remplacée par un hash '
'cryptographique. Il reste le même d\'un envoi à l\'autre, afin de '
'rattacher vos contributions à votre compte (récompenses, '
'modération, suppression sur demande).',
style: TextStyle(fontSize: 13), style: TextStyle(fontSize: 13),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
+6
View File
@@ -108,6 +108,7 @@ class AiExportService {
required List<Shot> shots, required List<Shot> shots,
int distanceMeters = 25, int distanceMeters = 25,
String caliber = 'unknown', String caliber = 'unknown',
int? expectedShots,
String? apiUrl, String? apiUrl,
}) async { }) async {
try { try {
@@ -172,6 +173,11 @@ class AiExportService {
"type": targetType.name, "type": targetType.name,
"distance_meters": distanceMeters, "distance_meters": distanceMeters,
"caliber": caliber, "caliber": caliber,
// Nombre de coups prevus pour cette cible, null hors session.
// Un ecart avec le nombre d'impacts ne signifie pas que le
// marquage est faux (un coup peut etre parti hors papier) : c'est
// au tri du dataset d'en decider, pas au client.
"expected_shots": expectedShots,
}, },
"plotting": { "plotting": {
"target_corners": corners, "target_corners": corners,