Untitled

 avatar
unknown
plain_text
a year ago
2.2 kB
6
Indexable
import 'package:chat360_base/debouncer/debouncer.dart';
import 'package:flutter/material.dart';

abstract class SearchListingProvider<V> extends ChangeNotifier {
  SearchListingProvider() {
    _loadData();
  }
  bool hasError = false;
  Future<List<V>?> fetchPage();
  bool searchComparer(String? text, V data);

  bool isRefreshing = false;
  List<V> get items => shouldSearching ? _searchItems : _pageItems;
  bool get loading => shouldSearching ? _isSearching : _isLoading;
  bool shouldSearching = false;
  bool _isSearching = false;
  bool _isLoading = true;

  List<V> _pageItems = [];
  List<V> _searchItems = [];

  TextEditingController searchTextController = TextEditingController();

  final Map<String, List<V>> _indexedSearch = {};
  final _debouncer = CustomDebouncer(milliseconds: 500);

  void refreshData() async {
    hasError = false;
    isRefreshing = true;
    notifyListeners();
    List<V>? model = await fetchPage();
    _pageItems = (model ?? []).cast();
    isRefreshing = false;
    notifyListeners();
  }

  void _loadData() async {
    _isLoading = true;
    notifyListeners();
    List<V>? model = await fetchPage();
    _pageItems.addAll((model ?? []).cast());
    _isLoading = false;
    notifyListeners();
  }

  searchCallback(String text) {
    if (text.isEmpty) {
      _resetSearching();
      return;
    }
    shouldSearching = true;
    notifyListeners();
    _debouncer.run(() async {
      _isSearching = true;
      notifyListeners();
      if (_indexedSearch[text] != null && _indexedSearch[text]!.isNotEmpty) {
        _searchItems = _indexedSearch[text] ?? [];
        _isSearching = false;
        notifyListeners();
      } else {
        _fetchSearchPage(text).then((items) {
          _indexedSearch[text] = items;
          _searchItems = items;
          _isSearching = false;
          notifyListeners();
        });
      }
    });
  }

  void _resetSearching() {
    _isSearching = false;
    shouldSearching = false;
    _searchItems.clear();
    notifyListeners();
    return;
  }

  Future<List<V>> _fetchSearchPage(String? text) async {
    List<V>? model = items.where((v) => searchComparer(text, v)).toList();
    return (model).cast();
  }
}
Editor is loading...
Leave a Comment