mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-30 00:36:28 +00:00
97 lines
2.2 KiB
Dart
97 lines
2.2 KiB
Dart
|
import 'package:comunic/ui/widgets/safe_state.dart';
|
||
|
import 'package:comunic/utils/intl_utils.dart';
|
||
|
import 'package:comunic/utils/ui_utils.dart';
|
||
|
import 'package:flutter/material.dart';
|
||
|
|
||
|
/// Widget that can be used to easily implement fetch of remote ressources
|
||
|
///
|
||
|
/// @author Pierre Hubert
|
||
|
|
||
|
class AsyncScreenWidget extends StatefulWidget {
|
||
|
/// Reload function
|
||
|
///
|
||
|
/// Can be an asynchronous function that takes no arguments and throw an
|
||
|
/// [Exception] in case of failure
|
||
|
///
|
||
|
/// You do not need to call [State.setState] on this function, it is
|
||
|
/// automatically done by this widget
|
||
|
final Future<void> Function() onReload;
|
||
|
|
||
|
/// Build function
|
||
|
///
|
||
|
/// This function will be called whenever [isReady] becomes true
|
||
|
final Widget Function() onBuild;
|
||
|
|
||
|
/// Error message that will be shown in case of error
|
||
|
final String errorMessage;
|
||
|
|
||
|
const AsyncScreenWidget({
|
||
|
Key key,
|
||
|
@required this.onReload,
|
||
|
@required this.onBuild,
|
||
|
@required this.errorMessage,
|
||
|
}) : assert(onReload != null),
|
||
|
assert(onBuild != null),
|
||
|
assert(errorMessage != null),
|
||
|
super(key: key);
|
||
|
|
||
|
@override
|
||
|
AsyncScreenWidgetState createState() => AsyncScreenWidgetState();
|
||
|
}
|
||
|
|
||
|
class AsyncScreenWidgetState extends SafeState<AsyncScreenWidget> {
|
||
|
bool error = false;
|
||
|
bool ready = false;
|
||
|
|
||
|
@override
|
||
|
void initState() {
|
||
|
refresh();
|
||
|
super.initState();
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
// In case of error
|
||
|
if (error)
|
||
|
return buildErrorCard(widget.errorMessage, actions: [
|
||
|
MaterialButton(
|
||
|
onPressed: () => refresh(),
|
||
|
child: Text(tr("Try again").toUpperCase()),
|
||
|
)
|
||
|
]);
|
||
|
|
||
|
// Show loading states
|
||
|
if (!ready) return buildCenteredProgressBar();
|
||
|
|
||
|
// The widget is ready, show it
|
||
|
return RefreshIndicator(
|
||
|
child: widget.onBuild(),
|
||
|
onRefresh: () => refresh(),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/// Refresh this screen
|
||
|
Future<void> refresh() async {
|
||
|
try {
|
||
|
setState(() {
|
||
|
error = false;
|
||
|
ready = false;
|
||
|
});
|
||
|
|
||
|
// Call parent method
|
||
|
await widget.onReload();
|
||
|
|
||
|
setState(() {
|
||
|
ready = true;
|
||
|
});
|
||
|
} catch (e, stack) {
|
||
|
print(e);
|
||
|
print(stack);
|
||
|
|
||
|
setState(() {
|
||
|
error = true;
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|