Keyboard Shortcuts

j / kScroll down / up
ggScroll to top
GScroll to bottom
K / /Open search
?Show this help
EscClose search / help
n / NNext / previous section
hGo to landing
dGo to docs
:Command mode — type section name

Press ? or Esc to close

Deep Dives

Pagination

List screens extend a base pagination Cubit. Two strategies ship out of the box — offset-based and cursor-based — chosen by the API's metadata shape.

Two metadata types

MetaShapeWhen
OffsetPaginationMetacount, next, previous page numbersClassic page-numbered feeds
CursorPaginationMetanextCursor, previousCursorInfinite scroll, stable ordering

Offset pagination

The feature Cubit extends PaginatedCubit<ItemT, FilterT, ExtraT> and implements only fetchPage. Load-more, refresh, and filtering are provided by the base.

lib/features/home/logic/posts_cubit.dart
class PostsCubit extends PaginatedCubit<PostModel, PostFilter, void> {
  PostsCubit(this._store) : super(PaginatedState.initial());

  @override
  Future<ApiResponse<List<PostModel>, OffsetPaginationMeta>> fetchPage(
    int page,
    PostFilter? filters,
  ) =>
      _store.getPosts(page: page, filters: filters);
}

// Provided by the base cubit:
//   loadFirst()  — page 1, replace list
//   loadMore()   — next page, append
//   refresh()    — reset to page 1
//   applyFilters(f) / clearFilters()

Cursor pagination

Same idea, but fetchPage takes the cursor string instead of a page number. The base tracks nextCursor and passes it forward on load-more.

lib/features/opportunities/logic/feed_cubit.dart
class FeedCubit extends CursorPaginatedCubit<FeedItem, FeedFilter> {
  FeedCubit(this._store) : super(CursorPaginatedState.initial());

  @override
  Future<ApiResponse<List<FeedItem>, CursorPaginationMeta>> fetchPage(
    String? nextCursor,
    FeedFilter? filters,
  ) =>
      _store.getFeed(cursor: nextCursor, filters: filters);
}

Offline reload

Both base cubits mix in ConnectivityReloadMixin. When connectivity returns, onReconnected() refreshes the current list automatically.

lib/config/network/paginated_cubit/offset_paginated_cubit/paginated_cubit.dart
abstract class PaginatedCubit<ItemT, FilterT, ExtraT>
    extends Cubit<PaginatedState<ItemT, FilterT, ExtraT>>
    with ConnectivityReloadMixin {

  @override
  void onReconnected() => refresh();
}

UI

PaginatedListView wires a scroll controller to loadMore at the bottom and shows a shimmer while loading. Feature code just passes the cubit.

sam's arch — A Pragmatic Flutter Architecture