feat: useInfiniteQuery hook add

This commit is contained in:
Kingkor Roy Tirtho
2023-02-23 23:21:57 +06:00
parent 7fabf44756
commit f9a5207403
7 changed files with 396 additions and 121 deletions
@@ -1,40 +1,61 @@
import 'dart:convert';
import 'package:fl_query_hooks/fl_query_hooks.dart';
import 'package:fl_query_hooks_example/models/product.dart';
import 'package:fl_query/fl_query.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:http/http.dart';
class InfiniteQueryPageWidget extends StatefulWidget {
class InfiniteQueryPageWidget extends HookWidget {
const InfiniteQueryPageWidget({super.key});
@override
State<InfiniteQueryPageWidget> createState() =>
_InfiniteQueryPageWidgetState();
}
class _InfiniteQueryPageWidgetState extends State<InfiniteQueryPageWidget> {
final controller = ScrollController();
@override
void initState() {
super.initState();
controller.addListener(() async {
if (controller.position.pixels == controller.position.maxScrollExtent) {
final query = QueryClient.of(context).getInfiniteQuery("products");
await query?.fetchNext();
}
});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final controller = useScrollController();
final query = useInfiniteQuery<PagedProducts, ClientException, int>(
"products",
(page) async {
final res = await get(Uri.parse(
"https://dummyjson.com/products?limit=10&skip=${page * 10}",
));
if (res.statusCode == 200) {
return PagedProducts.fromJson(jsonDecode(res.body));
} else {
throw ClientException(res.statusCode.toString(), res.request?.url);
}
},
nextPage: (lastPage, pages) {
if (pages.isNotEmpty &&
pages.last.products.length < pages[lastPage].limit) {
/// returning [null] will set [hasNextPage] to [false]
return null;
}
return lastPage + 1;
},
initialPage: 0,
jsonConfig: JsonConfig(
fromJson: (json) => PagedProducts.fromJson(json),
toJson: (data) => data.toJson(),
),
);
useEffect(() {
listener() async {
if (controller.position.pixels == controller.position.maxScrollExtent) {
final query = QueryClient.of(context).getInfiniteQuery("products");
await query?.fetchNext();
}
}
controller.addListener(listener);
return () => controller.removeListener(listener);
}, [controller]);
final products = query.pages.map((e) => e.products).expand((e) => e);
return Scaffold(
appBar: AppBar(
title: const Text('Infinite Query'),
@@ -48,58 +69,27 @@ class _InfiniteQueryPageWidgetState extends State<InfiniteQueryPageWidget> {
child: Text(query?.pages.length.toString() ?? "-69"),
);
}),
body: InfiniteQueryBuilder<PagedProducts, ClientException, int>(
"products",
(page) async {
final res = await get(Uri.parse(
"https://dummyjson.com/products?limit=10&skip=${page * 10}",
));
if (res.statusCode == 200) {
return PagedProducts.fromJson(jsonDecode(res.body));
} else {
throw ClientException(res.statusCode.toString(), res.request?.url);
}
},
nextPage: (lastPage, pages) {
if (pages.isNotEmpty &&
pages.last.products.length < pages[lastPage].limit) {
/// returning [null] will set [hasNextPage] to [false]
return null;
}
return lastPage + 1;
},
initialPage: 0,
jsonConfig: JsonConfig(
fromJson: (json) => PagedProducts.fromJson(json),
toJson: (data) => data.toJson(),
),
builder: (context, query) {
final products = query.pages.map((e) => e.products).expand((e) => e);
if (!query.hasPages) {
return const Center(
body: !query.hasPages
? const Center(
child: CircularProgressIndicator(),
);
}
return ListView(
controller: controller,
children: [
for (final product in products)
ListTile(
title: Text(product.title),
subtitle: Text(product.description),
leading: Image.network(product.thumbnail),
),
if (query.hasNextPage)
const Center(
child: CircularProgressIndicator(),
),
if (query.hasErrors)
...query.errors.map((e) => Text(e.message)).toList(),
],
);
},
),
)
: ListView(
controller: controller,
children: [
for (final product in products)
ListTile(
title: Text(product.title),
subtitle: Text(product.description),
leading: Image.network(product.thumbnail),
),
if (query.hasNextPage)
const Center(
child: CircularProgressIndicator(),
),
if (query.hasErrors)
...query.errors.map((e) => Text(e.message)).toList(),
],
),
);
}
}