alpha stale_time & caching support

This commit is contained in:
Kingkor Roy Tirtho
2022-05-27 13:21:58 +06:00
parent 64c852fddc
commit 4eadc99d15
3 changed files with 36 additions and 9 deletions
+10 -2
View File
@@ -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(
+18 -2
View File
@@ -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));
}
}
+8 -5
View File
@@ -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);
}
}