feat(exercice): affichage des médias pendant l'exécution (ticket #36)

Expose la galerie d'images d'exercice (backend du ticket #35) pendant
l'exécution de séance sur workout_execution_screen.dart et
program_screen.dart, avec les ajustements domain/use cases/repositories
nécessaires. flutter analyze propre, 67/67 tests verts, build APK
debug validé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 14:16:31 +02:00
parent 7385c96517
commit ff6b79b66e
10 changed files with 654 additions and 1 deletions

View File

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:drift/drift.dart';
import '../../application/application.dart';
@ -1208,6 +1210,9 @@ db.ProgramExercisesCompanion _programExerciseCompanion(
exerciseNameSnapshot: Value(exercise.exerciseNameSnapshot),
exerciseDescriptionSnapshot: Value(exercise.exerciseDescriptionSnapshot),
exerciseImageMediaIdSnapshot: Value(exercise.exerciseImageMediaIdSnapshot),
exerciseImageMediaIdsSnapshotJson: Value(
_encodeImageMediaIdsSnapshot(exercise.exerciseImageMediaIdsSnapshot),
),
exerciseVideoMediaIdSnapshot: Value(exercise.exerciseVideoMediaIdSnapshot),
exerciseArchivedSnapshot: Value(exercise.exerciseArchivedSnapshot),
availableTimeSnapshot: Value(exercise.availableTimeSnapshot),
@ -1239,6 +1244,10 @@ domain.ProgramExercise _programExerciseFromRow(db.ProgramExercise row) {
exerciseNameSnapshot: row.exerciseNameSnapshot,
exerciseDescriptionSnapshot: row.exerciseDescriptionSnapshot,
exerciseImageMediaIdSnapshot: row.exerciseImageMediaIdSnapshot,
exerciseImageMediaIdsSnapshot: _decodeImageMediaIdsSnapshot(
row.exerciseImageMediaIdsSnapshotJson,
row.exerciseImageMediaIdSnapshot,
),
exerciseVideoMediaIdSnapshot: row.exerciseVideoMediaIdSnapshot,
exerciseArchivedSnapshot: row.exerciseArchivedSnapshot,
availableTimeSnapshot: row.availableTimeSnapshot,
@ -1766,6 +1775,29 @@ domain.ActiveScoreStopwatchStatus _scoreStopwatchStatusFromDb(String value) =>
),
};
String? _encodeImageMediaIdsSnapshot(List<String> imageMediaIds) {
return imageMediaIds.isEmpty ? null : jsonEncode(imageMediaIds);
}
List<String> _decodeImageMediaIdsSnapshot(
String? encoded,
String? fallbackImageMediaId,
) {
if (encoded == null || encoded.trim().isEmpty) {
return [if (fallbackImageMediaId != null) fallbackImageMediaId];
}
final decoded = jsonDecode(encoded);
if (decoded is! List) {
throw const domain.DomainException(
'Invalid exercise image media ids snapshot.',
);
}
return decoded
.whereType<String>()
.where((id) => id.trim().isNotEmpty)
.toList(growable: false);
}
domain.ActiveWorkoutStatus _activeStatusFromDb(String value) => switch (value) {
'running' => domain.ActiveWorkoutStatus.running,
'paused' => domain.ActiveWorkoutStatus.paused,