Regroupe l'état de travail en cours réalisé dans un même worktree sur plusieurs tickets/sprints (#85, #136, #145, #155-160, #162-164), mélangeant des tickets QA et inProgress. Ne constitue pas une feature terminée : commit de sauvegarde avant triage/split par ticket en branches feature/* dédiées. Exclut les dossiers d'environnement de build locaux et le heap dump parasite (.gitignore mis à jour). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
16 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| gametime-ux-watch-companion | memory note gametime-ux-watch-companion |
|
GameTime — UX interface montre synchronisée (ticket #91, UX 2026-07-25)
Conception UX d'une app compagnon Wear OS synchronisée avec l'app téléphone pour piloter une séance en cours depuis le poignet.
Références à respecter :
gametime-session-execution-timer-refactorgametime-ux-step-chaining-overridegametime-architecture-step-chaining-overridegametime-ux-score-chronogametime-online-layer-philosophy
Décision produit structurante
La montre est une surface compagnon de pilotage, pas une deuxième app autonome de séance.
- Téléphone = source de vérité de l'exécution.
- Montre = télécommande + miroir d'état.
- Toute action lancée sur la montre est une intention utilisateur envoyée au téléphone, puis confirmée par le retour d'état.
- La montre ne doit jamais exposer un modèle d'exécution différent de celui du téléphone.
Justification :
- la logique de séance, des chronos, des overrides d'étapes et du repos existe déjà côté téléphone ;
- cela évite les divergences de calcul entre deux appareils ;
- cela rend la cohérence UX compréhensible : un seul état réel, visible sur deux surfaces.
Principe de surface
Sur montre, la hiérarchie doit être radicale :
- où j'en suis : série, exercice, étape/passage si nécessaire ;
- ce qui se passe maintenant : chrono dominant ou état dominant ;
- l'action unique la plus probable ;
- les actions de contournement dans une surface secondaire.
La montre ne doit pas tenter de reproduire toute l'interface téléphone. Pas de médias, pas d'édition, pas de paramètres, pas de détails historiques.
Surfaces montre
1. État sans séance active
Écran affiché si aucune séance n'est en cours côté téléphone.
Contenu :
Aucune séance en cours
Lance une séance sur le téléphone.
CTA optionnel si le système le permet :
[Actualiser]
Règles :
- aucun contrôle d'exécution affiché ;
- pas de faux bouton
Démarrer; - si la montre n'est pas connectée au téléphone, le message devient :
Téléphone indisponible
Rouvre GameTime sur le téléphone.
2. Écran principal Séance active
Écran par défaut dès qu'une séance en cours existe. C'est la surface centrale de la feature.
Structure recommandée sur écran rond :
SÉRIE 2 / 5
Pompes tempo
Passage 1 / 3 · Étape 2 / 4
00:18
Chrono étape
Série 01:42 · Score 00:51
[Pause]
Hiérarchie d'information
L'ordre visuel doit être fixe :
SÉRIE X / Ytoujours en haut.- Nom de l'exercice sur 1 à 2 lignes max.
- Ligne contextuelle compacte :
Passage A / Bseulement si l'exercice en a ;Étape C / Dseulement si l'exercice en a ;- si les deux existent, les concaténer sur une seule ligne.
- Chrono dominant en très grand.
- Libellé du chrono dominant ou de l'état.
- Ligne compacte des autres chronos simultanés, si utile.
- Bouton principal pleine largeur.
Règle du chrono dominant
La montre ne doit afficher qu'un seul chrono en grand. Ordre de priorité UX :
Repossi un repos est en cours.Étapesi une étape temps est active ou en étatChrono suivant prêt.Score chronos'il est actif et qu'aucune étape temps n'est prioritaire.Temps de sériesi actif.- Sinon, l'état dominant remplace le chrono.
Les autres chronos actifs restent en secondaire sur une seule ligne compacte, par exemple :
Série 03:12 · Score 01:08
But : rester lisible pendant l'effort tout en respectant le modèle multi-chronos existant.
Bouton principal contextuel
Le bas de l'écran porte une seule action primaire dont le libellé dépend de l'état :
Démarrer l'exercicePauseReprendreDémarrer le chronoPasser le repos
Cette action unique est le raccourci du cas d'usage le plus probable à cet instant.
3. Écran Actions
Surface secondaire accessible depuis Séance active par swipe horizontal ou tap sur un affordance discret Actions.
Cette surface contient les actions moins fréquentes, sous forme de gros boutons verticaux scrollables.
Ordre des actions :
[Passer l'étape] // seulement si applicable
[Passer le passage] // seulement si applicable
[Terminer la série]
[Passer la série]
[Passer le repos] // seulement pendant le repos
Règles :
- n'afficher que les actions réellement applicables à l'état courant ;
- ne pas afficher d'action impossible ou déjà satisfaite ;
- pendant un chrono en cours,
Passer la sériedoit demander une confirmation ; - pendant un repos,
Terminer la sériedisparaît car la série est déjà terminée.
Confirmations montre
Deux confirmations seulement, pour éviter les erreurs grossières pendant l'effort :
-
Passer la série ?Le chrono en cours sera ignoré.[Annuler] [Passer] -
Passer le passage ?L'étape en cours sera ignorée.[Annuler] [Passer]
Passer l'étape peut être immédiat : coût faible, fréquence plus élevée.
4. Écran Repos
Quand le repos est en cours, l'écran principal change de nature et devient un écran repos, pas un simple bandeau.
Structure :
REPOS
Après série 2 / 5
00:37
Repos en cours
Exercice suivant
Fentes sautées
[Pause]
Actions secondaires sur l'écran Actions :
[Passer le repos]
Si le repos est en pause :
REPOS
00:37
Repos en pause
[Reprendre]
États à couvrir
1. Séance pas encore lancée / début de série
Cas : la série existe, mais aucun chrono qui démarre au début de série n'a encore été lancé.
Affichage :
SÉRIE 1 / 4
Burpees
Étape 1 / 3
00:20
Prêt à démarrer
[Démarrer l'exercice]
Règle obligatoire :
- si l'exercice est sous chrono et que la première étape est une étape
Temps, le bouton reste unique :
[Démarrer l'exercice]
Cette action démarre à la fois :
- le timer de série si
timeEnabled; - le chrono de la première étape ;
- le score chrono si
scoreInputMode == stopwatch.
La montre ne doit jamais afficher deux boutons concurrents du type Démarrer l'exercice et Démarrer l'étape.
2. Chrono running
Cas nominal pendant l'effort.
Affichage :
- chrono dominant animé visuellement ;
- libellé
En coursou libellé du chrono (Chrono étape,Score chrono,Temps de série) ; - bouton principal
Pause.
Effet du bouton :
- met la séance en pause ;
- la pause suspend tous les chronos running, y compris le repos.
3. Séance en pause
Affichage :
SÉRIE 2 / 5
Pompes tempo
00:18
Séance en pause
[Reprendre]
Règles :
- l'état doit être explicite ;
- aucun chrono ne doit sembler continuer ;
- si l'utilisateur reprend depuis le téléphone, la montre revient automatiquement à l'état running.
4. Chrono suivant prêt
Cas imposé par autoStartNextTimedStep = false après une étape temps suivie d'une autre étape temps.
Affichage :
SÉRIE 2 / 5
Pompes tempo
Passage 1 / 3 · Étape 3 / 4
00:15
Chrono suivant prêt
[Démarrer le chrono]
Règles :
- ne pas réutiliser
Démarrer l'exercice; - ne pas auto-démarrer ;
- conserver l'état après pause/reprise ;
- l'écran doit rendre évident qu'on est déjà avancé dans la séquence, mais en attente d'un lancement manuel.
5. Entre les séries
Deux cas distincts :
- repos configuré et lancé ;
- pas de repos en cours, prochaine série prête.
Si pas de repos :
SÉRIE 3 / 5
Pompes tempo
Prêt pour la série suivante
[Démarrer l'exercice]
L'utilisateur comprend qu'il redémarre une nouvelle série, pas la séance depuis zéro.
6. Repos running / repos en pause
Voir surface Repos.
Le repos doit être traité comme un état de premier rang, car c'est souvent le seul moment où l'utilisateur regarde la montre entre deux séries.
7. Pas de séance active
Voir surface État sans séance active.
8. Téléphone temporairement indisponible
Cas spécifique à la cohabitation téléphone/montre.
La montre peut afficher le dernier état connu, mais il doit être clairement marqué comme potentiellement obsolète :
Connexion perdue
Dernier état reçu il y a quelques secondes
[Réessayer]
Règles :
- désactiver les actions de pilotage tant que la connexion n'est pas rétablie ;
- ne pas laisser croire qu'un tap local a réellement modifié la séance sans confirmation ;
- au retour de connexion, la montre remplace entièrement son affichage par l'état confirmé du téléphone.
Mapping des contrôles
Gestes retenus
- Tap sur le bouton principal : action primaire contextuelle.
- Swipe horizontal : bascule entre
Séance activeetActions. - Scroll vertical / couronne : parcours des actions si la liste dépasse.
- Bouton système / retour système : navigation système uniquement.
Décision UX : ne pas attribuer de commande métier obligatoire à un bouton physique matériel. Les montres Wear OS n'offrent pas toutes la même ergonomie matérielle.
Mapping détaillé
Sur Séance active
-
Démarrer l'exercice- déclenche tous les chronos de début de série applicables ;
- couvre explicitement le cas exercice chrono + première étape chrono.
-
Pause- met la séance en pause ;
- suspend série, étape, score chrono, repos.
-
Reprendre- reprend exactement l'état suspendu.
-
Démarrer le chrono- démarre l'étape temps prête après un enchaînement manuel.
-
Passer le repos- raccourci contextuel possible si UX test montre que c'est plus utile que
Pausependant le repos ; - sinon garder
Pauseen primaire et déplacerPasser le reposdansActions.
- raccourci contextuel possible si UX test montre que c'est plus utile que
Décision recommandée pour v1 :
- pendant le repos, bouton principal =
Pause, pour garder la cohérence avec le reste de la séance ; Passer le reposreste en action secondaire.
Sur Actions
-
Passer l'étape- disponible seulement si une étape courante existe.
-
Passer le passage- disponible seulement si l'exercice a plusieurs passages/séquences et si le passage courant n'est pas déjà terminé.
-
Terminer la série- finalise la série et arrête/enregistre les chronos actifs selon les règles existantes.
-
Passer la série- ignore la série courante avec confirmation si un chrono ou une séquence est en cours.
-
Passer le repos- disponible seulement si repos en cours.
Cohérence téléphone ↔ montre
Source de vérité
Décision UX ferme :
- l'état autoritaire de séance vit sur le téléphone ;
- la montre affiche une projection compacte de cet état ;
- la montre n'invente jamais un état final seule.
Modèle d'interaction
Cycle UX attendu pour une action montre :
- l'utilisateur tape sur la montre ;
- la montre passe brièvement le bouton en état
Envoi...; - le téléphone applique la commande ;
- la montre reçoit l'état confirmé et remplace l'affichage.
Si l'état confirmé diffère de l'intention initiale parce que le téléphone a déjà changé entre-temps, c'est le dernier état confirmé qui gagne visuellement.
Exemple :
- l'utilisateur tape
Pausesur la montre ; - presque au même moment, il a déjà repris sur le téléphone ;
- la montre ne doit pas essayer de "corriger" localement ; elle se recale sur le dernier snapshot confirmé.
Règle de conflit UX
En cas d'actions quasi simultanées téléphone/montre :
- le système applique un ordre réel côté source de vérité ;
- la montre n'affiche jamais un dialogue de conflit ;
- elle se contente d'afficher le résultat réel le plus récent.
Autrement dit : pas de résolution de conflit visible par l'utilisateur, seulement un réalignement rapide de l'UI.
Règle de latence
La montre doit distinguer trois cas UX :
-
latence courte
- simple état
Envoi...sur le bouton.
- simple état
-
latence perceptible
- texte discret
En attente du téléphone.
- texte discret
-
absence de réponse
- état
Connexion perdueet actions désactivées.
- état
Les seuils temporels exacts sont laissés à Architect, mais la surface doit prévoir ces trois états distincts.
Signaux sonores et haptiques
Principe
Pour respecter #92, la montre doit privilégier l'haptique. L'audio montre n'est pas requis pour le MVP.
Décisions UX :
- par défaut, pas de son obligatoire côté montre ;
- retour principal = vibration ;
- si un son est ajouté plus tard, il doit être bref, non intrusif, et ne jamais prendre le focus audio au détriment de la musique de fond.
Patterns recommandés
- démarrage/pause/reprise confirmé : impulsion courte ;
- fin d'un chrono ou fin de repos : double impulsion ;
- état
Chrono suivant prêt: double impulsion au moment où l'état est atteint, puis silence ; - perte de connexion après action utilisateur : impulsion lourde unique optionnelle.
Règles :
- pas de bip de décompte 3-2-1 imposé sur la montre au MVP ;
- pas de répétition haptique continue ;
- éviter la duplication agressive téléphone + montre sur le même événement.
Exigences de donnée pour Architect
La montre a besoin d'un view model compact, orienté exécution, pas de tout le snapshot séance brut.
Minimum UX requis :
- présence ou absence d'une séance active ;
- statut de connexion téléphone↔montre ;
seriesIndex,seriesTotal;exerciseName;- contexte séquence :
sequenceIndex?,sequenceTotal?stepIndex?,stepTotal?stepName?
- type et valeur du chrono dominant ;
- liste compacte des autres chronos actifs visibles ;
- état global :
readyrunningpausednextTimerReadyrestRunningrestPausednoActiveSessionphoneUnavailable
- libellé de l'action primaire autorisée ;
- liste des actions secondaires autorisées ;
- indicateur
commandPending.
Hypothèses techniques laissées à Architect
Points explicitement non tranchés par UX, à valider techniquement :
- faisabilité et coût d'une app Wear OS Flutter dédiée ou module compagnon séparé ;
- capacité à exposer côté téléphone un flux d'état d'exécution suffisamment compact et fréquent pour la montre ;
- stratégie de mise à jour du chrono affiché sur la montre :
- push fréquent depuis le téléphone ;
- ou interpolation locale à partir d'horodatages autoritaires ;
- transport exact téléphone↔montre et garanties d'acknowledgement pour les commandes ;
- comportement si le téléphone est verrouillé, en arrière-plan, ou si le process principal est suspendu ;
- possibilité de déclencher des vibrations montre sans prise de focus audio ;
- capacité à rendre idempotentes les commandes utilisateur (
pause,resume,skipStep,finishSet, etc.) ; - découpage des use cases côté téléphone pour exposer uniquement les commandes compatibles montre ;
- gestion exacte des timeouts et des seuils de latence visibles dans l'UI ;
- politique de duplication ou non des signaux entre téléphone et montre sur un même événement.
Synthèse décisionnelle pour la suite
La montre doit rester une surface extrêmement simple :
- un écran principal
Séance active; - un écran secondaire
Actions; - un écran dédié
Reposquand le repos est l'état dominant ; - des états explicites pour pause,
Chrono suivant prêt, absence de séance et perte de connexion ; - une seule action primaire contextuelle à la fois ;
- téléphone autoritaire, montre suiveuse interactive.
Cette forme couvre l'objectif utilisateur réel : piloter entièrement la séance sans sortir le téléphone, tout en conservant la logique d'exécution déjà stabilisée dans GameTime.