Skip to content

Instantly share code, notes, and snippets.

@ZaidSameer
Forked from thetrav/gd_async_button.dart
Created April 13, 2022 07:17
Show Gist options
  • Save ZaidSameer/ca658ff70e0fcdc805edf90f0d66b595 to your computer and use it in GitHub Desktop.
Save ZaidSameer/ca658ff70e0fcdc805edf90f0d66b595 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import 'gd_button.dart';
class GdAsyncButton extends StatefulWidget {
final Widget child;
final Color color;
final bool flat;
final bool disabled;
final Future Function() onPressed;
GdAsyncButton(this.child, this.onPressed, {this.color, this.flat: false, this.disabled: false});
@override
State<StatefulWidget> createState() => _ButtonState();
}
class _ButtonState extends State<GdAsyncButton> {
bool working;
@override
void initState() {
super.initState();
working = false;
}
void onPressed() => setState(() {
working = true;
widget.onPressed().whenComplete(() => setState(()=> working = false));
});
@override
Widget build(BuildContext context) => working ?
Center(child: CircularProgressIndicator()) :
GdButton.from(
widget.child,
onPressed,
disabled: widget.disabled,
color: widget.color,
flat: widget.flat
);
}
import 'package:flutter/material.dart';
import 'gd_spin_future_builder.dart';
class GdRefreshable<T> extends StatefulWidget {
final Future<T> Function() load;
final Widget Function(BuildContext, T, void Function() refresh) builder;
GdRefreshable(this.load, this.builder);
@override
State<StatefulWidget> createState() => _GdRefreshableState<T>();
}
class _GdRefreshableState<T> extends State<GdRefreshable<T>> {
Future<T> loading;
@override
void initState() {
super.initState();
loading = widget.load();
}
@override
Widget build(BuildContext context) => GdSpinFutureBuilder<T>(
loading,
(context, data) => widget.builder(
context,
data,
() => setState(() {loading = widget.load();}))
);
}
import 'package:flutter/material.dart';
import '../exception/invalid_token_exception.dart';
typedef Builder<T> = Widget Function(BuildContext, T);
class GdSpinFutureBuilder<T> extends StatelessWidget {
final Future<T> future;
final Builder<T> builder;
GdSpinFutureBuilder(this.future, this.builder);
@override
Widget build(BuildContext _) => FutureBuilder(
future: future,
builder: (context, snapshot) {
if(snapshot.hasError) {
if(snapshot.error is InvalidTokenException) {
//NOTE: this is a potential source of bugs, see https://github.com/flutter/flutter/issues/16218 for discussion
//It may be better to handle this by wrapping the future above (currently line 15) with a .catch that handles InvalidTokenException only
print("Your login has expired ${snapshot.error}");
Future<void>.microtask(() {
Navigator.pushNamedAndRemoveUntil(_, "/", (r) => false);
});
}
return Center(child:Text(
"Error: ${snapshot.error}",
style: TextStyle(color: Colors.red),)
);
} else if (snapshot.hasData) {
return builder(context, snapshot.data);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment