files moved to src folder

added flutter_hooks support with example
This commit is contained in:
Kingkor Roy Tirtho
2022-06-22 13:46:40 +06:00
parent e0c70d153f
commit 8c53f1b0fe
20 changed files with 319 additions and 30 deletions
+7 -7
View File
@@ -1,9 +1,9 @@
library fl_query;
export 'query.dart';
export 'query_bowl.dart';
export 'query_builder.dart';
export 'mutation.dart';
export 'mutation_builder.dart';
export 'models/query_job.dart';
export 'models/mutation_job.dart';
export 'src/query.dart';
export 'src/query_bowl.dart';
export 'src/query_builder.dart';
export 'src/mutation.dart';
export 'src/mutation_builder.dart';
export 'src/models/query_job.dart';
export 'src/models/mutation_job.dart';
@@ -0,0 +1,4 @@
library fl_query_hooks;
export 'src/hooks/use_query.dart';
export 'src/hooks/use_mutation.dart';
@@ -0,0 +1,116 @@
import 'package:fl_query/src/models/mutation_job.dart';
import 'package:fl_query/src/mutation.dart';
import 'package:fl_query/src/query_bowl.dart';
import 'package:fl_query/src/utils.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
Mutation<T, V> useMutation<T extends Object, V>({
required MutationJob<T, V> job,
/// Called when the query returns new data, on query
/// refetch or query gets expired
MutationListener<T>? onData,
/// Called when the query returns error
MutationListener<dynamic>? onError,
/// called right before the mutation is about to run
///
/// perfect scenario for doing optimistic updates
MutationListener<V>? onMutate,
List<Object?>? keys,
}) {
return use(_UseMutation<T, V>(
job: job,
onData: onData,
onError: onError,
onMutate: onMutate,
keys: keys,
));
}
class _UseMutation<T extends Object, V> extends Hook<Mutation<T, V>> {
final MutationJob<T, V> job;
/// Called when the query returns new data, on query
/// refetch or query gets expired
final MutationListener<T>? onData;
/// Called when the query returns error
final MutationListener<dynamic>? onError;
/// called right before the mutation is about to run
///
/// perfect scenario for doing optimistic updates
final MutationListener<V>? onMutate;
const _UseMutation({
required this.job,
this.onData,
this.onError,
this.onMutate,
super.keys,
});
@override
HookState<Mutation<T, V>, Hook<Mutation<T, V>>> createState() =>
_UseMutationHookState();
}
class _UseMutationHookState<T extends Object, V>
extends HookState<Mutation<T, V>, _UseMutation<T, V>> {
late QueryBowl queryBowl;
late final ValueKey<String> uKey;
late Mutation<T, V> mutation;
@override
void initHook() {
super.initHook();
uKey = ValueKey<String>(uuid.v4());
mutation = Mutation<T, V>.fromOptions(hook.job);
WidgetsBinding.instance.addPostFrameCallback((_) {
queryBowl = QueryBowl.of(context);
mutation = queryBowl.addMutation<T, V>(
mutation,
onData: hook.onData,
onError: hook.onError,
onMutate: hook.onMutate,
key: uKey,
);
});
}
@override
void didUpdateHook(_UseMutation<T, V> oldHook) {
if (oldHook.onData != hook.onData && oldHook.onData != null) {
mutation.onDataListeners.remove(oldHook.onData);
if (hook.onData != null) mutation.onDataListeners.add(hook.onData!);
}
if (oldHook.onError != hook.onError && oldHook.onError != null) {
mutation.onErrorListeners.remove(oldHook.onError);
if (hook.onError != null) mutation.onErrorListeners.add(hook.onError!);
}
if (oldHook.onMutate != hook.onMutate && oldHook.onMutate != null) {
mutation.onMutateListeners.remove(oldHook.onMutate);
if (hook.onMutate != null) mutation.onMutateListeners.add(hook.onMutate!);
}
super.didUpdateHook(oldHook);
}
@override
void dispose() {
mutation.unmount(uKey);
if (hook.onData != null) mutation.onDataListeners.remove(hook.onData);
if (hook.onError != null) mutation.onErrorListeners.remove(hook.onError);
if (hook.onMutate != null) mutation.onMutateListeners.remove(hook.onMutate);
}
@override
Mutation<T, V> build(BuildContext context) {
queryBowl = QueryBowl.of(context);
return queryBowl.getMutation<T, V>(mutation.mutationKey) ?? mutation;
}
@override
String get debugLabel => 'useQuery';
}
@@ -0,0 +1,122 @@
import 'package:fl_query/src/models/query_job.dart';
import 'package:fl_query/src/query.dart';
import 'package:fl_query/src/query_bowl.dart';
import 'package:fl_query/src/utils.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
Query<T, Outside> useQuery<T extends Object, Outside>({
required QueryJob<T, Outside> job,
required Outside externalData,
/// Called when the query returns new data, on query
/// refetch or query gets expired
QueryListener<T>? onData,
/// Called when the query returns error
QueryListener<dynamic>? onError,
List<Object?>? keys,
}) {
return use(_UseQuery<T, Outside>(
externalData: externalData,
job: job,
onData: onData,
onError: onError,
keys: keys,
));
}
class _UseQuery<T extends Object, Outside> extends Hook<Query<T, Outside>> {
final QueryJob<T, Outside> job;
final Outside externalData;
/// Called when the query returns new data, on query
/// refetch or query gets expired
final QueryListener<T>? onData;
/// Called when the query returns error
final QueryListener<dynamic>? onError;
const _UseQuery({
required this.job,
required this.externalData,
this.onData,
this.onError,
super.keys,
});
@override
HookState<Query<T, Outside>, Hook<Query<T, Outside>>> createState() =>
_UseQueryHookState();
}
class _UseQueryHookState<T extends Object, Outside>
extends HookState<Query<T, Outside>, _UseQuery<T, Outside>> {
late QueryBowl queryBowl;
late final ValueKey<String> uKey;
late Query<T, Outside> query;
@override
void initHook() {
super.initHook();
uKey = ValueKey<String>(uuid.v4());
query = Query<T, Outside>.fromOptions(
hook.job,
externalData: hook.externalData,
);
WidgetsBinding.instance.addPostFrameCallback((_) async {
query = QueryBowl.of(context).addQuery<T, Outside>(
query,
key: uKey,
onData: hook.onData,
onError: hook.onError,
);
final hasExternalDataChanged = query.externalData != null &&
query.prevUsedExternalData != null &&
!isShallowEqual(query.externalData!, query.prevUsedExternalData!);
(query.fetched && query.refetchOnMount == true) || hasExternalDataChanged
? await query.refetch()
: await query.fetch();
});
}
@override
void didUpdateHook(_UseQuery<T, Outside> oldHook) {
if (oldHook.externalData != null &&
hook.externalData != null &&
!isShallowEqual(oldHook.externalData!, hook.externalData!)) {
QueryBowl.of(context).fetchQuery(
hook.job,
externalData: hook.externalData,
onData: hook.onData,
onError: hook.onError,
key: uKey,
);
} else {
if (oldHook.onData != hook.onData && oldHook.onData != null) {
query.onDataListeners.remove(oldHook.onData);
if (hook.onData != null) query.onDataListeners.add(hook.onData!);
}
if (oldHook.onError != hook.onError && oldHook.onError != null) {
query.onErrorListeners.remove(oldHook.onError);
if (hook.onError != null) query.onErrorListeners.add(hook.onError!);
}
}
super.didUpdateHook(oldHook);
}
@override
void dispose() {
query.unmount(uKey);
if (hook.onData != null) query.onDataListeners.remove(hook.onData);
if (hook.onError != null) query.onErrorListeners.remove(hook.onError);
}
@override
Query<T, Outside> build(BuildContext context) {
queryBowl = QueryBowl.of(context);
return queryBowl.getQuery<T, Outside>(query.queryKey) ?? query;
}
@override
String get debugLabel => 'useQuery';
}
@@ -1,4 +1,4 @@
import 'package:fl_query/mutation.dart';
import 'package:fl_query/fl_query.dart';
class MutationJob<T extends Object, V> {
String _mutationKey;
@@ -1,4 +1,4 @@
import 'package:fl_query/query.dart';
import 'package:fl_query/src/query.dart';
class QueryJob<T extends Object, Outside> {
// all params
@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:fl_query/base_operation.dart';
import 'package:fl_query/models/mutation_job.dart';
import 'package:fl_query/src/base_operation.dart';
import 'package:fl_query/src/models/mutation_job.dart';
import 'package:flutter/widgets.dart';
enum MutationStatus {
@@ -1,7 +1,7 @@
import 'package:fl_query/models/mutation_job.dart';
import 'package:fl_query/mutation.dart';
import 'package:fl_query/query_bowl.dart';
import 'package:fl_query/utils.dart';
import 'package:fl_query/src/models/mutation_job.dart';
import 'package:fl_query/src/mutation.dart';
import 'package:fl_query/src/query_bowl.dart';
import 'package:fl_query/src/utils.dart';
import 'package:flutter/widgets.dart';
class MutationBuilder<T extends Object, V> extends StatefulWidget {
@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:fl_query/base_operation.dart';
import 'package:fl_query/models/query_job.dart';
import 'package:fl_query/src/base_operation.dart';
import 'package:fl_query/src/models/query_job.dart';
import 'package:flutter/widgets.dart';
enum QueryStatus {
@@ -1,10 +1,10 @@
import 'dart:async';
import 'package:fl_query/models/query_job.dart';
import 'package:fl_query/mutation.dart';
import 'package:fl_query/query.dart';
import 'package:fl_query/src/models/query_job.dart';
import 'package:fl_query/src/mutation.dart';
import 'package:fl_query/src/query.dart';
import 'package:fl_query/src/utils.dart';
import 'package:collection/collection.dart';
import 'package:fl_query/utils.dart';
import 'package:flutter/widgets.dart';
class QueryBowlScope extends StatefulWidget {
@@ -1,7 +1,7 @@
import 'package:fl_query/models/query_job.dart';
import 'package:fl_query/query.dart';
import 'package:fl_query/query_bowl.dart';
import 'package:fl_query/utils.dart';
import 'package:fl_query/src/models/query_job.dart';
import 'package:fl_query/src/query.dart';
import 'package:fl_query/src/query_bowl.dart';
import 'package:fl_query/src/utils.dart';
import 'package:flutter/widgets.dart';
class QueryBuilder<T extends Object, Outside> extends StatefulWidget {
@@ -1,4 +1,4 @@
import 'package:fl_query/query.dart';
import 'package:fl_query/src/query.dart';
import 'package:uuid/uuid.dart';
Future<void> callQueryListeners<T>(Set<QueryListener<T>> listeners, T data) {
+1
View File
@@ -19,6 +19,7 @@ dev_dependencies:
sdk: flutter
flutter_lints: ^2.0.0
mocktail: ^0.3.0
flutter_hooks: ^0.18.5
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
+2 -2
View File
@@ -1,7 +1,7 @@
import 'dart:math';
import 'package:fl_query/models/query_job.dart';
import 'package:fl_query/query.dart';
import 'package:fl_query/src/models/query_job.dart';
import 'package:fl_query/src/query.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';