feat(ui): écran Composition de séance-modèle
Ajoute l'écran de composition de séance-modèle (presentation/workout_template_screen.dart), avec les ajustements application/domaine/repositories nécessaires et la navigation depuis l'accueil. flutter analyze propre, 12/12 tests verts, build APK debug validé. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -191,21 +191,33 @@ final class DriftWorkoutTemplateRepository
|
||||
|
||||
@override
|
||||
Future<domain.WorkoutTemplate?> findById(String id) async {
|
||||
final row = await (database.select(
|
||||
database.workoutTemplates,
|
||||
)..where((table) => table.id.equals(id))).getSingleOrNull();
|
||||
final row =
|
||||
await (database.select(
|
||||
database.workoutTemplates,
|
||||
)..where((table) => table.id.equals(id) & table.deletedAt.isNull()))
|
||||
.getSingleOrNull();
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
final programs =
|
||||
await (database.select(database.workoutTemplatePrograms)
|
||||
..where((table) => table.workoutTemplateId.equals(id))
|
||||
..where(
|
||||
(table) =>
|
||||
table.workoutTemplateId.equals(id) &
|
||||
table.deletedAt.isNull(),
|
||||
)
|
||||
..orderBy([(table) => OrderingTerm.asc(table.position)]))
|
||||
.get();
|
||||
final programIds = programs.map((program) => program.id).toSet();
|
||||
final overrides = await (database.select(
|
||||
database.workoutTemplateExerciseOverrides,
|
||||
)..where((table) => table.workoutTemplateProgramId.isIn(programIds))).get();
|
||||
final overrides = programIds.isEmpty
|
||||
? <db.WorkoutTemplateExerciseOverride>[]
|
||||
: await (database.select(database.workoutTemplateExerciseOverrides)
|
||||
..where(
|
||||
(table) =>
|
||||
table.workoutTemplateProgramId.isIn(programIds) &
|
||||
table.deletedAt.isNull(),
|
||||
))
|
||||
.get();
|
||||
return _workoutTemplateFromRow(
|
||||
row,
|
||||
programs.map(_workoutTemplateProgramFromRow).toList(),
|
||||
@ -213,6 +225,23 @@ final class DriftWorkoutTemplateRepository
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<domain.WorkoutTemplate>> listActive() async {
|
||||
final rows =
|
||||
await (database.select(database.workoutTemplates)
|
||||
..where((table) => table.deletedAt.isNull())
|
||||
..orderBy([(table) => OrderingTerm.asc(table.name)]))
|
||||
.get();
|
||||
final templates = <domain.WorkoutTemplate>[];
|
||||
for (final row in rows) {
|
||||
final template = await findById(row.id);
|
||||
if (template != null) {
|
||||
templates.add(template);
|
||||
}
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> save(domain.WorkoutTemplate template) async {
|
||||
await database
|
||||
@ -243,6 +272,81 @@ final class DriftWorkoutTemplateRepository
|
||||
_workoutTemplateExerciseOverrideCompanion(override),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> replaceComposition(
|
||||
domain.WorkoutTemplate template,
|
||||
DateTime deletedAt,
|
||||
) async {
|
||||
await database.transaction(() async {
|
||||
final previousPrograms =
|
||||
await (database.select(database.workoutTemplatePrograms)..where(
|
||||
(table) =>
|
||||
table.workoutTemplateId.equals(template.metadata.id) &
|
||||
table.deletedAt.isNull(),
|
||||
))
|
||||
.get();
|
||||
final previousProgramIds = previousPrograms
|
||||
.map((program) => program.id)
|
||||
.toSet();
|
||||
await save(template);
|
||||
final activeProgramIds = template.programs
|
||||
.map((program) => program.metadata.id)
|
||||
.toSet();
|
||||
final programUpdate = database.update(database.workoutTemplatePrograms);
|
||||
if (activeProgramIds.isEmpty) {
|
||||
programUpdate.where(
|
||||
(table) =>
|
||||
table.workoutTemplateId.equals(template.metadata.id) &
|
||||
table.deletedAt.isNull(),
|
||||
);
|
||||
} else {
|
||||
programUpdate.where(
|
||||
(table) =>
|
||||
table.workoutTemplateId.equals(template.metadata.id) &
|
||||
table.deletedAt.isNull() &
|
||||
table.id.isNotIn(activeProgramIds),
|
||||
);
|
||||
}
|
||||
await programUpdate.write(
|
||||
db.WorkoutTemplateProgramsCompanion(
|
||||
deletedAt: Value(deletedAt),
|
||||
updatedAt: Value(deletedAt),
|
||||
),
|
||||
);
|
||||
|
||||
final activeOverrideIds = template.overrides
|
||||
.map((override) => override.metadata.id)
|
||||
.toSet();
|
||||
final relevantProgramIds = {...previousProgramIds, ...activeProgramIds};
|
||||
if (relevantProgramIds.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final overrideUpdate = database.update(
|
||||
database.workoutTemplateExerciseOverrides,
|
||||
);
|
||||
if (activeOverrideIds.isEmpty) {
|
||||
overrideUpdate.where(
|
||||
(table) =>
|
||||
table.workoutTemplateProgramId.isIn(relevantProgramIds) &
|
||||
table.deletedAt.isNull(),
|
||||
);
|
||||
} else {
|
||||
overrideUpdate.where(
|
||||
(table) =>
|
||||
table.workoutTemplateProgramId.isIn(relevantProgramIds) &
|
||||
table.deletedAt.isNull() &
|
||||
table.id.isNotIn(activeOverrideIds),
|
||||
);
|
||||
}
|
||||
await overrideUpdate.write(
|
||||
db.WorkoutTemplateExerciseOverridesCompanion(
|
||||
deletedAt: Value(deletedAt),
|
||||
updatedAt: Value(deletedAt),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
final class DriftActiveSessionRepository implements ActiveSessionRepository {
|
||||
|
||||
Reference in New Issue
Block a user