Skip to content

fix(voix): corrige le freeze iOS au premier usage du micro - #64

Merged
isc merged 2 commits into
mainfrom
claude/peaceful-turing-qei0a9
Jun 13, 2026
Merged

fix(voix): corrige le freeze iOS au premier usage du micro#64
isc merged 2 commits into
mainfrom
claude/peaceful-turing-qei0a9

Conversation

@isc

@isc isc commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Contexte

Signalé en test utilisateur sur deux appareils iOS (iPhone + iPad) : au tout premier usage du micro (clic sur « Utiliser le micro » en cours de séance), le prompt d'autorisation iOS s'affiche, est accordé, puis toute l'interface se fige — micro inactif, UI non réactive, obligation de force-quitter l'appli. Au 2ᵉ lancement, tout fonctionne.

Cause racine

Sur iOS, au tout premier octroi de permission, WebKit termine parfois la reconnaissance immédiatement (onend) sans jamais émettre onstart ni résultat. Or useSpeechRecognition redémarre dans onend pour garder le micro ouvert toute la séance (choix volontaire : éviter le « ding » système iOS à chaque start/stop). Sans garde-fou, on obtenait une boucle start→end→start→end qui saturait la boucle d'événements et figeait le thread principal.

De plus, le switch clavier → micro en cours de séance n'appelait aucun preflight de permission (contrairement au démarrage de séance en mode vocal), donc le tout premier SpeechRecognition.start() coïncidait avec le prompt natif — la situation exacte qui déclenche le glitch.

Correctif

  • useSpeechRecognition : garde-fou anti-boucle. On mesure la durée de chaque cycle ; un cycle anormalement court (< 500 ms, sans résultat) est compté comme « à vide ». Au-delà du seuil on temporise (backoff) avant de retenter, et après 5 cycles à vide consécutifs on coupe la boucle plutôt que de figer l'UI. Le chemin nominal (redémarrage entre deux questions) reste immédiat pour ne pas manquer une réponse enchaînée rapidement.
  • SessionScreen : le bouton « Utiliser le micro » pré-arme désormais la permission via preflightMicPermission() en consommant le geste du clic, comme déjà fait au démarrage de séance — ce qui évite de déclencher le glitch en premier lieu.
  • Test de non-régression simulant le glitch iOS (cycles qui se terminent aussitôt) et vérifiant que les start() sont plafonnés.

Validation

  • tsc -b
  • npm test — 174 tests ✅ (dont le nouveau)
  • npm run lint

Pas de changelog

Glitch iOS du tout premier octroi de permission, invisible une fois corrigé (et qui se résolvait déjà au 2ᵉ lancement) : sous le seuil de la page « Nouveautés ».

https://claude.ai/code/session_01RaEog9SSJeZJZA63kYoyD9


Generated by Claude Code

Sur iOS, au tout premier octroi de permission, WebKit termine parfois la
reconnaissance immédiatement (onend) sans émettre onstart ni résultat. Comme
le hook redémarre dans onend pour garder le micro ouvert toute la séance, on
obtenait une boucle start→end→start→end qui saturait la boucle d'événements
et figeait toute l'UI — l'utilisateur devait force-quitter l'appli. Au 2e
lancement, la permission déjà accordée, tout fonctionnait.

- useSpeechRecognition: garde-fou anti-boucle. On détecte les cycles
  anormalement courts (terminés presque aussitôt démarrés, sans résultat),
  on temporise avant de retenter, et on coupe au bout de 5 cycles à vide
  consécutifs plutôt que de figer le thread principal.
- SessionScreen: le switch clavier → micro en cours de séance pré-arme
  désormais la permission (preflightMicPermission) en consommant le geste du
  clic, comme au démarrage de séance, pour éviter de déclencher le glitch.
- Test de non-régression du garde-fou (simule le glitch iOS).

https://claude.ai/code/session_01RaEog9SSJeZJZA63kYoyD9
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Preview supprimée (PR fermée). Les URLs ne sont plus accessibles.

- useSpeechRecognition: extrait clearRestartTimer() (dédup entre abort() et le
  cleanup d'unmount).
- test: réduit la boucle du test anti-boucle (5 cycles suffisent, 100 → 10) et
  ajoute un cas nominal couvrant le redémarrage immédiat après un cycle ayant
  réellement duré.

https://claude.ai/code/session_01RaEog9SSJeZJZA63kYoyD9
@isc
isc marked this pull request as ready for review June 13, 2026 06:26
@isc
isc merged commit 4fe9f79 into main Jun 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants