fmassive/lib/home_page.dart

199 lines
5.6 KiB
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/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:intl/intl.dart';
import 'package:moor_flutter/moor_flutter.dart';
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},
{'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},
];
void toggleSearch() {
setState(() {
if (showSearch) search = '';
showSearch = !showSearch;
});
focusNode.requestFocus();
}
Widget getBody() {
switch (routes[selected]['title']) {
case 'Settings':
return SettingsPage(search: search);
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 SafeArea(
child: Scaffold(
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);
},
);
},
),
),
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 _HomePageWidget extends StatefulWidget {
final String search;
const _HomePageWidget({Key? key, required this.search}) : super(key: key);
@override
createState() => _HomePage();
}
class _HomePage extends State<_HomePageWidget> {
bool showSearch = false;
late Stream<List<GymSet>> stream;
@override
initState() {
super.initState();
setStream();
}
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
Widget build(BuildContext context) {
return Scaffold(
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),
subtitle: Text(
"${gymSets[index].reps} x ${gymSets[index].weight}kg"),
trailing: Text(DateFormat("yyyy-MM-dd")
.format(DateTime.parse(gymSets[index].created))),
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: GymSetsCompanion(
name: const Value(''),
reps: const Value(0),
weight: const Value(0),
image: const Value(''),
created: Value(DateTime.now().toString()))),
),
);
},
child: const Icon(Icons.add)));
}
}