Skip to content

Commit

Permalink
chore: update doc comments, minor changes
Browse files Browse the repository at this point in the history
Signed-off-by: Sahil Kumar <xdsahil@gmail.com>
  • Loading branch information
xsahil03x committed Jan 18, 2024
1 parent 102d127 commit 464c36c
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 106 deletions.
26 changes: 13 additions & 13 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.2"
version: "1.18.0"
convert:
dependency: transitive
description:
Expand Down Expand Up @@ -351,10 +351,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
mime:
dependency: transitive
description:
Expand Down Expand Up @@ -452,18 +452,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
stream_transform:
dependency: transitive
description:
Expand Down Expand Up @@ -499,10 +499,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
version: "0.6.1"
timing:
dependency: transitive
description:
Expand Down Expand Up @@ -539,10 +539,10 @@ packages:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
Expand All @@ -560,5 +560,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.1.0 <4.0.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.13.0"
17 changes: 9 additions & 8 deletions lib/src/load_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ part 'load_state.freezed.dart';

/// LoadState of a PagedList load - associated with a [LoadType]
///
/// [LoadState] of any [LoadType] may be observed for UI purposes by registering a listener via
/// [androidx.paging.PagingDataAdapter.addLoadStateListener] or
/// [androidx.paging.AsyncPagingDataDiffer.addLoadStateListener]
/// [LoadState] of any [LoadType] may be observed for UI purposes by registering
/// a listener via [SuperPager.addListener].
///
/// [endOfPaginationReached] `false` if there is more data to load in the [LoadType] this
/// [LoadState] is associated with, `true` otherwise. This parameter informs [Pager] if it
/// should continue to make requests for additional data in this direction or if it should
/// halt as the end of the dataset has been reached.
/// [endOfPaginationReached] `false` if there is more data to load in the
/// [LoadType] this [LoadState] is associated with, `true` otherwise.
/// This parameter informs [Pager] if it should continue to make requests for
/// additional data in this direction or if it should halt as the end of the
/// dataset has been reached.
///
/// @see LoadType
/// also see:
/// * [LoadType]
@freezed
sealed class LoadState with _$LoadState {
/// Indicates the [PagingData] is not currently loading, and no error currently observed.
Expand Down
13 changes: 6 additions & 7 deletions lib/src/load_type.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
/// Type of load a [PagingData] can trigger a [PagingSource] to perform.
/// Type of load a [SuperPager] can trigger a [PageFetcher] to perform.
///
/// [LoadState] of any [LoadType] may be observed for UI purposes by registering a listener via
/// [androidx.paging.PagingDataAdapter.addLoadStateListener] or
/// [androidx.paging.AsyncPagingDataDiffer.addLoadStateListener].
/// [LoadState] of any [LoadType] may be observed for UI purposes by registering
/// a listener via [SuperPager.addListener].
enum LoadType {
/// [PagingData] content being refreshed, which can be a result of refresh
/// [SuperPager] content being refreshed, which can be a result of refresh
/// that may contain content updates, or the initial load.
refresh,

/// Load at the start of a [PagingData].
/// Load at the start of a [SuperPager].
prepend,

/// Load at the end of a [PagingData].
/// Load at the end of a [SuperPager].
append,
}
2 changes: 1 addition & 1 deletion lib/src/page_fetcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ class PageFetcher<Key, Value> extends ValueNotifier<PagingState<Key, Value>> {
// Never drop below 2 pages as this can cause UI flickering with certain configs and it's
// much more important to protect against this behaviour over respecting a config where
// maxSize is set unusually (probably incorrectly) strict.
if (value.pages.length <= 2) return 0;
if (value.pages.length <= 3) return 0;

if (value.pages.itemCount <= maxSize) return 0;

Expand Down
59 changes: 30 additions & 29 deletions lib/src/paging_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,18 @@ class PagingConfig {
///
/// Should be several times the number of visible items onscreen.
///
/// Configuring your page size depends on how your data is being loaded and used. Smaller
/// page sizes improve memory usage, latency, and avoid GC churn. Larger pages generally
/// improve loading throughput, to a point (avoid loading more than 2MB from SQLite at
/// once, since it incurs extra cost).
/// Configuring your page size depends on how your data is being loaded and
/// used. Smaller page sizes improve memory usage, latency, and avoid
/// GC churn. Larger pages generally improve loading throughput.
///
/// If you're loading data for very large, social-media style cards that take up most of
/// a screen, and your database isn't a bottleneck, 10-20 may make sense. If you're
/// displaying dozens of items in a tiled grid, which can present items during a scroll
/// much more quickly, consider closer to 100.
/// If you're loading data for very large, social-media style cards that take
/// up most of a screen, and your database isn't a bottleneck, 10-20 may make
/// sense. If you're displaying dozens of items in a tiled grid, which can
/// present items during a scroll much more quickly, consider closer to 100.
///
/// Note: [pageSize] is used to inform [PagingSource.LoadParams.loadSize], but is not enforced.
/// A [PagingSource] may completely ignore this value and still return a valid
/// [Page][PagingSource.LoadResult.Page].
/// Note: [pageSize] is used to inform [LoadParams.loadSize], but is not
/// enforced. A [PagingSource] may completely ignore this value and still
/// return a valid [Page].
final int pageSize;

/// Prefetch index defines how far from the edge of loaded content an access must be to
Expand All @@ -50,33 +49,35 @@ class PagingConfig {
/// end of list while scrolling.
final int prefetchIndex;

/// Defines requested load size for initial load from [PagingSource], typically larger than
/// [pageSize], so on first load data there's a large enough range of content loaded to cover
/// small scrolls.
/// Defines requested load size for initial load from [PagingSource],
/// typically larger than [pageSize], so on first load data there's a large
/// enough range of content loaded to cover small scrolls.
///
/// Note: [initialLoadSize] is used to inform [PagingSource.LoadParams.loadSize], but is not
/// enforced. A [PagingSource] may completely ignore this value and still return a valid initial
/// [Page][PagingSource.LoadResult.Page].
/// Note: [initialLoadSize] is used to inform [LoadParams.loadSize], but is
/// not enforced. A [PagingSource] may completely ignore this value and still
/// return a valid initial [Page].
final int initialLoadSize;

/// Defines the maximum number of items that may be loaded into [PagingData] before pages should
/// be dropped.
/// Defines the maximum number of items that may be loaded into [PagingData]
/// before pages should be dropped.
///
/// If set to null (Default), pages will never be dropped.
///
/// This can be used to cap the number of items kept in memory by dropping pages. This value is
/// typically many pages so old pages are cached in case the user scrolls back.
/// This can be used to cap the number of items kept in memory by dropping
/// pages. This value is typically many pages so old pages are cached in case
/// the user scrolls back.
///
/// This value must be at least two times the [prefetchIndex] plus the [pageSize]). This
/// constraint prevent loads from being continuously fetched and discarded due to prefetching.
/// This value must be at least three times the [pageSize]. This constraint
/// prevent loads from being continuously fetched and discarded due to
/// prefetching.
///
/// [maxSize] is best effort, not a guarantee. In practice, if [maxSize] is
/// many times [pageSize], the number of items held by [PagingData] will not
/// grow above this number.
///
/// [maxSize] is best effort, not a guarantee. In practice, if [maxSize] is many times
/// [pageSize], the number of items held by [PagingData] will not grow above this number.
/// Exceptions are made as necessary to guarantee:
/// * Pages are never dropped until there are more than two pages loaded. Note that
/// a [PagingSource] may not be held strictly to [requested pageSize][PagingConfig.pageSize], so
/// * Pages are never dropped until there are more than two pages loaded.
/// Note that a [PagingSource] may not be held strictly to [pageSize], so
/// two pages may be larger than expected.
/// * Pages are never dropped if they are within a prefetch window (defined to be
/// `pageSize + (2 * prefetchDistance)`) of the most recent load.
final int? maxSize;
}
25 changes: 12 additions & 13 deletions lib/src/paging_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import 'preconditions.dart';

part 'paging_source.freezed.dart';

/// Base class for an abstraction of pageable static data from some source, where loading pages
/// of data is typically an expensive operation. Some examples of common [PagingSource]s might be
/// from network or from a database.
/// Base class for an abstraction of pageable static data from some source,
/// where loading pages of data is typically an expensive operation. Some
/// examples of common [PagingSource]s might be from network or from a database.
///
/// An instance of a [PagingSource] is used to load pages of data for an instance of [PagingData].
/// An instance of a [PagingSource] is used to load pages of data for an
/// instance of [PagingState].
///
/// A [PagingData] can grow as it loads more data, but the data loaded cannot be updated. If the
/// underlying data set is modified, a new [PagingSource] / [PagingData] pair must be created to
/// represent an updated snapshot of the data.
/// A [PagingState] can grow as it loads more data, but the data loaded cannot
/// be updated. If the underlying data set is modified, a new [PagingSource]
/// must be created to represent an updated snapshot of the data.
///
/// ### Loading Pages
///
Expand Down Expand Up @@ -55,18 +56,16 @@ abstract mixin class PagingSource<Key, Value> {

/// Loading API for [PagingSource].
///
/// Implement this method to trigger your async load (e.g. from database or network).
/// Implement this method to trigger your async load (e.g. from database or
/// network).
Future<LoadResult<Key, Value>> load(LoadParams<Key> params);

@override
String toString() => describeIdentity(this);
}

/// Params for a load request on a [PagingSource] from [PagingSource.load].
@freezed
sealed class LoadParams<Key> with _$LoadParams<Key> {
/// Params for an initial load request on a [PagingSource] from [PagingSource.load] or a
/// refresh triggered by [invalidate].
/// Params for an initial load request on a [PagingSource] from
/// [PagingSource.load] or a refresh triggered by [invalidate].
const factory LoadParams.refresh({
/// Key for the page to be loaded.
///
Expand Down
37 changes: 25 additions & 12 deletions lib/src/super_pager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ class SuperPager<Key, Value>
_pageFetcher.addListener(_onPageFetcherStateChange);
}

@visibleForTesting
SuperPager.custom({
required PageFetcherFactory<Key, Value> pageFetcherFactory,
PagingState<Key, Value> initialState = const PagingState(),
}) : _notifier = ValueNotifier(initialState),
_pageFetcherFactory = pageFetcherFactory {
// Create a new page fetcher and listen to its state changes.
_pageFetcher = _pageFetcherFactory.call(initialState);
_pageFetcher.addListener(_onPageFetcherStateChange);
}

// Called whenever the page fetcher's state changes.
void _onPageFetcherStateChange() {
_notifier.value = _pageFetcher.value;
Expand Down Expand Up @@ -72,25 +83,27 @@ class SuperPager<Key, Value>
}

/// Load data from the [PagingSource] represented by this [SuperPager].
Future<void> load(LoadType loadType) => _pageFetcher.load(loadType);
Future<void> load(LoadType loadType) {
return _pageFetcher.load(loadType);
}

/// Retry any failed load requests that would result in a [LoadState.Error] update to this
/// [PagingDataDiffer].
/// Retry any failed load requests that would result in a [LoadState.error]
/// update to this [PagingState].
///
/// Unlike [refresh], this does not invalidate [PagingSource], it only retries failed loads
/// within the same generation of [PagingData].
/// Unlike [refresh], this does not invalidate [PageFetcher], it only retries
/// failed loads within the same generation of [PageFetcher].
///
/// [LoadState.Error] can be generated from two types of load requests:
/// * [PagingSource.load] returning [PagingSource.LoadResult.Error]
/// * [RemoteMediator.load] returning [RemoteMediator.MediatorResult.Error]
/// [LoadState.error] can be generated from types of load requests:
/// * [PagingSource.load] returning [LoadResult.error]
Future<void> retry() => _pageFetcher.retry();

/// Refresh the data presented by this [PagingDataDiffer].
/// Refresh the data presented by this [SuperPager].
///
/// [refresh] triggers the creation of a new [PagingData] with a new instance of [PagingSource]
/// to represent an updated snapshot of the backing dataset.
/// [refresh] triggers the creation of a new [PagingState] with a new instance
/// of [PageFetcher] to represent an updated snapshot of the backing dataset.
///
/// Note: This API is intended for UI-driven refresh signals, such as swipe-to-refresh.
/// Note: This API is intended for UI-driven refresh signals, such as
/// swipe-to-refresh.
Future<void> refresh({bool resetPages = true}) {
final current = _pageFetcher;

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ dev_dependencies:
sdk: flutter
flutter_lints: ^2.0.3
build_runner: ^2.4.6
freezed: ^2.4.3
freezed: ^2.4.5

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down
4 changes: 2 additions & 2 deletions test/mock_paging_source.dart → test/fake_paging_source.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:super_pager/super_pager.dart';

class MockPagingSource extends PagingSource<int, String> {
const MockPagingSource({this.totalPageCount = 100});
class FakePagingSource extends PagingSource<int, String> {
const FakePagingSource({this.totalPageCount = 100});

final int totalPageCount;

Expand Down
Loading

0 comments on commit 464c36c

Please sign in to comment.