diff --git a/README.md b/README.md index 1517580..38dedd8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ sauvegarde JSON. **100 % local, aucun compte, aucun serveur.** > à titre informatif — ce ne sont pas des mesures. Fie-toi toujours à tes analyses de > sang et aux consignes de ton endocrinologue. -- **Statut** : v1.2.4 — build Android ✅, **62 tests unitaires** ✅ (44 sans les données de test locales ; 3 régressions épinglées sur données réelles **non versionnées**), intégration montre = notifications ✅, **dépôt Gitea privé + releases avec APK** ✅ +- **Statut** : v1.2.5 — build Android ✅, **62 tests unitaires** ✅ (44 sans les données de test locales ; 3 régressions épinglées sur données réelles **non versionnées**), intégration montre = notifications ✅, **dépôt Gitea privé + releases avec APK** ✅ - **Journal des versions** : [docs/CHANGELOG.md](docs/CHANGELOG.md) - **Guide utilisateur** : [docs/GUIDE_INSTALLATION.md](docs/GUIDE_INSTALLATION.md) - **Doc de développement** (architecture, maths, décisions, bugs) : [docs/DEVELOPPEMENT.md](docs/DEVELOPPEMENT.md) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 639e469..920ac50 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.hormonetrack" minSdk = 26 targetSdk = 36 - versionCode = 7 - versionName = "1.2.4" + versionCode = 8 + versionName = "1.2.5" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/hormonetrack/MainActivity.kt b/app/src/main/java/com/hormonetrack/MainActivity.kt index 0d9ccf9..ccd8bc5 100644 --- a/app/src/main/java/com/hormonetrack/MainActivity.kt +++ b/app/src/main/java/com/hormonetrack/MainActivity.kt @@ -6,6 +6,7 @@ import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate @@ -25,6 +26,13 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) val container = (application as HormoneTrackApp).container + // Edge-to-edge (Material You) : le contenu s'étend sous les barres système. + // Les insets sont alors consommés UNE SEULE FOIS — par les TopAppBar + // Material 3 (barre de statut) et la NavigationBar (barre de navigation). + // Avant : la fenêtre poussait déjà le contenu sous la barre de statut ET + // les TopAppBar rajoutaient leur padding interne → double espace vide en haut. + enableEdgeToEdge() + lifecycleScope.launch { val lang = container.settings.language.first() val locales = if (lang == "system") { diff --git a/app/src/main/java/com/hormonetrack/ui/HormoneTrackRoot.kt b/app/src/main/java/com/hormonetrack/ui/HormoneTrackRoot.kt index 0b3ddc0..aeedd79 100644 --- a/app/src/main/java/com/hormonetrack/ui/HormoneTrackRoot.kt +++ b/app/src/main/java/com/hormonetrack/ui/HormoneTrackRoot.kt @@ -1,5 +1,6 @@ package com.hormonetrack.ui +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Home @@ -55,6 +56,10 @@ fun HormoneTrackRoot(initialOpenLogDose: Boolean, initialTreatmentId: Long) { val currentRoute = backStack?.destination?.route Scaffold( + // Insets à zéro : les TopAppBar des écrans consomment elles-mêmes la + // barre de statut, la NavigationBar ci-dessous la barre de navigation — + // sinon les deux se cumulent (double espace en haut, bug v1.2.5). + contentWindowInsets = WindowInsets(0, 0, 0, 0), bottomBar = { if (currentRoute in tabs.map { it.route }) { NavigationBar { diff --git a/app/src/main/java/com/hormonetrack/ui/screens/DosesScreen.kt b/app/src/main/java/com/hormonetrack/ui/screens/DosesScreen.kt index 7b52091..eb69b2c 100644 --- a/app/src/main/java/com/hormonetrack/ui/screens/DosesScreen.kt +++ b/app/src/main/java/com/hormonetrack/ui/screens/DosesScreen.kt @@ -2,6 +2,7 @@ package com.hormonetrack.ui.screens import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -87,6 +88,8 @@ fun DosesScreen() { val timeFmt = remember { DateTimeFormatter.ofPattern("HH:mm") } Scaffold( + // Insets à zéro : le TopAppBar interne consomme déjà la barre de statut + contentWindowInsets = WindowInsets(0, 0, 0, 0), floatingActionButton = { FloatingActionButton(onClick = { showLogDialog = true }) { Icon(Icons.Filled.Add, contentDescription = stringResource(R.string.add_dose)) diff --git a/app/src/main/java/com/hormonetrack/ui/screens/LabsScreen.kt b/app/src/main/java/com/hormonetrack/ui/screens/LabsScreen.kt index 20ed6a1..80be255 100644 --- a/app/src/main/java/com/hormonetrack/ui/screens/LabsScreen.kt +++ b/app/src/main/java/com/hormonetrack/ui/screens/LabsScreen.kt @@ -2,6 +2,7 @@ package com.hormonetrack.ui.screens import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -81,6 +82,8 @@ fun LabsScreen() { } Scaffold( + // Insets à zéro : le TopAppBar interne consomme déjà la barre de statut + contentWindowInsets = WindowInsets(0, 0, 0, 0), floatingActionButton = { FloatingActionButton(onClick = { showLabDialog = true }) { Icon(Icons.Filled.Add, contentDescription = stringResource(R.string.add_lab)) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 75991de..55ed2a6 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,7 +1,21 @@ # Changelog — HormoneTrack Format : [Keep a Changelog](https://keepachangelog.com/fr-FR/1.1.0/). -Versionnage : [SemVer](https://semver.org/). Releases taguées dans git (`v1.2.4`, …). +Versionnage : [SemVer](https://semver.org/). Releases taguées dans git (`v1.2.5`, …). + +## [1.2.5] — 2026-09-05 (versionCode 8) + +### Corrigé +- **Espace vide en haut de l'écran** (contenu trop bas) : double consommation des + insets — la fenêtre poussait déjà le contenu sous la barre de statut (thème + AppCompat) ET les `TopAppBar` Material 3 rajoutaient leur padding de barre de + statut interne. Passage en **edge-to-edge propre** (`enableEdgeToEdge()`) : + - les `TopAppBar` consomment la barre de statut (une seule fois) ; + - les `Scaffold` (racine + imbriqués Doses/Analyses) ont + `contentWindowInsets = 0` pour ne pas cumuler ; + - la `NavigationBar` consomme la barre de navigation système. + Le contenu remonte, les listes défilent visuellement sous la barre de statut + (comportement Material You standard). ## [1.2.4] — 2026-09-05 (versionCode 7) diff --git a/docs/DEVELOPPEMENT.md b/docs/DEVELOPPEMENT.md index c884218..cfa80c2 100644 --- a/docs/DEVELOPPEMENT.md +++ b/docs/DEVELOPPEMENT.md @@ -64,6 +64,7 @@ Fonctionnalités v1 : | 5 sept. 2026 (session tests/docs) | Correction de toutes les erreurs de compilation (dont 3 vrais bugs logiciels trouvés par les tests), **24 tests unitaires verts**, APK debug généré (18 MB), documentation complète (README + docs/), préparation repo git. | | 5 sept. 2026 (session v1.1.0) | Bugs remontés par l'utilisatrice : courbes vides (casse EEn) + pas d'édition des doses → corrigés ; régression épinglée sur ses données réelles ; APK v1.1.0. | | 5 sept. 2026 (session v1.2.0) | **Repo git initialisé** (commits par couche + tags de release) ; montée toolchain AGP 9.4/Gradle 9.7.1/Kotlin 2.3.21/BOM 2026.08.00/compileSdk 37 ; panoramique du chart, superposition des deux modèles, prévision par « Fréquence », calibration automatique optionnelle, intervalles entre doses, TimePicker centré ; **36 tests verts**, APK v1.2.0 (23 MB). | +| 5 sept. 2026 (session v1.2.5) | Bug graphique : double espace en haut (double insets) → **edge-to-edge propre** (`enableEdgeToEdge` + insets consommés une seule fois) ; 62 tests verts, APK v1.2.5 + release. | | 5 sept. 2026 (session v1.2.4) | Bug `isActive` (simulation effacée) → sémantique « drapeau administratif » (§6.bis) ; régression n°3 sur le 3ᵉ export réel (transition EV inactif → EEn actif, 38 doses, 22 labs) ; **62 tests verts**, APK v1.2.4. | | 5 sept. 2026 (session push Gitea + v1.2.3) | Push initial vers **gitea.cloudyfy.fr/Siphonight/HormoneTrack** (privé) après **anonymisation de l'historique** (filter-branch : les premiers commits embarquaient les valeurs réelles des tests) ; **données de test réelles déplacées hors dépôt** (`local-test-data/` gitignoré, tests `Assume`-skippés) ; **releases avec APK en pièce jointe** ; pics/creux + calibration T par période d'ester ; **56 tests verts**. | | 5 sept. 2026 (session v1.2.1) | Remontées UX/utilisateur : calibration **par période d'ester** (labs EV → doses EV, labs EEn → doses EEn — corrige les courbes gonflées), lab T "pg/mL" neutralisé, **édition des labs**, tap accueil → Graphiques + mini-légende, auto-cal fusionnée (E2+T, un seul switch) ; 2ᵉ régression épinglée sur le nouvel export ; **44 tests verts**, APK v1.2.1. | @@ -483,6 +484,12 @@ Sur la montre : remontée par Gadgetbridge **ou** Huawei Health (cf §17). - Composants : `CurveChart` (§11), `DateTimeField` (DatePicker+TimePicker Material3, LocalDateTime, **horloge centrée**), `DoseDialog` (create/edit + override d'ester), `LabDialog`, `formatDose()` (top-level, dans `DoseDialog.kt`) +- **Insets edge-to-edge (v1.2.5)** : `enableEdgeToEdge()` dans MainActivity ; + les insets sont consommés UNE FOIS — TopAppBar M3 (barre de statut, insets + par défaut) et NavigationBar (barre système) ; les `Scaffold` (racine + HormoneTrackRoot + imbriqués Doses/Labs) ont `contentWindowInsets = 0` pour + ne pas cumuler. Avant : fenêtre AppCompat + padding interne TopAppBar = + double espace vide en haut. - Thème M3 custom (`ui/theme/Color.kt` : bleu #4F5BD5, rose #D6589E, labs orange, bandeau TransSky/TransPink), dynamic color désactivé ; `MaterialExpressiveTheme` encore **internal** dans la ligne material3 pinnée (cf §3) → `MaterialTheme` standard @@ -616,6 +623,10 @@ Historique complet — **à ne pas réintroduire** (utile pour diff/revert) : titre `[1.2.3]` : l'extraction cherchait `[vX.Y.Z]` → fallback silencieux. → `scripts/gitea-release.py` (corps = section CHANGELOG, APK attaché). +33. **Double insets edge-to-edge** (v1.2.5) : espace vide en haut de l'écran — + la fenêtre AppCompat poussait le contenu sous la barre de statut ET les + TopAppBar M3 rajoutaient leur padding interne. → `enableEdgeToEdge()` + + `contentWindowInsets = 0` sur les Scaffold, insets consommés une seule fois. 32. **`isActive` traité comme filtre de données** (v1.2.4) : passer un traitement à inactif effaçait sa simulation du graphique (écrans collectaient `activeTreatments`) tout en permettant d'y loger des doses. @@ -819,4 +830,4 @@ Sur le téléphone de test (à compléter par l'utilisatrice) : sur le graphique** et la calibration couvre toujours ses périodes --- -*Doc mise à jour le 5 sept. 2026 (v1.2.4) — build OK, 62/62 tests verts (44 sans les données locales), dépôt Gitea privé + releases APK, aucune donnée de santé dans le dépôt ni l'historique.* +*Doc mise à jour le 5 sept. 2026 (v1.2.5) — build OK, 62/62 tests verts (44 sans les données locales), dépôt Gitea privé + releases APK, aucune donnée de santé dans le dépôt ni l'historique.*