feat(exercice): icône d'exercice (ticket #38)

Étend le modèle Drift (tables.dart, app_database.dart/.g.dart), les
entités/use cases/repositories et les écrans bibliothèque d'exercices
et programme pour associer une icône à chaque exercice. flutter
analyze propre, 72/72 tests verts, build APK debug validé. Dernier
ticket du backlog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 14:25:26 +02:00
parent c92bded211
commit bdd7877ea5
10 changed files with 589 additions and 27 deletions

View File

@ -37,7 +37,7 @@ final class AppDatabase extends _$AppDatabase {
}
@override
int get schemaVersion => 6;
int get schemaVersion => 7;
@override
MigrationStrategy get migration {
@ -70,6 +70,9 @@ final class AppDatabase extends _$AppDatabase {
if (from < 6) {
await _migrateToSchema6();
}
if (from < 7) {
await _migrateToSchema7();
}
await _createIndexes();
},
beforeOpen: (details) async {
@ -260,4 +263,11 @@ extension on AppDatabase {
'exercise_image_media_ids_snapshot_json TEXT',
);
}
Future<void> _migrateToSchema7() async {
await customStatement(
'ALTER TABLE exercises ADD COLUMN icon_media_id TEXT '
'REFERENCES media_assets(id)',
);
}
}

View File

@ -7959,6 +7959,20 @@ class $ExercisesTable extends Exercises
type: DriftSqlType.string,
requiredDuringInsert: false,
);
static const VerificationMeta _iconMediaIdMeta = const VerificationMeta(
'iconMediaId',
);
@override
late final GeneratedColumn<String> iconMediaId = GeneratedColumn<String>(
'icon_media_id',
aliasedName,
true,
type: DriftSqlType.string,
requiredDuringInsert: false,
defaultConstraints: GeneratedColumn.constraintIsAlways(
'REFERENCES media_assets (id)',
),
);
static const VerificationMeta _videoMediaIdMeta = const VerificationMeta(
'videoMediaId',
);
@ -8119,6 +8133,7 @@ class $ExercisesTable extends Exercises
remoteRevision,
name,
description,
iconMediaId,
videoMediaId,
hasTimeMeasure,
hasRepsMeasure,
@ -8254,6 +8269,15 @@ class $ExercisesTable extends Exercises
),
);
}
if (data.containsKey('icon_media_id')) {
context.handle(
_iconMediaIdMeta,
iconMediaId.isAcceptableOrUnknown(
data['icon_media_id']!,
_iconMediaIdMeta,
),
);
}
if (data.containsKey('video_media_id')) {
context.handle(
_videoMediaIdMeta,
@ -8420,6 +8444,10 @@ class $ExercisesTable extends Exercises
DriftSqlType.string,
data['${effectivePrefix}description'],
),
iconMediaId: attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}icon_media_id'],
),
videoMediaId: attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}video_media_id'],
@ -8491,6 +8519,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
final String? remoteRevision;
final String name;
final String? description;
final String? iconMediaId;
final String? videoMediaId;
final bool hasTimeMeasure;
final bool hasRepsMeasure;
@ -8517,6 +8546,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
this.remoteRevision,
required this.name,
this.description,
this.iconMediaId,
this.videoMediaId,
required this.hasTimeMeasure,
required this.hasRepsMeasure,
@ -8556,6 +8586,9 @@ class Exercise extends DataClass implements Insertable<Exercise> {
if (!nullToAbsent || description != null) {
map['description'] = Variable<String>(description);
}
if (!nullToAbsent || iconMediaId != null) {
map['icon_media_id'] = Variable<String>(iconMediaId);
}
if (!nullToAbsent || videoMediaId != null) {
map['video_media_id'] = Variable<String>(videoMediaId);
}
@ -8616,6 +8649,9 @@ class Exercise extends DataClass implements Insertable<Exercise> {
description: description == null && nullToAbsent
? const Value.absent()
: Value(description),
iconMediaId: iconMediaId == null && nullToAbsent
? const Value.absent()
: Value(iconMediaId),
videoMediaId: videoMediaId == null && nullToAbsent
? const Value.absent()
: Value(videoMediaId),
@ -8668,6 +8704,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
remoteRevision: serializer.fromJson<String?>(json['remoteRevision']),
name: serializer.fromJson<String>(json['name']),
description: serializer.fromJson<String?>(json['description']),
iconMediaId: serializer.fromJson<String?>(json['iconMediaId']),
videoMediaId: serializer.fromJson<String?>(json['videoMediaId']),
hasTimeMeasure: serializer.fromJson<bool>(json['hasTimeMeasure']),
hasRepsMeasure: serializer.fromJson<bool>(json['hasRepsMeasure']),
@ -8705,6 +8742,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
'remoteRevision': serializer.toJson<String?>(remoteRevision),
'name': serializer.toJson<String>(name),
'description': serializer.toJson<String?>(description),
'iconMediaId': serializer.toJson<String?>(iconMediaId),
'videoMediaId': serializer.toJson<String?>(videoMediaId),
'hasTimeMeasure': serializer.toJson<bool>(hasTimeMeasure),
'hasRepsMeasure': serializer.toJson<bool>(hasRepsMeasure),
@ -8738,6 +8776,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
Value<String?> remoteRevision = const Value.absent(),
String? name,
Value<String?> description = const Value.absent(),
Value<String?> iconMediaId = const Value.absent(),
Value<String?> videoMediaId = const Value.absent(),
bool? hasTimeMeasure,
bool? hasRepsMeasure,
@ -8768,6 +8807,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
: this.remoteRevision,
name: name ?? this.name,
description: description.present ? description.value : this.description,
iconMediaId: iconMediaId.present ? iconMediaId.value : this.iconMediaId,
videoMediaId: videoMediaId.present ? videoMediaId.value : this.videoMediaId,
hasTimeMeasure: hasTimeMeasure ?? this.hasTimeMeasure,
hasRepsMeasure: hasRepsMeasure ?? this.hasRepsMeasure,
@ -8818,6 +8858,9 @@ class Exercise extends DataClass implements Insertable<Exercise> {
description: data.description.present
? data.description.value
: this.description,
iconMediaId: data.iconMediaId.present
? data.iconMediaId.value
: this.iconMediaId,
videoMediaId: data.videoMediaId.present
? data.videoMediaId.value
: this.videoMediaId,
@ -8871,6 +8914,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
..write('remoteRevision: $remoteRevision, ')
..write('name: $name, ')
..write('description: $description, ')
..write('iconMediaId: $iconMediaId, ')
..write('videoMediaId: $videoMediaId, ')
..write('hasTimeMeasure: $hasTimeMeasure, ')
..write('hasRepsMeasure: $hasRepsMeasure, ')
@ -8902,6 +8946,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
remoteRevision,
name,
description,
iconMediaId,
videoMediaId,
hasTimeMeasure,
hasRepsMeasure,
@ -8932,6 +8977,7 @@ class Exercise extends DataClass implements Insertable<Exercise> {
other.remoteRevision == this.remoteRevision &&
other.name == this.name &&
other.description == this.description &&
other.iconMediaId == this.iconMediaId &&
other.videoMediaId == this.videoMediaId &&
other.hasTimeMeasure == this.hasTimeMeasure &&
other.hasRepsMeasure == this.hasRepsMeasure &&
@ -8960,6 +9006,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
final Value<String?> remoteRevision;
final Value<String> name;
final Value<String?> description;
final Value<String?> iconMediaId;
final Value<String?> videoMediaId;
final Value<bool> hasTimeMeasure;
final Value<bool> hasRepsMeasure;
@ -8987,6 +9034,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
this.remoteRevision = const Value.absent(),
this.name = const Value.absent(),
this.description = const Value.absent(),
this.iconMediaId = const Value.absent(),
this.videoMediaId = const Value.absent(),
this.hasTimeMeasure = const Value.absent(),
this.hasRepsMeasure = const Value.absent(),
@ -9015,6 +9063,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
this.remoteRevision = const Value.absent(),
required String name,
this.description = const Value.absent(),
this.iconMediaId = const Value.absent(),
this.videoMediaId = const Value.absent(),
required bool hasTimeMeasure,
required bool hasRepsMeasure,
@ -9052,6 +9101,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
Expression<String>? remoteRevision,
Expression<String>? name,
Expression<String>? description,
Expression<String>? iconMediaId,
Expression<String>? videoMediaId,
Expression<bool>? hasTimeMeasure,
Expression<bool>? hasRepsMeasure,
@ -9081,6 +9131,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
if (remoteRevision != null) 'remote_revision': remoteRevision,
if (name != null) 'name': name,
if (description != null) 'description': description,
if (iconMediaId != null) 'icon_media_id': iconMediaId,
if (videoMediaId != null) 'video_media_id': videoMediaId,
if (hasTimeMeasure != null) 'has_time_measure': hasTimeMeasure,
if (hasRepsMeasure != null) 'has_reps_measure': hasRepsMeasure,
@ -9114,6 +9165,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
Value<String?>? remoteRevision,
Value<String>? name,
Value<String?>? description,
Value<String?>? iconMediaId,
Value<String?>? videoMediaId,
Value<bool>? hasTimeMeasure,
Value<bool>? hasRepsMeasure,
@ -9142,6 +9194,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
remoteRevision: remoteRevision ?? this.remoteRevision,
name: name ?? this.name,
description: description ?? this.description,
iconMediaId: iconMediaId ?? this.iconMediaId,
videoMediaId: videoMediaId ?? this.videoMediaId,
hasTimeMeasure: hasTimeMeasure ?? this.hasTimeMeasure,
hasRepsMeasure: hasRepsMeasure ?? this.hasRepsMeasure,
@ -9204,6 +9257,9 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
if (description.present) {
map['description'] = Variable<String>(description.value);
}
if (iconMediaId.present) {
map['icon_media_id'] = Variable<String>(iconMediaId.value);
}
if (videoMediaId.present) {
map['video_media_id'] = Variable<String>(videoMediaId.value);
}
@ -9266,6 +9322,7 @@ class ExercisesCompanion extends UpdateCompanion<Exercise> {
..write('remoteRevision: $remoteRevision, ')
..write('name: $name, ')
..write('description: $description, ')
..write('iconMediaId: $iconMediaId, ')
..write('videoMediaId: $videoMediaId, ')
..write('hasTimeMeasure: $hasTimeMeasure, ')
..write('hasRepsMeasure: $hasRepsMeasure, ')
@ -22861,6 +22918,27 @@ final class $$MediaAssetsTableReferences
extends BaseReferences<_$AppDatabase, $MediaAssetsTable, MediaAsset> {
$$MediaAssetsTableReferences(super.$_db, super.$_table, super.$_typedResult);
static MultiTypedResultKey<$ExercisesTable, List<Exercise>>
_exerciseIconReferencesTable(_$AppDatabase db) =>
MultiTypedResultKey.fromTable(
db.exercises,
aliasName: 'media_assets__id__exercises__icon_media_id',
);
$$ExercisesTableProcessedTableManager get exerciseIconReferences {
final manager = $$ExercisesTableTableManager(
$_db,
$_db.exercises,
).filter((f) => f.iconMediaId.id.sqlEquals($_itemColumn<String>('id')!));
final cache = $_typedResult.readTableOrNull(
_exerciseIconReferencesTable($_db),
);
return ProcessedTableManager(
manager.$state.copyWith(prefetchedData: cache),
);
}
static MultiTypedResultKey<$ExercisesTable, List<Exercise>>
_exerciseVideoReferencesTable(_$AppDatabase db) =>
MultiTypedResultKey.fromTable(
@ -23067,6 +23145,31 @@ class $$MediaAssetsTableFilterComposer
builder: (column) => ColumnFilters(column),
);
Expression<bool> exerciseIconReferences(
Expression<bool> Function($$ExercisesTableFilterComposer f) f,
) {
final $$ExercisesTableFilterComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.id,
referencedTable: $db.exercises,
getReferencedColumn: (t) => t.iconMediaId,
builder:
(
joinBuilder, {
$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer,
}) => $$ExercisesTableFilterComposer(
$db: $db,
$table: $db.exercises,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
),
);
return f(composer);
}
Expression<bool> exerciseVideoReferences(
Expression<bool> Function($$ExercisesTableFilterComposer f) f,
) {
@ -23371,6 +23474,31 @@ class $$MediaAssetsTableAnnotationComposer
builder: (column) => column,
);
Expression<T> exerciseIconReferences<T extends Object>(
Expression<T> Function($$ExercisesTableAnnotationComposer a) f,
) {
final $$ExercisesTableAnnotationComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.id,
referencedTable: $db.exercises,
getReferencedColumn: (t) => t.iconMediaId,
builder:
(
joinBuilder, {
$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer,
}) => $$ExercisesTableAnnotationComposer(
$db: $db,
$table: $db.exercises,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
),
);
return f(composer);
}
Expression<T> exerciseVideoReferences<T extends Object>(
Expression<T> Function($$ExercisesTableAnnotationComposer a) f,
) {
@ -23486,6 +23614,7 @@ class $$MediaAssetsTableTableManager
(MediaAsset, $$MediaAssetsTableReferences),
MediaAsset,
PrefetchHooks Function({
bool exerciseIconReferences,
bool exerciseVideoReferences,
bool exerciseImagesRefs,
bool programExerciseImageSnapshotReferences,
@ -23609,6 +23738,7 @@ class $$MediaAssetsTableTableManager
.toList(),
prefetchHooksCallback:
({
exerciseIconReferences = false,
exerciseVideoReferences = false,
exerciseImagesRefs = false,
programExerciseImageSnapshotReferences = false,
@ -23617,6 +23747,7 @@ class $$MediaAssetsTableTableManager
return PrefetchHooks(
db: db,
explicitlyWatchedTables: [
if (exerciseIconReferences) db.exercises,
if (exerciseVideoReferences) db.exercises,
if (exerciseImagesRefs) db.exerciseImages,
if (programExerciseImageSnapshotReferences)
@ -23627,6 +23758,27 @@ class $$MediaAssetsTableTableManager
addJoins: null,
getPrefetchedDataCallback: (items) async {
return [
if (exerciseIconReferences)
await $_getPrefetchedData<
MediaAsset,
$MediaAssetsTable,
Exercise
>(
currentTable: table,
referencedTable: $$MediaAssetsTableReferences
._exerciseIconReferencesTable(db),
managerFromTypedResult: (p0) =>
$$MediaAssetsTableReferences(
db,
table,
p0,
).exerciseIconReferences,
referencedItemsForCurrentItem:
(item, referencedItems) => referencedItems.where(
(e) => e.iconMediaId == item.id,
),
typedResults: items,
),
if (exerciseVideoReferences)
await $_getPrefetchedData<
MediaAsset,
@ -23734,6 +23886,7 @@ typedef $$MediaAssetsTableProcessedTableManager =
(MediaAsset, $$MediaAssetsTableReferences),
MediaAsset,
PrefetchHooks Function({
bool exerciseIconReferences,
bool exerciseVideoReferences,
bool exerciseImagesRefs,
bool programExerciseImageSnapshotReferences,
@ -23755,6 +23908,7 @@ typedef $$ExercisesTableCreateCompanionBuilder =
Value<String?> remoteRevision,
required String name,
Value<String?> description,
Value<String?> iconMediaId,
Value<String?> videoMediaId,
required bool hasTimeMeasure,
required bool hasRepsMeasure,
@ -23784,6 +23938,7 @@ typedef $$ExercisesTableUpdateCompanionBuilder =
Value<String?> remoteRevision,
Value<String> name,
Value<String?> description,
Value<String?> iconMediaId,
Value<String?> videoMediaId,
Value<bool> hasTimeMeasure,
Value<bool> hasRepsMeasure,
@ -23803,6 +23958,23 @@ final class $$ExercisesTableReferences
extends BaseReferences<_$AppDatabase, $ExercisesTable, Exercise> {
$$ExercisesTableReferences(super.$_db, super.$_table, super.$_typedResult);
static $MediaAssetsTable _iconMediaIdTable(_$AppDatabase db) =>
db.mediaAssets.createAlias('exercises__icon_media_id__media_assets__id');
$$MediaAssetsTableProcessedTableManager? get iconMediaId {
final $_column = $_itemColumn<String>('icon_media_id');
if ($_column == null) return null;
final manager = $$MediaAssetsTableTableManager(
$_db,
$_db.mediaAssets,
).filter((f) => f.id.sqlEquals($_column));
final item = $_typedResult.readTableOrNull(_iconMediaIdTable($_db));
if (item == null) return manager;
return ProcessedTableManager(
manager.$state.copyWith(prefetchedData: [item]),
);
}
static $MediaAssetsTable _videoMediaIdTable(_$AppDatabase db) =>
db.mediaAssets.createAlias('exercises__video_media_id__media_assets__id');
@ -23988,6 +24160,29 @@ class $$ExercisesTableFilterComposer
builder: (column) => ColumnFilters(column),
);
$$MediaAssetsTableFilterComposer get iconMediaId {
final $$MediaAssetsTableFilterComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.iconMediaId,
referencedTable: $db.mediaAssets,
getReferencedColumn: (t) => t.id,
builder:
(
joinBuilder, {
$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer,
}) => $$MediaAssetsTableFilterComposer(
$db: $db,
$table: $db.mediaAssets,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
),
);
return composer;
}
$$MediaAssetsTableFilterComposer get videoMediaId {
final $$MediaAssetsTableFilterComposer composer = $composerBuilder(
composer: this,
@ -24191,6 +24386,29 @@ class $$ExercisesTableOrderingComposer
builder: (column) => ColumnOrderings(column),
);
$$MediaAssetsTableOrderingComposer get iconMediaId {
final $$MediaAssetsTableOrderingComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.iconMediaId,
referencedTable: $db.mediaAssets,
getReferencedColumn: (t) => t.id,
builder:
(
joinBuilder, {
$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer,
}) => $$MediaAssetsTableOrderingComposer(
$db: $db,
$table: $db.mediaAssets,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
),
);
return composer;
}
$$MediaAssetsTableOrderingComposer get videoMediaId {
final $$MediaAssetsTableOrderingComposer composer = $composerBuilder(
composer: this,
@ -24330,6 +24548,29 @@ class $$ExercisesTableAnnotationComposer
builder: (column) => column,
);
$$MediaAssetsTableAnnotationComposer get iconMediaId {
final $$MediaAssetsTableAnnotationComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.iconMediaId,
referencedTable: $db.mediaAssets,
getReferencedColumn: (t) => t.id,
builder:
(
joinBuilder, {
$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer,
}) => $$MediaAssetsTableAnnotationComposer(
$db: $db,
$table: $db.mediaAssets,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
),
);
return composer;
}
$$MediaAssetsTableAnnotationComposer get videoMediaId {
final $$MediaAssetsTableAnnotationComposer composer = $composerBuilder(
composer: this,
@ -24418,6 +24659,7 @@ class $$ExercisesTableTableManager
(Exercise, $$ExercisesTableReferences),
Exercise,
PrefetchHooks Function({
bool iconMediaId,
bool videoMediaId,
bool exerciseImagesRefs,
bool programExercisesRefs,
@ -24449,6 +24691,7 @@ class $$ExercisesTableTableManager
Value<String?> remoteRevision = const Value.absent(),
Value<String> name = const Value.absent(),
Value<String?> description = const Value.absent(),
Value<String?> iconMediaId = const Value.absent(),
Value<String?> videoMediaId = const Value.absent(),
Value<bool> hasTimeMeasure = const Value.absent(),
Value<bool> hasRepsMeasure = const Value.absent(),
@ -24476,6 +24719,7 @@ class $$ExercisesTableTableManager
remoteRevision: remoteRevision,
name: name,
description: description,
iconMediaId: iconMediaId,
videoMediaId: videoMediaId,
hasTimeMeasure: hasTimeMeasure,
hasRepsMeasure: hasRepsMeasure,
@ -24505,6 +24749,7 @@ class $$ExercisesTableTableManager
Value<String?> remoteRevision = const Value.absent(),
required String name,
Value<String?> description = const Value.absent(),
Value<String?> iconMediaId = const Value.absent(),
Value<String?> videoMediaId = const Value.absent(),
required bool hasTimeMeasure,
required bool hasRepsMeasure,
@ -24532,6 +24777,7 @@ class $$ExercisesTableTableManager
remoteRevision: remoteRevision,
name: name,
description: description,
iconMediaId: iconMediaId,
videoMediaId: videoMediaId,
hasTimeMeasure: hasTimeMeasure,
hasRepsMeasure: hasRepsMeasure,
@ -24556,6 +24802,7 @@ class $$ExercisesTableTableManager
.toList(),
prefetchHooksCallback:
({
iconMediaId = false,
videoMediaId = false,
exerciseImagesRefs = false,
programExercisesRefs = false,
@ -24582,6 +24829,19 @@ class $$ExercisesTableTableManager
dynamic
>
>(state) {
if (iconMediaId) {
state =
state.withJoin(
currentTable: table,
currentColumn: table.iconMediaId,
referencedTable: $$ExercisesTableReferences
._iconMediaIdTable(db),
referencedColumn: $$ExercisesTableReferences
._iconMediaIdTable(db)
.id,
)
as T;
}
if (videoMediaId) {
state =
state.withJoin(
@ -24663,6 +24923,7 @@ typedef $$ExercisesTableProcessedTableManager =
(Exercise, $$ExercisesTableReferences),
Exercise,
PrefetchHooks Function({
bool iconMediaId,
bool videoMediaId,
bool exerciseImagesRefs,
bool programExercisesRefs,

View File

@ -1078,6 +1078,7 @@ db.ExercisesCompanion _exerciseCompanion(domain.Exercise exercise) {
remoteRevision: values[10] as Value<String?>,
name: Value(exercise.name),
description: Value(exercise.description),
iconMediaId: Value(exercise.iconMediaId),
videoMediaId: Value(exercise.videoMediaId),
hasTimeMeasure: Value(exercise.hasTimeMeasure),
hasRepsMeasure: Value(exercise.hasRepsMeasure),
@ -1099,6 +1100,7 @@ domain.Exercise _exerciseFromRow(db.Exercise row, List<String> imageMediaIds) {
name: row.name,
description: row.description,
imageMediaIds: imageMediaIds,
iconMediaId: row.iconMediaId,
videoMediaId: row.videoMediaId,
hasTimeMeasure: row.hasTimeMeasure,
hasRepsMeasure: row.hasRepsMeasure,

View File

@ -55,6 +55,9 @@ class Exercises extends SyncableTable {
TextColumn get name => text().withLength(min: 1)();
TextColumn get description => text().nullable()();
@ReferenceName('exerciseIconReferences')
TextColumn get iconMediaId =>
text().nullable().references(MediaAssets, #id)();
@ReferenceName('exerciseVideoReferences')
TextColumn get videoMediaId =>
text().nullable().references(MediaAssets, #id)();