fix(watch): finalise correctif sync workoutHistory/exercise et distance live montre (#157)

This commit is contained in:
2026-07-29 11:22:17 +02:00
parent 6f913e4e8d
commit 30c6259748
28 changed files with 1658 additions and 248 deletions

View File

@ -2570,6 +2570,10 @@ final class _StepSequencePanel extends StatelessWidget {
);
}
final currentStep = view.currentStep;
final currentStepIsRepsOnly =
currentStep != null &&
currentStep.type == ExerciseStepType.reps &&
!currentStep.hasScore;
final sequenceComplete =
view.state.status == ActiveExerciseStepProgressStatus.sequenceComplete;
final completedPassages = sequenceComplete
@ -2596,20 +2600,13 @@ final class _StepSequencePanel extends StatelessWidget {
],
),
const SizedBox(height: 6),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
for (var index = 0; index < view.steps.length; index++) ...[
_StepProgressChip(
index: index,
status: _stepDisplayStatus(view, index),
),
if (index < view.steps.length - 1) const SizedBox(width: 6),
],
],
if (currentStepIsRepsOnly)
Row(children: _stepProgressChips(view))
else
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(children: _stepProgressChips(view)),
),
),
const SizedBox(height: 8),
Expanded(
child: sequenceComplete || currentStep == null
@ -2645,6 +2642,15 @@ final class _StepSequencePanel extends StatelessWidget {
enum _StepSkipAction { passage, sequence }
List<Widget> _stepProgressChips(ActiveExerciseStepProgressView view) {
return [
for (var index = 0; index < view.steps.length; index++) ...[
_StepProgressChip(index: index, status: _stepDisplayStatus(view, index)),
if (index < view.steps.length - 1) const SizedBox(width: 6),
],
];
}
final class _BoundedAccentPanel extends StatelessWidget {
const _BoundedAccentPanel({required this.child, required this.padding});
@ -2802,96 +2808,96 @@ final class _CurrentStepPane extends StatelessWidget {
],
);
}
return SingleChildScrollView(
padding: const EdgeInsets.only(bottom: 8),
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
step.name,
style: Theme.of(context).textTheme.headlineSmall,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
Expanded(
child: step.type == ExerciseStepType.time
? _TimedStepBody(
step: step,
remainingLabel: remainingLabel,
running:
view.state.status ==
ActiveExerciseStepProgressStatus.runningTimer,
readyToStart: _isNextTimedStepReady(view),
onStartTimer: onStartTimer,
)
: Align(
alignment: Alignment.topCenter,
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.topCenter,
child: _RepsStepBody(
step: step,
onCompleteStep: onCompleteStep,
),
),
),
),
if (step.hasScore) ...[
const SizedBox(height: 8),
_StepScoreInput(
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
step.name,
style: Theme.of(context).textTheme.headlineSmall,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
Expanded(
child: step.type == ExerciseStepType.time
? _TimedStepBody(
step: step,
controller: stepScoreController,
elapsedLabel: stepScoreElapsedLabel,
running: stepScoreRunning,
onStart: onStartStepScore,
onStop: onStopStepScore,
onReset: onResetStepScore,
remainingLabel: remainingLabel,
running:
view.state.status ==
ActiveExerciseStepProgressStatus.runningTimer,
readyToStart: _isNextTimedStepReady(view),
onStartTimer: onStartTimer,
)
: Center(
child: FittedBox(
fit: BoxFit.scaleDown,
child: _RepsStepBody(step: step),
),
),
),
if (step.hasScore) ...[
const SizedBox(height: 8),
_StepScoreInput(
step: step,
controller: stepScoreController,
elapsedLabel: stepScoreElapsedLabel,
running: stepScoreRunning,
onStart: onStartStepScore,
onStop: onStopStepScore,
onReset: onResetStepScore,
),
],
const SizedBox(height: 4),
Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: onSkipStep,
style: OutlinedButton.styleFrom(
minimumSize: const Size.fromHeight(44),
),
child: const Text('Passer létape'),
),
),
const SizedBox(width: 8),
PopupMenuButton<_StepSkipAction>(
tooltip: 'Plus dactions',
icon: const Icon(Icons.more_horiz),
onSelected: (action) {
if (action == _StepSkipAction.passage) {
onSkipPassage();
} else {
onSkipSequence();
}
},
itemBuilder: (context) => const [
PopupMenuItem(
value: _StepSkipAction.passage,
child: Text('Passer ce passage'),
),
PopupMenuItem(
value: _StepSkipAction.sequence,
child: Text('Passer la séquence'),
),
],
const SizedBox(height: 4),
Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: onSkipStep,
style: OutlinedButton.styleFrom(
minimumSize: const Size.fromHeight(44),
),
child: const Text('Passer létape'),
),
),
if (step.type == ExerciseStepType.reps) ...[
const SizedBox(width: 8),
Expanded(
child: FilledButton.icon(
onPressed: onCompleteStep,
style: FilledButton.styleFrom(
minimumSize: const Size.fromHeight(44),
),
const SizedBox(width: 8),
PopupMenuButton<_StepSkipAction>(
tooltip: 'Plus dactions',
icon: const Icon(Icons.more_horiz),
onSelected: (action) {
if (action == _StepSkipAction.passage) {
onSkipPassage();
} else {
onSkipSequence();
}
},
itemBuilder: (context) => const [
PopupMenuItem(
value: _StepSkipAction.passage,
child: Text('Passer ce passage'),
),
PopupMenuItem(
value: _StepSkipAction.sequence,
child: Text('Passer la séquence'),
),
],
),
],
icon: const Icon(Icons.check),
label: const Text('Étape suivante'),
),
),
],
),
],
),
),
],
);
},
);
@ -3241,10 +3247,9 @@ bool _isNextTimedStepReady(ActiveExerciseStepProgressView view) {
}
final class _RepsStepBody extends StatelessWidget {
const _RepsStepBody({required this.step, required this.onCompleteStep});
const _RepsStepBody({required this.step});
final ExerciseStep step;
final VoidCallback onCompleteStep;
@override
Widget build(BuildContext context) {
@ -3257,12 +3262,6 @@ final class _RepsStepBody extends StatelessWidget {
).copyWith(color: Theme.of(context).colorScheme.primary),
),
Text('RÉPÉTITIONS', style: Theme.of(context).textTheme.labelLarge),
const SizedBox(height: 12),
FilledButton.icon(
onPressed: onCompleteStep,
icon: const Icon(Icons.check),
label: const Text('Étape suivante'),
),
],
);
}