Line data Source code
1 : import 'package:flutter/foundation.dart';
2 : import 'package:flutter/material.dart';
3 : import 'package:stream_feed/stream_feed.dart';
4 : import 'package:stream_feed_flutter_core/src/states/empty.dart';
5 : import 'package:stream_feed_flutter_core/src/states/states.dart';
6 : import 'package:stream_feed_flutter_core/src/typedefs.dart';
7 : import 'package:stream_feed_flutter_core/stream_feed_flutter_core.dart';
8 :
9 : /// [GenericFlatFeedCore] is a simplified class that allows fetching a list of
10 : /// enriched activities (flat) while exposing UI builders.
11 : ///
12 : ///
13 : /// ```dart
14 : /// class FlatActivityListPage extends StatelessWidget {
15 : /// @override
16 : /// Widget build(BuildContext context) {
17 : /// return Scaffold(
18 : /// body: FlatFeedCore(
19 : /// onErrorWidget: Center(
20 : /// child: Text('An error has occurred'),
21 : /// ),
22 : /// onEmptyWidget: Center(
23 : /// child: Text('Nothing here...'),
24 : /// ),
25 : /// onProgressWidget: Center(
26 : /// child: CircularProgressIndicator(),
27 : /// ),
28 : /// feedBuilder: (context, activities, idx) {
29 : /// return YourActivityWidget(activity: activities[idx]);
30 : /// }
31 : /// ),
32 : /// );
33 : /// }
34 : /// }
35 : /// ```
36 : ///
37 : /// Make sure to have a [StreamFeedCore] ancestor in order to provide the
38 : /// information about the activities.
39 : class GenericFlatFeedCore<A, Ob, T, Or> extends StatefulWidget {
40 1 : const GenericFlatFeedCore(
41 : {Key? key,
42 : required this.feedGroup,
43 : required this.feedBuilder,
44 : this.onErrorWidget = const ErrorStateWidget(),
45 : this.onProgressWidget = const ProgressStateWidget(),
46 : this.limit,
47 : this.offset,
48 : this.session,
49 : this.filter,
50 : this.flags,
51 : this.ranking,
52 : this.userId,
53 : this.onEmptyWidget =
54 : const EmptyStateWidget(message: 'No activities to display')})
55 1 : : super(key: key);
56 :
57 : /// A builder that let you build a ListView of EnrichedActivity based Widgets
58 : final EnrichedFeedBuilder<A, Ob, T, Or> feedBuilder;
59 :
60 : /// An error widget to show when an error occurs
61 : final Widget onErrorWidget;
62 :
63 : /// A progress widget to show when a request is in progress
64 : final Widget onProgressWidget;
65 :
66 : /// A widget to show when the feed is empty
67 : final Widget onEmptyWidget;
68 :
69 : /// The limit of activities to fetch
70 : final int? limit;
71 :
72 : /// The offset of activities to fetch
73 : final int? offset;
74 :
75 : /// The session to use for the request
76 : final String? session;
77 :
78 : /// The filter to use for the request
79 : final Filter? filter;
80 :
81 : /// The flags to use for the request
82 : final EnrichmentFlags? flags;
83 :
84 : /// The ranking to use for the request
85 : final String? ranking;
86 :
87 : /// The user id to use for the request
88 : final String? userId;
89 :
90 : /// The feed group to use for the request
91 : final String feedGroup;
92 :
93 1 : @override
94 : _GenericFlatFeedCoreState<A, Ob, T, Or> createState() =>
95 1 : _GenericFlatFeedCoreState<A, Ob, T, Or>();
96 : }
97 :
98 : class _GenericFlatFeedCoreState<A, Ob, T, Or>
99 : extends State<GenericFlatFeedCore<A, Ob, T, Or>> {
100 : late GenericFeedBloc<A, Ob, T, Or> bloc;
101 :
102 : /// Fetches initial reactions and updates the widget
103 3 : Future<void> loadData() => bloc.queryEnrichedActivities(
104 2 : feedGroup: widget.feedGroup,
105 2 : limit: widget.limit,
106 2 : offset: widget.offset,
107 2 : session: widget.session,
108 2 : filter: widget.filter,
109 2 : flags: widget.flags,
110 2 : ranking: widget.ranking,
111 2 : userId: widget.userId,
112 : );
113 :
114 1 : @override
115 : void didChangeDependencies() {
116 1 : super.didChangeDependencies();
117 4 : bloc = GenericFeedProvider<A, Ob, T, Or>.of(context).bloc;
118 1 : loadData();
119 : }
120 :
121 1 : @override
122 : Widget build(BuildContext context) {
123 1 : return StreamBuilder<List<GenericEnrichedActivity<A, Ob, T, Or>>>(
124 1 : stream: GenericFeedProvider<A, Ob, T, Or>.of(context)
125 1 : .bloc
126 3 : .getActivitiesStream(widget.feedGroup),
127 1 : builder: (context, snapshot) {
128 1 : if (snapshot.hasError) {
129 0 : return widget
130 0 : .onErrorWidget; //TODO: snapshot.error / do we really want backend error here?
131 : }
132 1 : if (!snapshot.hasData) {
133 2 : return widget.onProgressWidget;
134 : }
135 0 : final activities = snapshot.data!;
136 0 : if (activities.isEmpty) {
137 0 : return widget.onEmptyWidget;
138 : }
139 0 : return ListView.builder(
140 0 : itemCount: activities.length,
141 0 : itemBuilder: (context, idx) => widget.feedBuilder(
142 : context,
143 : activities,
144 : idx,
145 : ),
146 : );
147 : },
148 : );
149 : }
150 :
151 0 : @override
152 : void debugFillProperties(DiagnosticPropertiesBuilder properties) {
153 0 : super.debugFillProperties(properties);
154 : properties
155 0 : .add(DiagnosticsProperty<GenericFeedBloc<A, Ob, T, Or>>('bloc', bloc));
156 : }
157 : }
|