D-James-GH / cached_query

Simple caching for flutter apps
MIT License
55 stars 10 forks source link

feat: InfinitQuery needs to have more data as on what is actually loaded #29

Open iOSonntag opened 6 months ago

iOSonntag commented 6 months ago

First of all GREAT WORK!

What I am missing in the framework is to know exactly what is beeing loaded. This is so you can decide wether to show a loading indicator in the center of the srceen, or just at the end of the list OR if you dont want to show a loading indicator at all because it is silengthly refreshing in the back.

I wanted to address these issues in an extension of the InfinitQuery but it turns out that the factory design + the private _internal constructors made it impossible.

So my ugly workaround looks likes this:

class ExtendedInfinitQueryData {

  bool isFetchingNextPage;
  bool isRefetchingByUser;
  bool isRefetchingBySystem;

  ExtendedInfinitQueryData({
    required this.isFetchingNextPage,
    required this.isRefetchingByUser,
    required this.isRefetchingBySystem,
  });
}

final Map<InfiniteQuery, ExtendedInfinitQueryData> _inifnitQueryData = {};

extension ExtensionOnInfiniteQuery<T, Arg> on InfiniteQuery<T, Arg> {

  ExtendedInfinitQueryData _getData()
  {
    ExtendedInfinitQueryData? data = _inifnitQueryData[this];

    if (data != null) return data;

    final newData = ExtendedInfinitQueryData(
      isFetchingNextPage: false,
      isRefetchingByUser: false,
      isRefetchingBySystem: false,
    );

    _inifnitQueryData[this] = newData;

    return newData;
  }

  bool get isFetchingNextPage => _getData().isFetchingNextPage;
  bool get isRefetching => isRefetchingByUser || isRefetchingBySystem;
  bool get isRefetchingByUser => _getData().isRefetchingByUser;
  bool get isRefetchingBySystem => _getData().isRefetchingBySystem;
  bool get isFetchingForTheFirstTime => state.status == QueryStatus.loading && state.data == null;

  Future<InfiniteQueryState<T>> refetchByUser() async
  {
    _getData().isRefetchingByUser = true;
    final state = await refetch();
    _getData().isRefetchingByUser = false;
    update((oldData) => oldData);

    return state;
  }

  Future<InfiniteQueryState<T>> refetchBySystem() async
  {
    _getData().isRefetchingByUser = true;
    final state = await refetch();
    _getData().isRefetchingByUser = false;
    update((oldData) => oldData);

    return state;
  }

  Future<InfiniteQueryState<T>?> fetchNextPageAdvanced() async
  {
    _getData().isFetchingNextPage = true;
    final state = await getNextPage();
    _getData().isFetchingNextPage = false;
    update((oldData) => oldData);

    return state;
  }

}

Also note that I know need to remember to call getNextPageAdvanced() and that i am not allowed to call the others.

I am not suggesting to add the refetchByUser and refetchBySystem features to the framework. But I am suggesting to add at least if it is an explicit refresh. This way the UI can be build nicely.