66 lines
1.7 KiB
Dart
66 lines
1.7 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'models.dart';
|
|
import 'service.dart';
|
|
|
|
class BankSearchProvider extends ChangeNotifier {
|
|
BankSearchProvider(this.service);
|
|
final DestinationService service;
|
|
Timer? _timer;
|
|
Completer<void>? _abort;
|
|
int _generation = 0;
|
|
bool _disposed = false, loading = false;
|
|
String query = '';
|
|
List<Bank> results = [];
|
|
DestinationIssue? error;
|
|
void search(String value) {
|
|
_timer?.cancel();
|
|
if (_abort != null && !_abort!.isCompleted) _abort!.complete();
|
|
_abort = null;
|
|
final generation = ++_generation;
|
|
query = value;
|
|
results = [];
|
|
error = null;
|
|
loading = false;
|
|
if (value.trim().length >= 2) {
|
|
_timer = Timer(
|
|
const Duration(milliseconds: 350),
|
|
() => _lookup(value, generation),
|
|
);
|
|
}
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> _lookup(String value, int generation) async {
|
|
loading = true;
|
|
notifyListeners();
|
|
try {
|
|
final abort = Completer<void>();
|
|
_abort = abort;
|
|
final rows = await service.banks(value, abortTrigger: abort.future);
|
|
if (_disposed || generation != _generation) return;
|
|
results = rows;
|
|
if (rows.isEmpty) error = DestinationIssue.invalid;
|
|
} on DestinationException catch (e) {
|
|
if (!_disposed && generation == _generation) error = e.issue;
|
|
} catch (_) {
|
|
if (!_disposed && generation == _generation)
|
|
error = DestinationIssue.unavailable;
|
|
}
|
|
if (_disposed || generation != _generation) return;
|
|
loading = false;
|
|
notifyListeners();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_disposed = true;
|
|
_generation++;
|
|
_timer?.cancel();
|
|
if (_abort != null && !_abort!.isCompleted) _abort!.complete();
|
|
super.dispose();
|
|
}
|
|
}
|