Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions rhythm_coach/lib/controllers/session_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,13 @@ class SessionController extends ChangeNotifier {
/// post-fail est inutile.
static const double _breathSkipStaminaThreshold = 60.0;

/// Intervalle minimal (s) entre deux ordres énoncés pendant un break
/// scénarisé (issue #77). ~1 ordre toutes les 25 s sur une pause de 60-120 s.
static const int _breakOrderIntervalSeconds = 25;
/// Intervalle aléatoire borné (s) entre deux ordres énoncés pendant un break
/// scénarisé (issue #77). Tiré dans [min, max] après chaque ordre (et à
/// l'entrée) plutôt que fixe — une cadence régulière sonne mécanique, un peu
/// d'irrégularité est plus naturel (cf. variété des cycles de séance). ~1
/// ordre toutes les ~25 s en moyenne sur une pause de 60-120 s.
static const int _breakOrderMinIntervalSeconds = 18;
static const int _breakOrderMaxIntervalSeconds = 32;

final Stopwatch _stopwatch = Stopwatch();

Expand Down Expand Up @@ -404,9 +408,14 @@ class SessionController extends ChangeNotifier {
int _nextBreakIndex = 0;

/// `elapsedSeconds` du dernier ordre de break énoncé. Sert à espacer les
/// ordres (`_breakOrderIntervalSeconds`).
/// ordres.
int _breakOrderLastAtSec = 0;

/// Intervalle courant (s) avant le prochain ordre de break, re-tiré dans
/// [`_breakOrderMinIntervalSeconds`, `_breakOrderMaxIntervalSeconds`] à
/// l'entrée du break et après chaque ordre (cadence irrégulière).
int _breakOrderInterval = _breakOrderMinIntervalSeconds;

/// Posture courante imposée (issue #77). Initialisée à
/// `session.initialPose` au `start()`, mise à jour à la reprise de chaque
/// break qui change de pose. Exposée pour l'indicateur de posture (PR5).
Expand Down
14 changes: 10 additions & 4 deletions rhythm_coach/lib/controllers/session_controller_break.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ extension BreakSequencer on SessionController {
_activeBreak = b;
_nextBreakIndex++;
_breakOrderLastAtSec = elapsedSeconds;
_breakOrderInterval = _pickBreakOrderInterval();
_disarmHoldVerifier();
unawaited(_beep.pause());
final entry = _phraseBank?.pickBreakEntry(_random);
Expand All @@ -75,17 +76,22 @@ extension BreakSequencer on SessionController {
final bank = _phraseBank;
if (bank == null) return;
final now = elapsedSeconds;
if (now - _breakOrderLastAtSec <
SessionController._breakOrderIntervalSeconds) {
return;
}
if (now - _breakOrderLastAtSec < _breakOrderInterval) return;
if (_tts.isSpeaking) return;
final order = bank.pickBreakOrder(_random);
if (order == null) return;
_breakOrderLastAtSec = now;
_breakOrderInterval = _pickBreakOrderInterval();
_speakScripted(order);
}

/// Tire un intervalle d'ordre dans [min, max] (cadence irrégulière).
int _pickBreakOrderInterval() =>
SessionController._breakOrderMinIntervalSeconds +
_random.nextInt(SessionController._breakOrderMaxIntervalSeconds -
SessionController._breakOrderMinIntervalSeconds +
1);

/// Sortie d'un break : applique la nouvelle posture, énonce la phrase de
/// changement de pose (ou de reprise neutre en récup pure), et relâche
/// `_breakActive`. Le beep n'est PAS restauré ici : `_checkSteps` (appelé
Expand Down
5 changes: 4 additions & 1 deletion rhythm_coach/lib/screens/session_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,10 @@ class _SessionScreenContentState extends State<_SessionScreenContent> {
if (_showTimer)
TimerDisplay(
elapsed: ctrl.elapsed, total: ctrl.session.duration)
else if (ctrl.hasConfig)
// Pendant un break (issue #77), on fige l'animation : l'orbe
// en mouvement = effort, ce qui contredirait la bannière
// PAUSE. Slot de même hauteur → pas de saut de layout.
else if (ctrl.hasConfig && !ctrl.breakActive)
MovementAnimation(
mode: ctrl.currentMode,
from: ctrl.currentFrom,
Expand Down
Loading