feat(online): partage sortant et boîte de réception (ticket #69)
Ajoute l'écran de partage sortant (presentation/share_screen.dart) et la boîte de réception des partages (presentation/share_inbox_screen.dart), avec les points d'entrée sur profile_screen.dart, home_screen.dart, program_screen.dart et workout_template_screen.dart. flutter analyze propre (mêmes infos préexistantes), 132/132 tests verts, build APK debug validé. Dernier ticket de développement du chantier "Ajouter les features serveur au client" (#63) — il ne reste que la QA finale (#70). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -5,16 +5,23 @@ import 'package:flutter/material.dart';
|
||||
import '../application/application.dart';
|
||||
import '../domain/domain.dart';
|
||||
import 'exercise_library_screen.dart';
|
||||
import 'share_screen.dart';
|
||||
|
||||
final class ProgramListScreen extends StatefulWidget {
|
||||
const ProgramListScreen({
|
||||
required this.programUseCases,
|
||||
required this.exerciseUseCases,
|
||||
this.shareUseCases,
|
||||
this.authUseCases,
|
||||
this.syncUseCases,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final ProgramUseCases programUseCases;
|
||||
final ExerciseUseCases exerciseUseCases;
|
||||
final ShareUseCases? shareUseCases;
|
||||
final AuthUseCases? authUseCases;
|
||||
final SyncUseCases? syncUseCases;
|
||||
|
||||
@override
|
||||
State<ProgramListScreen> createState() => _ProgramListScreenState();
|
||||
@ -101,6 +108,9 @@ final class _ProgramListScreenState extends State<ProgramListScreen> {
|
||||
builder: (context) => ProgramFormScreen(
|
||||
programUseCases: widget.programUseCases,
|
||||
exerciseUseCases: widget.exerciseUseCases,
|
||||
shareUseCases: widget.shareUseCases,
|
||||
authUseCases: widget.authUseCases,
|
||||
syncUseCases: widget.syncUseCases,
|
||||
program: program,
|
||||
),
|
||||
),
|
||||
@ -161,12 +171,18 @@ final class ProgramFormScreen extends StatefulWidget {
|
||||
const ProgramFormScreen({
|
||||
required this.programUseCases,
|
||||
required this.exerciseUseCases,
|
||||
this.shareUseCases,
|
||||
this.authUseCases,
|
||||
this.syncUseCases,
|
||||
this.program,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final ProgramUseCases programUseCases;
|
||||
final ExerciseUseCases exerciseUseCases;
|
||||
final ShareUseCases? shareUseCases;
|
||||
final AuthUseCases? authUseCases;
|
||||
final SyncUseCases? syncUseCases;
|
||||
final Program? program;
|
||||
|
||||
@override
|
||||
@ -216,6 +232,14 @@ final class _ProgramFormScreenState extends State<ProgramFormScreen> {
|
||||
title: Text(
|
||||
_isEditing ? 'Modifier le programme' : 'Créer un programme',
|
||||
),
|
||||
actions: [
|
||||
if (_isEditing && widget.shareUseCases != null)
|
||||
IconButton(
|
||||
tooltip: 'Partager',
|
||||
icon: const Icon(Icons.ios_share),
|
||||
onPressed: _shareProgram,
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: SafeArea(
|
||||
minimum: const EdgeInsets.all(16),
|
||||
@ -395,6 +419,25 @@ final class _ProgramFormScreenState extends State<ProgramFormScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _shareProgram() async {
|
||||
final program = widget.program;
|
||||
final shareUseCases = widget.shareUseCases;
|
||||
if (program == null || shareUseCases == null) return;
|
||||
await Navigator.of(context).push<void>(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ShareFormScreen(
|
||||
shareUseCases: shareUseCases,
|
||||
authUseCases: widget.authUseCases,
|
||||
syncUseCases: widget.syncUseCases,
|
||||
resourceType: ShareResourceType.program,
|
||||
localResourceId: program.metadata.id,
|
||||
resourceName: program.name,
|
||||
resourceSummary: _programSummary(program),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String? _nonNegativeIntValidator(String? value) {
|
||||
final number = int.tryParse(value?.trim() ?? '');
|
||||
if (number == null || number < 0) {
|
||||
|
||||
Reference in New Issue
Block a user