alpha stale_time & caching support
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:fl_query/query_bowl.dart';
|
||||
import 'package:fl_query/query_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -22,9 +24,14 @@ class MyApp extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatelessWidget {
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -35,7 +42,8 @@ class MyHomePage extends StatelessWidget {
|
||||
children: [
|
||||
QueryBuilder<String>(
|
||||
queryKey: "greetings",
|
||||
task: (queryKey) => Future.value("Welcome ($queryKey)"),
|
||||
task: (queryKey) => Future.value(
|
||||
"Welcome ($queryKey) ${Random.secure().nextInt(100)}"),
|
||||
builder: (context, query) {
|
||||
if (query.isLoading) return const CircularProgressIndicator();
|
||||
return Row(
|
||||
|
||||
@@ -21,13 +21,14 @@ class Query<T> extends ChangeNotifier {
|
||||
QueryTaskFunction<T> task;
|
||||
final int retries;
|
||||
final Duration retryDelay;
|
||||
final Duration _staleTime;
|
||||
|
||||
// all properties
|
||||
T? data;
|
||||
dynamic error;
|
||||
QueryStatus status;
|
||||
int retryAttempts = 0;
|
||||
late DateTime updatedAt;
|
||||
DateTime updatedAt;
|
||||
int refetchCount = 0;
|
||||
|
||||
@protected
|
||||
@@ -39,15 +40,18 @@ class Query<T> extends ChangeNotifier {
|
||||
Query({
|
||||
required this.queryKey,
|
||||
required this.task,
|
||||
required Duration staleTime,
|
||||
this.retries = 3,
|
||||
this.retryDelay = const Duration(milliseconds: 200),
|
||||
T? initialData,
|
||||
QueryListener<T>? onData,
|
||||
QueryListener<dynamic>? onError,
|
||||
}) : status = QueryStatus.pending,
|
||||
_staleTime = staleTime,
|
||||
data = initialData,
|
||||
_onData = onData,
|
||||
_onError = onError;
|
||||
_onError = onError,
|
||||
updatedAt = DateTime.now();
|
||||
|
||||
// all getters & setters
|
||||
bool get hasData => data != null && error == null;
|
||||
@@ -60,6 +64,9 @@ class Query<T> extends ChangeNotifier {
|
||||
bool get isSucceeded => status == QueryStatus.succeed && data != null;
|
||||
|
||||
// all methods
|
||||
|
||||
/// Calls the task function & doesn't check if there's already
|
||||
/// cached data available
|
||||
Future<void> _execute({bool isFetch = true}) async {
|
||||
try {
|
||||
retryAttempts = 0;
|
||||
@@ -95,6 +102,9 @@ class Query<T> extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<T?> fetch() async {
|
||||
if (!_isStaleData() && hasData) {
|
||||
return data;
|
||||
}
|
||||
return _execute().then((_) {
|
||||
fetched = true;
|
||||
return data;
|
||||
@@ -105,4 +115,10 @@ class Query<T> extends ChangeNotifier {
|
||||
refetchCount++;
|
||||
return _execute(isFetch: false).then((_) => data);
|
||||
}
|
||||
|
||||
bool _isStaleData() {
|
||||
// when current DateTime is after [update_at + stale_time] it means
|
||||
// the data has become stale
|
||||
return DateTime.now().isAfter(updatedAt.add(_staleTime));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,22 @@ class QueryBuilder<T> extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _QueryBuilderState<T> extends State<QueryBuilder<T>> {
|
||||
late Query<T> query;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
query = Query<T>(queryKey: widget.queryKey, task: widget.task);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await QueryBowl.of(context).fetchQuery(query);
|
||||
await QueryBowl.of(context).fetchQuery(Query<T>(
|
||||
queryKey: widget.queryKey,
|
||||
task: widget.task,
|
||||
staleTime: QueryBowl.of(context).staleTime,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final queryRT = QueryBowl.of(context).getQuery<T>(widget.queryKey) ?? query;
|
||||
return widget.builder(context, queryRT);
|
||||
final query = QueryBowl.of(context).getQuery<T>(widget.queryKey);
|
||||
if (query == null) return Container();
|
||||
return widget.builder(context, query);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user