Changelog UrbaFix
Toutes les modifications notables de ce projet seront documentées
dans ce fichier.
[1.5.0] - 03 Janvier 2026
Support des Vidéos (5
secondes max)
Capture et Upload de Vidéos
- Nouveau module VideoCompressor.kt : Compression et
validation des vidéos
- Durée maximale : 5 secondes (troncature automatique si
dépassement)
- Taille maximale : 5 MB
- Format : MP4 (conversion automatique via MediaMuxer)
- Validation automatique (dimensions, durée, taille)
- utils/VideoCompressor.kt (240 lignes)
Base de Données Étendue
- PhotoEntity modifié pour supporter les vidéos :
- Nouveau champ
mediaType: MediaType (PHOTO ou
VIDEO)
- Nouveau champ
durationMs: Long? (durée en
millisecondes)
- Nouveau champ
photoData: String? (données Base64 pour
upload)
- Nouveau enum
MediaType { PHOTO, VIDEO }
- Version base de données : 3 → 4
- PhotoEntity.kt:34-38
Interface Utilisateur
Enrichie
- ReportScreen amélioré :
- 4 boutons : Photo (caméra), Galerie (photos), Vidéo 5s (caméra),
Galerie ▶ (vidéos)
- Aperçu des vidéos avec indicateurs visuels :
- Bordure bleue (2dp) pour distinguer des photos
- Icône ▶ centrée
- Badge durée en bas à droite (ex: “3s”)
- Compteur séparé : “2 photo(s) • 1 vidéo(s)”
- ReportScreen.kt:310-534
Traitement des Vidéos
- ReportViewModel étendu :
- Nouvelle méthode
addVideo(uri: Uri) pour traitement
vidéo
- Validation avec VideoCompressor.getVideoInfo()
- Troncature automatique si durée > 5 secondes
- Conversion Base64 pour upload API (compatible infrastructure
existante)
- PhotoItem étendu :
isVideo: Boolean,
durationMs: Long?
- ReportViewModel.kt:24-28, 331-405
Algorithme de Troncature
- trimVideoTo5Seconds() : Extraction des 5 premières
secondes
- Utilise MediaExtractor pour lire la vidéo source
- Utilise MediaMuxer pour écrire la vidéo tronquée
- Copie toutes les pistes (vidéo + audio)
- Arrêt à 5000ms (5 secondes exactement)
- VideoCompressor.kt:119-188
API et Backend
- Nouveau format JSON pour submit_incident.php :
- Méthode
submitIncidentJson() avec @Body au
lieu de multipart
- Champ
videos: List<VideoData>? dans
SubmitIncidentRequest
- Structure VideoData :
{video: "data:video/mp4;base64,...", latitude, longitude}
- Coordonnées GPS incluises pour chaque vidéo
- UrbafixApi.kt:67-69, SubmitIncidentRequest.kt:5-26
- Nouvelle table videos_incident (serveur) :
- Colonnes : id, incident_id, type, filename, filepath,
description
- Champs supplémentaires : duration, filesize, mime_type, latitude,
longitude, encrypted
- Foreign key vers incidents (CASCADE DELETE)
- Stockage : /uploads/videos/ (fichiers MP4)
- database/migration_videos.sql
- Upload Repository :
sendIncidentToApi() modifié pour séparer photos et
vidéos
- Photos → tableau
photos (Base64 avec prefix
“data:image/jpeg;base64,…”)
- Vidéos → tableau
videos (objets VideoData avec
GPS)
- Validation prefix Base64 automatique
- IncidentRepository.kt:406-502
- Synchronisation Worker :
- SyncIncidentsWorker utilise maintenant le repository
- Support automatique photos + vidéos
- Récupération via
getPhotosByIncidentIdAndType()
- workers/SyncIncidentsWorker.kt:61-88
Avertissement RGPD pour les
Vidéos
- Dialogue d’avertissement obligatoire avant
capture/sélection vidéo
- Icône ⚠️ orange (48dp)
- Titre : “⚠️ Important - Protection des données”
- Message explicatif : Floutage automatique non disponible pour
vidéos
- Recommandations RGPD :
- Évitez de filmer des personnes identifiables
- Concentrez-vous sur le problème à signaler
- Respectez la vie privée des passants
- Boutons : “Annuler” ou “J’ai compris, continuer”
- Engagement utilisateur : Confirmation explicite requise
- ReportScreen.kt:691-782
Limitations Connues
⚠️ Floutage des visages non implémenté pour les
vidéos : - Complexité élevée (traitement frame par frame
requis) - Solution future possible : ML Kit Face Detection sur chaque
frame - Mitigation actuelle : Dialogue d’avertissement
RGPD obligatoire avant capture
Fichiers Modifiés
utils/VideoCompressor.kt (nouveau, 240 lignes)
data/local/entities/PhotoEntity.kt - Ajout mediaType,
durationMs
data/local/AppDatabase.kt - Version 4
data/local/Converters.kt - TypeConverters pour
MediaType et PhotoType
ui/screens/report/ReportScreen.kt - Interface capture
vidéo
ui/screens/report/ReportViewModel.kt - Traitement
vidéo
Dépendances
- Utilise MediaExtractor, MediaMuxer, MediaMetadataRetriever (Android
SDK)
- Aucune dépendance externe ajoutée
Tests
- ✅ Compilation réussie (BUILD SUCCESSFUL)
- ⏳ Tests sur appareil physique requis
- ⏳ Validation de l’upload vers l’API backend
[1.4.0] - 03 Janvier 2026
Filtrage Géographique
Dynamique
Filtrage par Rayon de la
Carte
- Rayon de 10 km : Les incidents affichés sont
filtrés selon la position actuelle de la carte
- Utilise l’algorithme Haversine pour calculer la distance entre le
centre de la carte et chaque incident
- Constante
FILTER_RADIUS_METERS = 10000.0 (10 km)
- Filtre appliqué via
Flow.combine() pour réactivité
- HomeViewModel.kt:42-74
Synchronisation Basée
sur la Position GPS
- Code postal dynamique : La synchronisation récupère
le code postal basé sur la position GPS actuelle
- Utilise l’API geo.gouv.fr pour géolocalisation inverse
- Récupère automatiquement : nom commune, code INSEE, code postal
- Fallback sur “06500” (Menton) si échec de géolocalisation
- HomeViewModel.kt:116-144
Nouvelle Méthode Repository
getCommuneData() : Récupération
complète des données d’une commune
- Paramètres : latitude, longitude
- Retourne :
CommuneData(nom, codeInsee, codePostal)
- Utilise GeoGouvApi pour appel à geo.api.gouv.fr
- IncidentRepository.kt:244-276
Comportement
Avant v1.4.0 : - Liste affichait TOUS les incidents
de la base de données (Menton hardcodé) - Carte centrée sur Nice mais
liste montrait Menton - Code postal hardcodé à “06500”
Après v1.4.0 : - Liste affiche UNIQUEMENT les
incidents à moins de 10 km du centre de la carte - Synchronisation
récupère les incidents pour le code postal détecté via GPS - Code postal
dynamique basé sur la position actuelle
Exemple :
Position GPS : Nice (43.7102, 7.2620)
↓
geo.gouv.fr → Commune: Nice, CP: 06000, INSEE: 06088
↓
API sync → GET /api/get_incidents.php?code_postal=06000
↓
Filtrage 10km → Affiche uniquement incidents de Nice
Fichiers Modifiés
ui/screens/home/HomeViewModel.kt - Filtrage
géographique + sync dynamique
data/repository/IncidentRepository.kt - Nouvelle
méthode getCommuneData()
Dépendances
- Utilise
GeoGouvApi existant (geo.api.gouv.fr)
- Aucune nouvelle dépendance
- ✅ Pas de hardcoding de code postal
- ✅ Détection automatique de la commune
- ✅ Filtrage géographique précis (Haversine)
- ✅ Synchronisation contextuelle (position utilisateur)
[1.3.0] - 03 Janvier 2026
Refonte de l’Écran de
Détail d’Incident
Nouvelle Mise en Page
- Layout 1/3 + 2/3 : Écran divisé en deux parties
fixes
- 1/3 supérieur : Carte OSM plein écran avec
marqueur
- 2/3 inférieur : Bloc de contenu scrollable avec
fond opaque
- Aucun chevauchement entre la carte et le contenu
IncidentDetailScreen.kt:78-170
Animation de Zoom
- Effet de zoom progressif lors de l’ouverture du
détail
- Zoom initial : 12 (vue éloignée)
- Zoom final : 17 (vue rapprochée sur l’incident)
- Durée : 1200ms avec easing
FastOutSlowInEasing
- Recentrage automatique sur le marqueur pendant l’animation
IncidentDetailScreen.kt:180-250
Galerie Photos Améliorée
- Miniatures réduites : 100dp (au lieu de 150dp)
- Zoom cliquable : Dialog plein écran avec gestes
- Pinch-to-zoom : de 1x à 5x
- Pan pour déplacer l’image zoomée
- Fond noir avec bouton fermer
PhotoZoomDialog : IncidentDetailScreen.kt:576-648
- Cache optimisé : Clés de cache uniques par photo
memoryCacheKey("photo_${photo.id}")
diskCacheKey("photo_${photo.id}_${photoUrl.hashCode()}")
- IncidentDetailScreen.kt:478-480
Corrections UX
- Galerie conditionnelle : N’apparaît que si des
photos existent
- Condition
if (allPhotos.isNotEmpty())
- IncidentDetailScreen.kt:142-149
- Tous les incidents affichés en fullscreen :
Suppression de
IncidentDetailSheet
- Incidents individuels ET groupes utilisent
IncidentDetailScreen
- UX cohérente pour tous les cas
- HomeScreen.kt:90-121
Retour à l’Accueil Amélioré
- Dézoomer au retour : La carte de l’accueil dézoome
et recentre
- Stockage de la position GPS initiale dans
userHomePosition
- Restauration du zoom 13f et du centre GPS au retour
- HomeViewModel.kt:29,73-78,163-167,215-219
Fixes Techniques
- ViewModel avec clé unique : Résout le bug des
photos manquantes
key = "incident_detail_${id}" pour éviter
recréation
- HomeScreen.kt:94
- Surface avec fond opaque : Empêche le texte de se
superposer à la carte
color = MaterialTheme.colorScheme.background
shadowElevation = 8.dp
- IncidentDetailScreen.kt:95-101
Fichiers Modifiés
ui/screens/home/IncidentDetailScreen.kt - Refonte
complète du layout et animations
ui/screens/home/HomeScreen.kt - Suppression
IncidentDetailSheet, ajout clé ViewModel
ui/screens/home/HomeViewModel.kt - Gestion position GPS
initiale et retour
Dépendances
- Ajout imports animations :
animateFloatAsState,
tween, FastOutSlowInEasing
- Ajout imports gestes :
detectTransformGestures
- IncidentDetailScreen.kt:19-21
[1.2.0] - 01 Janvier 2026
Ajouts
Floutage Automatique des
Visages (RGPD)
- FaceBlurrer.kt : Nouveau module de détection et
anonymisation des visages
- Détection on-device avec ML Kit Face Detection (v16.1.6)
- 100% on-device : aucune donnée envoyée sur le réseau
- RGPD : obligatoire, automatique, non désactivable
- Deux méthodes d’anonymisation :
- Flou gaussien : Stack Blur optimisé (rayon 25px,
marge 30%)
- Pixelisation : Alternative rapide (blocs de
20px)
- Gestion mémoire optimisée (bitmap recycling)
- Logs détaillés pour debug
- FaceBlurrer.kt (430 lignes)
Pipeline de Traitement
Photo Sécurisé
- ImageCompressor.kt : Intégration du floutage dans
la compression
- Ordre de traitement :
- Chargement image
- Correction orientation EXIF
- Redimensionnement (max 1024px)
- Floutage visages (étape obligatoire)
- Compression JPEG 85%
- Encodage Base64
- Fonction convertie en
suspend fun pour traitement
asynchrone
- Rejet de l’image si échec du floutage (sécurité RGPD)
- ImageCompressor.kt:45-115
Modifications
Configuration ML Kit
- Détecteur configuré en mode PERFORMANCE_MODE_ACCURATE
- Détection de visages ≥10% de la taille de l’image
- Pas de landmarks ni classification (économie CPU)
- Tracking activé pour futures évolutions (vidéo)
Algorithme Stack Blur
- Alternative rapide au Gaussian Blur (complexité O(n) vs O(n²))
- Optimisé pour appareils mobiles
- Passes horizontale et verticale séparées
- Qualité visuelle proche du Gaussian Blur
Dépendances Ajoutées
com.google.mlkit:face-detection:16.1.6 - Détection
visages on-device
org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3
- Extension coroutines pour Google Play Services
Fichiers Modifiés
app/src/main/java/com/example/urbafixkotlin/utils/ImageCompressor.kt
app/build.gradle.kts
Nouveaux Fichiers
app/src/main/java/com/example/monquartierkotlin/utils/FaceBlurrer.kt
(430 lignes)
- ✅ Traitement 100% on-device (pas d’envoi réseau)
- ✅ Anonymisation automatique et obligatoire
- ✅ Pas d’option de désactivation
- ✅ Image originale jamais sauvegardée après traitement
- ✅ Floutage appliqué AVANT envoi au serveur
- ✅ Compatible Android 8+ (API 26+)
[1.1.1] - 01 Janvier 2026
Corrections de Bugs
Synchronisation des Photos
- Fix : Les photos des incidents sont maintenant
synchronisées depuis l’API
- Ajout de la synchronisation des photos dans
syncIncidentsFromApi()
- Déduplication automatique des photos en double
(
.distinct())
- Nettoyage systématique avant insertion
(
photoDao.deleteByIncidentId())
- IncidentRepository.kt:156-180
Base de Données
- Fix : Correction du nom de table
photos → photos_incident
- Alignement avec le schéma serveur
- PhotoEntity.kt:9
- PhotoDao.kt (toutes les requêtes mises à jour)
- Version de la base de données : 2 → 3 (AppDatabase.kt:20)
Vue Détaillée - Mes
Signalements
- Fix : Utilisation de la même vue détaillée que
l’écran d’accueil
- Remplacement de IncidentDetailSheet par IncidentDetailScreen
- Affichage de la carte OSM intégrée
- Galerie photos horizontale
- MyReportsScreen.kt:260-290
Améliorations
Synchronisation
- Les photos sont maintenant synchronisées pour tous les incidents
(pas seulement les nouveaux)
- Gestion robuste des doublons via déduplication
- Logs détaillés pour le debug (IncidentRepository.kt,
IncidentDetailViewModel.kt)
Fichiers Modifiés
app/src/main/java/com/example/urbafixkotlin/data/local/entities/PhotoEntity.kt
app/src/main/java/com/example/urbafixkotlin/data/local/dao/PhotoDao.kt
app/src/main/java/com/example/urbafixkotlin/data/local/AppDatabase.kt
app/src/main/java/com/example/urbafixkotlin/data/repository/IncidentRepository.kt
app/src/main/java/com/example/urbafixkotlin/ui/screens/myreports/MyReportsScreen.kt
[1.1.0] - 31 Décembre 2025
Ajouts
Vue Détaillée Complète des
Incidents
- IncidentDetailScreen : Nouvel écran plein écran
remplaçant le ModalBottomSheet
- Carte OSM intégrée (200dp) centrée sur l’incident (zoom 16)
- Badge “⭐ Incident principal” avec compteur (affiché uniquement pour
les groupes)
- Section détails avec icônes : type, description, adresse, date,
statut
- Galerie photos horizontale scrollable (LazyRow)
- Affiche TOUTES les photos de TOUS les incidents du groupe
- Photos 150x150dp, coins arrondis 12dp, bordure
- Chargement asynchrone avec Coil
- Titre avec compteur : “Photos (5)”
- Sous-titre conditionnel : “• De tous les incidents”
- Liste des incidents secondaires (affichée uniquement pour les
groupes)
- Triés par date décroissante
- Header avec couleur du type + date relative
- Description limitée à 3 lignes (ellipsis)
- Séparateurs visuels (Divider)
- IncidentDetailViewModel : Chargement et combinaison
des photos
- Utilise
Flow.combine() pour fusionner les photos de
tous les incidents
- StateFlow réactif pour mise à jour automatique de l’UI
- Factory pattern pour injection de dépendances
- Dates courtes : Format “28 déc. à 14:30”
(SimpleDateFormat avec Locale.FRENCH)
- Dates relatives :
- Moins d’1h : “il y a Xmin”
- Moins de 24h : “il y a Xh”
- 1 jour : “il y a 1 jour”
- Plus : “il y a X jours”
Partage de l’Application
Nouvelle section dans ProfileScreen : “Partager
l’application”
- Card avec icône Share et couleur tertiaryContainer
- Bouton “Partager via SMS, WhatsApp…”
- Intent Android ACTION_SEND (type: text/plain)
- Compatible avec toutes les apps de partage (SMS, WhatsApp, Email,
Telegram, Messenger, etc.)
Message de partage personnalisé :
🏘️ Rejoins-moi sur UrbaFix !
UrbaFix permet de signaler facilement les problèmes dans ton quartier
(nids-de-poule, dépôts sauvages, éclairage défaillant, etc.).
📱 Télécharge l'application ici :
https://urbafix.fr/download
Ensemble, améliorons notre cadre de vie !
Modifications
HomeScreen
- Remplacement du ModalBottomSheet par Dialog plein écran
- DialogProperties avec
usePlatformDefaultWidth = false
- Passage du repository au HomeScreen pour créer
IncidentDetailViewModel
- Meilleure intégration avec le système de navigation Android
Affichage des Photos
- Normalisation des URLs photos (préfixe
https://urbafix.fr pour les URLs relatives)
- Gestion des URLs serveur vs chemins locaux
- Support des états de chargement et d’erreur
Améliorations
- Chargement des photos uniquement quand nécessaire (Flow lazy)
- Combinaison efficace des Flow avec
combine()
- Réutilisation des composables existants (StatusBadge)
UX/UI
- Visibilité conditionnelle des sections selon le type (groupe vs
individuel)
- Effet empilé conservé pour les cartes de groupes
- Transitions fluides entre liste et vue détaillée
- Scrolling vertical dans la vue détaillée
Documentation
- Mise à jour complète de README.md
- Mise à jour de CLAUDE.md avec les nouvelles fonctionnalités
- Ajout de schémas ASCII pour la vue détaillée
- Changelog détaillé (ce fichier)
Fichiers Modifiés
app/src/main/java/com/example/urbafixkotlin/ui/screens/home/HomeScreen.kt
app/src/main/java/com/example/urbafixkotlin/ui/screens/profile/ProfileScreen.kt
app/src/main/java/com/example/urbafixkotlin/MainActivity.kt
README.md
CLAUDE.md
Nouveaux Fichiers
app/src/main/java/com/example/monquartierkotlin/ui/screens/home/IncidentDetailScreen.kt
(530 lignes)
app/src/main/java/com/example/monquartierkotlin/ui/screens/home/IncidentDetailViewModel.kt
(47 lignes)
CHANGELOG.md (ce fichier)
Corrections de Bugs
- Fix : Utilisation de
Divider au lieu de
HorizontalDivider (compatibilité Material3)
- Fix : Import manquant
StatusBadge dans
IncidentDetailScreen
Dépendances
Aucune nouvelle dépendance ajoutée. Utilisation des bibliothèques
existantes : - Jetpack Compose Material3 - Coil (chargement images) -
osmdroid (cartes) - Room + Flow (données réactives)
[1.0.0] - 30 Novembre 2024
Version Initiale
Fonctionnalités Principales
- Écran d’accueil avec carte OpenStreetMap et liste des incidents
- Groupement intelligent des incidents proches (< 10m, même
type)
- Profil utilisateur (anonyme par défaut)
- Synchronisation offline-first avec Room Database
- Chiffrement AES-256 de la base de données (SQLCipher)
- Certificate pinning pour sécurité réseau
- WorkManager pour synchronisation en arrière-plan
Architecture
- MVVM (Model-View-ViewModel)
- Jetpack Compose + Material Design 3
- Room Database + SQLCipher
- Retrofit + OkHttp
- osmdroid (OpenStreetMap)
Sécurité
- Conforme recommandations ANSSI
- Chiffrement base de données locale (AES-256)
- Certificate pinning (double : OkHttp + Network Security Config)
- Logs conditionnels (production : aucun log)
- HTTP en clair bloqué
Format du changelog : Keep a Changelog
Versioning : Semantic Versioning