@@ -2,10 +2,11 @@ import 'package:flutter/material.dart';
2
2
import 'package:flutter_riverpod/flutter_riverpod.dart' ;
3
3
import 'package:titan/tools/constants.dart' ;
4
4
import 'package:titan/tools/ui/widgets/loader.dart' ;
5
+ import 'package:tuple/tuple.dart' ;
5
6
6
- class AsyncChild <T > extends StatelessWidget {
7
- final AsyncValue <T > value;
8
- final Widget Function (BuildContext context, T value) builder;
7
+ class AsyncChild <P > extends StatelessWidget {
8
+ final AsyncValue <P > value;
9
+ final Widget Function (BuildContext context, P value) builder;
9
10
final Widget Function (Object ? error, StackTrace ? stack)? errorBuilder;
10
11
final Widget Function (BuildContext context)? loadingBuilder;
11
12
final Widget Function (BuildContext context, Widget child)? orElseBuilder;
@@ -42,3 +43,217 @@ class AsyncChild<T> extends StatelessWidget {
42
43
);
43
44
}
44
45
}
46
+
47
+ Widget handleLoadingAndError (
48
+ List <AsyncValue > values,
49
+ BuildContext context, {
50
+ Widget Function (BuildContext context)? loadingBuilder,
51
+ Widget Function (Object ? error, StackTrace ? stack)? errorBuilder,
52
+ Widget Function (BuildContext context, Widget child)? orElseBuilder,
53
+ Color ? loaderColor,
54
+ }) {
55
+ final nonNullOrElseBuilder = orElseBuilder ?? (context, child) => child;
56
+ if (values.any ((value) => value.hasError)) {
57
+ final nonNullErrorBuilder =
58
+ errorBuilder ??
59
+ (error, stack) => Center (
60
+ child: Text (
61
+ "${TextConstants .error }:$error " ,
62
+ style: TextStyle (color: loaderColor),
63
+ ),
64
+ );
65
+ final firstError = values.firstWhere ((value) => value.hasError);
66
+ final error = firstError.error;
67
+ final stackTrace = firstError.stackTrace;
68
+ return nonNullOrElseBuilder (
69
+ context,
70
+ nonNullErrorBuilder (error, stackTrace),
71
+ );
72
+ }
73
+ if (values.any ((value) => value.isLoading)) {
74
+ final nonNullLoadingBuilder =
75
+ loadingBuilder ?? (context) => Loader (color: loaderColor);
76
+ return nonNullOrElseBuilder (context, nonNullLoadingBuilder (context));
77
+ }
78
+ return nonNullOrElseBuilder (context, const SizedBox .shrink ());
79
+ }
80
+
81
+ class Async2Children <P , Q > extends StatelessWidget {
82
+ final Tuple2 <AsyncValue <P >, AsyncValue <Q >> values;
83
+ final Widget Function (BuildContext context, P value1, Q value2) builder;
84
+ final Widget Function (Object ? error, StackTrace ? stack)? errorBuilder;
85
+ final Widget Function (BuildContext context)? loadingBuilder;
86
+ final Widget Function (BuildContext context, Widget child)? orElseBuilder;
87
+ final Color ? loaderColor;
88
+ const Async2Children ({
89
+ super .key,
90
+ required this .values,
91
+ required this .builder,
92
+ this .errorBuilder,
93
+ this .loaderColor,
94
+ this .orElseBuilder,
95
+ this .loadingBuilder,
96
+ });
97
+ @override
98
+ Widget build (BuildContext context) {
99
+ List <AsyncValue > listValues = [values.item1, values.item2];
100
+ if (listValues.any ((value) => value.hasError || value.isLoading)) {
101
+ return handleLoadingAndError (
102
+ listValues,
103
+ context,
104
+ loadingBuilder: loadingBuilder,
105
+ errorBuilder: errorBuilder,
106
+ orElseBuilder: orElseBuilder,
107
+ loaderColor: loaderColor,
108
+ );
109
+ }
110
+ return builder (context, listValues[0 ].value as P , listValues[1 ].value as Q );
111
+ }
112
+ }
113
+
114
+ class Async3Children <P , Q , R > extends StatelessWidget {
115
+ final Tuple3 <AsyncValue <P >, AsyncValue <Q >, AsyncValue <R >> values;
116
+ final Widget Function (BuildContext context, P value1, Q value2, R value3)
117
+ builder;
118
+ final Widget Function (Object ? error, StackTrace ? stack)? errorBuilder;
119
+ final Widget Function (BuildContext context)? loadingBuilder;
120
+ final Widget Function (BuildContext context, Widget child)? orElseBuilder;
121
+ final Color ? loaderColor;
122
+ const Async3Children ({
123
+ super .key,
124
+ required this .values,
125
+ required this .builder,
126
+ this .errorBuilder,
127
+ this .loaderColor,
128
+ this .orElseBuilder,
129
+ this .loadingBuilder,
130
+ });
131
+ @override
132
+ Widget build (BuildContext context) {
133
+ List <AsyncValue > listValues = [values.item1, values.item2, values.item3];
134
+ if (listValues.any ((value) => value.hasError || value.isLoading)) {
135
+ return handleLoadingAndError (
136
+ listValues,
137
+ context,
138
+ loadingBuilder: loadingBuilder,
139
+ errorBuilder: errorBuilder,
140
+ orElseBuilder: orElseBuilder,
141
+ loaderColor: loaderColor,
142
+ );
143
+ }
144
+ return builder (
145
+ context,
146
+ listValues[0 ].value as P ,
147
+ listValues[1 ].value as Q ,
148
+ listValues[2 ].value as R ,
149
+ );
150
+ }
151
+ }
152
+
153
+ class Async4Children <P , Q , R , S > extends StatelessWidget {
154
+ final Tuple4 <AsyncValue <P >, AsyncValue <Q >, AsyncValue <R >, AsyncValue <S >>
155
+ values;
156
+ final Widget Function (
157
+ BuildContext context,
158
+ P value1,
159
+ Q value2,
160
+ R value3,
161
+ S value4,
162
+ )
163
+ builder;
164
+ final Widget Function (Object ? error, StackTrace ? stack)? errorBuilder;
165
+ final Widget Function (BuildContext context)? loadingBuilder;
166
+ final Widget Function (BuildContext context, Widget child)? orElseBuilder;
167
+ final Color ? loaderColor;
168
+ const Async4Children ({
169
+ super .key,
170
+ required this .values,
171
+ required this .builder,
172
+ this .errorBuilder,
173
+ this .loaderColor,
174
+ this .orElseBuilder,
175
+ this .loadingBuilder,
176
+ });
177
+ @override
178
+ Widget build (BuildContext context) {
179
+ List <AsyncValue > listValues = [values.item1, values.item2, values.item3];
180
+ if (listValues.any ((value) => value.hasError || value.isLoading)) {
181
+ return handleLoadingAndError (
182
+ listValues,
183
+ context,
184
+ loadingBuilder: loadingBuilder,
185
+ errorBuilder: errorBuilder,
186
+ orElseBuilder: orElseBuilder,
187
+ loaderColor: loaderColor,
188
+ );
189
+ }
190
+ return builder (
191
+ context,
192
+ listValues[0 ].value as P ,
193
+ listValues[1 ].value as Q ,
194
+ listValues[2 ].value as R ,
195
+ listValues[3 ].value as S ,
196
+ );
197
+ }
198
+ }
199
+
200
+ class Async5Children <P , Q , R , S , T > extends StatelessWidget {
201
+ final Tuple5 <
202
+ AsyncValue <P >,
203
+ AsyncValue <Q >,
204
+ AsyncValue <R >,
205
+ AsyncValue <S >,
206
+ AsyncValue <T >
207
+ >
208
+ values;
209
+ final Widget Function (
210
+ BuildContext context,
211
+ P value1,
212
+ Q value2,
213
+ R value3,
214
+ S value4,
215
+ T value5,
216
+ )
217
+ builder;
218
+ final Widget Function (Object ? error, StackTrace ? stack)? errorBuilder;
219
+ final Widget Function (BuildContext context)? loadingBuilder;
220
+ final Widget Function (BuildContext context, Widget child)? orElseBuilder;
221
+ final Color ? loaderColor;
222
+ const Async5Children ({
223
+ super .key,
224
+ required this .values,
225
+ required this .builder,
226
+ this .errorBuilder,
227
+ this .loaderColor,
228
+ this .orElseBuilder,
229
+ this .loadingBuilder,
230
+ });
231
+ @override
232
+ Widget build (BuildContext context) {
233
+ List <AsyncValue > listValues = [
234
+ values.item1,
235
+ values.item2,
236
+ values.item3,
237
+ values.item4,
238
+ values.item5,
239
+ ];
240
+ if (listValues.any ((value) => value.hasError || value.isLoading)) {
241
+ return handleLoadingAndError (
242
+ listValues,
243
+ context,
244
+ loadingBuilder: loadingBuilder,
245
+ errorBuilder: errorBuilder,
246
+ orElseBuilder: orElseBuilder,
247
+ loaderColor: loaderColor,
248
+ );
249
+ }
250
+ return builder (
251
+ context,
252
+ listValues[0 ].value as P ,
253
+ listValues[1 ].value as Q ,
254
+ listValues[2 ].value as R ,
255
+ listValues[3 ].value as S ,
256
+ listValues[4 ].value as T ,
257
+ );
258
+ }
259
+ }
0 commit comments