feat: useInfiniteQuery hook add
This commit is contained in:
@@ -8,6 +8,7 @@ import 'package:fl_query/src/core/client.dart';
|
|||||||
import 'package:fl_query/src/core/infinite_query.dart';
|
import 'package:fl_query/src/core/infinite_query.dart';
|
||||||
import 'package:fl_query/src/widgets/mixins/rebuilder.dart';
|
import 'package:fl_query/src/widgets/mixins/rebuilder.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/src/foundation/diagnostics.dart';
|
||||||
|
|
||||||
typedef InfiniteQueryBuilderFn<DataType, ErrorType, PageType> = Widget Function(
|
typedef InfiniteQueryBuilderFn<DataType, ErrorType, PageType> = Widget Function(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
@@ -68,15 +69,7 @@ class _InfiniteQueryBuilderState<DataType, ErrorType, PageType>
|
|||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
query = QueryClient.of(context).createInfiniteQuery(
|
_createQuery();
|
||||||
widget.queryKey,
|
|
||||||
widget.queryFn,
|
|
||||||
initialParam: widget.initialPage,
|
|
||||||
nextPage: widget.nextPage,
|
|
||||||
retryConfig: widget.retryConfig,
|
|
||||||
refreshConfig: widget.refreshConfig,
|
|
||||||
jsonConfig: widget.jsonConfig,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (widget.onData != null)
|
if (widget.onData != null)
|
||||||
dataSubscription = query!.dataStream.listen(widget.onData);
|
dataSubscription = query!.dataStream.listen(widget.onData);
|
||||||
@@ -90,6 +83,18 @@ class _InfiniteQueryBuilderState<DataType, ErrorType, PageType>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _createQuery() {
|
||||||
|
query = QueryClient.of(context).createInfiniteQuery(
|
||||||
|
widget.queryKey,
|
||||||
|
widget.queryFn,
|
||||||
|
initialParam: widget.initialPage,
|
||||||
|
nextPage: widget.nextPage,
|
||||||
|
retryConfig: widget.retryConfig,
|
||||||
|
refreshConfig: widget.refreshConfig,
|
||||||
|
jsonConfig: widget.jsonConfig,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -140,8 +145,61 @@ class _InfiniteQueryBuilderState<DataType, ErrorType, PageType>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
return const SizedBox.shrink();
|
_createQuery();
|
||||||
}
|
}
|
||||||
return widget.builder(context, query!);
|
return widget.builder(context, query!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
super.debugFillProperties(properties);
|
||||||
|
properties.add(DiagnosticsProperty<
|
||||||
|
InfiniteQueryBuilderFn<DataType, ErrorType, PageType>>(
|
||||||
|
'builder',
|
||||||
|
widget.builder,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<InfiniteQueryFn<DataType, PageType>>(
|
||||||
|
'queryFn',
|
||||||
|
widget.queryFn,
|
||||||
|
));
|
||||||
|
properties
|
||||||
|
.add(DiagnosticsProperty<InfiniteQueryNextPage<DataType, PageType>>(
|
||||||
|
'nextPage',
|
||||||
|
widget.nextPage,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<PageType>(
|
||||||
|
'initialPage',
|
||||||
|
widget.initialPage,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<RetryConfig>(
|
||||||
|
'retryConfig',
|
||||||
|
widget.retryConfig,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<RefreshConfig>(
|
||||||
|
'refreshConfig',
|
||||||
|
widget.refreshConfig,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<JsonConfig<DataType>>(
|
||||||
|
'jsonConfig',
|
||||||
|
widget.jsonConfig,
|
||||||
|
));
|
||||||
|
properties
|
||||||
|
.add(DiagnosticsProperty<ValueChanged<PageEvent<DataType, PageType>>>(
|
||||||
|
'onData',
|
||||||
|
widget.onData,
|
||||||
|
));
|
||||||
|
properties
|
||||||
|
.add(DiagnosticsProperty<ValueChanged<PageEvent<ErrorType, PageType>>>(
|
||||||
|
'onError',
|
||||||
|
widget.onError,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<bool>(
|
||||||
|
'enabled',
|
||||||
|
widget.enabled,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<String>(
|
||||||
|
'queryKey',
|
||||||
|
widget.queryKey,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,11 +123,7 @@ class _MutationBuilderState<DataType, ErrorType, VariablesType, RecoveryType>
|
|||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
mutation = QueryClient.of(context).createMutation(
|
_createMutation();
|
||||||
widget.mutationKey,
|
|
||||||
widget.mutationFn,
|
|
||||||
retryConfig: widget.retryConfig,
|
|
||||||
);
|
|
||||||
subscribeOnMutate();
|
subscribeOnMutate();
|
||||||
subscribeOnData();
|
subscribeOnData();
|
||||||
subscribeOnError();
|
subscribeOnError();
|
||||||
@@ -135,6 +131,14 @@ class _MutationBuilderState<DataType, ErrorType, VariablesType, RecoveryType>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _createMutation() {
|
||||||
|
mutation = QueryClient.of(context).createMutation(
|
||||||
|
widget.mutationKey,
|
||||||
|
widget.mutationFn,
|
||||||
|
retryConfig: widget.retryConfig,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -190,7 +194,7 @@ class _MutationBuilderState<DataType, ErrorType, VariablesType, RecoveryType>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (mutation == null) {
|
if (mutation == null) {
|
||||||
return const SizedBox.shrink();
|
_createMutation();
|
||||||
}
|
}
|
||||||
return widget.builder(context, mutation!);
|
return widget.builder(context, mutation!);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,17 +63,20 @@ class _QueryBuilderState<DataType, ErrorType>
|
|||||||
StreamSubscription<DataType>? dataSubscription;
|
StreamSubscription<DataType>? dataSubscription;
|
||||||
StreamSubscription<ErrorType>? errorSubscription;
|
StreamSubscription<ErrorType>? errorSubscription;
|
||||||
|
|
||||||
|
void _createQuery() {
|
||||||
|
query = QueryClient.of(context).createQuery(
|
||||||
|
widget.queryKey,
|
||||||
|
widget.queryFn,
|
||||||
|
initial: widget.initial,
|
||||||
|
retryConfig: widget.retryConfig,
|
||||||
|
refreshConfig: widget.refreshConfig,
|
||||||
|
jsonConfig: widget.jsonConfig,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
query = QueryClient.of(context).createQuery(
|
_createQuery();
|
||||||
widget.queryKey,
|
|
||||||
widget.queryFn,
|
|
||||||
initial: widget.initial,
|
|
||||||
retryConfig: widget.retryConfig,
|
|
||||||
refreshConfig: widget.refreshConfig,
|
|
||||||
jsonConfig: widget.jsonConfig,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (widget.onData != null)
|
if (widget.onData != null)
|
||||||
dataSubscription = query!.dataStream.listen(widget.onData);
|
dataSubscription = query!.dataStream.listen(widget.onData);
|
||||||
if (widget.onData != null)
|
if (widget.onData != null)
|
||||||
@@ -135,7 +138,7 @@ class _QueryBuilderState<DataType, ErrorType>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
return const SizedBox.shrink();
|
_createQuery();
|
||||||
}
|
}
|
||||||
return widget.builder(context, query!);
|
return widget.builder(context, query!);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,61 @@
|
|||||||
import 'dart:convert';
|
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_hooks_example/models/product.dart';
|
||||||
import 'package:fl_query/fl_query.dart';
|
import 'package:fl_query/fl_query.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
|
||||||
class InfiniteQueryPageWidget extends StatefulWidget {
|
class InfiniteQueryPageWidget extends HookWidget {
|
||||||
const InfiniteQueryPageWidget({super.key});
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
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(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Infinite Query'),
|
title: const Text('Infinite Query'),
|
||||||
@@ -48,58 +69,27 @@ class _InfiniteQueryPageWidgetState extends State<InfiniteQueryPageWidget> {
|
|||||||
child: Text(query?.pages.length.toString() ?? "-69"),
|
child: Text(query?.pages.length.toString() ?? "-69"),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
body: InfiniteQueryBuilder<PagedProducts, ClientException, int>(
|
body: !query.hasPages
|
||||||
"products",
|
? const Center(
|
||||||
(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(
|
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
);
|
)
|
||||||
}
|
: ListView(
|
||||||
return ListView(
|
controller: controller,
|
||||||
controller: controller,
|
children: [
|
||||||
children: [
|
for (final product in products)
|
||||||
for (final product in products)
|
ListTile(
|
||||||
ListTile(
|
title: Text(product.title),
|
||||||
title: Text(product.title),
|
subtitle: Text(product.description),
|
||||||
subtitle: Text(product.description),
|
leading: Image.network(product.thumbnail),
|
||||||
leading: Image.network(product.thumbnail),
|
),
|
||||||
),
|
if (query.hasNextPage)
|
||||||
if (query.hasNextPage)
|
const Center(
|
||||||
const Center(
|
child: CircularProgressIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
),
|
||||||
),
|
if (query.hasErrors)
|
||||||
if (query.hasErrors)
|
...query.errors.map((e) => Text(e.message)).toList(),
|
||||||
...query.errors.map((e) => Text(e.message)).toList(),
|
],
|
||||||
],
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
library fl_query_hooks;
|
library fl_query_hooks;
|
||||||
|
|
||||||
export 'src/use_query.dart';
|
|
||||||
export 'src/use_query_client.dart';
|
export 'src/use_query_client.dart';
|
||||||
|
export 'src/use_query.dart';
|
||||||
|
export 'src/use_infinite_query.dart';
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:fl_query/src/collections/default_configs.dart';
|
||||||
|
import 'package:fl_query/src/collections/json_config.dart';
|
||||||
|
import 'package:fl_query/src/collections/refresh_config.dart';
|
||||||
|
import 'package:fl_query/src/collections/retry_config.dart';
|
||||||
|
import 'package:fl_query/src/core/client.dart';
|
||||||
|
import 'package:fl_query/src/core/infinite_query.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/src/foundation/diagnostics.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
|
||||||
|
InfiniteQuery<DataType, ErrorType, PageType>
|
||||||
|
useInfiniteQuery<DataType, ErrorType, PageType>(
|
||||||
|
String queryKey,
|
||||||
|
InfiniteQueryFn<DataType, PageType> queryFn, {
|
||||||
|
required InfiniteQueryNextPage<DataType, PageType> nextPage,
|
||||||
|
required PageType initialPage,
|
||||||
|
RetryConfig retryConfig = DefaultConstants.retryConfig,
|
||||||
|
RefreshConfig refreshConfig = DefaultConstants.refreshConfig,
|
||||||
|
JsonConfig<DataType>? jsonConfig,
|
||||||
|
ValueChanged<PageEvent<DataType, PageType>>? onData,
|
||||||
|
ValueChanged<PageEvent<ErrorType, PageType>>? onError,
|
||||||
|
bool enabled = true,
|
||||||
|
}) {
|
||||||
|
return use(UseInfiniteQuery(
|
||||||
|
queryKey,
|
||||||
|
queryFn,
|
||||||
|
nextPage: nextPage,
|
||||||
|
initialPage: initialPage,
|
||||||
|
retryConfig: retryConfig,
|
||||||
|
refreshConfig: refreshConfig,
|
||||||
|
jsonConfig: jsonConfig,
|
||||||
|
onData: onData,
|
||||||
|
onError: onError,
|
||||||
|
enabled: enabled,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
class UseInfiniteQuery<DataType, ErrorType, PageType>
|
||||||
|
extends Hook<InfiniteQuery<DataType, ErrorType, PageType>> {
|
||||||
|
final InfiniteQueryFn<DataType, PageType> queryFn;
|
||||||
|
final String queryKey;
|
||||||
|
|
||||||
|
final PageType initialPage;
|
||||||
|
final InfiniteQueryNextPage<DataType, PageType> nextPage;
|
||||||
|
|
||||||
|
final RetryConfig retryConfig;
|
||||||
|
final RefreshConfig refreshConfig;
|
||||||
|
final JsonConfig<DataType>? jsonConfig;
|
||||||
|
|
||||||
|
final ValueChanged<PageEvent<DataType, PageType>>? onData;
|
||||||
|
final ValueChanged<PageEvent<ErrorType, PageType>>? onError;
|
||||||
|
|
||||||
|
// widget specific
|
||||||
|
final bool enabled;
|
||||||
|
|
||||||
|
const UseInfiniteQuery(
|
||||||
|
this.queryKey,
|
||||||
|
this.queryFn, {
|
||||||
|
required this.nextPage,
|
||||||
|
required this.initialPage,
|
||||||
|
this.retryConfig = DefaultConstants.retryConfig,
|
||||||
|
this.refreshConfig = DefaultConstants.refreshConfig,
|
||||||
|
this.jsonConfig,
|
||||||
|
this.onData,
|
||||||
|
this.onError,
|
||||||
|
this.enabled = true,
|
||||||
|
super.keys,
|
||||||
|
}) : assert(
|
||||||
|
(jsonConfig != null && enabled) || jsonConfig == null,
|
||||||
|
'jsonConfig is only supported when enabled is true',
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
createState() => _UseInfiniteQueryState<DataType, ErrorType, PageType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UseInfiniteQueryState<DataType, ErrorType, PageType> extends HookState<
|
||||||
|
InfiniteQuery<DataType, ErrorType, PageType>,
|
||||||
|
UseInfiniteQuery<DataType, ErrorType, PageType>> {
|
||||||
|
InfiniteQuery<DataType, ErrorType, PageType>? query;
|
||||||
|
|
||||||
|
VoidCallback? removeListener;
|
||||||
|
|
||||||
|
StreamSubscription<PageEvent<DataType, PageType>>? dataSubscription;
|
||||||
|
StreamSubscription<PageEvent<ErrorType, PageType>>? errorSubscription;
|
||||||
|
|
||||||
|
void rebuild([_]) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initialize() async {
|
||||||
|
setState(() {
|
||||||
|
_createQuery();
|
||||||
|
|
||||||
|
if (hook.onData != null)
|
||||||
|
dataSubscription = query!.dataStream.listen(hook.onData);
|
||||||
|
if (hook.onError != null)
|
||||||
|
errorSubscription = query!.errorStream.listen(hook.onError);
|
||||||
|
|
||||||
|
removeListener = query!.addListener(rebuild);
|
||||||
|
});
|
||||||
|
if (hook.enabled) {
|
||||||
|
await query!.fetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _createQuery() {
|
||||||
|
query = QueryClient.of(context).createInfiniteQuery(
|
||||||
|
hook.queryKey,
|
||||||
|
hook.queryFn,
|
||||||
|
initialParam: hook.initialPage,
|
||||||
|
nextPage: hook.nextPage,
|
||||||
|
retryConfig: hook.retryConfig,
|
||||||
|
refreshConfig: hook.refreshConfig,
|
||||||
|
jsonConfig: hook.jsonConfig,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initHook() {
|
||||||
|
super.initHook();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
initialize();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
dataSubscription?.cancel();
|
||||||
|
errorSubscription?.cancel();
|
||||||
|
removeListener?.call();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateHook(oldHook) {
|
||||||
|
super.didUpdateHook(oldHook);
|
||||||
|
|
||||||
|
if (oldHook.queryKey != hook.queryKey) {
|
||||||
|
dataSubscription?.cancel();
|
||||||
|
errorSubscription?.cancel();
|
||||||
|
removeListener?.call();
|
||||||
|
initialize();
|
||||||
|
return;
|
||||||
|
} else if (oldHook.enabled != hook.enabled && hook.enabled) {
|
||||||
|
query!.fetch();
|
||||||
|
}
|
||||||
|
if (oldHook.queryFn != hook.queryFn) {
|
||||||
|
query!.updateQueryFn(hook.queryFn);
|
||||||
|
}
|
||||||
|
if (oldHook.nextPage != hook.nextPage) {
|
||||||
|
query!.updateNextPageFn(hook.nextPage);
|
||||||
|
}
|
||||||
|
if (oldHook.onData != hook.onData) {
|
||||||
|
dataSubscription?.cancel();
|
||||||
|
if (hook.onData != null)
|
||||||
|
dataSubscription = query!.dataStream.listen(hook.onData);
|
||||||
|
}
|
||||||
|
if (oldHook.onError != hook.onError) {
|
||||||
|
errorSubscription?.cancel();
|
||||||
|
if (hook.onError != null)
|
||||||
|
errorSubscription = query!.errorStream.listen(hook.onError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
build(BuildContext context) {
|
||||||
|
if (query == null) {
|
||||||
|
_createQuery();
|
||||||
|
}
|
||||||
|
return query!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
super.debugFillProperties(properties);
|
||||||
|
properties.add(DiagnosticsProperty<InfiniteQueryFn<DataType, PageType>>(
|
||||||
|
'queryFn',
|
||||||
|
hook.queryFn,
|
||||||
|
));
|
||||||
|
properties
|
||||||
|
.add(DiagnosticsProperty<InfiniteQueryNextPage<DataType, PageType>>(
|
||||||
|
'nextPage',
|
||||||
|
hook.nextPage,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<PageType>(
|
||||||
|
'initialPage',
|
||||||
|
hook.initialPage,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<RetryConfig>(
|
||||||
|
'retryConfig',
|
||||||
|
hook.retryConfig,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<RefreshConfig>(
|
||||||
|
'refreshConfig',
|
||||||
|
hook.refreshConfig,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<JsonConfig<DataType>>(
|
||||||
|
'jsonConfig',
|
||||||
|
hook.jsonConfig,
|
||||||
|
));
|
||||||
|
properties
|
||||||
|
.add(DiagnosticsProperty<ValueChanged<PageEvent<DataType, PageType>>>(
|
||||||
|
'onData',
|
||||||
|
hook.onData,
|
||||||
|
));
|
||||||
|
properties
|
||||||
|
.add(DiagnosticsProperty<ValueChanged<PageEvent<ErrorType, PageType>>>(
|
||||||
|
'onError',
|
||||||
|
hook.onError,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<bool>(
|
||||||
|
'enabled',
|
||||||
|
hook.enabled,
|
||||||
|
));
|
||||||
|
properties.add(DiagnosticsProperty<String>(
|
||||||
|
'queryKey',
|
||||||
|
hook.queryKey,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -83,17 +83,20 @@ class _UseQueryState<DataType, ErrorType> extends HookState<
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _createQuery() {
|
||||||
|
query = QueryClient.of(context).createQuery(
|
||||||
|
hook.queryKey,
|
||||||
|
hook.queryFn,
|
||||||
|
initial: hook.initial,
|
||||||
|
retryConfig: hook.retryConfig,
|
||||||
|
refreshConfig: hook.refreshConfig,
|
||||||
|
jsonConfig: hook.jsonConfig,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
query = QueryClient.of(context).createQuery(
|
_createQuery();
|
||||||
hook.queryKey,
|
|
||||||
hook.queryFn,
|
|
||||||
initial: hook.initial,
|
|
||||||
retryConfig: hook.retryConfig,
|
|
||||||
refreshConfig: hook.refreshConfig,
|
|
||||||
jsonConfig: hook.jsonConfig,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hook.onData != null)
|
if (hook.onData != null)
|
||||||
dataSubscription = query!.dataStream.listen(hook.onData);
|
dataSubscription = query!.dataStream.listen(hook.onData);
|
||||||
if (hook.onData != null)
|
if (hook.onData != null)
|
||||||
@@ -155,14 +158,7 @@ class _UseQueryState<DataType, ErrorType> extends HookState<
|
|||||||
@override
|
@override
|
||||||
Query<DataType, ErrorType> build(BuildContext context) {
|
Query<DataType, ErrorType> build(BuildContext context) {
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
query = QueryClient.of(context).createQuery(
|
_createQuery();
|
||||||
hook.queryKey,
|
|
||||||
hook.queryFn,
|
|
||||||
initial: hook.initial,
|
|
||||||
retryConfig: hook.retryConfig,
|
|
||||||
refreshConfig: hook.refreshConfig,
|
|
||||||
jsonConfig: hook.jsonConfig,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return query!;
|
return query!;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user