ente/lib/utils/debouncer.dart

54 lines
1.4 KiB
Dart
Raw Normal View History

import 'dart:async';
import 'package:flutter/material.dart';
import "package:photos/models/typedefs.dart";
class Debouncer {
2022-08-19 09:06:25 +00:00
final Duration _duration;
2022-08-22 08:26:01 +00:00
final ValueNotifier<bool> _debounceActiveNotifier = ValueNotifier(false);
/// If executionInterval is not null, then the debouncer will execute the
/// current callback it has in run() method repeatedly in the given interval.
final int? executionInterval;
2022-09-20 12:13:15 +00:00
Timer? _debounceTimer;
2022-08-22 09:14:52 +00:00
Debouncer(this._duration, {this.executionInterval});
final Stopwatch _stopwatch = Stopwatch();
void run(FutureVoidCallback fn) {
if (executionInterval != null) {
runCallbackIfIntervalTimeElapses(fn);
}
2022-08-22 08:26:01 +00:00
if (isActive()) {
2022-09-20 12:13:15 +00:00
_debounceTimer!.cancel();
}
2022-08-22 08:26:01 +00:00
_debounceTimer = Timer(_duration, () async {
await fn();
_debounceActiveNotifier.value = false;
});
_debounceActiveNotifier.value = true;
}
2022-08-22 09:14:52 +00:00
void cancelDebounce() {
2022-08-19 09:16:26 +00:00
if (_debounceTimer != null) {
2022-09-20 12:13:15 +00:00
_debounceTimer!.cancel();
}
}
2022-08-19 09:06:25 +00:00
runCallbackIfIntervalTimeElapses(FutureVoidCallback fn) {
_stopwatch.isRunning ? null : _stopwatch.start();
if (_stopwatch.elapsedMilliseconds > executionInterval!) {
_stopwatch.reset();
fn();
}
}
2022-09-20 12:13:15 +00:00
bool isActive() => _debounceTimer != null && _debounceTimer!.isActive;
2022-08-19 09:16:26 +00:00
2022-08-22 08:26:01 +00:00
ValueNotifier<bool> get debounceActiveNotifier {
return _debounceActiveNotifier;
}
}