lemmur-app-android/lib/hooks/refreshable.dart

45 lines
1.3 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'memo_future.dart';
class Refreshable<T> {
const Refreshable({@required this.snapshot, @required this.refresh})
: assert(snapshot != null),
assert(refresh != null);
final AsyncSnapshot<T> snapshot;
final AsyncCallback refresh;
}
/// Similar to [useMemoFuture] but adds a `.refresh` method which
/// allows to re-run the fetcher. Calling `.refresh` will not
/// turn AsyncSnapshot into a loading state. Instead it will
/// replace the ready state with the new data when available
///
/// `keys` will re-run the initial fetching thus yielding a
/// loading state in the AsyncSnapshot
Refreshable<T> useRefreshable<T>(AsyncValueGetter<T> fetcher,
[List<Object> keys = const <dynamic>[]]) {
final newData = useState<T>(null);
final snapshot = useMemoFuture(() async {
newData.value = null;
return fetcher();
}, keys);
final outSnapshot = () {
if (newData.value != null) {
return AsyncSnapshot.withData(ConnectionState.done, newData.value);
}
return snapshot;
}();
return Refreshable(
snapshot: outSnapshot,
refresh: () async {
newData.value = await fetcher();
},
);
}