Fix searching on home page
This commit is contained in:
parent
84837de3de
commit
4d3de751f3
|
@ -5,11 +5,8 @@ class BestPage extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return const Scaffold(
|
||||||
appBar: AppBar(
|
body: Center(
|
||||||
title: const Text('Best'),
|
|
||||||
),
|
|
||||||
body: const Center(
|
|
||||||
child: Text('Welcome to the Best Page!'),
|
child: Text('Welcome to the Best Page!'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:fmassive/gym_set.dart';
|
||||||
import 'package:moor/ffi.dart';
|
import 'package:moor/ffi.dart';
|
||||||
import 'package:moor/moor.dart';
|
import 'package:moor/moor.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
|
@ -8,7 +9,7 @@ import 'settings.dart';
|
||||||
|
|
||||||
part 'database.g.dart';
|
part 'database.g.dart';
|
||||||
|
|
||||||
@UseMoor(tables: [Settings])
|
@UseMoor(tables: [Settings, GymSets])
|
||||||
class MyDatabase extends _$MyDatabase {
|
class MyDatabase extends _$MyDatabase {
|
||||||
MyDatabase() : super(_openConnection());
|
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 {
|
abstract class _$MyDatabase extends GeneratedDatabase {
|
||||||
_$MyDatabase(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
|
_$MyDatabase(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
|
||||||
late final $SettingsTable settings = $SettingsTable(this);
|
late final $SettingsTable settings = $SettingsTable(this);
|
||||||
|
late final $GymSetsTable gymSets = $GymSetsTable(this);
|
||||||
@override
|
@override
|
||||||
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
|
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
|
||||||
@override
|
@override
|
||||||
List<DatabaseSchemaEntity> get allSchemaEntities => [settings];
|
List<DatabaseSchemaEntity> get allSchemaEntities => [settings, gymSets];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import 'package:flutter/material.dart';
|
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 {
|
class EditGymSetPage extends StatefulWidget {
|
||||||
final GymSet gymSet;
|
final GymSetsCompanion gymSet;
|
||||||
|
|
||||||
const EditGymSetPage({required this.gymSet, super.key});
|
const EditGymSetPage({required this.gymSet, super.key});
|
||||||
|
|
||||||
|
@ -14,40 +17,34 @@ class _EditGymSetPageState extends State<EditGymSetPage> {
|
||||||
final TextEditingController _nameController = TextEditingController();
|
final TextEditingController _nameController = TextEditingController();
|
||||||
final TextEditingController _repsController = TextEditingController();
|
final TextEditingController _repsController = TextEditingController();
|
||||||
final TextEditingController _weightController = TextEditingController();
|
final TextEditingController _weightController = TextEditingController();
|
||||||
|
late GymSetsCompanion gymSet;
|
||||||
late GymSet _editedGymSet;
|
|
||||||
late GymSetDatabaseHelper _db;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_db = GymSetDatabaseHelper.instance;
|
gymSet = widget.gymSet;
|
||||||
_editedGymSet = GymSet(
|
_nameController.text = gymSet.name.value;
|
||||||
id: widget.gymSet.id,
|
_repsController.text = gymSet.reps.value.toString();
|
||||||
name: widget.gymSet.name,
|
_weightController.text = gymSet.weight.value.toString();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
List<Widget> actions = [];
|
||||||
appBar: AppBar(title: const Text('Edit Gym Set'), actions: [
|
if (widget.gymSet.id.present)
|
||||||
IconButton(
|
actions.add(IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await _db.delete(_editedGymSet);
|
await db.gymSets.deleteOne(widget.gymSet);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Navigator.pop(context, _editedGymSet);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.delete))
|
icon: const Icon(Icons.delete)));
|
||||||
]),
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('Edit Gym Set'), actions: actions),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: material.Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
|
@ -55,7 +52,7 @@ class _EditGymSetPageState extends State<EditGymSetPage> {
|
||||||
decoration: const InputDecoration(labelText: 'Name'),
|
decoration: const InputDecoration(labelText: 'Name'),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_editedGymSet.name = value;
|
gymSet = gymSet.copyWith(name: Value(value));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -65,7 +62,8 @@ class _EditGymSetPageState extends State<EditGymSetPage> {
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
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,
|
keyboardType: TextInputType.number,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
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(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
print('edited gym set id: ${_editedGymSet.id}');
|
if (gymSet.id.present)
|
||||||
if (_editedGymSet.id != null)
|
await db.update(db.gymSets).write(gymSet);
|
||||||
await _db.update(_editedGymSet);
|
|
||||||
else
|
else
|
||||||
await _db.insert(_editedGymSet);
|
await db.into(db.gymSets).insert(gymSet);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Navigator.pop(context, _editedGymSet);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.check),
|
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:moor_flutter/moor_flutter.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
|
||||||
|
|
||||||
class GymSet {
|
class GymSets extends Table {
|
||||||
int? id;
|
IntColumn get id => integer().autoIncrement()();
|
||||||
String name;
|
TextColumn get name => text()();
|
||||||
int reps;
|
IntColumn get reps => integer()();
|
||||||
int weight;
|
IntColumn get weight => integer()();
|
||||||
DateTime created;
|
IntColumn get sets => integer().withDefault(const Constant(3))();
|
||||||
|
IntColumn get minutes => integer().withDefault(const Constant(3))();
|
||||||
GymSet(
|
IntColumn get seconds => integer().withDefault(const Constant(30))();
|
||||||
{this.id,
|
BoolColumn get hidden => boolean().withDefault(const Constant(false))();
|
||||||
required this.name,
|
TextColumn get created => text()();
|
||||||
required this.reps,
|
TextColumn get unit => text().withDefault(const Constant('kg'))();
|
||||||
required this.weight,
|
TextColumn get image => text()();
|
||||||
required this.created});
|
TextColumn get steps => text().nullable()();
|
||||||
}
|
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,26 @@
|
||||||
import 'package:flutter/material.dart';
|
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/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 {
|
class HomePage extends StatefulWidget {
|
||||||
HomePage({super.key});
|
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 = [
|
final List<Map<String, dynamic>> routes = [
|
||||||
{'title': 'Home', 'icon': Icons.home},
|
{'title': 'Home', 'icon': Icons.home},
|
||||||
|
@ -14,134 +31,160 @@ class HomePage extends StatelessWidget {
|
||||||
{'title': 'Settings', 'icon': Icons.settings},
|
{'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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
|
||||||
title: Text(routes[0]['title']),
|
|
||||||
),
|
|
||||||
drawer: Drawer(
|
drawer: Drawer(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: routes.length,
|
itemCount: routes.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
selected: selected == index,
|
||||||
leading: Icon(routes[index]['icon']),
|
leading: Icon(routes[index]['icon']),
|
||||||
title: Text(routes[index]['title']),
|
title: Text(routes[index]['title']),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
selected = index;
|
||||||
|
});
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
Navigator.pushNamed(
|
|
||||||
context, '/${routes[index]['title'].toLowerCase()}');
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: const Center(
|
appBar: AppBar(
|
||||||
child: GymSetPage(),
|
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 {
|
class _HomePageWidget extends StatefulWidget {
|
||||||
const GymSetPage({Key? key}) : super(key: key);
|
final String search;
|
||||||
|
|
||||||
|
const _HomePageWidget({Key? key, required this.search}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
createState() => GymSetPageState();
|
createState() => _HomePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
class GymSetPageState extends State<GymSetPage> {
|
class _HomePage extends State<_HomePageWidget> {
|
||||||
late GymSetDatabaseHelper db;
|
bool showSearch = false;
|
||||||
List<GymSet> sets = [];
|
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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() async {
|
|
||||||
print('Resetting...');
|
|
||||||
final data = await db.getAll();
|
|
||||||
setState(() {
|
|
||||||
sets = data;
|
|
||||||
searchResults = data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
db = GymSetDatabaseHelper.instance;
|
setStream();
|
||||||
reset();
|
}
|
||||||
|
|
||||||
|
void setStream() {
|
||||||
|
stream = (db.select(db.gymSets)
|
||||||
|
..where((gymSet) => gymSet.name.contains(widget.search))
|
||||||
|
..limit(10, offset: 0))
|
||||||
|
.watch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
didUpdateWidget(covariant _HomePageWidget oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
setStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleSearch() {
|
||||||
|
setState(() {
|
||||||
|
showSearch = !showSearch;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
body: StreamBuilder<List<GymSet>>(
|
||||||
title: TextField(
|
stream: stream,
|
||||||
controller: searchController,
|
builder: (context, snapshot) {
|
||||||
decoration: const InputDecoration(
|
final gymSets = snapshot.data;
|
||||||
hintText: 'Search Gym Sets',
|
|
||||||
border: InputBorder.none,
|
if (gymSets == null)
|
||||||
),
|
return const Center(child: CircularProgressIndicator());
|
||||||
onChanged: (searchQuery) {
|
|
||||||
search(searchQuery);
|
return ListView.builder(
|
||||||
},
|
itemCount: gymSets.length,
|
||||||
),
|
|
||||||
),
|
|
||||||
body: ListView.builder(
|
|
||||||
itemCount: searchResults.length,
|
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(gymSets[index].name),
|
||||||
'${searchResults[index].name}: ${searchResults[index].reps}x${searchResults[index].weight}kg'),
|
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await Navigator.push(
|
await Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) => EditGymSetPage(
|
||||||
EditGymSetPage(gymSet: searchResults[index]),
|
gymSet: gymSets[index].toCompanion(false)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
reset();
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
|
}),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Navigator.push(
|
await Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => EditGymSetPage(
|
builder: (context) => EditGymSetPage(
|
||||||
gymSet: GymSet(
|
gymSet: GymSetsCompanion(
|
||||||
name: '',
|
name: const Value(''),
|
||||||
reps: 0,
|
reps: const Value(0),
|
||||||
weight: 0,
|
weight: const Value(0),
|
||||||
created: DateTime.now())),
|
image: const Value(''),
|
||||||
|
created: Value(DateTime.now().toString()))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
reset();
|
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.add)));
|
child: const Icon(Icons.add)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fmassive/best_page.dart';
|
|
||||||
import 'package:fmassive/database.dart';
|
import 'package:fmassive/database.dart';
|
||||||
import 'package:fmassive/edit_set.dart';
|
import 'package:fmassive/edit_set.dart';
|
||||||
import 'package:fmassive/gym_set.dart';
|
|
||||||
import 'package:fmassive/home_page.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();
|
MyDatabase db = MyDatabase();
|
||||||
|
|
||||||
|
@ -22,16 +16,10 @@ class MyApp extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final edit = EditGymSetPage(
|
const edit = EditGymSetPage(gymSet: GymSetsCompanion());
|
||||||
gymSet: GymSet(name: '', reps: 0, weight: 0, created: DateTime.now()));
|
|
||||||
|
|
||||||
final Map<String, WidgetBuilder> routes = {
|
final Map<String, WidgetBuilder> routes = {
|
||||||
'/home': (context) => HomePage(),
|
'/home': (context) => const HomePage(),
|
||||||
'/plans': (context) => const PlansPage(),
|
|
||||||
'/best': (context) => const BestPage(),
|
|
||||||
'/workouts': (context) => const WorkoutsPage(),
|
|
||||||
'/timer': (context) => const TimerPage(),
|
|
||||||
'/settings': (context) => SettingsPage(),
|
|
||||||
'/edit-set': (context) => edit,
|
'/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';
|
||||||
|
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 {
|
class PlansPage extends StatelessWidget {
|
||||||
const PlansPage({super.key});
|
const PlansPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return const Scaffold(
|
||||||
appBar: AppBar(
|
body: Center(
|
||||||
title: const Text('Plans'),
|
child: _PlansPage(),
|
||||||
),
|
|
||||||
body: const Center(
|
|
||||||
child: Text('Welcome to the Plans Page!'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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';
|
import 'package:moor/moor.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
SettingsPage({super.key});
|
const 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},
|
|
||||||
];
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return const Scaffold(
|
||||||
appBar: AppBar(
|
body: Center(
|
||||||
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(
|
|
||||||
child: _SettingsPage(),
|
child: _SettingsPage(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -61,14 +33,12 @@ class _SettingsPageState extends State<_SettingsPage> {
|
||||||
void reset() async {
|
void reset() async {
|
||||||
var data = await db.select(db.settings).get();
|
var data = await db.select(db.settings).get();
|
||||||
if (data.isEmpty) await db.into(db.settings).insert(defaultSettings);
|
if (data.isEmpty) await db.into(db.settings).insert(defaultSettings);
|
||||||
setState(() {
|
|
||||||
if (data.isEmpty) return;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
reset();
|
||||||
stream = db.select(db.settings).watchSingle();
|
stream = db.select(db.settings).watchSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user