Line data Source code
1 : import 'package:amadeus_proto/api/utils/api_error.dart';
2 : import 'package:amadeus_proto/api/widget/api_error_displayer.dart';
3 : import 'package:either_dart/either.dart';
4 : import 'package:flutter/foundation.dart';
5 : import 'package:flutter/material.dart';
6 :
7 : /// Widget to facilitate the display of data obtained through an Web API call.
8 : ///
9 : /// - [future] is a future describing the API call, containing an [Either] where the right is of type [T],
10 : /// and the left is a [ApiError] in case the call is unsuccessful.
11 : /// - [builder] is a builder function that build a [Widget] from the result of the [future] in case it's a
12 : /// right [Either]
13 : /// - [errorMessage] is an error message to display in case of error, if not provide, the message will be
14 : /// `"Une erreur est survenue"`
15 : ///
16 : /// This widget will build another [Widget] based on the result of [future]:
17 : /// - If the future has no data yet,
18 : /// [ApiResultWrapper] will display a [CircularProgressIndicator].
19 : /// - If the [future] has an error, the [errorMessage]
20 : /// will be displayed though a [Text] widget and if the app run in debug mode, a [String] conversion of the error will
21 : /// be displayed beneath the message.
22 : /// - If the future is a left [Either], the [ApiError] will be displayed with the [ApiErrorDisplayer] widget.
23 : /// - Finally, if the future is a right [Either] the [T] result will be passed to [builder], and the [Widget] returned by
24 : /// [builder] will be returned.
25 : class ApiResultWrapper<T> extends StatelessWidget {
26 2 : const ApiResultWrapper(
27 : {super.key, required this.future, required this.builder, this.errorMessage});
28 :
29 : final Future<Either<ApiError, T>> future;
30 : final Widget Function(BuildContext context, T result) builder;
31 : final String? errorMessage;
32 :
33 2 : @override
34 : Widget build(BuildContext context) {
35 2 : return FutureBuilder(
36 2 : future: future,
37 2 : builder: (context, snapshot) {
38 2 : if (snapshot.hasError) {
39 4 : return Center(child: Column(
40 2 : children: [
41 4 : Text(errorMessage ?? "Une erreur est survenue"),
42 6 : if (!const bool.fromEnvironment("release") || !kReleaseMode) Text(snapshot.error!.toString())
43 : ],
44 : ));
45 : }
46 2 : if (!snapshot.hasData) {
47 : return const Center(child: CircularProgressIndicator());
48 : }
49 4 : if (snapshot.data!.isLeft) {
50 8 : return ApiErrorDisplayer(apiError: snapshot.data!.left, errorMessage: errorMessage);
51 : }
52 4 : return builder(context, snapshot.data!.right);
53 : },
54 : );
55 : }
56 : }
|