feat(énergie): la vue Mois est le mois civil
Patrick, 2026-10-16 : le titre disait « oct. 2026 » au-dessus d'une vue des 30 derniers jours (17/9 → 16/10). L'onglet Mois prend désormais le mois civil du jour choisi, du 1er au dernier jour — barres, tuiles du bilan et titre disent la même chose. Les flèches avancent d'un MOIS (et non de 30 jours : le 31 janvier menait au 2 mars) ; revenir sur le mois en cours reprend le suivi d'aujourd'hui. Vu sur le téléphone (oct. 2026, sept. 2026). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e562fb5bf5
commit
4da904fc7a
@ -137,10 +137,16 @@ class _Tab {
|
||||
/// les N dernières heures. C'est ce que « Jour » promet, et ce qu'il ne faisait pas.
|
||||
final bool journeeCivile;
|
||||
|
||||
/// Vrai si la plage est le **mois civil** du jour choisi (du 1er au dernier jour), et non
|
||||
/// les 30 derniers jours (Patrick, 2026-10-16 : le titre disait « oct. 2026 » au-dessus
|
||||
/// d'une vue du 17/9 au 16/10).
|
||||
final bool moisCivil;
|
||||
|
||||
const _Tab(this.label, this.range, this.sampleRate,
|
||||
{required this.showTime,
|
||||
this.rendu = _Rendu.courbes,
|
||||
this.journeeCivile = false});
|
||||
this.journeeCivile = false,
|
||||
this.moisCivil = false});
|
||||
}
|
||||
|
||||
class EnergyScreen extends StatefulWidget {
|
||||
@ -163,7 +169,7 @@ class _EnergyScreenState extends State<EnergyScreen> {
|
||||
showTime: true, rendu: _Rendu.barres, journeeCivile: true),
|
||||
_Tab('Semaine', Duration(days: 7), 'SampleRate1Day',
|
||||
showTime: false, rendu: _Rendu.barres),
|
||||
_Tab('Mois', Duration(days: 30), 'SampleRate1Day',
|
||||
_Tab('Mois', Duration(days: 30), 'SampleRate1Day', moisCivil: true,
|
||||
showTime: false, rendu: _Rendu.barres),
|
||||
_Tab('Année', Duration(days: 365), 'SampleRate1Month',
|
||||
showTime: false, rendu: _Rendu.barres),
|
||||
@ -424,6 +430,10 @@ class _EnergyScreenState extends State<EnergyScreen> {
|
||||
/// que l'onglet promet. Les autres restent glissantes à partir de maintenant.
|
||||
(DateTime, DateTime) _fenetreRequete(_Tab tab) {
|
||||
final ancre = _anchorDate();
|
||||
if (tab.moisCivil) {
|
||||
final debut = DateTime(ancre.year, ancre.month, 1);
|
||||
return (debut.subtract(_pasEchantillon(tab)), DateTime(ancre.year, ancre.month + 1, 1));
|
||||
}
|
||||
// 🔴 **Toutes les vues en barres se calent sur minuit**, pas seulement « Jour ».
|
||||
//
|
||||
// Sans ça, une plage de 7 jours partant de 08:12 coupe deux journées en deux : le
|
||||
@ -461,6 +471,13 @@ class _EnergyScreenState extends State<EnergyScreen> {
|
||||
final a = _anchorDate();
|
||||
final maintenant = DateTime.now();
|
||||
final jourSeul = tab.label == 'Heures' || tab.journeeCivile;
|
||||
if (tab.moisCivil) {
|
||||
final finMois = DateTime(a.year, a.month + 1, 1);
|
||||
return (
|
||||
DateTime(a.year, a.month, 1),
|
||||
finMois.isAfter(maintenant) ? maintenant : finMois,
|
||||
);
|
||||
}
|
||||
final finJour = DateTime(a.year, a.month, a.day + 1);
|
||||
final debut = jourSeul
|
||||
? DateTime(a.year, a.month, a.day)
|
||||
@ -526,19 +543,30 @@ class _EnergyScreenState extends State<EnergyScreen> {
|
||||
///
|
||||
/// Sans cette borne, on part dans un futur où la box n'a rien : un graphe vide qui ne
|
||||
/// dit pas qu'il est vide **parce qu'on est allé trop loin**.
|
||||
bool _peutAvancer() =>
|
||||
_selectedDate != null &&
|
||||
_anchorDate().add(_tabs[_tabIdx].range).isBefore(DateTime.now());
|
||||
bool _peutAvancer() {
|
||||
if (_selectedDate == null) return false;
|
||||
final tab = _tabs[_tabIdx];
|
||||
final a = _anchorDate();
|
||||
if (tab.moisCivil) return !DateTime(a.year, a.month + 1, 1).isAfter(DateTime.now());
|
||||
return a.add(tab.range).isBefore(DateTime.now());
|
||||
}
|
||||
|
||||
void _decalerPeriode(int sens) {
|
||||
final tab = _tabs[_tabIdx];
|
||||
final base = _selectedDate ?? DateTime.now();
|
||||
final cible = base.add(tab.range * sens);
|
||||
// Mois civil : on avance d'UN mois, pas de 30 jours — sinon le 31 janvier mènerait au
|
||||
// 2 mars. Le 1er du mois visé suffit d'ancre : la vue prend le mois entier.
|
||||
final cible = tab.moisCivil
|
||||
? DateTime(base.year, base.month + sens, 1)
|
||||
: base.add(tab.range * sens);
|
||||
setState(() {
|
||||
// Revenir sur aujourd'hui remet le mode « suivi », où la fenêtre se recale à chaque
|
||||
// lecture. Rester sur une date figée l'aurait gelée sans le dire.
|
||||
final maintenant = DateTime.now();
|
||||
_selectedDate = cible.isAfter(maintenant) ? null : cible;
|
||||
final moisCourant = tab.moisCivil &&
|
||||
cible.year == maintenant.year &&
|
||||
cible.month == maintenant.month;
|
||||
_selectedDate = cible.isAfter(maintenant) || moisCourant ? null : cible;
|
||||
_initialSocFetched = false;
|
||||
});
|
||||
_fetch();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user