feat(watch): clôture lot #91 - fréquence cardiaque live, notifications de séance et finitions montre
Consolide le lot applicatif watch companion validé : - télémétrie fréquence cardiaque live remontée montre -> téléphone (collecteur watch, adapter Wear Data Layer, persistance Drift, propagation aux écrans historique/programme/profil/exécution) - notifications de séance en arrière-plan côté téléphone (service foreground de statut + passerelle applicative) - finitions montre : chrono d'étape, score d'étape, retrait du bouton "lancer une séance", thème, icônes et polices watch_app Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -420,6 +420,7 @@ final class _ProgramFormScreenState extends State<ProgramFormScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final canSave = !_saving && _exercises.isNotEmpty;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
@ -436,15 +437,21 @@ final class _ProgramFormScreenState extends State<ProgramFormScreen> {
|
||||
),
|
||||
bottomNavigationBar: SafeArea(
|
||||
minimum: const EdgeInsets.all(16),
|
||||
child: FilledButton.icon(
|
||||
onPressed: _saving ? null : _save,
|
||||
icon: _saving
|
||||
? const SizedBox.square(
|
||||
dimension: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.check),
|
||||
label: const Text('Enregistrer'),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
FilledButton.icon(
|
||||
onPressed: canSave ? _save : null,
|
||||
icon: _saving
|
||||
? const SizedBox.square(
|
||||
dimension: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.check),
|
||||
label: const Text('Enregistrer'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
@ -495,7 +502,8 @@ final class _ProgramFormScreenState extends State<ProgramFormScreen> {
|
||||
child: _exercises.isEmpty
|
||||
? const _CenteredMessage(
|
||||
title: 'Aucun exercice ajouté',
|
||||
message: 'Ajoute un exercice depuis la bibliothèque.',
|
||||
message:
|
||||
'Ajoute au moins un exercice pour enregistrer ce programme.',
|
||||
)
|
||||
: ReorderableListView.builder(
|
||||
buildDefaultDragHandles: false,
|
||||
@ -595,6 +603,9 @@ final class _ProgramFormScreenState extends State<ProgramFormScreen> {
|
||||
}
|
||||
|
||||
Future<void> _save() async {
|
||||
if (_exercises.isEmpty) {
|
||||
return;
|
||||
}
|
||||
if (!_formKey.currentState!.validate()) {
|
||||
return;
|
||||
}
|
||||
@ -1402,7 +1413,7 @@ final class _CenteredMessage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
||||
Reference in New Issue
Block a user