Fix searching on home page
This commit is contained in:
		
							parent
							
								
									84837de3de
								
							
						
					
					
						commit
						4d3de751f3
					
				|  | @ -5,11 +5,8 @@ class BestPage extends StatelessWidget { | |||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       appBar: AppBar( | ||||
|         title: const Text('Best'), | ||||
|       ), | ||||
|       body: const Center( | ||||
|     return const Scaffold( | ||||
|       body: Center( | ||||
|         child: Text('Welcome to the Best Page!'), | ||||
|       ), | ||||
|     ); | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import 'dart:io'; | ||||
| 
 | ||||
| import 'package:fmassive/gym_set.dart'; | ||||
| import 'package:moor/ffi.dart'; | ||||
| import 'package:moor/moor.dart'; | ||||
| import 'package:path/path.dart'; | ||||
|  | @ -8,7 +9,7 @@ import 'settings.dart'; | |||
| 
 | ||||
| part 'database.g.dart'; | ||||
| 
 | ||||
| @UseMoor(tables: [Settings]) | ||||
| @UseMoor(tables: [Settings, GymSets]) | ||||
| class MyDatabase extends _$MyDatabase { | ||||
|   MyDatabase() : super(_openConnection()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -699,11 +699,552 @@ class $SettingsTable extends Settings with TableInfo<$SettingsTable, Setting> { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| class GymSet extends DataClass implements Insertable<GymSet> { | ||||
|   final int id; | ||||
|   final String name; | ||||
|   final int reps; | ||||
|   final int weight; | ||||
|   final int sets; | ||||
|   final int minutes; | ||||
|   final int seconds; | ||||
|   final bool hidden; | ||||
|   final String created; | ||||
|   final String unit; | ||||
|   final String image; | ||||
|   final String? steps; | ||||
|   GymSet( | ||||
|       {required this.id, | ||||
|       required this.name, | ||||
|       required this.reps, | ||||
|       required this.weight, | ||||
|       required this.sets, | ||||
|       required this.minutes, | ||||
|       required this.seconds, | ||||
|       required this.hidden, | ||||
|       required this.created, | ||||
|       required this.unit, | ||||
|       required this.image, | ||||
|       this.steps}); | ||||
|   factory GymSet.fromData(Map<String, dynamic> data, GeneratedDatabase db, | ||||
|       {String? prefix}) { | ||||
|     final effectivePrefix = prefix ?? ''; | ||||
|     return GymSet( | ||||
|       id: const IntType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}id'])!, | ||||
|       name: const StringType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}name'])!, | ||||
|       reps: const IntType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}reps'])!, | ||||
|       weight: const IntType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}weight'])!, | ||||
|       sets: const IntType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}sets'])!, | ||||
|       minutes: const IntType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}minutes'])!, | ||||
|       seconds: const IntType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}seconds'])!, | ||||
|       hidden: const BoolType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}hidden'])!, | ||||
|       created: const StringType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}created'])!, | ||||
|       unit: const StringType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}unit'])!, | ||||
|       image: const StringType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}image'])!, | ||||
|       steps: const StringType() | ||||
|           .mapFromDatabaseResponse(data['${effectivePrefix}steps']), | ||||
|     ); | ||||
|   } | ||||
|   @override | ||||
|   Map<String, Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, Expression>{}; | ||||
|     map['id'] = Variable<int>(id); | ||||
|     map['name'] = Variable<String>(name); | ||||
|     map['reps'] = Variable<int>(reps); | ||||
|     map['weight'] = Variable<int>(weight); | ||||
|     map['sets'] = Variable<int>(sets); | ||||
|     map['minutes'] = Variable<int>(minutes); | ||||
|     map['seconds'] = Variable<int>(seconds); | ||||
|     map['hidden'] = Variable<bool>(hidden); | ||||
|     map['created'] = Variable<String>(created); | ||||
|     map['unit'] = Variable<String>(unit); | ||||
|     map['image'] = Variable<String>(image); | ||||
|     if (!nullToAbsent || steps != null) { | ||||
|       map['steps'] = Variable<String?>(steps); | ||||
|     } | ||||
|     return map; | ||||
|   } | ||||
| 
 | ||||
|   GymSetsCompanion toCompanion(bool nullToAbsent) { | ||||
|     return GymSetsCompanion( | ||||
|       id: Value(id), | ||||
|       name: Value(name), | ||||
|       reps: Value(reps), | ||||
|       weight: Value(weight), | ||||
|       sets: Value(sets), | ||||
|       minutes: Value(minutes), | ||||
|       seconds: Value(seconds), | ||||
|       hidden: Value(hidden), | ||||
|       created: Value(created), | ||||
|       unit: Value(unit), | ||||
|       image: Value(image), | ||||
|       steps: | ||||
|           steps == null && nullToAbsent ? const Value.absent() : Value(steps), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   factory GymSet.fromJson(Map<String, dynamic> json, | ||||
|       {ValueSerializer? serializer}) { | ||||
|     serializer ??= moorRuntimeOptions.defaultSerializer; | ||||
|     return GymSet( | ||||
|       id: serializer.fromJson<int>(json['id']), | ||||
|       name: serializer.fromJson<String>(json['name']), | ||||
|       reps: serializer.fromJson<int>(json['reps']), | ||||
|       weight: serializer.fromJson<int>(json['weight']), | ||||
|       sets: serializer.fromJson<int>(json['sets']), | ||||
|       minutes: serializer.fromJson<int>(json['minutes']), | ||||
|       seconds: serializer.fromJson<int>(json['seconds']), | ||||
|       hidden: serializer.fromJson<bool>(json['hidden']), | ||||
|       created: serializer.fromJson<String>(json['created']), | ||||
|       unit: serializer.fromJson<String>(json['unit']), | ||||
|       image: serializer.fromJson<String>(json['image']), | ||||
|       steps: serializer.fromJson<String?>(json['steps']), | ||||
|     ); | ||||
|   } | ||||
|   @override | ||||
|   Map<String, dynamic> toJson({ValueSerializer? serializer}) { | ||||
|     serializer ??= moorRuntimeOptions.defaultSerializer; | ||||
|     return <String, dynamic>{ | ||||
|       'id': serializer.toJson<int>(id), | ||||
|       'name': serializer.toJson<String>(name), | ||||
|       'reps': serializer.toJson<int>(reps), | ||||
|       'weight': serializer.toJson<int>(weight), | ||||
|       'sets': serializer.toJson<int>(sets), | ||||
|       'minutes': serializer.toJson<int>(minutes), | ||||
|       'seconds': serializer.toJson<int>(seconds), | ||||
|       'hidden': serializer.toJson<bool>(hidden), | ||||
|       'created': serializer.toJson<String>(created), | ||||
|       'unit': serializer.toJson<String>(unit), | ||||
|       'image': serializer.toJson<String>(image), | ||||
|       'steps': serializer.toJson<String?>(steps), | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   GymSet copyWith( | ||||
|           {int? id, | ||||
|           String? name, | ||||
|           int? reps, | ||||
|           int? weight, | ||||
|           int? sets, | ||||
|           int? minutes, | ||||
|           int? seconds, | ||||
|           bool? hidden, | ||||
|           String? created, | ||||
|           String? unit, | ||||
|           String? image, | ||||
|           String? steps}) => | ||||
|       GymSet( | ||||
|         id: id ?? this.id, | ||||
|         name: name ?? this.name, | ||||
|         reps: reps ?? this.reps, | ||||
|         weight: weight ?? this.weight, | ||||
|         sets: sets ?? this.sets, | ||||
|         minutes: minutes ?? this.minutes, | ||||
|         seconds: seconds ?? this.seconds, | ||||
|         hidden: hidden ?? this.hidden, | ||||
|         created: created ?? this.created, | ||||
|         unit: unit ?? this.unit, | ||||
|         image: image ?? this.image, | ||||
|         steps: steps ?? this.steps, | ||||
|       ); | ||||
|   @override | ||||
|   String toString() { | ||||
|     return (StringBuffer('GymSet(') | ||||
|           ..write('id: $id, ') | ||||
|           ..write('name: $name, ') | ||||
|           ..write('reps: $reps, ') | ||||
|           ..write('weight: $weight, ') | ||||
|           ..write('sets: $sets, ') | ||||
|           ..write('minutes: $minutes, ') | ||||
|           ..write('seconds: $seconds, ') | ||||
|           ..write('hidden: $hidden, ') | ||||
|           ..write('created: $created, ') | ||||
|           ..write('unit: $unit, ') | ||||
|           ..write('image: $image, ') | ||||
|           ..write('steps: $steps') | ||||
|           ..write(')')) | ||||
|         .toString(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   int get hashCode => Object.hash(id, name, reps, weight, sets, minutes, | ||||
|       seconds, hidden, created, unit, image, steps); | ||||
|   @override | ||||
|   bool operator ==(Object other) => | ||||
|       identical(this, other) || | ||||
|       (other is GymSet && | ||||
|           other.id == this.id && | ||||
|           other.name == this.name && | ||||
|           other.reps == this.reps && | ||||
|           other.weight == this.weight && | ||||
|           other.sets == this.sets && | ||||
|           other.minutes == this.minutes && | ||||
|           other.seconds == this.seconds && | ||||
|           other.hidden == this.hidden && | ||||
|           other.created == this.created && | ||||
|           other.unit == this.unit && | ||||
|           other.image == this.image && | ||||
|           other.steps == this.steps); | ||||
| } | ||||
| 
 | ||||
| class GymSetsCompanion extends UpdateCompanion<GymSet> { | ||||
|   final Value<int> id; | ||||
|   final Value<String> name; | ||||
|   final Value<int> reps; | ||||
|   final Value<int> weight; | ||||
|   final Value<int> sets; | ||||
|   final Value<int> minutes; | ||||
|   final Value<int> seconds; | ||||
|   final Value<bool> hidden; | ||||
|   final Value<String> created; | ||||
|   final Value<String> unit; | ||||
|   final Value<String> image; | ||||
|   final Value<String?> steps; | ||||
|   const GymSetsCompanion({ | ||||
|     this.id = const Value.absent(), | ||||
|     this.name = const Value.absent(), | ||||
|     this.reps = const Value.absent(), | ||||
|     this.weight = const Value.absent(), | ||||
|     this.sets = const Value.absent(), | ||||
|     this.minutes = const Value.absent(), | ||||
|     this.seconds = const Value.absent(), | ||||
|     this.hidden = const Value.absent(), | ||||
|     this.created = const Value.absent(), | ||||
|     this.unit = const Value.absent(), | ||||
|     this.image = const Value.absent(), | ||||
|     this.steps = const Value.absent(), | ||||
|   }); | ||||
|   GymSetsCompanion.insert({ | ||||
|     this.id = const Value.absent(), | ||||
|     required String name, | ||||
|     required int reps, | ||||
|     required int weight, | ||||
|     this.sets = const Value.absent(), | ||||
|     this.minutes = const Value.absent(), | ||||
|     this.seconds = const Value.absent(), | ||||
|     this.hidden = const Value.absent(), | ||||
|     required String created, | ||||
|     this.unit = const Value.absent(), | ||||
|     required String image, | ||||
|     this.steps = const Value.absent(), | ||||
|   })  : name = Value(name), | ||||
|         reps = Value(reps), | ||||
|         weight = Value(weight), | ||||
|         created = Value(created), | ||||
|         image = Value(image); | ||||
|   static Insertable<GymSet> custom({ | ||||
|     Expression<int>? id, | ||||
|     Expression<String>? name, | ||||
|     Expression<int>? reps, | ||||
|     Expression<int>? weight, | ||||
|     Expression<int>? sets, | ||||
|     Expression<int>? minutes, | ||||
|     Expression<int>? seconds, | ||||
|     Expression<bool>? hidden, | ||||
|     Expression<String>? created, | ||||
|     Expression<String>? unit, | ||||
|     Expression<String>? image, | ||||
|     Expression<String?>? steps, | ||||
|   }) { | ||||
|     return RawValuesInsertable({ | ||||
|       if (id != null) 'id': id, | ||||
|       if (name != null) 'name': name, | ||||
|       if (reps != null) 'reps': reps, | ||||
|       if (weight != null) 'weight': weight, | ||||
|       if (sets != null) 'sets': sets, | ||||
|       if (minutes != null) 'minutes': minutes, | ||||
|       if (seconds != null) 'seconds': seconds, | ||||
|       if (hidden != null) 'hidden': hidden, | ||||
|       if (created != null) 'created': created, | ||||
|       if (unit != null) 'unit': unit, | ||||
|       if (image != null) 'image': image, | ||||
|       if (steps != null) 'steps': steps, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   GymSetsCompanion copyWith( | ||||
|       {Value<int>? id, | ||||
|       Value<String>? name, | ||||
|       Value<int>? reps, | ||||
|       Value<int>? weight, | ||||
|       Value<int>? sets, | ||||
|       Value<int>? minutes, | ||||
|       Value<int>? seconds, | ||||
|       Value<bool>? hidden, | ||||
|       Value<String>? created, | ||||
|       Value<String>? unit, | ||||
|       Value<String>? image, | ||||
|       Value<String?>? steps}) { | ||||
|     return GymSetsCompanion( | ||||
|       id: id ?? this.id, | ||||
|       name: name ?? this.name, | ||||
|       reps: reps ?? this.reps, | ||||
|       weight: weight ?? this.weight, | ||||
|       sets: sets ?? this.sets, | ||||
|       minutes: minutes ?? this.minutes, | ||||
|       seconds: seconds ?? this.seconds, | ||||
|       hidden: hidden ?? this.hidden, | ||||
|       created: created ?? this.created, | ||||
|       unit: unit ?? this.unit, | ||||
|       image: image ?? this.image, | ||||
|       steps: steps ?? this.steps, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Map<String, Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, Expression>{}; | ||||
|     if (id.present) { | ||||
|       map['id'] = Variable<int>(id.value); | ||||
|     } | ||||
|     if (name.present) { | ||||
|       map['name'] = Variable<String>(name.value); | ||||
|     } | ||||
|     if (reps.present) { | ||||
|       map['reps'] = Variable<int>(reps.value); | ||||
|     } | ||||
|     if (weight.present) { | ||||
|       map['weight'] = Variable<int>(weight.value); | ||||
|     } | ||||
|     if (sets.present) { | ||||
|       map['sets'] = Variable<int>(sets.value); | ||||
|     } | ||||
|     if (minutes.present) { | ||||
|       map['minutes'] = Variable<int>(minutes.value); | ||||
|     } | ||||
|     if (seconds.present) { | ||||
|       map['seconds'] = Variable<int>(seconds.value); | ||||
|     } | ||||
|     if (hidden.present) { | ||||
|       map['hidden'] = Variable<bool>(hidden.value); | ||||
|     } | ||||
|     if (created.present) { | ||||
|       map['created'] = Variable<String>(created.value); | ||||
|     } | ||||
|     if (unit.present) { | ||||
|       map['unit'] = Variable<String>(unit.value); | ||||
|     } | ||||
|     if (image.present) { | ||||
|       map['image'] = Variable<String>(image.value); | ||||
|     } | ||||
|     if (steps.present) { | ||||
|       map['steps'] = Variable<String?>(steps.value); | ||||
|     } | ||||
|     return map; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   String toString() { | ||||
|     return (StringBuffer('GymSetsCompanion(') | ||||
|           ..write('id: $id, ') | ||||
|           ..write('name: $name, ') | ||||
|           ..write('reps: $reps, ') | ||||
|           ..write('weight: $weight, ') | ||||
|           ..write('sets: $sets, ') | ||||
|           ..write('minutes: $minutes, ') | ||||
|           ..write('seconds: $seconds, ') | ||||
|           ..write('hidden: $hidden, ') | ||||
|           ..write('created: $created, ') | ||||
|           ..write('unit: $unit, ') | ||||
|           ..write('image: $image, ') | ||||
|           ..write('steps: $steps') | ||||
|           ..write(')')) | ||||
|         .toString(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class $GymSetsTable extends GymSets with TableInfo<$GymSetsTable, GymSet> { | ||||
|   @override | ||||
|   final GeneratedDatabase attachedDatabase; | ||||
|   final String? _alias; | ||||
|   $GymSetsTable(this.attachedDatabase, [this._alias]); | ||||
|   final VerificationMeta _idMeta = const VerificationMeta('id'); | ||||
|   @override | ||||
|   late final GeneratedColumn<int?> id = GeneratedColumn<int?>( | ||||
|       'id', aliasedName, false, | ||||
|       type: const IntType(), | ||||
|       requiredDuringInsert: false, | ||||
|       defaultConstraints: 'PRIMARY KEY AUTOINCREMENT'); | ||||
|   final VerificationMeta _nameMeta = const VerificationMeta('name'); | ||||
|   @override | ||||
|   late final GeneratedColumn<String?> name = GeneratedColumn<String?>( | ||||
|       'name', aliasedName, false, | ||||
|       type: const StringType(), requiredDuringInsert: true); | ||||
|   final VerificationMeta _repsMeta = const VerificationMeta('reps'); | ||||
|   @override | ||||
|   late final GeneratedColumn<int?> reps = GeneratedColumn<int?>( | ||||
|       'reps', aliasedName, false, | ||||
|       type: const IntType(), requiredDuringInsert: true); | ||||
|   final VerificationMeta _weightMeta = const VerificationMeta('weight'); | ||||
|   @override | ||||
|   late final GeneratedColumn<int?> weight = GeneratedColumn<int?>( | ||||
|       'weight', aliasedName, false, | ||||
|       type: const IntType(), requiredDuringInsert: true); | ||||
|   final VerificationMeta _setsMeta = const VerificationMeta('sets'); | ||||
|   @override | ||||
|   late final GeneratedColumn<int?> sets = GeneratedColumn<int?>( | ||||
|       'sets', aliasedName, false, | ||||
|       type: const IntType(), | ||||
|       requiredDuringInsert: false, | ||||
|       defaultValue: const Constant(3)); | ||||
|   final VerificationMeta _minutesMeta = const VerificationMeta('minutes'); | ||||
|   @override | ||||
|   late final GeneratedColumn<int?> minutes = GeneratedColumn<int?>( | ||||
|       'minutes', aliasedName, false, | ||||
|       type: const IntType(), | ||||
|       requiredDuringInsert: false, | ||||
|       defaultValue: const Constant(3)); | ||||
|   final VerificationMeta _secondsMeta = const VerificationMeta('seconds'); | ||||
|   @override | ||||
|   late final GeneratedColumn<int?> seconds = GeneratedColumn<int?>( | ||||
|       'seconds', aliasedName, false, | ||||
|       type: const IntType(), | ||||
|       requiredDuringInsert: false, | ||||
|       defaultValue: const Constant(30)); | ||||
|   final VerificationMeta _hiddenMeta = const VerificationMeta('hidden'); | ||||
|   @override | ||||
|   late final GeneratedColumn<bool?> hidden = GeneratedColumn<bool?>( | ||||
|       'hidden', aliasedName, false, | ||||
|       type: const BoolType(), | ||||
|       requiredDuringInsert: false, | ||||
|       defaultConstraints: 'CHECK (hidden IN (0, 1))', | ||||
|       defaultValue: const Constant(false)); | ||||
|   final VerificationMeta _createdMeta = const VerificationMeta('created'); | ||||
|   @override | ||||
|   late final GeneratedColumn<String?> created = GeneratedColumn<String?>( | ||||
|       'created', aliasedName, false, | ||||
|       type: const StringType(), requiredDuringInsert: true); | ||||
|   final VerificationMeta _unitMeta = const VerificationMeta('unit'); | ||||
|   @override | ||||
|   late final GeneratedColumn<String?> unit = GeneratedColumn<String?>( | ||||
|       'unit', aliasedName, false, | ||||
|       type: const StringType(), | ||||
|       requiredDuringInsert: false, | ||||
|       defaultValue: const Constant('kg')); | ||||
|   final VerificationMeta _imageMeta = const VerificationMeta('image'); | ||||
|   @override | ||||
|   late final GeneratedColumn<String?> image = GeneratedColumn<String?>( | ||||
|       'image', aliasedName, false, | ||||
|       type: const StringType(), requiredDuringInsert: true); | ||||
|   final VerificationMeta _stepsMeta = const VerificationMeta('steps'); | ||||
|   @override | ||||
|   late final GeneratedColumn<String?> steps = GeneratedColumn<String?>( | ||||
|       'steps', aliasedName, true, | ||||
|       type: const StringType(), requiredDuringInsert: false); | ||||
|   @override | ||||
|   List<GeneratedColumn> get $columns => [ | ||||
|         id, | ||||
|         name, | ||||
|         reps, | ||||
|         weight, | ||||
|         sets, | ||||
|         minutes, | ||||
|         seconds, | ||||
|         hidden, | ||||
|         created, | ||||
|         unit, | ||||
|         image, | ||||
|         steps | ||||
|       ]; | ||||
|   @override | ||||
|   String get aliasedName => _alias ?? 'gym_sets'; | ||||
|   @override | ||||
|   String get actualTableName => 'gym_sets'; | ||||
|   @override | ||||
|   VerificationContext validateIntegrity(Insertable<GymSet> instance, | ||||
|       {bool isInserting = false}) { | ||||
|     final context = VerificationContext(); | ||||
|     final data = instance.toColumns(true); | ||||
|     if (data.containsKey('id')) { | ||||
|       context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); | ||||
|     } | ||||
|     if (data.containsKey('name')) { | ||||
|       context.handle( | ||||
|           _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); | ||||
|     } else if (isInserting) { | ||||
|       context.missing(_nameMeta); | ||||
|     } | ||||
|     if (data.containsKey('reps')) { | ||||
|       context.handle( | ||||
|           _repsMeta, reps.isAcceptableOrUnknown(data['reps']!, _repsMeta)); | ||||
|     } else if (isInserting) { | ||||
|       context.missing(_repsMeta); | ||||
|     } | ||||
|     if (data.containsKey('weight')) { | ||||
|       context.handle(_weightMeta, | ||||
|           weight.isAcceptableOrUnknown(data['weight']!, _weightMeta)); | ||||
|     } else if (isInserting) { | ||||
|       context.missing(_weightMeta); | ||||
|     } | ||||
|     if (data.containsKey('sets')) { | ||||
|       context.handle( | ||||
|           _setsMeta, sets.isAcceptableOrUnknown(data['sets']!, _setsMeta)); | ||||
|     } | ||||
|     if (data.containsKey('minutes')) { | ||||
|       context.handle(_minutesMeta, | ||||
|           minutes.isAcceptableOrUnknown(data['minutes']!, _minutesMeta)); | ||||
|     } | ||||
|     if (data.containsKey('seconds')) { | ||||
|       context.handle(_secondsMeta, | ||||
|           seconds.isAcceptableOrUnknown(data['seconds']!, _secondsMeta)); | ||||
|     } | ||||
|     if (data.containsKey('hidden')) { | ||||
|       context.handle(_hiddenMeta, | ||||
|           hidden.isAcceptableOrUnknown(data['hidden']!, _hiddenMeta)); | ||||
|     } | ||||
|     if (data.containsKey('created')) { | ||||
|       context.handle(_createdMeta, | ||||
|           created.isAcceptableOrUnknown(data['created']!, _createdMeta)); | ||||
|     } else if (isInserting) { | ||||
|       context.missing(_createdMeta); | ||||
|     } | ||||
|     if (data.containsKey('unit')) { | ||||
|       context.handle( | ||||
|           _unitMeta, unit.isAcceptableOrUnknown(data['unit']!, _unitMeta)); | ||||
|     } | ||||
|     if (data.containsKey('image')) { | ||||
|       context.handle( | ||||
|           _imageMeta, image.isAcceptableOrUnknown(data['image']!, _imageMeta)); | ||||
|     } else if (isInserting) { | ||||
|       context.missing(_imageMeta); | ||||
|     } | ||||
|     if (data.containsKey('steps')) { | ||||
|       context.handle( | ||||
|           _stepsMeta, steps.isAcceptableOrUnknown(data['steps']!, _stepsMeta)); | ||||
|     } | ||||
|     return context; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Set<GeneratedColumn> get $primaryKey => {id}; | ||||
|   @override | ||||
|   GymSet map(Map<String, dynamic> data, {String? tablePrefix}) { | ||||
|     return GymSet.fromData(data, attachedDatabase, | ||||
|         prefix: tablePrefix != null ? '$tablePrefix.' : null); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   $GymSetsTable createAlias(String alias) { | ||||
|     return $GymSetsTable(attachedDatabase, alias); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| abstract class _$MyDatabase extends GeneratedDatabase { | ||||
|   _$MyDatabase(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e); | ||||
|   late final $SettingsTable settings = $SettingsTable(this); | ||||
|   late final $GymSetsTable gymSets = $GymSetsTable(this); | ||||
|   @override | ||||
|   Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>(); | ||||
|   @override | ||||
|   List<DatabaseSchemaEntity> get allSchemaEntities => [settings]; | ||||
|   List<DatabaseSchemaEntity> get allSchemaEntities => [settings, gymSets]; | ||||
| } | ||||
|  |  | |||
|  | @ -1,8 +1,11 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:fmassive/gym_set.dart'; | ||||
| import 'package:flutter/material.dart' as material; | ||||
| import 'package:fmassive/database.dart'; | ||||
| import 'package:fmassive/main.dart'; | ||||
| import 'package:moor_flutter/moor_flutter.dart'; | ||||
| 
 | ||||
| class EditGymSetPage extends StatefulWidget { | ||||
|   final GymSet gymSet; | ||||
|   final GymSetsCompanion gymSet; | ||||
| 
 | ||||
|   const EditGymSetPage({required this.gymSet, super.key}); | ||||
| 
 | ||||
|  | @ -14,40 +17,34 @@ class _EditGymSetPageState extends State<EditGymSetPage> { | |||
|   final TextEditingController _nameController = TextEditingController(); | ||||
|   final TextEditingController _repsController = TextEditingController(); | ||||
|   final TextEditingController _weightController = TextEditingController(); | ||||
| 
 | ||||
|   late GymSet _editedGymSet; | ||||
|   late GymSetDatabaseHelper _db; | ||||
|   late GymSetsCompanion gymSet; | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _db = GymSetDatabaseHelper.instance; | ||||
|     _editedGymSet = GymSet( | ||||
|         id: widget.gymSet.id, | ||||
|         name: widget.gymSet.name, | ||||
|         reps: widget.gymSet.reps, | ||||
|         weight: widget.gymSet.weight, | ||||
|         created: DateTime.now()); | ||||
|     _nameController.text = _editedGymSet.name; | ||||
|     _repsController.text = _editedGymSet.reps.toString(); | ||||
|     _weightController.text = _editedGymSet.weight.toString(); | ||||
|     gymSet = widget.gymSet; | ||||
|     _nameController.text = gymSet.name.value; | ||||
|     _repsController.text = gymSet.reps.value.toString(); | ||||
|     _weightController.text = gymSet.weight.value.toString(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     List<Widget> actions = []; | ||||
|     if (widget.gymSet.id.present) | ||||
|       actions.add(IconButton( | ||||
|           onPressed: () async { | ||||
|             await db.gymSets.deleteOne(widget.gymSet); | ||||
|             if (!mounted) return; | ||||
|             Navigator.pop(context); | ||||
|           }, | ||||
|           icon: const Icon(Icons.delete))); | ||||
| 
 | ||||
|     return Scaffold( | ||||
|       appBar: AppBar(title: const Text('Edit Gym Set'), actions: [ | ||||
|         IconButton( | ||||
|             onPressed: () async { | ||||
|               await _db.delete(_editedGymSet); | ||||
|               if (!mounted) return; | ||||
|               Navigator.pop(context, _editedGymSet); | ||||
|             }, | ||||
|             icon: const Icon(Icons.delete)) | ||||
|       ]), | ||||
|       appBar: AppBar(title: const Text('Edit Gym Set'), actions: actions), | ||||
|       body: Padding( | ||||
|         padding: const EdgeInsets.all(16.0), | ||||
|         child: Column( | ||||
|         child: material.Column( | ||||
|           crossAxisAlignment: CrossAxisAlignment.start, | ||||
|           children: [ | ||||
|             TextFormField( | ||||
|  | @ -55,7 +52,7 @@ class _EditGymSetPageState extends State<EditGymSetPage> { | |||
|               decoration: const InputDecoration(labelText: 'Name'), | ||||
|               onChanged: (value) { | ||||
|                 setState(() { | ||||
|                   _editedGymSet.name = value; | ||||
|                   gymSet = gymSet.copyWith(name: Value(value)); | ||||
|                 }); | ||||
|               }, | ||||
|             ), | ||||
|  | @ -65,7 +62,8 @@ class _EditGymSetPageState extends State<EditGymSetPage> { | |||
|               keyboardType: TextInputType.number, | ||||
|               onChanged: (value) { | ||||
|                 setState(() { | ||||
|                   _editedGymSet.reps = int.tryParse(value) ?? 0; | ||||
|                   gymSet = | ||||
|                       gymSet.copyWith(reps: Value(int.tryParse(value) ?? 0)); | ||||
|                 }); | ||||
|               }, | ||||
|             ), | ||||
|  | @ -75,7 +73,8 @@ class _EditGymSetPageState extends State<EditGymSetPage> { | |||
|               keyboardType: TextInputType.number, | ||||
|               onChanged: (value) { | ||||
|                 setState(() { | ||||
|                   _editedGymSet.weight = int.tryParse(value) ?? 0; | ||||
|                   gymSet = | ||||
|                       gymSet.copyWith(weight: Value(int.tryParse(value) ?? 0)); | ||||
|                 }); | ||||
|               }, | ||||
|             ), | ||||
|  | @ -84,13 +83,12 @@ class _EditGymSetPageState extends State<EditGymSetPage> { | |||
|       ), | ||||
|       floatingActionButton: FloatingActionButton( | ||||
|         onPressed: () async { | ||||
|           print('edited gym set id: ${_editedGymSet.id}'); | ||||
|           if (_editedGymSet.id != null) | ||||
|             await _db.update(_editedGymSet); | ||||
|           if (gymSet.id.present) | ||||
|             await db.update(db.gymSets).write(gymSet); | ||||
|           else | ||||
|             await _db.insert(_editedGymSet); | ||||
|             await db.into(db.gymSets).insert(gymSet); | ||||
|           if (!mounted) return; | ||||
|           Navigator.pop(context, _editedGymSet); | ||||
|           Navigator.pop(context); | ||||
|         }, | ||||
|         child: const Icon(Icons.check), | ||||
|       ), | ||||
|  |  | |||
							
								
								
									
										113
									
								
								lib/gym_set.dart
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								lib/gym_set.dart
									
									
									
									
									
								
							|  | @ -1,101 +1,16 @@ | |||
| import 'package:path/path.dart'; | ||||
| import 'package:sqflite/sqflite.dart'; | ||||
| import 'package:moor_flutter/moor_flutter.dart'; | ||||
| 
 | ||||
| class GymSet { | ||||
|   int? id; | ||||
|   String name; | ||||
|   int reps; | ||||
|   int weight; | ||||
|   DateTime created; | ||||
| 
 | ||||
|   GymSet( | ||||
|       {this.id, | ||||
|       required this.name, | ||||
|       required this.reps, | ||||
|       required this.weight, | ||||
|       required this.created}); | ||||
| } | ||||
| 
 | ||||
| class GymSetDatabaseHelper { | ||||
|   static const _databaseName = "gym_set_database.db"; | ||||
|   static const _databaseVersion = 1; | ||||
|   static const table = 'gym_sets'; | ||||
|   static const columnId = '_id'; | ||||
|   static const columnName = 'name'; | ||||
|   static const columnReps = 'reps'; | ||||
|   static const columnWeight = 'weight'; | ||||
|   static const columnCreated = 'created'; | ||||
| 
 | ||||
|   GymSetDatabaseHelper._privateConstructor(); | ||||
|   static final GymSetDatabaseHelper instance = | ||||
|       GymSetDatabaseHelper._privateConstructor(); | ||||
| 
 | ||||
|   static Database? _database; | ||||
|   Future<Database> get database async { | ||||
|     if (_database != null) return _database!; | ||||
|     _database = await _initDatabase(); | ||||
|     return _database!; | ||||
|   } | ||||
| 
 | ||||
|   _initDatabase() async { | ||||
|     String path = join(await getDatabasesPath(), _databaseName); | ||||
|     return await openDatabase(path, | ||||
|         version: _databaseVersion, onCreate: _onCreate); | ||||
|   } | ||||
| 
 | ||||
|   Future _onCreate(Database db, int version) async { | ||||
|     await db.execute(''' | ||||
|           CREATE TABLE $table ( | ||||
|             $columnId INTEGER PRIMARY KEY, | ||||
|             $columnName TEXT NOT NULL, | ||||
|             $columnReps INTEGER NOT NULL, | ||||
|             $columnWeight INTEGER NOT NULL, | ||||
|             $columnCreated TEXT NOT NULL | ||||
|           ) | ||||
|           '''); | ||||
|   } | ||||
| 
 | ||||
|   Future<int> insert(GymSet gymSet) async { | ||||
|     Database db = await instance.database; | ||||
|     return await db.insert(table, { | ||||
|       columnName: gymSet.name, | ||||
|       columnReps: gymSet.reps, | ||||
|       columnWeight: gymSet.weight, | ||||
|       columnCreated: gymSet.created.toIso8601String() | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   Future<List<GymSet>> getAll() async { | ||||
|     Database db = await instance.database; | ||||
|     List<Map<String, dynamic>> result = await db.query(table); | ||||
|     return result | ||||
|         .map((gymSetMap) => GymSet( | ||||
|               id: gymSetMap[columnId], | ||||
|               name: gymSetMap[columnName], | ||||
|               reps: gymSetMap[columnReps], | ||||
|               weight: gymSetMap[columnWeight], | ||||
|               created: DateTime.parse(gymSetMap[columnCreated]), | ||||
|             )) | ||||
|         .toList(); | ||||
|   } | ||||
| 
 | ||||
|   Future<int> update(GymSet gymSet) async { | ||||
|     Database db = await instance.database; | ||||
|     return await db.update( | ||||
|         table, | ||||
|         { | ||||
|           columnName: gymSet.name, | ||||
|           columnReps: gymSet.reps, | ||||
|           columnWeight: gymSet.weight, | ||||
|           columnCreated: gymSet.created.toIso8601String() | ||||
|         }, | ||||
|         where: '$columnId = ?', | ||||
|         whereArgs: [gymSet.id]); | ||||
|   } | ||||
| 
 | ||||
|   Future<int> delete(GymSet gymSet) async { | ||||
|     Database db = await instance.database; | ||||
|     return await db | ||||
|         .delete(table, where: '$columnId = ?', whereArgs: [gymSet.id]); | ||||
|   } | ||||
| class GymSets extends Table { | ||||
|   IntColumn get id => integer().autoIncrement()(); | ||||
|   TextColumn get name => text()(); | ||||
|   IntColumn get reps => integer()(); | ||||
|   IntColumn get weight => integer()(); | ||||
|   IntColumn get sets => integer().withDefault(const Constant(3))(); | ||||
|   IntColumn get minutes => integer().withDefault(const Constant(3))(); | ||||
|   IntColumn get seconds => integer().withDefault(const Constant(30))(); | ||||
|   BoolColumn get hidden => boolean().withDefault(const Constant(false))(); | ||||
|   TextColumn get created => text()(); | ||||
|   TextColumn get unit => text().withDefault(const Constant('kg'))(); | ||||
|   TextColumn get image => text()(); | ||||
|   TextColumn get steps => text().nullable()(); | ||||
| } | ||||
|  |  | |||
|  | @ -1,9 +1,26 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:fmassive/best_page.dart'; | ||||
| import 'package:fmassive/database.dart'; | ||||
| import 'package:fmassive/edit_set.dart'; | ||||
| import 'package:fmassive/gym_set.dart'; | ||||
| import 'package:fmassive/main.dart'; | ||||
| import 'package:fmassive/plans_page.dart'; | ||||
| import 'package:fmassive/settings_page.dart'; | ||||
| import 'package:fmassive/timer_page.dart'; | ||||
| import 'package:fmassive/workouts_page.dart'; | ||||
| import 'package:moor_flutter/moor_flutter.dart'; | ||||
| 
 | ||||
| class HomePage extends StatelessWidget { | ||||
|   HomePage({super.key}); | ||||
| class HomePage extends StatefulWidget { | ||||
|   const HomePage({super.key}); | ||||
| 
 | ||||
|   @override | ||||
|   createState() => RootPage(); | ||||
| } | ||||
| 
 | ||||
| class RootPage extends State<HomePage> { | ||||
|   bool showSearch = false; | ||||
|   int selected = 0; | ||||
|   String search = ''; | ||||
|   final focusNode = FocusNode(); | ||||
| 
 | ||||
|   final List<Map<String, dynamic>> routes = [ | ||||
|     {'title': 'Home', 'icon': Icons.home}, | ||||
|  | @ -14,134 +31,160 @@ class HomePage extends StatelessWidget { | |||
|     {'title': 'Settings', 'icon': Icons.settings}, | ||||
|   ]; | ||||
| 
 | ||||
|   void toggleSearch() { | ||||
|     setState(() { | ||||
|       showSearch = !showSearch; | ||||
|     }); | ||||
|     focusNode.requestFocus(); | ||||
|   } | ||||
| 
 | ||||
|   Widget getBody() { | ||||
|     switch (routes[selected]['title']) { | ||||
|       case 'Settings': | ||||
|         return const SettingsPage(); | ||||
|       case 'Timer': | ||||
|         return const TimerPage(); | ||||
|       case 'Workouts': | ||||
|         return const WorkoutsPage(); | ||||
|       case 'Best': | ||||
|         return const BestPage(); | ||||
|       case 'Plans': | ||||
|         return const PlansPage(); | ||||
|       default: | ||||
|         return _HomePageWidget(search: search); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       appBar: AppBar( | ||||
|         title: Text(routes[0]['title']), | ||||
|       ), | ||||
|       drawer: Drawer( | ||||
|         child: ListView.builder( | ||||
|           itemCount: routes.length, | ||||
|           itemBuilder: (context, index) { | ||||
|             return ListTile( | ||||
|               selected: selected == index, | ||||
|               leading: Icon(routes[index]['icon']), | ||||
|               title: Text(routes[index]['title']), | ||||
|               onTap: () { | ||||
|                 setState(() { | ||||
|                   selected = index; | ||||
|                 }); | ||||
|                 Navigator.pop(context); | ||||
|                 Navigator.pushNamed( | ||||
|                     context, '/${routes[index]['title'].toLowerCase()}'); | ||||
|               }, | ||||
|             ); | ||||
|           }, | ||||
|         ), | ||||
|       ), | ||||
|       body: const Center( | ||||
|         child: GymSetPage(), | ||||
|       appBar: AppBar( | ||||
|         title: showSearch | ||||
|             ? TextField( | ||||
|                 focusNode: focusNode, | ||||
|                 cursorColor: Colors.white, | ||||
|                 onChanged: (String value) { | ||||
|                   setState(() { | ||||
|                     search = value; | ||||
|                   }); | ||||
|                 }, | ||||
|                 decoration: const InputDecoration( | ||||
|                   hintText: 'Search...', | ||||
|                   border: InputBorder.none, | ||||
|                   hintStyle: TextStyle(color: Colors.white), | ||||
|                 ), | ||||
|               ) | ||||
|             : Text(routes[selected]['title']), | ||||
|         actions: [ | ||||
|           IconButton( | ||||
|             icon: const Icon(Icons.search), | ||||
|             onPressed: toggleSearch, | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|       body: getBody(), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class GymSetPage extends StatefulWidget { | ||||
|   const GymSetPage({Key? key}) : super(key: key); | ||||
| class _HomePageWidget extends StatefulWidget { | ||||
|   final String search; | ||||
| 
 | ||||
|   const _HomePageWidget({Key? key, required this.search}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   createState() => GymSetPageState(); | ||||
|   createState() => _HomePage(); | ||||
| } | ||||
| 
 | ||||
| class GymSetPageState extends State<GymSetPage> { | ||||
|   late GymSetDatabaseHelper db; | ||||
|   List<GymSet> sets = []; | ||||
| class _HomePage extends State<_HomePageWidget> { | ||||
|   bool showSearch = false; | ||||
|   late Stream<List<GymSet>> stream; | ||||
| 
 | ||||
|   List<GymSet> searchResults = []; | ||||
| 
 | ||||
|   final TextEditingController searchController = TextEditingController(); | ||||
| 
 | ||||
|   void search(String searchQuery) { | ||||
|     List<GymSet> results = []; | ||||
| 
 | ||||
|     if (searchQuery.isEmpty) { | ||||
|       results = sets; | ||||
|     } else { | ||||
|       for (int i = 0; i < sets.length; i++) { | ||||
|         if (sets[i].reps.toString().contains(searchQuery) || | ||||
|             sets[i].weight.toString().contains(searchQuery) || | ||||
|             sets[i].created.toString().contains(searchQuery) || | ||||
|             sets[i].name.contains(searchQuery)) { | ||||
|           results.add(sets[i]); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     setState(() { | ||||
|       searchResults = results; | ||||
|     }); | ||||
|   @override | ||||
|   initState() { | ||||
|     super.initState(); | ||||
|     setStream(); | ||||
|   } | ||||
| 
 | ||||
|   void reset() async { | ||||
|     print('Resetting...'); | ||||
|     final data = await db.getAll(); | ||||
|     setState(() { | ||||
|       sets = data; | ||||
|       searchResults = data; | ||||
|     }); | ||||
|   void setStream() { | ||||
|     stream = (db.select(db.gymSets) | ||||
|           ..where((gymSet) => gymSet.name.contains(widget.search)) | ||||
|           ..limit(10, offset: 0)) | ||||
|         .watch(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     db = GymSetDatabaseHelper.instance; | ||||
|     reset(); | ||||
|   didUpdateWidget(covariant _HomePageWidget oldWidget) { | ||||
|     super.didUpdateWidget(oldWidget); | ||||
|     setStream(); | ||||
|   } | ||||
| 
 | ||||
|   void toggleSearch() { | ||||
|     setState(() { | ||||
|       showSearch = !showSearch; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|         appBar: AppBar( | ||||
|           title: TextField( | ||||
|             controller: searchController, | ||||
|             decoration: const InputDecoration( | ||||
|               hintText: 'Search Gym Sets', | ||||
|               border: InputBorder.none, | ||||
|             ), | ||||
|             onChanged: (searchQuery) { | ||||
|               search(searchQuery); | ||||
|             }, | ||||
|           ), | ||||
|         ), | ||||
|         body: ListView.builder( | ||||
|           itemCount: searchResults.length, | ||||
|           itemBuilder: (context, index) { | ||||
|             return ListTile( | ||||
|                 title: Text( | ||||
|                     '${searchResults[index].name}: ${searchResults[index].reps}x${searchResults[index].weight}kg'), | ||||
|                 onTap: () async { | ||||
|                   await Navigator.push( | ||||
|                     context, | ||||
|                     MaterialPageRoute( | ||||
|                       builder: (context) => | ||||
|                           EditGymSetPage(gymSet: searchResults[index]), | ||||
|                     ), | ||||
|                   ); | ||||
|                   reset(); | ||||
|                 }); | ||||
|           }, | ||||
|         ), | ||||
|         body: StreamBuilder<List<GymSet>>( | ||||
|             stream: stream, | ||||
|             builder: (context, snapshot) { | ||||
|               final gymSets = snapshot.data; | ||||
| 
 | ||||
|               if (gymSets == null) | ||||
|                 return const Center(child: CircularProgressIndicator()); | ||||
| 
 | ||||
|               return ListView.builder( | ||||
|                 itemCount: gymSets.length, | ||||
|                 itemBuilder: (context, index) { | ||||
|                   return ListTile( | ||||
|                       title: Text(gymSets[index].name), | ||||
|                       onTap: () async { | ||||
|                         await Navigator.push( | ||||
|                           context, | ||||
|                           MaterialPageRoute( | ||||
|                             builder: (context) => EditGymSetPage( | ||||
|                                 gymSet: gymSets[index].toCompanion(false)), | ||||
|                           ), | ||||
|                         ); | ||||
|                       }); | ||||
|                 }, | ||||
|               ); | ||||
|             }), | ||||
|         floatingActionButton: FloatingActionButton( | ||||
|             onPressed: () async { | ||||
|               await Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => EditGymSetPage( | ||||
|                       gymSet: GymSet( | ||||
|                           name: '', | ||||
|                           reps: 0, | ||||
|                           weight: 0, | ||||
|                           created: DateTime.now())), | ||||
|                       gymSet: GymSetsCompanion( | ||||
|                           name: const Value(''), | ||||
|                           reps: const Value(0), | ||||
|                           weight: const Value(0), | ||||
|                           image: const Value(''), | ||||
|                           created: Value(DateTime.now().toString()))), | ||||
|                 ), | ||||
|               ); | ||||
|               reset(); | ||||
|             }, | ||||
|             child: const Icon(Icons.add))); | ||||
|   } | ||||
|  |  | |||
|  | @ -1,13 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:fmassive/best_page.dart'; | ||||
| import 'package:fmassive/database.dart'; | ||||
| import 'package:fmassive/edit_set.dart'; | ||||
| import 'package:fmassive/gym_set.dart'; | ||||
| import 'package:fmassive/home_page.dart'; | ||||
| import 'package:fmassive/plans_page.dart'; | ||||
| import 'package:fmassive/settings_page.dart'; | ||||
| import 'package:fmassive/timer_page.dart'; | ||||
| import 'package:fmassive/workouts_page.dart'; | ||||
| 
 | ||||
| MyDatabase db = MyDatabase(); | ||||
| 
 | ||||
|  | @ -22,16 +16,10 @@ class MyApp extends StatelessWidget { | |||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     final edit = EditGymSetPage( | ||||
|         gymSet: GymSet(name: '', reps: 0, weight: 0, created: DateTime.now())); | ||||
|     const edit = EditGymSetPage(gymSet: GymSetsCompanion()); | ||||
| 
 | ||||
|     final Map<String, WidgetBuilder> routes = { | ||||
|       '/home': (context) => HomePage(), | ||||
|       '/plans': (context) => const PlansPage(), | ||||
|       '/best': (context) => const BestPage(), | ||||
|       '/workouts': (context) => const WorkoutsPage(), | ||||
|       '/timer': (context) => const TimerPage(), | ||||
|       '/settings': (context) => SettingsPage(), | ||||
|       '/home': (context) => const HomePage(), | ||||
|       '/edit-set': (context) => edit, | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										31
									
								
								lib/massive_drawer.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								lib/massive_drawer.dart
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class MassiveDrawer extends StatefulWidget { | ||||
|   final Widget body; | ||||
|   final PreferredSizeWidget appBar; | ||||
| 
 | ||||
|   const MassiveDrawer({super.key, required this.body, required this.appBar}); | ||||
| 
 | ||||
|   @override | ||||
|   createState() => _MassiveDrawer(); | ||||
| } | ||||
| 
 | ||||
| class _MassiveDrawer extends State<MassiveDrawer> { | ||||
|   final List<Map<String, dynamic>> routes = [ | ||||
|     {'title': 'Home', 'icon': Icons.home}, | ||||
|     {'title': 'Plans', 'icon': Icons.calendar_today}, | ||||
|     {'title': 'Best', 'icon': Icons.star}, | ||||
|     {'title': 'Workouts', 'icon': Icons.fitness_center}, | ||||
|     {'title': 'Timer', 'icon': Icons.timer}, | ||||
|     {'title': 'Settings', 'icon': Icons.settings}, | ||||
|   ]; | ||||
|   int selected = 0; | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       body: widget.body, | ||||
|       appBar: widget.appBar, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | @ -1,17 +1,163 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/material.dart' as material; | ||||
| import 'package:fmassive/database.dart'; | ||||
| import 'package:fmassive/main.dart'; | ||||
| import 'package:fmassive/settings.dart'; | ||||
| import 'package:moor/moor.dart'; | ||||
| 
 | ||||
| class PlansPage extends StatelessWidget { | ||||
|   const PlansPage({super.key}); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       appBar: AppBar( | ||||
|         title: const Text('Plans'), | ||||
|       ), | ||||
|       body: const Center( | ||||
|         child: Text('Welcome to the Plans Page!'), | ||||
|     return const Scaffold( | ||||
|       body: Center( | ||||
|         child: _PlansPage(), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class _PlansPage extends StatefulWidget { | ||||
|   const _PlansPage({Key? key}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   createState() => _PlansPageState(); | ||||
| } | ||||
| 
 | ||||
| class _PlansPageState extends State<_PlansPage> { | ||||
|   late Stream<Setting> stream; | ||||
| 
 | ||||
|   final TextEditingController searchController = TextEditingController(); | ||||
| 
 | ||||
|   void reset() async { | ||||
|     var data = await db.select(db.settings).get(); | ||||
|     if (data.isEmpty) await db.into(db.settings).insert(defaultSettings); | ||||
|     setState(() { | ||||
|       if (data.isEmpty) return; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     stream = db.select(db.settings).watchSingle(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       body: StreamBuilder<Setting>( | ||||
|           stream: stream, | ||||
|           builder: (context, snapshot) { | ||||
|             final settings = snapshot.data; | ||||
| 
 | ||||
|             if (settings == null) | ||||
|               return const Center(child: CircularProgressIndicator()); | ||||
| 
 | ||||
|             return SingleChildScrollView( | ||||
|               padding: const EdgeInsets.all(8.0), | ||||
|               child: material.Column( | ||||
|                 crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                 children: [ | ||||
|                   SwitchListTile( | ||||
|                     title: const Text('Alarm'), | ||||
|                     value: settings.alarm, | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(alarm: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   SwitchListTile( | ||||
|                     title: const Text('Vibrate'), | ||||
|                     value: settings.vibrate, | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(vibrate: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   SwitchListTile( | ||||
|                     title: const Text('Notify'), | ||||
|                     value: settings.notify, | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(notify: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   SwitchListTile( | ||||
|                     title: const Text('Images'), | ||||
|                     value: settings.images, | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(images: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   SwitchListTile( | ||||
|                     title: const Text('Show Unit'), | ||||
|                     value: settings.showUnit, | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(showUnit: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   SwitchListTile( | ||||
|                     title: const Text('Steps'), | ||||
|                     value: settings.steps, | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(steps: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   TextField( | ||||
|                     decoration: const InputDecoration( | ||||
|                       labelText: 'Sound', | ||||
|                     ), | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(sound: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   TextField( | ||||
|                     decoration: const InputDecoration( | ||||
|                       labelText: 'Light Color', | ||||
|                     ), | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(lightColor: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   TextField( | ||||
|                     decoration: const InputDecoration( | ||||
|                       labelText: 'Dark Color', | ||||
|                     ), | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(darkColor: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                   TextField( | ||||
|                     decoration: const InputDecoration( | ||||
|                       labelText: 'Date', | ||||
|                     ), | ||||
|                     onChanged: (value) { | ||||
|                       db | ||||
|                           .update(db.settings) | ||||
|                           .write(SettingsCompanion(date: Value(value))); | ||||
|                     }, | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ); | ||||
|           }), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -6,40 +6,12 @@ import 'package:fmassive/settings.dart'; | |||
| import 'package:moor/moor.dart'; | ||||
| 
 | ||||
| class SettingsPage extends StatelessWidget { | ||||
|   SettingsPage({super.key}); | ||||
| 
 | ||||
|   final List<Map<String, dynamic>> routes = [ | ||||
|     {'title': 'Home', 'icon': Icons.home}, | ||||
|     {'title': 'Plans', 'icon': Icons.calendar_today}, | ||||
|     {'title': 'Best', 'icon': Icons.star}, | ||||
|     {'title': 'Workouts', 'icon': Icons.fitness_center}, | ||||
|     {'title': 'Timer', 'icon': Icons.timer}, | ||||
|     {'title': 'Settings', 'icon': Icons.settings}, | ||||
|   ]; | ||||
|   const SettingsPage({super.key}); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       appBar: AppBar( | ||||
|         title: const Text('Settings'), | ||||
|       ), | ||||
|       drawer: Drawer( | ||||
|         child: ListView.builder( | ||||
|           itemCount: routes.length, | ||||
|           itemBuilder: (context, index) { | ||||
|             return ListTile( | ||||
|               leading: Icon(routes[index]['icon']), | ||||
|               title: Text(routes[index]['title']), | ||||
|               onTap: () { | ||||
|                 Navigator.pop(context); | ||||
|                 Navigator.pushNamed( | ||||
|                     context, '/${routes[index]['title'].toLowerCase()}'); | ||||
|               }, | ||||
|             ); | ||||
|           }, | ||||
|         ), | ||||
|       ), | ||||
|       body: const Center( | ||||
|     return const Scaffold( | ||||
|       body: Center( | ||||
|         child: _SettingsPage(), | ||||
|       ), | ||||
|     ); | ||||
|  | @ -61,14 +33,12 @@ class _SettingsPageState extends State<_SettingsPage> { | |||
|   void reset() async { | ||||
|     var data = await db.select(db.settings).get(); | ||||
|     if (data.isEmpty) await db.into(db.settings).insert(defaultSettings); | ||||
|     setState(() { | ||||
|       if (data.isEmpty) return; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     reset(); | ||||
|     stream = db.select(db.settings).watchSingle(); | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user