Files
GameTime/.ideai/tickets/166/carnet.md

8.4 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#166 12
kind agent_id
agent 57695b92-24d0-4876-837c-76116e70a6ae
1785311597894

#166/#167/#169 — Cadrage UX coordonné : slot "donnée dominante sans chrono" (UX, 2026-07-28)

Statut : cadrage exploitable, à traiter comme une seule mini-refonte, pas trois patchs indépendants (voir point 4). Détail complet ici sur #166, #167 et #169 pointent vers ce carnet + leur delta propre.

Base : écran Séance active déjà révisé par #161 (fermé) — un chrono/donnée dominante + un bouton d'action unique sur la même ligne, un seul libellé, FC en icône en pied d'écran. Ce lot traite les cas où il n'y a pas de chrono actif, laissés de côté par #161.

Constat commun

Quand il n'y a pas de chrono actif, l'écran retombe aujourd'hui sur des solutions par défaut peu utiles : le compteur SÉRIE X/Y se répète en donnée dominante alors qu'il est déjà affiché en en-tête (#167), aucune action rapide n'est proposée pour une étape à répétitions alors que c'est justement l'action la plus probable à cet instant (#166), et un sous-titre Prêt pour la série suivante occupe une ligne entière pour une information déjà déductible du reste de l'écran (#169).

1. Comportement attendu par ticket

#166 : sur une étape à répétitions (sans chrono), un bouton de validation/passage à l'étape suivante est visible directement sur l'écran principal — pas besoin de swiper vers Actions. Ce bouton déclenche la même commande que Étape suivante (valide l'étape, avance), pas un Passer l'étape (qui reste une action de contournement, toujours dans Actions).

#167 : sur une étape à répétitions (sans chrono), la donnée dominante centrale devient le nombre de répétitions à faire pour cette étape, et non plus le nombre de séries de l'exercice (déjà visible en en-tête SÉRIE X/Y, donc redondant).

#169 : le sous-titre Prêt pour la série suivante est supprimé, sans remplacement — l'écran (nom d'exercice + bouton Démarrer l'exercice) reste compréhensible sans lui.

2. Disposition recommandée — écran principal, cas étape reps-only

Réutilise exactement le template ligne chrono+bouton posé par #161, appliqué à la donnée reps au lieu du chrono :

SÉRIE 2 / 5
Pompes tempo
Passage 1 / 3 · Étape 2 / 4

Répétitions
  10            [✓]

♥ 132
  • Légende Répétitions une seule fois, au-dessus de la valeur — même règle que le libellé de chrono (#161).
  • Bouton icône [✓] (valider/étape suivante) à droite de la valeur, même ligne, même cible tactile ≥48dp que le bouton pause/play (#128/#161) — pas un nouveau composant, le même gabarit rejoue avec une icône différente.
  • Un seul bouton d'action visible à la fois sur cette ligne : jamais [✓] et [⏸] en même temps. Si l'étape a aussi un chrono (score chrono d'étape, cas #140), ce cas reste géré par le layout dédié _ManualScoreContent existant, non touché par ce lot.
  • Cœur FC inchangé, en pied d'écran (#161).

3. Disposition recommandée — écran Prêt pour la série suivante

SÉRIE 3 / 5
Pompes tempo


[Démarrer l'exercice]

Le sous-titre disparaît, l'espace libéré n'est pas réutilisé pour un nouvel élément (contrainte explicite : ne pas ajouter de bruit) — juste un espacement plus respirant entre le nom d'exercice et le bouton.

4. Garde-fous de lisibilité / priorité visuelle

  • Un seul élément "action" par écran, toujours à droite de la donnée dominante quand il y en a une (chrono → [⏸], reps → [✓]) — jamais empilé en dessous, jamais dupliqué ailleurs. C'est la même règle que #161, appliquée maintenant au cas reps.
  • Ne jamais afficher deux fois la même information sous deux formes (le principe qui motive #167) : si une donnée est déjà visible ailleurs sur l'écran (ex. SÉRIE X/Y en en-tête), elle n'a pas sa place une seconde fois dans le slot dominant.
  • Suppression de texte (#169) : ne jamais compenser par un ajout ailleurs sauf besoin explicite ; le vide contrôlé est préférable au bruit, conformément à la contrainte utilisateur de ce lot.
  • Icône [✓] distincte visuellement de [⏸]/[▶] pour éviter toute ambiguïté entre "valider l'étape" et "mettre en pause la séance" — même style (or sur fond #141824, anneau crimson au tap, cf. #128) mais pictogramme différent.

5. Coordination des 3 tickets

Oui, à traiter comme une seule mini-refonte cohérente, pas trois patchs séparés :

  • #166 et #167 modifient la même zone d'écran (slot donnée dominante + bouton d'action pour une étape reps-only) — les livrer séparément risquerait qu'un commit écrase la mise en page de l'autre, ou que le bouton [✓] soit ajouté sans que la redondance SÉRIE X/Y soit corrigée en même temps (ou l'inverse).
  • #169 touche un état adjacent du même écran (Séance active sans chrono actif) et applique le même principe (pas de texte qui ne porte pas d'action ni de donnée nécessaire) — le traiter isolément ferait revivre exactement la dérive de densité déjà diagnostiquée et corrigée par #161 (accumulation de correctifs isolés qui perdent la cohérence d'ensemble).
  • Recommandation : un seul lot Architect/DevFrontend pour les trois, avec cette section comme spec unique de référence.

Cadrage Architect (2026-07-28)

Statut : ticket déjà implémenté dans le code actuel, conforme au cadrage UX ci-dessus. Vérifié en lecture directe sur watch_app/lib/presentation/watch_session_screen.dart :

  • _ActiveContent.build() (~L704-788) calcule repsTarget et bascule déjà sur _DominantRepsLine quand repsTarget != null (L753-758), au lieu de la donnée SÉRIE — #167 déjà appliqué.
  • _DominantRepsLine (~L790-815) affiche la valeur reps + _CompleteStepButton sur la même ligne, gabarit SizedBox(height: 52) + Row — conforme au template ligne unique posé par #161.
  • _CompleteStepButton (~L817-844) : SizedBox.square(dimension: 48) (cible tactile 48dp respectée), icône Icons.check, couleur or #C9A24A sur fond #141824 avec liseré crimson #D72638 — conforme au style #128/#161, visuellement distinct de pause/play.
  • Câblage commande : le bouton appelle onCompleteStepWatchSessionViewModel.completeCurrentStep() (watch_session_view_model.dart:190-191) → WatchCommandType.completeCurrentStep, une commande distincte de WatchCommandType.skipCurrentStep (utilisée par Passer l'étape dans Actions) — la séparation validation/contournement exigée par le cadrage UX est bien respectée, pas de confusion de commande.
  • Libellé Répétitions déjà affiché une seule fois au-dessus de la valeur (L751, _SmallLabel(repsTarget == null ? dominantLabel : 'Répétitions')) — #167 confirmé.
  • Recherche du texte Prêt pour la série suivante dans tout le repo Dart : aucune occurrence — le sous-titre visé par #169 n'existe déjà plus.
  • Aucun double bouton [✓]/[⏸] possible : _ActiveContent.build() structure les branches repsTarget != null / timer == null / chrono en if/else if/else mutuellement exclusifs (L753-767).

Conclusion

Aucun développement restant. #166 (et vraisemblablement #167/#169 associés dans ce même carnet) sont fonctionnellement livrés dans le code présent sur la branche. Il n'y a ni contrat, ni port, ni frontière hexagonale à faire évoluer ici — pure présentation Flutter déjà en place.

Recommandation

  • Ne pas relancer de lot DevFrontend sur ce ticket : le repasser directement en validation QA sur device/émulateur Wear OS réel, avec ces points de contrôle précis :
    1. Étape reps-only sans chrono → bouton [✓] visible et fonctionnel sur l'écran principal (pas besoin de swiper vers Actions).
    2. Étape avec score chrono manuel (_ManualScoreContent) → bouton [✓] absent de ce layout dédié, pas de régression croisée.
    3. Écran Prêt pour la série suivante → absence confirmée du sous-titre, pas de nouvel élément parasite.
    4. Cible tactile et absence d'ambiguïté visuelle avec le bouton pause/play sur écran chrono.
  • Si le ticket reste "open" c'est vraisemblablement un oubli de requalification après une implémentation antérieure (probablement dans le même lot que #161/#159, cf. commit bc533d6c "lot #165-169 validé QA") plutôt qu'un travail réellement en attente. À confirmer avec Main avant clôture pure, mais aucune architecture nouvelle n'est à cadrer.