/
subscription.dart
105 lines (99 loc) · 2.93 KB
/
subscription.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:graphql/client.dart';
import 'package:graphql_flutter/src/widgets/hooks/graphql_client.dart';
import 'package:graphql_flutter/src/widgets/hooks/subscription.dart';
/// Creats a subscription with [GraphQLClient.subscribe].
///
/// The [builder] is passed a [QueryResult] with only the **most recent**
/// `data`. [ResultAccumulator] can be used to accumulate results.
///
/// [onSubscriptionResult] can be used to react to changes,
/// and has access to the `client`.
///
/// {@tool snippet}
///
/// Excerpt from the starwars example using [ResultAccumulator]
///
/// ```dart
/// class ReviewFeed extends StatelessWidget {
/// @override
/// Widget build(BuildContext context) {
/// return Subscription(
/// options: SubscriptionOptions(
/// document: gql(
/// r'''
/// subscription reviewAdded {
/// reviewAdded {
/// stars, commentary, episode
/// }
/// }
/// ''',
/// ),
/// ),
/// builder: (result) {
/// if (result.hasException) {
/// return Text(result.exception.toString());
/// }
///
/// if (result.isLoading) {
/// return Center(
/// child: const CircularProgressIndicator(),
/// );
/// }
/// return ResultAccumulator.appendUniqueEntries(
/// latest: result.data,
/// builder: (context, {results}) => DisplayReviews(
/// reviews: results.reversed.toList(),
/// ),
/// );
/// },
/// );
/// }
/// }
/// ```
/// {@end-tool}
class Subscription<TParsed> extends HookWidget {
const Subscription({
required this.options,
required this.builder,
this.onSubscriptionResult,
Key? key,
}) : super(key: key);
final SubscriptionOptions<TParsed> options;
final SubscriptionBuilder<TParsed> builder;
final OnSubscriptionResult<TParsed>? onSubscriptionResult;
@override
Widget build(BuildContext context) {
final client = useGraphQLClient();
return SubscriptionOnClient(
client: client,
options: options,
builder: builder,
);
}
}
/// Creats a subscription widget like [Subscription] but
/// with an external client.
class SubscriptionOnClient<TParsed> extends HookWidget {
const SubscriptionOnClient({
required this.client,
required this.options,
required this.builder,
this.onSubscriptionResult,
Key? key,
}) : super(key: key);
final GraphQLClient client;
final SubscriptionOptions<TParsed> options;
final SubscriptionBuilder<TParsed> builder;
final OnSubscriptionResult<TParsed>? onSubscriptionResult;
@override
Widget build(BuildContext context) {
final result = useSubscriptionOnClient<TParsed>(
client,
options,
onSubscriptionResult: onSubscriptionResult,
);
return builder(result);
}
}