2020-09-20 20:00:48 +02:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
|
|
|
|
|
|
import 'ref.dart';
|
|
|
|
|
|
|
|
class Debounce {
|
|
|
|
final bool loading;
|
2021-01-03 21:03:32 +01:00
|
|
|
final VoidCallback callback;
|
2020-09-21 01:00:38 +02:00
|
|
|
|
2020-09-20 20:00:48 +02:00
|
|
|
const Debounce({
|
|
|
|
@required this.loading,
|
2020-09-22 16:33:02 +02:00
|
|
|
@required this.callback,
|
2020-09-20 20:00:48 +02:00
|
|
|
});
|
2021-01-03 19:43:39 +01:00
|
|
|
|
|
|
|
void call() => callback();
|
2020-09-20 20:00:48 +02:00
|
|
|
}
|
|
|
|
|
2020-09-22 16:39:02 +02:00
|
|
|
/// will run `callback()` after debounce hook hasn't been called for the
|
|
|
|
/// specified `delayDuration`
|
2020-09-20 20:00:48 +02:00
|
|
|
Debounce useDebounce(
|
2021-01-03 21:03:32 +01:00
|
|
|
Future<void> Function() callback, [
|
2020-09-24 15:41:03 +02:00
|
|
|
Duration delayDuration = const Duration(seconds: 1),
|
2020-09-20 20:00:48 +02:00
|
|
|
]) {
|
|
|
|
final loading = useState(false);
|
|
|
|
final timerHandle = useRef<Timer>(null);
|
|
|
|
|
|
|
|
cancel() {
|
|
|
|
timerHandle.current?.cancel();
|
|
|
|
loading.value = false;
|
|
|
|
}
|
|
|
|
|
2020-09-24 16:26:24 +02:00
|
|
|
useEffect(() => () => timerHandle.current?.cancel(), []);
|
|
|
|
|
2020-09-20 20:00:48 +02:00
|
|
|
start() {
|
2020-09-21 01:00:38 +02:00
|
|
|
timerHandle.current = Timer(delayDuration, () async {
|
2020-09-20 20:00:48 +02:00
|
|
|
loading.value = true;
|
2020-09-22 13:50:54 +02:00
|
|
|
await callback();
|
2020-09-21 01:00:38 +02:00
|
|
|
cancel();
|
2020-09-20 20:00:48 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return Debounce(
|
2020-09-24 15:01:20 +02:00
|
|
|
loading: loading.value,
|
|
|
|
callback: () {
|
|
|
|
cancel();
|
|
|
|
start();
|
|
|
|
},
|
|
|
|
);
|
2020-09-20 20:00:48 +02:00
|
|
|
}
|