activity things #6

Merged
jshbrmn merged 5 commits from activity-things into main 2025-01-07 12:50:19 -08:00
20 changed files with 2891 additions and 293 deletions

View File

@ -4,17 +4,21 @@ import 'package:sendtrain/database/database.dart';
part 'session_activities_dao.g.dart'; part 'session_activities_dao.g.dart';
@DriftAccessor(tables: [SessionActivities]) @DriftAccessor(tables: [SessionActivities])
class SessionActivitiesDao extends DatabaseAccessor<AppDatabase> with _$SessionActivitiesDaoMixin { class SessionActivitiesDao extends DatabaseAccessor<AppDatabase>
with _$SessionActivitiesDaoMixin {
SessionActivitiesDao(super.db); SessionActivitiesDao(super.db);
Future createOrUpdate(SessionActivitiesCompanion sessionActivity) => into(sessionActivities).insertOnConflictUpdate(sessionActivity); Future createOrUpdate(SessionActivitiesCompanion sessionActivity) =>
into(sessionActivities).insertOnConflictUpdate(sessionActivity);
Future<List<SessionActivity>> all() async { Future<List<SessionActivity>> all() async {
return await select(sessionActivities).get(); return await select(sessionActivities).get();
} }
Future<SessionActivity> find(int id) async { Future<SessionActivity> find(int id) async {
return await (select(sessionActivities)..where((sessionActivity) => sessionActivity.id.equals(id) )).getSingle(); return await (select(sessionActivities)
..where((sessionActivity) => sessionActivity.id.equals(id)))
.getSingle();
} }
Future<List<SessionActivity>> fromSessionId(int id) async { Future<List<SessionActivity>> fromSessionId(int id) async {
@ -23,4 +27,16 @@ class SessionActivitiesDao extends DatabaseAccessor<AppDatabase> with _$SessionA
return result.get(); return result.get();
} }
}
Future remove(SessionActivity sessionActivity) =>
delete(sessionActivities).delete(sessionActivity);
Future removeAssociation(int activityId, int sessionId) {
return (delete(sessionActivities)
..where((t) =>
t.sessionId.equals(sessionId) & t.activityId.equals(activityId)))
.go();
}
}
// return (delete(todos)..where((t) => t.id.isSmallerThanValue(10))).go();

View File

@ -35,7 +35,7 @@ class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection()); AppDatabase() : super(_openConnection());
@override @override
int get schemaVersion => 19; int get schemaVersion => 20;
@override @override
MigrationStrategy get migration { MigrationStrategy get migration {
@ -193,7 +193,7 @@ enum MediaType { youtube, image, location, localImage, localVideo }
class MediaItems extends Table { class MediaItems extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
TextColumn get title => text().withLength(min: 3, max: 32)(); TextColumn get title => text().withLength(min: 3, max: 64)();
TextColumn get description => text().named('body')(); TextColumn get description => text().named('body')();
TextColumn get reference => text()(); TextColumn get reference => text()();
TextColumn get type => textEnum<MediaType>()(); TextColumn get type => textEnum<MediaType>()();

View File

@ -515,11 +515,6 @@ class $ActivitiesTable extends Activities
type: DriftSqlType.string, requiredDuringInsert: false) type: DriftSqlType.string, requiredDuringInsert: false)
.withConverter<ActivityMuscle?>( .withConverter<ActivityMuscle?>(
$ActivitiesTable.$convertersecondaryMusclesn); $ActivitiesTable.$convertersecondaryMusclesn);
static const VerificationMeta _imagesMeta = const VerificationMeta('images');
@override
late final GeneratedColumn<String> images = GeneratedColumn<String>(
'images', aliasedName, true,
type: DriftSqlType.string, requiredDuringInsert: false);
static const VerificationMeta _createdAtMeta = static const VerificationMeta _createdAtMeta =
const VerificationMeta('createdAt'); const VerificationMeta('createdAt');
@override @override
@ -541,7 +536,6 @@ class $ActivitiesTable extends Activities
equipment, equipment,
primaryMuscles, primaryMuscles,
secondaryMuscles, secondaryMuscles,
images,
createdAt createdAt
]; ];
@override @override
@ -578,10 +572,6 @@ class $ActivitiesTable extends Activities
context.handle(_equipmentMeta, const VerificationResult.success()); context.handle(_equipmentMeta, const VerificationResult.success());
context.handle(_primaryMusclesMeta, const VerificationResult.success()); context.handle(_primaryMusclesMeta, const VerificationResult.success());
context.handle(_secondaryMusclesMeta, const VerificationResult.success()); context.handle(_secondaryMusclesMeta, const VerificationResult.success());
if (data.containsKey('images')) {
context.handle(_imagesMeta,
images.isAcceptableOrUnknown(data['images']!, _imagesMeta));
}
if (data.containsKey('created_at')) { if (data.containsKey('created_at')) {
context.handle(_createdAtMeta, context.handle(_createdAtMeta,
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta));
@ -624,8 +614,6 @@ class $ActivitiesTable extends Activities
secondaryMuscles: $ActivitiesTable.$convertersecondaryMusclesn.fromSql( secondaryMuscles: $ActivitiesTable.$convertersecondaryMusclesn.fromSql(
attachedDatabase.typeMapping.read(DriftSqlType.string, attachedDatabase.typeMapping.read(DriftSqlType.string,
data['${effectivePrefix}secondary_muscles'])), data['${effectivePrefix}secondary_muscles'])),
images: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}images']),
createdAt: attachedDatabase.typeMapping createdAt: attachedDatabase.typeMapping
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
); );
@ -685,7 +673,6 @@ class Activity extends DataClass implements Insertable<Activity> {
final ActivityEquipment? equipment; final ActivityEquipment? equipment;
final ActivityMuscle? primaryMuscles; final ActivityMuscle? primaryMuscles;
final ActivityMuscle? secondaryMuscles; final ActivityMuscle? secondaryMuscles;
final String? images;
final DateTime createdAt; final DateTime createdAt;
const Activity( const Activity(
{required this.id, {required this.id,
@ -699,7 +686,6 @@ class Activity extends DataClass implements Insertable<Activity> {
this.equipment, this.equipment,
this.primaryMuscles, this.primaryMuscles,
this.secondaryMuscles, this.secondaryMuscles,
this.images,
required this.createdAt}); required this.createdAt});
@override @override
Map<String, Expression> toColumns(bool nullToAbsent) { Map<String, Expression> toColumns(bool nullToAbsent) {
@ -740,9 +726,6 @@ class Activity extends DataClass implements Insertable<Activity> {
map['secondary_muscles'] = Variable<String>( map['secondary_muscles'] = Variable<String>(
$ActivitiesTable.$convertersecondaryMusclesn.toSql(secondaryMuscles)); $ActivitiesTable.$convertersecondaryMusclesn.toSql(secondaryMuscles));
} }
if (!nullToAbsent || images != null) {
map['images'] = Variable<String>(images);
}
map['created_at'] = Variable<DateTime>(createdAt); map['created_at'] = Variable<DateTime>(createdAt);
return map; return map;
} }
@ -774,8 +757,6 @@ class Activity extends DataClass implements Insertable<Activity> {
secondaryMuscles: secondaryMuscles == null && nullToAbsent secondaryMuscles: secondaryMuscles == null && nullToAbsent
? const Value.absent() ? const Value.absent()
: Value(secondaryMuscles), : Value(secondaryMuscles),
images:
images == null && nullToAbsent ? const Value.absent() : Value(images),
createdAt: Value(createdAt), createdAt: Value(createdAt),
); );
} }
@ -802,7 +783,6 @@ class Activity extends DataClass implements Insertable<Activity> {
.fromJson(serializer.fromJson<String?>(json['primaryMuscles'])), .fromJson(serializer.fromJson<String?>(json['primaryMuscles'])),
secondaryMuscles: $ActivitiesTable.$convertersecondaryMusclesn secondaryMuscles: $ActivitiesTable.$convertersecondaryMusclesn
.fromJson(serializer.fromJson<String?>(json['secondaryMuscles'])), .fromJson(serializer.fromJson<String?>(json['secondaryMuscles'])),
images: serializer.fromJson<String?>(json['images']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']), createdAt: serializer.fromJson<DateTime>(json['createdAt']),
); );
} }
@ -829,7 +809,6 @@ class Activity extends DataClass implements Insertable<Activity> {
'secondaryMuscles': serializer.toJson<String?>($ActivitiesTable 'secondaryMuscles': serializer.toJson<String?>($ActivitiesTable
.$convertersecondaryMusclesn .$convertersecondaryMusclesn
.toJson(secondaryMuscles)), .toJson(secondaryMuscles)),
'images': serializer.toJson<String?>(images),
'createdAt': serializer.toJson<DateTime>(createdAt), 'createdAt': serializer.toJson<DateTime>(createdAt),
}; };
} }
@ -846,7 +825,6 @@ class Activity extends DataClass implements Insertable<Activity> {
Value<ActivityEquipment?> equipment = const Value.absent(), Value<ActivityEquipment?> equipment = const Value.absent(),
Value<ActivityMuscle?> primaryMuscles = const Value.absent(), Value<ActivityMuscle?> primaryMuscles = const Value.absent(),
Value<ActivityMuscle?> secondaryMuscles = const Value.absent(), Value<ActivityMuscle?> secondaryMuscles = const Value.absent(),
Value<String?> images = const Value.absent(),
DateTime? createdAt}) => DateTime? createdAt}) =>
Activity( Activity(
id: id ?? this.id, id: id ?? this.id,
@ -863,7 +841,6 @@ class Activity extends DataClass implements Insertable<Activity> {
secondaryMuscles: secondaryMuscles.present secondaryMuscles: secondaryMuscles.present
? secondaryMuscles.value ? secondaryMuscles.value
: this.secondaryMuscles, : this.secondaryMuscles,
images: images.present ? images.value : this.images,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
); );
Activity copyWithCompanion(ActivitiesCompanion data) { Activity copyWithCompanion(ActivitiesCompanion data) {
@ -884,7 +861,6 @@ class Activity extends DataClass implements Insertable<Activity> {
secondaryMuscles: data.secondaryMuscles.present secondaryMuscles: data.secondaryMuscles.present
? data.secondaryMuscles.value ? data.secondaryMuscles.value
: this.secondaryMuscles, : this.secondaryMuscles,
images: data.images.present ? data.images.value : this.images,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
); );
} }
@ -903,27 +879,14 @@ class Activity extends DataClass implements Insertable<Activity> {
..write('equipment: $equipment, ') ..write('equipment: $equipment, ')
..write('primaryMuscles: $primaryMuscles, ') ..write('primaryMuscles: $primaryMuscles, ')
..write('secondaryMuscles: $secondaryMuscles, ') ..write('secondaryMuscles: $secondaryMuscles, ')
..write('images: $images, ')
..write('createdAt: $createdAt') ..write('createdAt: $createdAt')
..write(')')) ..write(')'))
.toString(); .toString();
} }
@override @override
int get hashCode => Object.hash( int get hashCode => Object.hash(id, title, type, description, category, force,
id, level, mechanic, equipment, primaryMuscles, secondaryMuscles, createdAt);
title,
type,
description,
category,
force,
level,
mechanic,
equipment,
primaryMuscles,
secondaryMuscles,
images,
createdAt);
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
@ -939,7 +902,6 @@ class Activity extends DataClass implements Insertable<Activity> {
other.equipment == this.equipment && other.equipment == this.equipment &&
other.primaryMuscles == this.primaryMuscles && other.primaryMuscles == this.primaryMuscles &&
other.secondaryMuscles == this.secondaryMuscles && other.secondaryMuscles == this.secondaryMuscles &&
other.images == this.images &&
other.createdAt == this.createdAt); other.createdAt == this.createdAt);
} }
@ -955,7 +917,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
final Value<ActivityEquipment?> equipment; final Value<ActivityEquipment?> equipment;
final Value<ActivityMuscle?> primaryMuscles; final Value<ActivityMuscle?> primaryMuscles;
final Value<ActivityMuscle?> secondaryMuscles; final Value<ActivityMuscle?> secondaryMuscles;
final Value<String?> images;
final Value<DateTime> createdAt; final Value<DateTime> createdAt;
const ActivitiesCompanion({ const ActivitiesCompanion({
this.id = const Value.absent(), this.id = const Value.absent(),
@ -969,7 +930,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
this.equipment = const Value.absent(), this.equipment = const Value.absent(),
this.primaryMuscles = const Value.absent(), this.primaryMuscles = const Value.absent(),
this.secondaryMuscles = const Value.absent(), this.secondaryMuscles = const Value.absent(),
this.images = const Value.absent(),
this.createdAt = const Value.absent(), this.createdAt = const Value.absent(),
}); });
ActivitiesCompanion.insert({ ActivitiesCompanion.insert({
@ -984,7 +944,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
this.equipment = const Value.absent(), this.equipment = const Value.absent(),
this.primaryMuscles = const Value.absent(), this.primaryMuscles = const Value.absent(),
this.secondaryMuscles = const Value.absent(), this.secondaryMuscles = const Value.absent(),
this.images = const Value.absent(),
this.createdAt = const Value.absent(), this.createdAt = const Value.absent(),
}) : title = Value(title); }) : title = Value(title);
static Insertable<Activity> custom({ static Insertable<Activity> custom({
@ -999,7 +958,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
Expression<String>? equipment, Expression<String>? equipment,
Expression<String>? primaryMuscles, Expression<String>? primaryMuscles,
Expression<String>? secondaryMuscles, Expression<String>? secondaryMuscles,
Expression<String>? images,
Expression<DateTime>? createdAt, Expression<DateTime>? createdAt,
}) { }) {
return RawValuesInsertable({ return RawValuesInsertable({
@ -1014,7 +972,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
if (equipment != null) 'equipment': equipment, if (equipment != null) 'equipment': equipment,
if (primaryMuscles != null) 'primary_muscles': primaryMuscles, if (primaryMuscles != null) 'primary_muscles': primaryMuscles,
if (secondaryMuscles != null) 'secondary_muscles': secondaryMuscles, if (secondaryMuscles != null) 'secondary_muscles': secondaryMuscles,
if (images != null) 'images': images,
if (createdAt != null) 'created_at': createdAt, if (createdAt != null) 'created_at': createdAt,
}); });
} }
@ -1031,7 +988,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
Value<ActivityEquipment?>? equipment, Value<ActivityEquipment?>? equipment,
Value<ActivityMuscle?>? primaryMuscles, Value<ActivityMuscle?>? primaryMuscles,
Value<ActivityMuscle?>? secondaryMuscles, Value<ActivityMuscle?>? secondaryMuscles,
Value<String?>? images,
Value<DateTime>? createdAt}) { Value<DateTime>? createdAt}) {
return ActivitiesCompanion( return ActivitiesCompanion(
id: id ?? this.id, id: id ?? this.id,
@ -1045,7 +1001,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
equipment: equipment ?? this.equipment, equipment: equipment ?? this.equipment,
primaryMuscles: primaryMuscles ?? this.primaryMuscles, primaryMuscles: primaryMuscles ?? this.primaryMuscles,
secondaryMuscles: secondaryMuscles ?? this.secondaryMuscles, secondaryMuscles: secondaryMuscles ?? this.secondaryMuscles,
images: images ?? this.images,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
); );
} }
@ -1095,9 +1050,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
.$convertersecondaryMusclesn .$convertersecondaryMusclesn
.toSql(secondaryMuscles.value)); .toSql(secondaryMuscles.value));
} }
if (images.present) {
map['images'] = Variable<String>(images.value);
}
if (createdAt.present) { if (createdAt.present) {
map['created_at'] = Variable<DateTime>(createdAt.value); map['created_at'] = Variable<DateTime>(createdAt.value);
} }
@ -1118,7 +1070,6 @@ class ActivitiesCompanion extends UpdateCompanion<Activity> {
..write('equipment: $equipment, ') ..write('equipment: $equipment, ')
..write('primaryMuscles: $primaryMuscles, ') ..write('primaryMuscles: $primaryMuscles, ')
..write('secondaryMuscles: $secondaryMuscles, ') ..write('secondaryMuscles: $secondaryMuscles, ')
..write('images: $images, ')
..write('createdAt: $createdAt') ..write('createdAt: $createdAt')
..write(')')) ..write(')'))
.toString(); .toString();
@ -2098,7 +2049,7 @@ class $MediaItemsTable extends MediaItems
late final GeneratedColumn<String> title = GeneratedColumn<String>( late final GeneratedColumn<String> title = GeneratedColumn<String>(
'title', aliasedName, false, 'title', aliasedName, false,
additionalChecks: additionalChecks:
GeneratedColumn.checkTextLength(minTextLength: 3, maxTextLength: 32), GeneratedColumn.checkTextLength(minTextLength: 3, maxTextLength: 64),
type: DriftSqlType.string, type: DriftSqlType.string,
requiredDuringInsert: true); requiredDuringInsert: true);
static const VerificationMeta _descriptionMeta = static const VerificationMeta _descriptionMeta =
@ -3117,7 +3068,6 @@ typedef $$ActivitiesTableCreateCompanionBuilder = ActivitiesCompanion Function({
Value<ActivityEquipment?> equipment, Value<ActivityEquipment?> equipment,
Value<ActivityMuscle?> primaryMuscles, Value<ActivityMuscle?> primaryMuscles,
Value<ActivityMuscle?> secondaryMuscles, Value<ActivityMuscle?> secondaryMuscles,
Value<String?> images,
Value<DateTime> createdAt, Value<DateTime> createdAt,
}); });
typedef $$ActivitiesTableUpdateCompanionBuilder = ActivitiesCompanion Function({ typedef $$ActivitiesTableUpdateCompanionBuilder = ActivitiesCompanion Function({
@ -3132,7 +3082,6 @@ typedef $$ActivitiesTableUpdateCompanionBuilder = ActivitiesCompanion Function({
Value<ActivityEquipment?> equipment, Value<ActivityEquipment?> equipment,
Value<ActivityMuscle?> primaryMuscles, Value<ActivityMuscle?> primaryMuscles,
Value<ActivityMuscle?> secondaryMuscles, Value<ActivityMuscle?> secondaryMuscles,
Value<String?> images,
Value<DateTime> createdAt, Value<DateTime> createdAt,
}); });
@ -3232,9 +3181,6 @@ class $$ActivitiesTableFilterComposer
column: $table.secondaryMuscles, column: $table.secondaryMuscles,
builder: (column) => ColumnWithTypeConverterFilters(column)); builder: (column) => ColumnWithTypeConverterFilters(column));
ColumnFilters<String> get images => $composableBuilder(
column: $table.images, builder: (column) => ColumnFilters(column));
ColumnFilters<DateTime> get createdAt => $composableBuilder( ColumnFilters<DateTime> get createdAt => $composableBuilder(
column: $table.createdAt, builder: (column) => ColumnFilters(column)); column: $table.createdAt, builder: (column) => ColumnFilters(column));
@ -3325,9 +3271,6 @@ class $$ActivitiesTableOrderingComposer
column: $table.secondaryMuscles, column: $table.secondaryMuscles,
builder: (column) => ColumnOrderings(column)); builder: (column) => ColumnOrderings(column));
ColumnOrderings<String> get images => $composableBuilder(
column: $table.images, builder: (column) => ColumnOrderings(column));
ColumnOrderings<DateTime> get createdAt => $composableBuilder( ColumnOrderings<DateTime> get createdAt => $composableBuilder(
column: $table.createdAt, builder: (column) => ColumnOrderings(column)); column: $table.createdAt, builder: (column) => ColumnOrderings(column));
} }
@ -3376,9 +3319,6 @@ class $$ActivitiesTableAnnotationComposer
get secondaryMuscles => $composableBuilder( get secondaryMuscles => $composableBuilder(
column: $table.secondaryMuscles, builder: (column) => column); column: $table.secondaryMuscles, builder: (column) => column);
GeneratedColumn<String> get images =>
$composableBuilder(column: $table.images, builder: (column) => column);
GeneratedColumn<DateTime> get createdAt => GeneratedColumn<DateTime> get createdAt =>
$composableBuilder(column: $table.createdAt, builder: (column) => column); $composableBuilder(column: $table.createdAt, builder: (column) => column);
@ -3461,7 +3401,6 @@ class $$ActivitiesTableTableManager extends RootTableManager<
Value<ActivityEquipment?> equipment = const Value.absent(), Value<ActivityEquipment?> equipment = const Value.absent(),
Value<ActivityMuscle?> primaryMuscles = const Value.absent(), Value<ActivityMuscle?> primaryMuscles = const Value.absent(),
Value<ActivityMuscle?> secondaryMuscles = const Value.absent(), Value<ActivityMuscle?> secondaryMuscles = const Value.absent(),
Value<String?> images = const Value.absent(),
Value<DateTime> createdAt = const Value.absent(), Value<DateTime> createdAt = const Value.absent(),
}) => }) =>
ActivitiesCompanion( ActivitiesCompanion(
@ -3476,7 +3415,6 @@ class $$ActivitiesTableTableManager extends RootTableManager<
equipment: equipment, equipment: equipment,
primaryMuscles: primaryMuscles, primaryMuscles: primaryMuscles,
secondaryMuscles: secondaryMuscles, secondaryMuscles: secondaryMuscles,
images: images,
createdAt: createdAt, createdAt: createdAt,
), ),
createCompanionCallback: ({ createCompanionCallback: ({
@ -3491,7 +3429,6 @@ class $$ActivitiesTableTableManager extends RootTableManager<
Value<ActivityEquipment?> equipment = const Value.absent(), Value<ActivityEquipment?> equipment = const Value.absent(),
Value<ActivityMuscle?> primaryMuscles = const Value.absent(), Value<ActivityMuscle?> primaryMuscles = const Value.absent(),
Value<ActivityMuscle?> secondaryMuscles = const Value.absent(), Value<ActivityMuscle?> secondaryMuscles = const Value.absent(),
Value<String?> images = const Value.absent(),
Value<DateTime> createdAt = const Value.absent(), Value<DateTime> createdAt = const Value.absent(),
}) => }) =>
ActivitiesCompanion.insert( ActivitiesCompanion.insert(
@ -3506,7 +3443,6 @@ class $$ActivitiesTableTableManager extends RootTableManager<
equipment: equipment, equipment: equipment,
primaryMuscles: primaryMuscles, primaryMuscles: primaryMuscles,
secondaryMuscles: secondaryMuscles, secondaryMuscles: secondaryMuscles,
images: images,
createdAt: createdAt, createdAt: createdAt,
), ),
withReferenceMapper: (p0) => p0 withReferenceMapper: (p0) => p0

View File

@ -2901,6 +2901,178 @@ i1.GeneratedColumn<String> _column_40(String aliasedName) =>
additionalChecks: i1.GeneratedColumn.checkTextLength( additionalChecks: i1.GeneratedColumn.checkTextLength(
minTextLength: 3, maxTextLength: 100), minTextLength: 3, maxTextLength: 100),
type: i1.DriftSqlType.string); type: i1.DriftSqlType.string);
final class Schema20 extends i0.VersionedSchema {
Schema20({required super.database}) : super(version: 20);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
sessions,
activities,
sessionActivities,
actions,
activityActions,
mediaItems,
objectMediaItems,
];
late final Shape12 sessions = Shape12(
source: i0.VersionedTable(
entityName: 'sessions',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
_column_11,
_column_20,
_column_4,
_column_5,
],
attachedDatabase: database,
),
alias: null);
late final Shape17 activities = Shape17(
source: i0.VersionedTable(
entityName: 'activities',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_40,
_column_36,
_column_37,
_column_38,
_column_27,
_column_28,
_column_29,
_column_35,
_column_31,
_column_32,
_column_5,
],
attachedDatabase: database,
),
alias: null);
late final Shape13 sessionActivities = Shape13(
source: i0.VersionedTable(
entityName: 'session_activities',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_21,
_column_22,
_column_19,
_column_10,
_column_5,
],
attachedDatabase: database,
),
alias: null);
late final Shape3 actions = Shape3(
source: i0.VersionedTable(
entityName: 'actions',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_2,
_column_12,
_column_5,
],
attachedDatabase: database,
),
alias: null);
late final Shape10 activityActions = Shape10(
source: i0.VersionedTable(
entityName: 'activity_actions',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_22,
_column_23,
_column_19,
_column_5,
],
attachedDatabase: database,
),
alias: null);
late final Shape5 mediaItems = Shape5(
source: i0.VersionedTable(
entityName: 'media_items',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_41,
_column_2,
_column_25,
_column_6,
_column_5,
],
attachedDatabase: database,
),
alias: null);
late final Shape6 objectMediaItems = Shape6(
source: i0.VersionedTable(
entityName: 'object_media_items',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_15,
_column_16,
_column_24,
_column_5,
],
attachedDatabase: database,
),
alias: null);
}
class Shape17 extends i0.VersionedTable {
Shape17({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get title =>
columnsByName['title']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get type =>
columnsByName['type']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get description =>
columnsByName['body']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get category =>
columnsByName['category']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get force =>
columnsByName['force']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get level =>
columnsByName['level']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get mechanic =>
columnsByName['mechanic']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get equipment =>
columnsByName['equipment']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get primaryMuscles =>
columnsByName['primary_muscles']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get secondaryMuscles =>
columnsByName['secondary_muscles']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
}
i1.GeneratedColumn<String> _column_41(String aliasedName) =>
i1.GeneratedColumn<String>('title', aliasedName, false,
additionalChecks: i1.GeneratedColumn.checkTextLength(
minTextLength: 3, maxTextLength: 64),
type: i1.DriftSqlType.string);
i0.MigrationStepWithVersion migrationSteps({ i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2, required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3, required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
@ -2920,6 +3092,7 @@ i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17, required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18, required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18,
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19, required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
required Future<void> Function(i1.Migrator m, Schema20 schema) from19To20,
}) { }) {
return (currentVersion, database) async { return (currentVersion, database) async {
switch (currentVersion) { switch (currentVersion) {
@ -3013,6 +3186,11 @@ i0.MigrationStepWithVersion migrationSteps({
final migrator = i1.Migrator(database, schema); final migrator = i1.Migrator(database, schema);
await from18To19(migrator, schema); await from18To19(migrator, schema);
return 19; return 19;
case 19:
final schema = Schema20(database: database);
final migrator = i1.Migrator(database, schema);
await from19To20(migrator, schema);
return 20;
default: default:
throw ArgumentError.value('Unknown migration from $currentVersion'); throw ArgumentError.value('Unknown migration from $currentVersion');
} }
@ -3038,6 +3216,7 @@ i1.OnUpgrade stepByStep({
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17, required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18, required Future<void> Function(i1.Migrator m, Schema18 schema) from17To18,
required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19, required Future<void> Function(i1.Migrator m, Schema19 schema) from18To19,
required Future<void> Function(i1.Migrator m, Schema20 schema) from19To20,
}) => }) =>
i0.VersionedSchema.stepByStepHelper( i0.VersionedSchema.stepByStepHelper(
step: migrationSteps( step: migrationSteps(
@ -3059,4 +3238,5 @@ i1.OnUpgrade stepByStep({
from16To17: from16To17, from16To17: from16To17,
from17To18: from17To18, from17To18: from17To18,
from18To19: from18To19, from18To19: from18To19,
from19To20: from19To20,
)); ));

File diff suppressed because one or more lines are too long

View File

@ -73,7 +73,7 @@ Future<void> seedDb(AppDatabase database) async {
Map<Symbol, Value> payload = { Map<Symbol, Value> payload = {
Symbol('title'): Value<String>(exercise['name']), Symbol('title'): Value<String>(exercise['name']),
Symbol('description'): Value<String>(exercise['instructions'].toString()), Symbol('description'): Value<String>(json.encode(exercise['instructions'])),
Symbol('force'): Value<String>(exercise['force'] ?? "") Symbol('force'): Value<String>(exercise['force'] ?? "")
}; };
@ -124,9 +124,9 @@ Future<void> seedDb(AppDatabase database) async {
await database await database
.into(database.mediaItems) .into(database.mediaItems)
.insert(MediaItemsCompanion.insert( .insert(MediaItemsCompanion.insert(
title: 'Media title $m', title: exercise['name'],
description: description:
'Media description $m Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.', exercise['name'],
reference: mediaItem, reference: mediaItem,
type: MediaType.image)) type: MediaType.image))
.then((mediaId) async { .then((mediaId) async {

View File

@ -6,10 +6,11 @@ showMediaDetailWidget(BuildContext context, MediaItem media) {
showEditorSheet(context, MediaDetails(media: media)); showEditorSheet(context, MediaDetails(media: media));
} }
showEditorSheet(BuildContext context, Widget widget) { showGenericSheet(BuildContext context, Widget widget) {
showModalBottomSheet<void>( showModalBottomSheet<void>(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)), borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)),
), ),
context: context, context: context,
showDragHandle: true, showDragHandle: true,
@ -19,3 +20,21 @@ showEditorSheet(BuildContext context, Widget widget) {
return widget; return widget;
}); });
} }
showEditorSheet(BuildContext context, Widget widget) {
showGenericSheet(context, widget);
}
String jsonToDescription(List text) {
String content = '';
for (int i = 0; i < text.length; i++) {
if (content.isEmpty) {
content = text[i];
} else {
content = "$content\n\n${text[i]}";
}
}
return content;
}

View File

@ -19,9 +19,9 @@ class ActivityTimerModel with ChangeNotifier {
int get actionCount => _actionCounter; int get actionCount => _actionCounter;
int get currentActionNum => _currentActionNum; int get currentActionNum => _currentActionNum;
dynamic get currentAction => currentSet[_currentActionNum]; dynamic get currentAction => currentSet.isNotEmpty ? currentSet[_currentActionNum] : {};
int get currentSetNum => _currentSetNum; int get currentSetNum => _currentSetNum;
dynamic get currentSet => _sets[_currentSetNum]; dynamic get currentSet => _sets.isNotEmpty ? _sets[_currentSetNum] : {};
Activity? get activity => _activity; Activity? get activity => _activity;
List get sets => _sets; List get sets => _sets;
Timer? get periodicTimer => _periodicTimer; Timer? get periodicTimer => _periodicTimer;
@ -36,7 +36,7 @@ class ActivityTimerModel with ChangeNotifier {
_isc = null; _isc = null;
_activity = activity; _activity = activity;
// only one action for now // only one action for now
_sets = json.decode(actions[0].set); _sets = actions.isNotEmpty ? json.decode(actions[0].set) : [];
// _actions = actions; // _actions = actions;
_currentActionNum = 0; _currentActionNum = 0;
_currentSetNum = 0; _currentSetNum = 0;
@ -92,7 +92,7 @@ class ActivityTimerModel with ChangeNotifier {
} }
void setActionCount() { void setActionCount() {
_actionCounter = currentAction['amount']; _actionCounter = currentAction.isNotEmpty ? currentAction['amount'] : 0;
} }
void pause() { void pause() {

View File

@ -1,8 +1,10 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/daos/activities_dao.dart'; import 'package:sendtrain/daos/activities_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
// import 'package:sendtrain/widgets/activities/activity_card.dart'; import 'package:sendtrain/helpers/widget_helpers.dart';
import 'package:sendtrain/widgets/generic/elements/form_search_input.dart'; import 'package:sendtrain/widgets/generic/elements/form_search_input.dart';
class ActivityFinderService { class ActivityFinderService {
@ -27,10 +29,10 @@ class ActivityFinderService {
} }
Widget resultWidget(Activity activity, Function? callback) { Widget resultWidget(Activity activity, Function? callback) {
// return ActivityCard(activity: activity, callback: callback);
return ListTile( return ListTile(
title: Text(activity.title), title: Text(activity.title),
subtitle: Text(activity.description ?? ""), subtitle: Text(jsonToDescription(json.decode(activity.description ?? "")),
maxLines: 2, softWrap: true, overflow: TextOverflow.ellipsis),
onTap: () { onTap: () {
if (callback != null) { if (callback != null) {
callback(); callback();

View File

@ -1,11 +1,14 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/daos/activities_dao.dart';
import 'package:sendtrain/daos/media_items_dao.dart'; import 'package:sendtrain/daos/media_items_dao.dart';
import 'package:sendtrain/daos/session_activities_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/extensions/string_extensions.dart'; import 'package:sendtrain/extensions/string_extensions.dart';
import 'package:sendtrain/helpers/date_time_helpers.dart'; import 'package:sendtrain/helpers/date_time_helpers.dart';
import 'package:sendtrain/helpers/media_helpers.dart'; import 'package:sendtrain/helpers/media_helpers.dart';
import 'package:sendtrain/helpers/widget_helpers.dart';
import 'package:sendtrain/models/activity_timer_model.dart'; import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/widgets/activities/activity_view.dart'; import 'package:sendtrain/widgets/activities/activity_view.dart';
import 'package:sendtrain/widgets/builders/dialogs.dart'; import 'package:sendtrain/widgets/builders/dialogs.dart';
@ -14,9 +17,14 @@ import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.da
class ActivityCard extends StatefulWidget { class ActivityCard extends StatefulWidget {
final Activity activity; final Activity activity;
final Session session;
final Function? callback; final Function? callback;
const ActivityCard({super.key, required this.activity, this.callback}); const ActivityCard(
{super.key,
required this.activity,
required this.session,
this.callback});
@override @override
State<ActivityCard> createState() => ActivityCardState(); State<ActivityCard> createState() => ActivityCardState();
@ -54,16 +62,22 @@ class ActivityCardState extends State<ActivityCard> {
if (atm.activity?.id == widget.activity.id) { if (atm.activity?.id == widget.activity.id) {
return Text( return Text(
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis,
"${widget.activity.title.toTitleCase()} (${formattedTime(atm.totalTime)})"); "${widget.activity.title.toTitleCase()} (${formattedTime(atm.totalTime)})");
} else { } else {
return Text( return Text(
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis,
widget.activity.title.toTitleCase()); widget.activity.title.toTitleCase());
} }
}, },
), ),
subtitle: subtitle: Text(
Text(maxLines: 2, widget.activity.description ?? ""), overflow: TextOverflow.ellipsis,
maxLines: 2,
softWrap: true,
jsonToDescription(json
.decode(widget.activity.description ?? ""))),
contentPadding: EdgeInsets.only(left: 13), contentPadding: EdgeInsets.only(left: 13),
trailing: Flex( trailing: Flex(
direction: Axis.vertical, direction: Axis.vertical,
@ -79,10 +93,11 @@ class ActivityCardState extends State<ActivityCard> {
'Activity Removal', 'Activity Removal',
'Would you like to permanently remove this activity from the current session?', 'Would you like to permanently remove this activity from the current session?',
context, () { context, () {
ActivitiesDao(Provider.of<AppDatabase>( SessionActivitiesDao(
context, Provider.of<AppDatabase>(context,
listen: false)) listen: false))
.remove(widget.activity); .removeAssociation(widget.activity.id,
widget.session.id);
}).then((result) { }).then((result) {
setState(() {}); setState(() {});
}); });

View File

@ -1,18 +1,20 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/daos/actions_dao.dart'; import 'package:sendtrain/daos/actions_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/extensions/string_extensions.dart'; import 'package:sendtrain/extensions/string_extensions.dart';
import 'package:sendtrain/helpers/widget_helpers.dart';
import 'package:sendtrain/models/activity_timer_model.dart'; import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/widgets/activities/activity_action_view.dart'; import 'package:sendtrain/widgets/activities/activity_action_view.dart';
import 'package:sendtrain/widgets/activities/activity_view_categories.dart'; import 'package:sendtrain/widgets/activities/activity_view_categories.dart';
import 'package:sendtrain/widgets/activities/activity_view_media.dart'; import 'package:sendtrain/widgets/activities/activity_view_media.dart';
import 'package:sendtrain/widgets/activities/activity_view_types.dart'; import 'package:sendtrain/widgets/generic/elements/add_card_generic.dart';
class ActivityView extends StatefulWidget { class ActivityView extends StatefulWidget {
const ActivityView( const ActivityView({super.key, required this.activity});
{super.key, required this.activity});
final Activity activity; final Activity activity;
@override @override
@ -20,6 +22,98 @@ class ActivityView extends StatefulWidget {
} }
class _ActivityViewState extends State<ActivityView> { class _ActivityViewState extends State<ActivityView> {
List<ActivityMuscle> activity_muscle(Activity activity) {
List<ActivityMuscle> muscles = [];
if (activity.primaryMuscles != null) {
muscles.add(activity.primaryMuscles!);
}
if (activity.secondaryMuscles != null) {
muscles.add(activity.secondaryMuscles!);
}
return muscles;
}
List<Widget> action(actions) {
if (actions.isNotEmpty) {
return [
Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Card(
clipBehavior: Clip.antiAlias,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10)),
),
color: Theme.of(context).colorScheme.onPrimary,
child: Row(children: [
Ink(
width: 70,
color: Theme.of(context).colorScheme.primaryContainer,
child: Consumer<ActivityTimerModel>(
builder: (context, atm, child) {
return IconButton(
alignment: AlignmentDirectional.center,
icon: atm.isActive
? const Icon(Icons.pause_rounded)
: const Icon(Icons.play_arrow_rounded),
onPressed: () =>
{atm.isActive ? atm.pause() : atm.start()});
},
)),
Expanded(
flex: 1,
child: Stack(alignment: Alignment.center, children: [
Container(
alignment: Alignment.center,
child: Consumer<ActivityTimerModel>(
builder: (context, atm, child) {
return Text(
style: const TextStyle(fontSize: 20),
textAlign: TextAlign.center,
'${atm.actionCount} ${atm.currentAction['type']}'
.toTitleCase());
},
),
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 15),
child: Consumer<ActivityTimerModel>(
builder: (context, atm, child) {
return Text(
style: const TextStyle(fontSize: 12),
textAlign: TextAlign.right,
'${atm.currentAction['actionID'] + 1} of ${atm.totalActions()}');
})),
])),
]))),
Padding(
padding: EdgeInsets.only(left: 14, right: 14),
child: Consumer<ActivityTimerModel>(builder: (context, atm, child) {
return LinearProgressIndicator(
value: atm.progress,
semanticsLabel: 'Activity Progress',
);
})),
ActivityActionView(actions: actions)
];
} else {
return [
AddCardGeneric(
title: 'Add an Action!',
description:
'Click here to create an exercise template (sets and reps, etc) for your activity!',
action: () {
print('teset');
})
];
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Activity activity = widget.activity; final Activity activity = widget.activity;
@ -44,11 +138,11 @@ class _ActivityViewState extends State<ActivityView> {
blur: 10, blur: 10,
), ),
children: [ children: [
FloatingActionButton.extended( // FloatingActionButton.extended(
icon: const Icon(Icons.upload_outlined), // icon: const Icon(Icons.upload_outlined),
label: Text('Upload Media'), // label: Text('Upload Media'),
onPressed: () {}, // onPressed: () {},
), // ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.note_add_outlined), icon: const Icon(Icons.note_add_outlined),
label: Text('Add Note'), label: Text('Add Note'),
@ -68,125 +162,204 @@ class _ActivityViewState extends State<ActivityView> {
body: Column( body: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
AppBar( AppBar(
titleSpacing: 0, titleSpacing: 0,
centerTitle: true, centerTitle: true,
title: const Text('Activity', title: const Text('Activity',
style: TextStyle(fontSize: 15)), style: TextStyle(fontSize: 15)),
), ),
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 15, right: 20, top: 15, bottom: 10), left: 15, right: 20, top: 15, bottom: 10),
child: Text( child: Text(
maxLines: 1, maxLines: 1,
style: const TextStyle( style: const TextStyle(
fontSize: 25, fontWeight: FontWeight.bold), fontSize: 25,
activity.title.toTitleCase())), fontWeight: FontWeight.bold),
Padding( activity.title.toTitleCase())),
padding: const EdgeInsets.fromLTRB(10, 0, 0, 10), SizedBox(
child: Flex(direction: Axis.horizontal, children: [ height: 40,
ActivityViewCategories( child: ListView(
categories: activity.category != null ? [activity.category!] : []), scrollDirection: Axis.horizontal,
ActivityViewTypes(types: [activity.type!]) padding:
])), const EdgeInsets.fromLTRB(10, 0, 10, 0),
Padding( shrinkWrap: true,
padding: const EdgeInsets.only( children: [
top: 0, bottom: 10, left: 15, right: 15), ActivityViewCategories<List<ActivityLevel>>(
child: Text( icon: Icon(Icons.stairs_rounded),
textAlign: TextAlign.left, text: "Activity Level",
style: const TextStyle(fontSize: 15), object: activity.level != null
activity.description ?? "")), ? [activity.level!]
const Padding( : []),
padding: EdgeInsets.fromLTRB(15, 20, 0, 10), // ActivityViewCategories<List<ActivityMechanic>>(
child: Text( // icon: Icon(Icons.),
style: TextStyle( // text: 'Activity Mechanic',
fontSize: 20, fontWeight: FontWeight.bold), // object: activity.mechanic != null
'Media:')), // ? [activity.mechanic!]
ActivityViewMedia(activity: activity), // : []),
const Padding( ActivityViewCategories<
padding: EdgeInsets.fromLTRB(15, 30, 0, 10), List<ActivityEquipment>>(
child: Text( icon:
textAlign: TextAlign.left, Icon(Icons.fitness_center_rounded),
style: TextStyle( text: 'Equipment Used',
fontSize: 20, fontWeight: FontWeight.bold), object: activity.equipment != null
'Actions')), ? [activity.equipment!]
Padding( : []),
padding: const EdgeInsets.only(left: 10, right: 10), ActivityViewCategories<List<ActivityType>>(
child: Card( icon: Icon(Icons.type_specimen_rounded),
clipBehavior: Clip.antiAlias, text: 'Activity Type',
shape: const RoundedRectangleBorder( object: activity.type != null
borderRadius: BorderRadius.only( ? [activity.type!]
topLeft: Radius.circular(10), : []),
topRight: Radius.circular(10)), ActivityViewCategories<
), List<ActivityMuscle>>(
color: Theme.of(context).colorScheme.onPrimary, icon: Icon(Icons.person),
child: Row(children: [ text: 'Muscles used',
Ink( object: activity_muscle(activity))
width: 70, ])),
color: Theme.of(context) Padding(
.colorScheme padding: const EdgeInsets.only(
.primaryContainer, top: 10, bottom: 0, left: 15, right: 15),
child: Consumer<ActivityTimerModel>( child: Text(
builder: (context, atm, child) { maxLines: 4,
return IconButton( overflow: TextOverflow.ellipsis,
alignment: // softWrap: true,
AlignmentDirectional.center, textAlign: TextAlign.left,
icon: atm.isActive style: const TextStyle(fontSize: 15),
? const Icon( jsonToDescription([
Icons.pause_rounded) json.decode(activity.description ?? "")[0]
: const Icon( ]))),
Icons.play_arrow_rounded), Padding(
onPressed: () => { padding: EdgeInsets.only(right: 15),
atm.isActive child: Align(
? atm.pause() alignment: Alignment.topRight,
: atm.start() child: TextButton(
}); style: ButtonStyle(
}, textStyle:
)), WidgetStateProperty.all<TextStyle>(
Expanded( TextStyle(
flex: 1, fontWeight:
child: Stack( FontWeight.normal)),
alignment: Alignment.center, shape: WidgetStateProperty.all<
children: [ RoundedRectangleBorder>(
Container( RoundedRectangleBorder(
alignment: Alignment.center, borderRadius:
child: Consumer<ActivityTimerModel>( BorderRadius.circular(10.0),
builder: (context, atm, child) { ))),
return Text( onPressed: () {
style: const TextStyle( showGenericSheet(
fontSize: 20), context,
textAlign: TextAlign.center, Padding(
'${atm.actionCount} ${atm.currentAction['type']}'.toTitleCase()); padding: EdgeInsets.all(15),
}, child: Text(
), style:
), TextStyle(fontSize: 18),
Container( jsonToDescription(json.decode(
alignment: Alignment.centerRight, activity.description ??
padding: "")))));
EdgeInsets.only(right: 15), },
child: child: Text(
Consumer<ActivityTimerModel>( "read more",
builder: (context, atm, textAlign: TextAlign.right,
child) { style: TextStyle(fontSize: 12),
return Text( ),
style: const TextStyle( ))),
fontSize: 12), const Padding(
textAlign: TextAlign.right, padding: EdgeInsets.fromLTRB(15, 10, 0, 10),
'${atm.currentAction['actionID'] + 1} of ${atm.totalActions()}'); child: Text(
})), style: TextStyle(
])), fontSize: 20,
]))), fontWeight: FontWeight.bold),
Padding( 'Media:')),
padding: EdgeInsets.only(left: 14, right: 14), ActivityViewMedia(activity: activity),
child: Consumer<ActivityTimerModel>( const Padding(
builder: (context, atm, child) { padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
return LinearProgressIndicator( child: Text(
value: atm.progress, textAlign: TextAlign.left,
semanticsLabel: 'Activity Progress', style: TextStyle(
); fontSize: 20,
})), fontWeight: FontWeight.bold),
ActivityActionView(actions: actions), 'Actions')),
]));
// Padding(
// padding: const EdgeInsets.only(left: 10, right: 10),
// child: Card(
// clipBehavior: Clip.antiAlias,
// shape: const RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(10),
// topRight: Radius.circular(10)),
// ),
// color: Theme.of(context).colorScheme.onPrimary,
// child: Row(children: [
// Ink(
// width: 70,
// color: Theme.of(context)
// .colorScheme
// .primaryContainer,
// child: Consumer<ActivityTimerModel>(
// builder: (context, atm, child) {
// return IconButton(
// alignment:
// AlignmentDirectional.center,
// icon: atm.isActive
// ? const Icon(
// Icons.pause_rounded)
// : const Icon(
// Icons.play_arrow_rounded),
// onPressed: () => {
// atm.isActive
// ? atm.pause()
// : atm.start()
// });
// },
// )),
// Expanded(
// flex: 1,
// child: Stack(
// alignment: Alignment.center,
// children: [
// Container(
// alignment: Alignment.center,
// child: Consumer<ActivityTimerModel>(
// builder: (context, atm, child) {
// return Text(
// style: const TextStyle(
// fontSize: 20),
// textAlign: TextAlign.center,
// '${atm.actionCount} ${atm.currentAction['type']}'
// .toTitleCase());
// },
// ),
// ),
// Container(
// alignment: Alignment.centerRight,
// padding:
// EdgeInsets.only(right: 15),
// child:
// Consumer<ActivityTimerModel>(
// builder: (context, atm,
// child) {
// return Text(
// style: const TextStyle(
// fontSize: 12),
// textAlign: TextAlign.right,
// '${atm.currentAction['actionID'] + 1} of ${atm.totalActions()}');
// })),
// ])),
// ]))),
// Padding(
// padding: EdgeInsets.only(left: 14, right: 14),
// child: Consumer<ActivityTimerModel>(
// builder: (context, atm, child) {
// return LinearProgressIndicator(
// value: atm.progress,
// semanticsLabel: 'Activity Progress',
// );
// })),
// ActivityActionView(actions: actions),
] +
action(actions)));
} else { } else {
return Container( return Container(
alignment: Alignment.center, alignment: Alignment.center,

View File

@ -1,30 +1,35 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/extensions/string_extensions.dart'; import 'package:sendtrain/extensions/string_extensions.dart';
class ActivityViewCategories extends StatelessWidget { class ActivityViewCategories<T extends List<Enum>> extends StatelessWidget {
const ActivityViewCategories({super.key, required this.categories}); const ActivityViewCategories(
{super.key,
required this.object,
required this.icon,
required this.text});
final List<ActivityCategories> categories; final T object;
final Icon icon;
final String text;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return ListView.builder(
height: 40, shrinkWrap: true,
child: ListView.builder( scrollDirection: Axis.horizontal,
shrinkWrap: true, // padding: const EdgeInsets.only(right: 10, left: 10),
scrollDirection: Axis.horizontal, itemCount: object.length,
padding: const EdgeInsets.only(right: 10), itemBuilder: (BuildContext context, int index) {
itemCount: categories.length, return Padding(
itemBuilder: (BuildContext context, int index) { padding: EdgeInsets.only(right: 10),
return ActionChip( child: ActionChip(
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
avatar: const Icon(Icons.category_rounded), avatar: icon,
label: Text(maxLines: 1, categories[index].name.toTitleCase()), label: Text(maxLines: 1, object[index].name.toTitleCase()),
tooltip: "Activity Category", tooltip: text,
onPressed: () {}, onPressed: () {},
); ));
}, },
)); );
} }
} }

View File

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
class AddCardGeneric extends StatelessWidget {
const AddCardGeneric(
{super.key, required this.title, required this.description, this.action});
final String title;
final String description;
final Function? action;
@override
Widget build(BuildContext context) {
return Expanded(
child: ListView(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
children: [
Card.outlined(
child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
onTap: () {
if (action != null) {
action!();
}
},
child: ListTile(
contentPadding:
EdgeInsets.only(top: 5, left: 15, right: 5, bottom: 5),
autofocus: true,
leading: Icon(Icons.add_box_rounded),
title: Text(title),
subtitle: Text(description),
)))
]));
}
}

View File

@ -57,8 +57,7 @@ class _FormSearchInputState extends State<FormSearchInput> {
_currentQuery = query; _currentQuery = query;
// In a real application, there should be some error handling here. // In a real application, there should be some error handling here.
// final Iterable<String> options = await _FakeAPI.search(_currentQuery!); if (query.isNotEmpty && query.length > 3) {
if (query.isNotEmpty) {
final List<Suggestion>? suggestions = final List<Suggestion>? suggestions =
await service.fetchSuggestions(_currentQuery!); await service.fetchSuggestions(_currentQuery!);

View File

@ -11,9 +11,11 @@ import 'package:sendtrain/widgets/builders/dialogs.dart';
import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
class MediaCard extends StatelessWidget { class MediaCard extends StatelessWidget {
const MediaCard({super.key, required this.media, this.callback}); const MediaCard(
{super.key, required this.media, this.callback, this.canDelete});
final MediaItem media; final MediaItem media;
final bool? canDelete;
final Function? callback; final Function? callback;
@override @override
@ -44,7 +46,9 @@ class MediaCard extends StatelessWidget {
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
shadowColor: const Color.fromARGB(0, 255, 255, 255), shadowColor: const Color.fromARGB(0, 255, 255, 255),
child: TextButton( child: TextButton(
onLongPress: () => showRemovalDialog( onLongPress: () {
if (canDelete == true) {
showRemovalDialog(
'Media Removal', 'Media Removal',
'Would you like to permanently remove this media from the current session?', 'Would you like to permanently remove this media from the current session?',
context, () { context, () {
@ -55,7 +59,9 @@ class MediaCard extends StatelessWidget {
if (callback != null) { if (callback != null) {
callback!(); callback!();
} }
}), });
}
},
onPressed: () => showMediaDetailWidget(context, media), onPressed: () => showMediaDetailWidget(context, media),
child: const ListTile( child: const ListTile(
title: Text(''), title: Text(''),

View File

@ -83,7 +83,7 @@ class _SessionViewState extends State<SessionView> {
), ),
children: [ children: [
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined), icon: const Icon(Icons.military_tech_rounded),
label: Text('Add Achievement'), label: Text('Add Achievement'),
onPressed: () { onPressed: () {
showEditorSheet( showEditorSheet(
@ -93,7 +93,7 @@ class _SessionViewState extends State<SessionView> {
}, },
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined), icon: const Icon(Icons.sports_gymnastics_rounded),
label: Text('Add Activity'), label: Text('Add Activity'),
onPressed: () { onPressed: () {
showEditorSheet( showEditorSheet(
@ -104,7 +104,7 @@ class _SessionViewState extends State<SessionView> {
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined), icon: const Icon(Icons.edit_outlined),
label: Text('Edit'), label: Text('Edit Session'),
onPressed: () { onPressed: () {
showEditorSheet( showEditorSheet(
context, context,
@ -114,7 +114,7 @@ class _SessionViewState extends State<SessionView> {
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.history_outlined), icon: const Icon(Icons.history_outlined),
label: Text('Restart'), label: Text('Restart Session'),
onPressed: () { onPressed: () {
Session newSession = Session newSession =
session.copyWith(status: SessionStatus.pending); session.copyWith(status: SessionStatus.pending);
@ -131,7 +131,7 @@ class _SessionViewState extends State<SessionView> {
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.done_all_outlined), icon: const Icon(Icons.done_all_outlined),
label: Text('Done'), label: Text('Finish Session'),
onPressed: () { onPressed: () {
Session newSession = Session newSession =
session.copyWith(status: SessionStatus.completed); session.copyWith(status: SessionStatus.completed);

View File

@ -4,6 +4,7 @@ import 'package:sendtrain/daos/activities_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/helpers/widget_helpers.dart'; import 'package:sendtrain/helpers/widget_helpers.dart';
import 'package:sendtrain/widgets/activities/activity_card.dart'; import 'package:sendtrain/widgets/activities/activity_card.dart';
import 'package:sendtrain/widgets/generic/elements/add_card_generic.dart';
import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart'; import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart';
import 'package:sendtrain/widgets/sessions/session_activities_editor.dart'; import 'package:sendtrain/widgets/sessions/session_activities_editor.dart';
@ -32,36 +33,21 @@ class _SessionViewActivitiesState extends State<SessionViewActivities> {
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
itemCount: activities.length, itemCount: activities.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ActivityCard(activity: activities[index]); return ActivityCard(
activity: activities[index], session: widget.session);
}, },
)); ));
} else { } else {
return Expanded( return AddCardGeneric(
child: ListView( title: 'Add an Activity!',
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), description:
children: [ 'Here you can associate one or more activities that you can follow along with during your session.',
Card.outlined( action: () {
child: InkWell( showEditorSheet(
customBorder: RoundedRectangleBorder( context,
borderRadius: BorderRadius.circular(10), SessionActivitiesEditor(
), session: widget.session, callback: () {}));
onTap: () { });
showEditorSheet(
context,
SessionActivitiesEditor(
session: widget.session,
callback: () {}));
},
child: ListTile(
contentPadding: EdgeInsets.only(
top: 5, left: 15, right: 5, bottom: 5),
autofocus: true,
leading: Icon(Icons.add_box_rounded),
title: Text('Add an Activity!'),
subtitle: Text(
'Here you can associate one or more activities that you can follow along with during your session.'),
)))
]));
} }
} else { } else {
return GenericProgressIndicator(); return GenericProgressIndicator();

View File

@ -32,7 +32,7 @@ class _SessionViewMediaState extends State<SessionViewMedia> {
List<Widget> content; List<Widget> content;
if (mediaItems.isNotEmpty) { if (mediaItems.isNotEmpty) {
List<Widget> mediaCards = List.generate(mediaItems.length, List<Widget> mediaCards = List.generate(mediaItems.length,
(i) => MediaCard(media: mediaItems[i], callback: resetState)); (i) => MediaCard(media: mediaItems[i], callback: resetState, canDelete: true));
content = mediaCards; content = mediaCards;
} else { } else {
content = [ content = [

View File

@ -7,11 +7,6 @@ import 'schema_v1.dart' as v1;
import 'schema_v2.dart' as v2; import 'schema_v2.dart' as v2;
import 'schema_v3.dart' as v3; import 'schema_v3.dart' as v3;
import 'schema_v4.dart' as v4; import 'schema_v4.dart' as v4;
import 'schema_v5.dart' as v5;
import 'schema_v6.dart' as v6;
import 'schema_v7.dart' as v7;
import 'schema_v8.dart' as v8;
import 'schema_v9.dart' as v9;
import 'schema_v10.dart' as v10; import 'schema_v10.dart' as v10;
import 'schema_v11.dart' as v11; import 'schema_v11.dart' as v11;
import 'schema_v12.dart' as v12; import 'schema_v12.dart' as v12;
@ -22,6 +17,12 @@ import 'schema_v16.dart' as v16;
import 'schema_v17.dart' as v17; import 'schema_v17.dart' as v17;
import 'schema_v18.dart' as v18; import 'schema_v18.dart' as v18;
import 'schema_v19.dart' as v19; import 'schema_v19.dart' as v19;
import 'schema_v5.dart' as v5;
import 'schema_v6.dart' as v6;
import 'schema_v7.dart' as v7;
import 'schema_v8.dart' as v8;
import 'schema_v9.dart' as v9;
import 'schema_v20.dart' as v20;
class GeneratedHelper implements SchemaInstantiationHelper { class GeneratedHelper implements SchemaInstantiationHelper {
@override @override
@ -35,16 +36,6 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v3.DatabaseAtV3(db); return v3.DatabaseAtV3(db);
case 4: case 4:
return v4.DatabaseAtV4(db); return v4.DatabaseAtV4(db);
case 5:
return v5.DatabaseAtV5(db);
case 6:
return v6.DatabaseAtV6(db);
case 7:
return v7.DatabaseAtV7(db);
case 8:
return v8.DatabaseAtV8(db);
case 9:
return v9.DatabaseAtV9(db);
case 10: case 10:
return v10.DatabaseAtV10(db); return v10.DatabaseAtV10(db);
case 11: case 11:
@ -65,6 +56,18 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v18.DatabaseAtV18(db); return v18.DatabaseAtV18(db);
case 19: case 19:
return v19.DatabaseAtV19(db); return v19.DatabaseAtV19(db);
case 5:
return v5.DatabaseAtV5(db);
case 6:
return v6.DatabaseAtV6(db);
case 7:
return v7.DatabaseAtV7(db);
case 8:
return v8.DatabaseAtV8(db);
case 9:
return v9.DatabaseAtV9(db);
case 20:
return v20.DatabaseAtV20(db);
default: default:
throw MissingSchemaException(version, versions); throw MissingSchemaException(version, versions);
} }
@ -89,6 +92,7 @@ class GeneratedHelper implements SchemaInstantiationHelper {
16, 16,
17, 17,
18, 18,
19 19,
20
]; ];
} }

File diff suppressed because it is too large Load Diff