Add pagination to home page

This commit is contained in:
Brandon Presley 2023-04-17 11:03:27 +12:00
parent 1445c19933
commit 59c9c539d2
3 changed files with 85 additions and 48 deletions

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:fmassive/database.dart';
import 'package:fmassive/edit_set.dart';
import 'package:fmassive/main.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:intl/intl.dart';
import 'package:moor_flutter/moor_flutter.dart';
@ -16,25 +17,41 @@ class SetList extends StatefulWidget {
class _SetList extends State<SetList> {
bool showSearch = false;
late Stream<List<GymSet>> stream;
final PagingController<int, GymSet> pagingController =
PagingController(firstPageKey: 0);
@override
initState() {
super.initState();
setStream();
}
void setStream() {
stream = (db.select(db.gymSets)
..where((gymSet) => gymSet.name.contains(widget.search))
..limit(10, offset: 0))
.watch();
pagingController.addPageRequestListener((pageKey) {
fetch(pageKey);
});
}
@override
didUpdateWidget(covariant SetList oldWidget) {
super.didUpdateWidget(oldWidget);
setStream();
pagingController.refresh();
}
Future<void> fetch(int pageKey) async {
try {
final gymSets = await (db.select(db.gymSets)
..where((gymSet) => gymSet.name.contains(widget.search))
..limit(10, offset: pageKey * 10))
.get();
final isLastPage = gymSets.length < 10;
if (isLastPage) {
pagingController.appendLastPage(gymSets);
} else {
final nextPageKey = pageKey + 1;
pagingController.appendPage(gymSets, nextPageKey);
}
} catch (error) {
pagingController.error = error;
}
}
void toggleSearch() {
@ -46,50 +63,53 @@ class _SetList extends State<SetList> {
@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 {
body: PagedListView<int, GymSet>(
pagingController: pagingController,
builderDelegate: PagedChildBuilderDelegate<GymSet>(
itemBuilder: (context, gymSet, index) => ListTile(
title: Text(gymSet.name),
subtitle: Text("${gymSet.reps} x ${gymSet.weight}kg"),
trailing: Text(
DateFormat("yyyy-MM-dd").format(DateTime.parse(gymSet.created)),
),
onTap: () 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()))),
gymSet: gymSet.toCompanion(false),
),
),
);
pagingController.refresh();
},
child: const Icon(Icons.add)));
),
firstPageProgressIndicatorBuilder: (_) =>
const Center(child: CircularProgressIndicator()),
newPageProgressIndicatorBuilder: (_) =>
const Center(child: CircularProgressIndicator()),
),
),
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()),
),
),
),
);
pagingController.refresh();
},
child: const Icon(Icons.add),
),
);
}
}

View File

@ -392,6 +392,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
infinite_scroll_pagination:
dependency: "direct main"
description:
name: infinite_scroll_pagination
sha256: "9517328f4e373f08f57dbb11c5aac5b05554142024d6b60c903f3b73476d52db"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
intl:
dependency: "direct main"
description:
@ -677,6 +685,14 @@ packages:
description: flutter
source: sdk
version: "0.0.99"
sliver_tools:
dependency: transitive
description:
name: sliver_tools
sha256: ccdc502098a8bfa07b3ec582c282620031481300035584e1bb3aca296a505e8c
url: "https://pub.dev"
source: hosted
version: "0.2.10"
source_gen:
dependency: transitive
description:

View File

@ -46,6 +46,7 @@ dependencies:
audioplayers: ^4.0.1
intl: ^0.18.0
permission_handler: ^10.2.0
infinite_scroll_pagination: ^3.2.0
dev_dependencies:
flutter_test: