feat: add initial support for InfiniteQuery
Added new infinite query class with it's own builder widget and integration with query_bowl The `cast` method used in mutation and query are now a mixin instead of BasicOperation property
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fl_query/src/mixins/autocast.dart';
|
||||
import 'package:fl_query/src/models/infinite_query_job.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
typedef InfiniteQueryTaskFunction<T extends Object, Outside,
|
||||
PageParam extends Object>
|
||||
= FutureOr<T> Function(
|
||||
String queryKey,
|
||||
PageParam pageParam,
|
||||
Outside externalData,
|
||||
);
|
||||
typedef InfiniteQueryPageParamFunction<T extends Object,
|
||||
PageParam extends Object>
|
||||
= FutureOr<PageParam> Function(T lastPage, PageParam lastParam);
|
||||
|
||||
class InfiniteQuery<T extends Object, Outside, PageParam extends Object>
|
||||
with ChangeNotifier, AutoCast {
|
||||
String queryKey;
|
||||
|
||||
Map<PageParam, T?> _data;
|
||||
Map<PageParam, dynamic> _error;
|
||||
|
||||
InfiniteQueryTaskFunction<T, Outside, PageParam> task;
|
||||
|
||||
InfiniteQueryPageParamFunction<T, PageParam>? getNextPageParam;
|
||||
InfiniteQueryPageParamFunction<T, PageParam>? getPreviousPageParam;
|
||||
|
||||
List<PageParam> get pageParams => _data.keys.toList();
|
||||
List<dynamic> get errors => _error.values.toList();
|
||||
List<T?> get pages => _data.values.toList();
|
||||
|
||||
PageParam currentParam;
|
||||
|
||||
Outside _externalData;
|
||||
|
||||
bool _hasNextPage = false;
|
||||
bool _hasPreviousPage = false;
|
||||
|
||||
bool get hasNextPage => _hasNextPage;
|
||||
bool get hasPreviousPage => _hasPreviousPage;
|
||||
|
||||
InfiniteQuery({
|
||||
required this.queryKey,
|
||||
required this.task,
|
||||
required PageParam initialParam,
|
||||
required Outside externalData,
|
||||
this.getNextPageParam,
|
||||
this.getPreviousPageParam,
|
||||
T? initialPage,
|
||||
}) : currentParam = initialParam,
|
||||
_externalData = externalData,
|
||||
_error = {},
|
||||
_data = {
|
||||
if (initialPage != null) initialParam: initialPage,
|
||||
};
|
||||
|
||||
InfiniteQuery.fromOptions(
|
||||
InfiniteQueryJob<T, Outside, PageParam> options, {
|
||||
required Outside externalData,
|
||||
}) : queryKey = options.queryKey,
|
||||
task = options.task,
|
||||
currentParam = options.initialParam,
|
||||
_externalData = externalData,
|
||||
_error = {},
|
||||
getNextPageParam = options.getNextPageParam,
|
||||
getPreviousPageParam = options.getPreviousPageParam,
|
||||
_data = {
|
||||
if (options.initialPage != null)
|
||||
options.initialParam: options.initialPage,
|
||||
};
|
||||
|
||||
Future<void> _execute() async {
|
||||
final page = await task(
|
||||
queryKey,
|
||||
currentParam,
|
||||
_externalData,
|
||||
);
|
||||
_data[currentParam] = page;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<List<T?>> fetch() async {
|
||||
if (_data.isEmpty) await _execute();
|
||||
return pages;
|
||||
}
|
||||
|
||||
Future<T?> fetchNextPage([
|
||||
InfiniteQueryPageParamFunction<T, PageParam>? getNextPageParam,
|
||||
]) async {
|
||||
try {
|
||||
if (_data[currentParam] == null) await _execute();
|
||||
final nextParam = await (getNextPageParam ?? this.getNextPageParam)?.call(
|
||||
_data[currentParam]!,
|
||||
currentParam,
|
||||
);
|
||||
if (nextParam == null) {
|
||||
_hasNextPage = false;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
_hasNextPage = true;
|
||||
currentParam = nextParam;
|
||||
return await _execute().then((_) => _data[currentParam]);
|
||||
} catch (e) {
|
||||
print("[InfiniteQuery.fetchNextPage]: $e");
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<T?> fetchPreviousPage([
|
||||
InfiniteQueryPageParamFunction<T, PageParam>? getPreviousPageParam,
|
||||
]) async {
|
||||
try {
|
||||
if (_data[currentParam] == null) await _execute();
|
||||
final prevParam =
|
||||
await (getNextPageParam ?? this.getPreviousPageParam)?.call(
|
||||
_data[currentParam]!,
|
||||
currentParam,
|
||||
);
|
||||
if (prevParam == null) {
|
||||
_hasPreviousPage = false;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
_hasPreviousPage = true;
|
||||
currentParam = prevParam;
|
||||
return await _execute().then((_) => _data[currentParam]);
|
||||
} catch (e) {
|
||||
print("[InfiniteQuery.fetchPreviousPage]: $e");
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import 'package:fl_query/src/infinite_query.dart';
|
||||
import 'package:fl_query/src/models/infinite_query_job.dart';
|
||||
import 'package:fl_query/src/query_bowl.dart';
|
||||
import 'package:fl_query/src/utils.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class InfiniteQueryBuilder<T extends Object, Outside, PageParam extends Object>
|
||||
extends StatefulWidget {
|
||||
final Function(
|
||||
BuildContext context,
|
||||
InfiniteQuery<T, Outside, PageParam> query,
|
||||
) builder;
|
||||
final InfiniteQueryJob<T, Outside, PageParam> job;
|
||||
final Outside externalData;
|
||||
InfiniteQueryBuilder({
|
||||
required this.job,
|
||||
required this.builder,
|
||||
required this.externalData,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<InfiniteQueryBuilder<T, Outside, PageParam>> createState() =>
|
||||
_InfiniteQueryBuilderState<T, Outside, PageParam>();
|
||||
}
|
||||
|
||||
class _InfiniteQueryBuilderState<T extends Object, Outside,
|
||||
PageParam extends Object>
|
||||
extends State<InfiniteQueryBuilder<T, Outside, PageParam>> {
|
||||
InfiniteQuery<T, Outside, PageParam>? infiniteQuery;
|
||||
late QueryBowl queryBowl;
|
||||
late final ValueKey<String> uKey;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
uKey = ValueKey<String>(uuid.v4());
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => init());
|
||||
}
|
||||
|
||||
void init([T? previousData]) async {
|
||||
final bowl = QueryBowl.of(context);
|
||||
infiniteQuery = bowl.addInfiniteQuery<T, Outside, PageParam>(
|
||||
widget.job,
|
||||
externalData: widget.externalData,
|
||||
key: uKey,
|
||||
);
|
||||
// final hasExternalDataChanged = infiniteQuery!.externalData != null &&
|
||||
// infiniteQuery!.prevUsedExternalData != null &&
|
||||
// !isShallowEqual(infiniteQuery!.externalData!, infiniteQuery!.prevUsedExternalData!);
|
||||
// if (infiniteQuery!.fetched && hasExternalDataChanged) {
|
||||
// await infiniteQuery!.refetch();
|
||||
// } else if (!infiniteQuery!.fetched) {
|
||||
await infiniteQuery!.fetch();
|
||||
// }
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
queryBowl = QueryBowl.of(context);
|
||||
final latestInfiniteQuery = queryBowl
|
||||
.getInfiniteQuery<T, Outside, PageParam>(widget.job.queryKey) ??
|
||||
infiniteQuery;
|
||||
if (latestInfiniteQuery == null) return Container();
|
||||
return widget.builder(context, latestInfiniteQuery);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mixin AutoCast {
|
||||
A? cast<A>() => this is A ? this as A : null;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class InfiniteQueryData<T extends Object> {
|
||||
final Set<T> pages;
|
||||
final Set<String> pageParams;
|
||||
|
||||
InfiniteQueryData({
|
||||
required this.pages,
|
||||
required this.pageParams,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:fl_query/src/infinite_query.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class InfiniteQueryJob<T extends Object, Outside, PageParam extends Object> {
|
||||
// all params
|
||||
String _queryKey;
|
||||
InfiniteQueryTaskFunction<T, Outside, PageParam> task;
|
||||
final int? retries;
|
||||
final Duration? retryDelay;
|
||||
T? initialPage;
|
||||
PageParam initialParam;
|
||||
|
||||
/// If set to false then the initial fetch will not be called & to
|
||||
/// start the process the user has to call the refetch first
|
||||
final bool? enabled;
|
||||
|
||||
// got from global options
|
||||
final bool? refetchOnMount;
|
||||
final bool? refetchOnReconnect;
|
||||
final bool? refetchOnExternalDataChange;
|
||||
final bool? keepPreviousData;
|
||||
final Duration? staleTime;
|
||||
final Duration? cacheTime;
|
||||
|
||||
final Duration? refetchInterval;
|
||||
final Connectivity? connectivity;
|
||||
final InfiniteQueryPageParamFunction<T, PageParam> getNextPageParam;
|
||||
final InfiniteQueryPageParamFunction<T, PageParam> getPreviousPageParam;
|
||||
|
||||
@protected
|
||||
bool isDynamic = false;
|
||||
|
||||
InfiniteQueryJob({
|
||||
required String queryKey,
|
||||
required this.task,
|
||||
required this.initialParam,
|
||||
required this.getNextPageParam,
|
||||
required this.getPreviousPageParam,
|
||||
this.retries,
|
||||
this.retryDelay,
|
||||
this.initialPage,
|
||||
this.staleTime,
|
||||
this.cacheTime,
|
||||
this.enabled,
|
||||
this.refetchInterval,
|
||||
this.refetchOnMount,
|
||||
this.refetchOnReconnect,
|
||||
this.refetchOnExternalDataChange,
|
||||
this.connectivity,
|
||||
this.keepPreviousData,
|
||||
}) : _queryKey = queryKey;
|
||||
|
||||
String get queryKey => _queryKey;
|
||||
|
||||
static InfiniteQueryJob<T, Outside, PageParam> Function(String queryKey)
|
||||
withVariableKey<T extends Object, Outside, PageParam extends Object>({
|
||||
required InfiniteQueryTaskFunction<T, Outside, PageParam> task,
|
||||
required InfiniteQueryPageParamFunction<T, PageParam> getNextPageParam,
|
||||
required InfiniteQueryPageParamFunction<T, PageParam> getPreviousPageParam,
|
||||
required PageParam initialParam,
|
||||
|
||||
/// a extra key joined with queryKey by a '#'
|
||||
///
|
||||
/// useful for matching a group query
|
||||
String? preQueryKey,
|
||||
int? retries,
|
||||
Duration? retryDelay,
|
||||
T? initialPage,
|
||||
Duration? staleTime,
|
||||
Duration? cacheTime,
|
||||
bool? enabled,
|
||||
Duration? refetchInterval,
|
||||
bool? refetchOnMount,
|
||||
bool? refetchOnReconnect,
|
||||
bool? refetchOnExternalDataChange,
|
||||
Connectivity? connectivity,
|
||||
bool? keepPreviousData,
|
||||
}) {
|
||||
return (String queryKey) {
|
||||
if (preQueryKey != null) queryKey = "$preQueryKey#$queryKey";
|
||||
final query = InfiniteQueryJob<T, Outside, PageParam>(
|
||||
queryKey: queryKey,
|
||||
task: task,
|
||||
getNextPageParam: getNextPageParam,
|
||||
getPreviousPageParam: getPreviousPageParam,
|
||||
retries: retries,
|
||||
retryDelay: retryDelay,
|
||||
initialPage: initialPage,
|
||||
staleTime: staleTime,
|
||||
cacheTime: cacheTime,
|
||||
enabled: enabled,
|
||||
refetchInterval: refetchInterval,
|
||||
refetchOnMount: refetchOnMount,
|
||||
refetchOnReconnect: refetchOnReconnect,
|
||||
refetchOnExternalDataChange: refetchOnExternalDataChange,
|
||||
connectivity: connectivity,
|
||||
keepPreviousData: keepPreviousData,
|
||||
initialParam: initialParam,
|
||||
);
|
||||
query.isDynamic = true;
|
||||
return query;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:fl_query/fl_query.dart';
|
||||
import 'package:fl_query/src/base_operation.dart';
|
||||
import 'package:fl_query/src/mixins/autocast.dart';
|
||||
import 'package:fl_query/src/models/mutation_job.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@@ -23,7 +24,7 @@ typedef MutationListener<T, V> = FutureOr<void> Function(
|
||||
typedef MutationTaskFunction<T, V> = FutureOr<T> Function(
|
||||
String queryKey, V variables);
|
||||
|
||||
class Mutation<T extends Object, V> extends BaseOperation<T> {
|
||||
class Mutation<T extends Object, V> extends BaseOperation<T> with AutoCast {
|
||||
// all params
|
||||
final String mutationKey;
|
||||
MutationTaskFunction<T, V> task;
|
||||
@@ -201,8 +202,6 @@ class Mutation<T extends Object, V> extends BaseOperation<T> {
|
||||
_sideEffectContext = null;
|
||||
}
|
||||
|
||||
A? cast<A>() => this is A ? this as A : null;
|
||||
|
||||
bool get isError => status == MutationStatus.error;
|
||||
bool get isIdle => status == MutationStatus.idle;
|
||||
bool get isLoading => status == MutationStatus.loading;
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:fl_query/src/base_operation.dart';
|
||||
import 'package:fl_query/src/mixins/autocast.dart';
|
||||
import 'package:fl_query/src/models/query_job.dart';
|
||||
import 'package:fl_query/src/utils.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@@ -36,7 +37,7 @@ typedef ListenerUnsubscriber = void Function();
|
||||
|
||||
typedef QueryUpdateFunction<T> = FutureOr<T> Function(T? oldData);
|
||||
|
||||
class Query<T extends Object, Outside> extends BaseOperation<T> {
|
||||
class Query<T extends Object, Outside> extends BaseOperation<T> with AutoCast {
|
||||
// all params
|
||||
final String queryKey;
|
||||
QueryTaskFunction<T, Outside> task;
|
||||
@@ -234,7 +235,7 @@ class Query<T extends Object, Outside> extends BaseOperation<T> {
|
||||
/// and will only return the available data
|
||||
///
|
||||
/// If a [fetch] is already running in the background it'll just return
|
||||
/// the current available [data] (which can be nul if no [initialData]
|
||||
/// the current available [data] (which can be nul if no [initialPage]
|
||||
/// was provided) instead of running the task to prevent race conditions
|
||||
Future<T?> fetch() async {
|
||||
if (!enabled) return null;
|
||||
@@ -391,8 +392,6 @@ class Query<T extends Object, Outside> extends BaseOperation<T> {
|
||||
return _previousData != null ? _previousData == data : false;
|
||||
}
|
||||
|
||||
A? cast<A>() => this is A ? this as A : null;
|
||||
|
||||
String get debugLabel => "Query($queryKey)";
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:fl_query/src/infinite_query.dart';
|
||||
import 'package:fl_query/src/models/infinite_query_job.dart';
|
||||
import 'package:fl_query/src/models/mutation_job.dart';
|
||||
import 'package:fl_query/src/models/query_job.dart';
|
||||
import 'package:fl_query/src/mutation.dart';
|
||||
@@ -90,6 +92,7 @@ class QueryBowlScope extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
late Set<InfiniteQuery> infiniteQueries;
|
||||
late Set<Query> queries;
|
||||
late Set<Mutation> mutations;
|
||||
|
||||
@@ -98,6 +101,7 @@ class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
infiniteQueries = {};
|
||||
queries = {};
|
||||
mutations = {};
|
||||
|
||||
@@ -122,6 +126,9 @@ class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
}
|
||||
|
||||
void _listenToUpdates() {
|
||||
for (final infiniteQuery in infiniteQueries) {
|
||||
infiniteQuery.addListener(() => updateInfiniteQueries(infiniteQuery));
|
||||
}
|
||||
for (final query in queries) {
|
||||
query.addListener(() => updateQueries(query));
|
||||
}
|
||||
@@ -131,6 +138,9 @@ class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
}
|
||||
|
||||
void _disposeUpdateListeners() {
|
||||
for (final infiniteQuery in infiniteQueries) {
|
||||
infiniteQuery.removeListener(() => updateInfiniteQueries(infiniteQuery));
|
||||
}
|
||||
for (final query in queries) {
|
||||
query.removeListener(() => updateQueries(query));
|
||||
}
|
||||
@@ -153,6 +163,21 @@ class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
});
|
||||
}
|
||||
|
||||
void updateInfiniteQueries(InfiniteQuery infiniteQuery) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// checking & not including inactive queries
|
||||
// basically garbage collecting queries
|
||||
setState(() {
|
||||
infiniteQueries = Set.from(
|
||||
// infiniteQuery.isInactive
|
||||
// ? infiniteQueries.where((el) => el.queryKey != infiniteQuery.queryKey)
|
||||
// : infiniteQuery,
|
||||
infiniteQueries,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void updateMutations(Mutation mutation) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
@@ -169,6 +194,15 @@ class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
});
|
||||
}
|
||||
|
||||
void addInfiniteQuery<T extends Object, Outside, PageParam extends Object>(
|
||||
InfiniteQuery<T, Outside, PageParam> infiniteQuery) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
infiniteQueries = Set.from({...infiniteQueries, infiniteQuery});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void addQuery<T extends Object, Outside>(Query<T, Outside> query) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
@@ -215,10 +249,12 @@ class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
_disposeUpdateListeners();
|
||||
_listenToUpdates();
|
||||
return QueryBowl(
|
||||
addInfiniteQuery: addInfiniteQuery,
|
||||
addQuery: addQuery,
|
||||
addMutation: addMutation,
|
||||
removeQueries: removeQueries,
|
||||
clear: clear,
|
||||
infiniteQueries: infiniteQueries,
|
||||
queries: queries,
|
||||
mutations: mutations,
|
||||
staleTime: widget.staleTime,
|
||||
@@ -238,6 +274,7 @@ class _QueryBowlScopeState extends State<QueryBowlScope> {
|
||||
/// Its responsible or can be used for (not recommended) creating,
|
||||
/// updating & deleting queries & mutations
|
||||
class QueryBowl extends InheritedWidget {
|
||||
final Set<InfiniteQuery> _infiniteQueries;
|
||||
final Set<Query> _queries;
|
||||
final Set<Mutation> _mutations;
|
||||
final Duration staleTime;
|
||||
@@ -248,6 +285,9 @@ class QueryBowl extends InheritedWidget {
|
||||
final bool refetchOnReconnect;
|
||||
final bool refetchOnExternalDataChange;
|
||||
|
||||
final void Function<T extends Object, Outside, PageParam extends Object>(
|
||||
InfiniteQuery<T, Outside, PageParam> infiniteQuery) _addInfiniteQuery;
|
||||
|
||||
final void Function<T extends Object, Outside>(Query<T, Outside> query)
|
||||
_addQuery;
|
||||
|
||||
@@ -260,11 +300,16 @@ class QueryBowl extends InheritedWidget {
|
||||
|
||||
const QueryBowl({
|
||||
required Widget child,
|
||||
required final void Function<T extends Object, Outside,
|
||||
PageParam extends Object>(
|
||||
InfiniteQuery<T, Outside, PageParam> infiniteQuery)
|
||||
addInfiniteQuery,
|
||||
required final void Function<T extends Object, Outside>(
|
||||
Query<T, Outside> query)
|
||||
addQuery,
|
||||
required final void Function<T extends Object, V>(Mutation<T, V> mutation)
|
||||
addMutation,
|
||||
required final Set<InfiniteQuery> infiniteQueries,
|
||||
required final Set<Query> queries,
|
||||
required final Set<Mutation> mutations,
|
||||
required this.staleTime,
|
||||
@@ -280,6 +325,8 @@ class QueryBowl extends InheritedWidget {
|
||||
_queries = queries,
|
||||
_mutations = mutations,
|
||||
_addMutation = addMutation,
|
||||
_addInfiniteQuery = addInfiniteQuery,
|
||||
_infiniteQueries = infiniteQueries,
|
||||
super(child: child, key: key);
|
||||
|
||||
Query<T, Outside> _createQueryWithDefaults<T extends Object, Outside>(
|
||||
@@ -303,6 +350,26 @@ class QueryBowl extends InheritedWidget {
|
||||
return query;
|
||||
}
|
||||
|
||||
// InfiniteQuery<T, Outside, PageParam> _createInfiniteQueryWithDefaults<
|
||||
// T extends Object, Outside, PageParam extends Object>(
|
||||
// InfiniteQueryJob<T, Outside, PageParam> options,
|
||||
// Outside externalData,
|
||||
// ) {
|
||||
// final query = InfiniteQuery<T, Outside, PageParam>.fromOptions(
|
||||
// options,
|
||||
// externalData: externalData,
|
||||
// queryBowl: this,
|
||||
// );
|
||||
// query.updateDefaultOptions(
|
||||
// cacheTime: cacheTime,
|
||||
// staleTime: staleTime,
|
||||
// refetchInterval: refetchInterval,
|
||||
// refetchOnMount: refetchOnMount,
|
||||
// refetchOnReconnect: refetchOnReconnect,
|
||||
// );
|
||||
// return query;
|
||||
// }
|
||||
|
||||
Future<T?> prefetchQuery<T extends Object, Outside>(
|
||||
QueryJob<T, Outside> options, {
|
||||
required Outside externalData,
|
||||
@@ -355,6 +422,50 @@ class QueryBowl extends InheritedWidget {
|
||||
return await query.fetch();
|
||||
}
|
||||
|
||||
@protected
|
||||
InfiniteQuery<T, Outside, PageParam>
|
||||
addInfiniteQuery<T extends Object, Outside, PageParam extends Object>(
|
||||
InfiniteQueryJob<T, Outside, PageParam> infiniteQueryJob, {
|
||||
required Outside externalData,
|
||||
required ValueKey<String> key,
|
||||
final QueryListener<T>? onData,
|
||||
final QueryListener<dynamic>? onError,
|
||||
}) {
|
||||
final prevInfiniteQuery = _infiniteQueries.firstWhereOrNull(
|
||||
(q) => q.queryKey == infiniteQueryJob.queryKey,
|
||||
);
|
||||
if (prevInfiniteQuery is InfiniteQuery<T, Outside, PageParam>) {
|
||||
// run the query if its still not called or if externalData has
|
||||
// changed
|
||||
// if (prevQuery.prevUsedExternalData != null &&
|
||||
// externalData != null &&
|
||||
// !isShallowEqual(
|
||||
// prevQuery.prevUsedExternalData!,
|
||||
// externalData,
|
||||
// )) {
|
||||
// prevQuery.setExternalData(externalData);
|
||||
// }
|
||||
// prevQuery.mount(key);
|
||||
// if (onData != null) prevQuery.addDataListener(onData);
|
||||
// if (onError != null) prevQuery.addErrorListener(onError);
|
||||
// mounting the widget that is using the query in the prevQuery
|
||||
return prevInfiniteQuery;
|
||||
}
|
||||
// _createQueryWithDefaults<T, Outside, PageParam>(
|
||||
// infiniteQueryJob,
|
||||
// externalData,
|
||||
// );
|
||||
final infiniteQuery = InfiniteQuery<T, Outside, PageParam>.fromOptions(
|
||||
infiniteQueryJob,
|
||||
externalData: externalData,
|
||||
);
|
||||
// if (onData != null) infiniteQuery.addDataListener(onData);
|
||||
// if (onError != null) infiniteQuery.addErrorListener(onError);
|
||||
// infiniteQuery.mount(key);
|
||||
_addInfiniteQuery<T, Outside, PageParam>(infiniteQuery);
|
||||
return infiniteQuery;
|
||||
}
|
||||
|
||||
/// !⚠️**Warning** only for internal library usage
|
||||
@protected
|
||||
Query<T, Outside> addQuery<T extends Object, Outside>(
|
||||
@@ -428,6 +539,16 @@ class QueryBowl extends InheritedWidget {
|
||||
}
|
||||
}
|
||||
|
||||
InfiniteQuery<T, Outside, PageParam>?
|
||||
getInfiniteQuery<T extends Object, Outside, PageParam extends Object>(
|
||||
String queryKey,
|
||||
) {
|
||||
return _infiniteQueries.firstWhereOrNull((infiniteQuery) {
|
||||
return infiniteQuery.queryKey == queryKey &&
|
||||
infiniteQuery is InfiniteQuery<T, Outside, PageParam>;
|
||||
})?.cast<InfiniteQuery<T, Outside, PageParam>>();
|
||||
}
|
||||
|
||||
/// Get a query by providing queryKey only
|
||||
///
|
||||
/// Useful for optimistic update or single query refetch
|
||||
@@ -519,6 +640,7 @@ class QueryBowl extends InheritedWidget {
|
||||
bool updateShouldNotify(QueryBowl oldWidget) {
|
||||
return oldWidget.staleTime != staleTime ||
|
||||
oldWidget._queries != _queries ||
|
||||
oldWidget._mutations != _mutations;
|
||||
oldWidget._mutations != _mutations ||
|
||||
oldWidget._infiniteQueries != _infiniteQueries;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user