From c9fc536d09e69ca93fe347e3cdb30199b24b93fd Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 20 Sep 2020 20:00:48 +0200 Subject: [PATCH] add debounce hook --- lib/hooks/debounce.dart | 58 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/hooks/debounce.dart diff --git a/lib/hooks/debounce.dart b/lib/hooks/debounce.dart new file mode 100644 index 0000000..ce9065e --- /dev/null +++ b/lib/hooks/debounce.dart @@ -0,0 +1,58 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; + +import 'ref.dart'; + +class Debounce { + final bool pending; + final bool loading; + final void Function() start; + final void Function() cancel; + final void Function() reset; + + const Debounce({ + @required this.pending, + @required this.loading, + @required this.start, + @required this.cancel, + @required this.reset, + }); +} + +/// When loading is [.start()]ed, it goes into a pending state +/// and loading is triggered after [delayDuration]. +/// Everything can be reset with [.cancel()] +Debounce useDebounce( + Function(Function cancel) onDebounce, [ + Duration delayDuration = const Duration(milliseconds: 500), +]) { + final loading = useState(false); + final pending = useState(false); + final timerHandle = useRef(null); + + cancel() { + timerHandle.current?.cancel(); + pending.value = false; + loading.value = false; + } + + start() { + timerHandle.current = Timer(delayDuration, () { + loading.value = true; + onDebounce(cancel); + }); + pending.value = true; + } + + return Debounce( + loading: loading.value, + pending: pending.value, + start: start, + cancel: cancel, + reset: () { + cancel(); + start(); + }); +}