mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 02:27:08 -04:00 
			
		
		
		
	* feat(mobile): drift map page * refactor: map query * perf: do not filter markers * fix: refresh timeline by key * chore: rename * remove ref listen and global key * clean code * remove locked and favorite * temporary change for stress test * optimizations * fix bottom sheet * cleaner bounds check * cleanup * feat: back button --------- Co-authored-by: wuzihao051119 <wuzihao051119@outlook.com> Co-authored-by: Alex <alex.tran1502@gmail.com>
		
			
				
	
	
		
			96 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'dart:async';
 | |
| 
 | |
| import 'package:flutter_hooks/flutter_hooks.dart';
 | |
| 
 | |
| /// Used to debounce function calls with the [interval] provided.
 | |
| /// If [maxWaitTime] is provided, the first [run] call as well as the next call since [maxWaitTime] has passed will be immediately executed, even if [interval] is not satisfied.
 | |
| class Debouncer {
 | |
|   Debouncer({required this.interval, this.maxWaitTime});
 | |
|   final Duration interval;
 | |
|   final Duration? maxWaitTime;
 | |
|   Timer? _timer;
 | |
|   FutureOr<void> Function()? _lastAction;
 | |
|   DateTime? _lastActionTime;
 | |
|   Future<void>? _actionFuture;
 | |
| 
 | |
|   void run(FutureOr<void> Function() action) {
 | |
|     _lastAction = action;
 | |
|     _timer?.cancel();
 | |
| 
 | |
|     if (maxWaitTime != null &&
 | |
|         // _actionFuture == null && // TODO: should this check be here?
 | |
|         (_lastActionTime == null || DateTime.now().difference(_lastActionTime!) > maxWaitTime!)) {
 | |
|       _callAndRest();
 | |
|       return;
 | |
|     }
 | |
|     _timer = Timer(interval, _callAndRest);
 | |
|   }
 | |
| 
 | |
|   Future<void>? drain() {
 | |
|     final timer = _timer;
 | |
|     if (timer != null && timer.isActive) {
 | |
|       timer.cancel();
 | |
|       if (_lastAction != null) {
 | |
|         _callAndRest();
 | |
|       }
 | |
|     }
 | |
|     return _actionFuture;
 | |
|   }
 | |
| 
 | |
|   @pragma('vm:prefer-inline')
 | |
|   void _callAndRest() {
 | |
|     _lastActionTime = DateTime.now();
 | |
|     final action = _lastAction;
 | |
|     _lastAction = null;
 | |
| 
 | |
|     final result = action!();
 | |
|     if (result is Future) {
 | |
|       _actionFuture = result.whenComplete(() {
 | |
|         _actionFuture = null;
 | |
|       });
 | |
|     }
 | |
|     _timer = null;
 | |
|   }
 | |
| 
 | |
|   void dispose() {
 | |
|     _timer?.cancel();
 | |
|     _timer = null;
 | |
|     _lastAction = null;
 | |
|     _lastActionTime = null;
 | |
|     _actionFuture = null;
 | |
|   }
 | |
| 
 | |
|   bool get isActive => _actionFuture != null || (_timer != null && _timer!.isActive);
 | |
| }
 | |
| 
 | |
| /// Creates a [Debouncer] that will be disposed automatically. If no [interval] is provided, a
 | |
| /// default interval of 300ms is used to debounce the function calls
 | |
| Debouncer useDebouncer({
 | |
|   Duration interval = const Duration(milliseconds: 300),
 | |
|   Duration? maxWaitTime,
 | |
|   List<Object?>? keys,
 | |
| }) => use(_DebouncerHook(interval: interval, maxWaitTime: maxWaitTime, keys: keys));
 | |
| 
 | |
| class _DebouncerHook extends Hook<Debouncer> {
 | |
|   const _DebouncerHook({required this.interval, this.maxWaitTime, super.keys});
 | |
| 
 | |
|   final Duration interval;
 | |
|   final Duration? maxWaitTime;
 | |
| 
 | |
|   @override
 | |
|   HookState<Debouncer, Hook<Debouncer>> createState() => _DebouncerHookState();
 | |
| }
 | |
| 
 | |
| class _DebouncerHookState extends HookState<Debouncer, _DebouncerHook> {
 | |
|   late final debouncer = Debouncer(interval: hook.interval, maxWaitTime: hook.maxWaitTime);
 | |
| 
 | |
|   @override
 | |
|   Debouncer build(_) => debouncer;
 | |
| 
 | |
|   @override
 | |
|   void dispose() => debouncer.dispose();
 | |
| 
 | |
|   @override
 | |
|   String get debugLabel => 'useDebouncer';
 | |
| }
 |