Skip to content

Commit

Permalink
Merge pull request #32 from K9i-0/feature/add_samples
Browse files Browse the repository at this point in the history
Chore: new sample
  • Loading branch information
K9i-0 authored Jun 15, 2024
2 parents 55baa9f + 5bc0ac3 commit 18a84a4
Show file tree
Hide file tree
Showing 8 changed files with 351 additions and 52 deletions.
13 changes: 10 additions & 3 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:example/data/sample_item.dart';
import 'package:example/repository/sample_repository.dart';
import 'package:example/ui/first_page_error_screen.dart';
import 'package:example/ui/id_screen.dart';
import 'package:example/ui/paging_method_screen.dart';
import 'package:example/ui/passing_args_screen.dart';
import 'package:example/ui/second_page_error_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Expand Down Expand Up @@ -96,9 +97,15 @@ class SampleScreen extends StatelessWidget {
),
),
ListTile(
title: const Text('Id screen'),
title: const Text('Passing args screen'),
onTap: () => Navigator.of(context).push(
IdScreen.route(),
PassingArgsScreen.route(),
),
),
ListTile(
title: const Text('Paging method screen'),
onTap: () => Navigator.of(context).push(
PagingMethodScreen.route(),
),
),
],
Expand Down
42 changes: 42 additions & 0 deletions example/lib/repository/sample_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,48 @@ SampleRepository sampleRepository(SampleRepositoryRef ref) =>
SampleRepository();

class SampleRepository {
Future<(List<SampleItem> items, bool hasMore)> getByPage({
required int page,
required int limit,
}) async {
await Future<void>.delayed(const Duration(milliseconds: 500));

final items = _db
.sublist((page - 1) * limit, page * limit)
.mapRecord(
(id, name) => SampleItem(id: id.toString(), name: name),
)
.toList();

final hasMore = _db.length > page * limit;

return (
items,
hasMore,
);
}

Future<(List<SampleItem> items, bool hasMore)> getByOffset({
required int offset,
required int limit,
}) async {
await Future<void>.delayed(const Duration(milliseconds: 500));

final items = _db
.sublist(offset, offset + limit)
.mapRecord(
(id, name) => SampleItem(id: id.toString(), name: name),
)
.toList();

final hasMore = _db.length > offset + limit;

return (
items,
hasMore,
);
}

Future<(List<SampleItem> items, String? nextCursor)> getByCursor(
String? cursor,
) async {
Expand Down
2 changes: 1 addition & 1 deletion example/lib/ui/first_page_error_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class FirstPageErrorScreen extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('1st Page Error Screen'),
title: const Text('1st Page Error Sample'),
),
body: PagingHelperView(
provider: firstPageErrorNotifierProvider,
Expand Down
186 changes: 186 additions & 0 deletions example/lib/ui/paging_method_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import 'package:example/data/sample_item.dart';
import 'package:example/repository/sample_repository.dart';
import 'package:flutter/material.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';

part 'paging_method_screen.g.dart';

@riverpod
class PageBasedNotifier extends _$PageBasedNotifier
with PagePagingNotifierMixin<SampleItem> {
@override
Future<PagePagingData<SampleItem>> build() => fetch(page: 1);

@override
Future<PagePagingData<SampleItem>> fetch({
required int page,
}) async {
final repository = ref.read(sampleRepositoryProvider);
final (items, hasMore) = await repository.getByPage(page: page, limit: 50);
ref.keepAlive();

return PagePagingData(
items: items,
hasMore: hasMore,
page: page,
);
}
}

@riverpod
class OffsetBasedNotifier extends _$OffsetBasedNotifier
with OffsetPagingNotifierMixin<SampleItem> {
@override
Future<OffsetPagingData<SampleItem>> build() => fetch(offset: 0);

@override
Future<OffsetPagingData<SampleItem>> fetch({
required int offset,
}) async {
final repository = ref.read(sampleRepositoryProvider);
final (items, hasMore) =
await repository.getByOffset(offset: offset, limit: 75);
ref.keepAlive();

return OffsetPagingData(
items: items,
hasMore: hasMore,
offset: offset + 75,
);
}
}

@riverpod
class CursorBasedNotifier extends _$CursorBasedNotifier
with CursorPagingNotifierMixin<SampleItem> {
@override
Future<CursorPagingData<SampleItem>> build() => fetch(cursor: null);

@override
Future<CursorPagingData<SampleItem>> fetch({
required String? cursor,
}) async {
final repository = ref.read(sampleRepositoryProvider);
final (items, nextCursor) = await repository.getByCursor(cursor);
ref.keepAlive();
final hasMore = nextCursor != null && nextCursor.isNotEmpty;

return CursorPagingData(
items: items,
hasMore: hasMore,
nextCursor: nextCursor,
);
}
}

class PagingMethodScreen extends StatelessWidget {
const PagingMethodScreen._();

static Route<void> route() {
return MaterialPageRoute(
builder: (context) => const PagingMethodScreen._(),
);
}

@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('Paging Method Sample'),
bottom: const TabBar(
tabs: [
Tab(
text: 'Page',
),
Tab(
text: 'Offset',
),
Tab(
text: 'Cursor',
),
],
),
),
body: TabBarView(
children: [
PagingHelperView(
provider: pageBasedNotifierProvider,
futureRefreshable: pageBasedNotifierProvider.future,
notifierRefreshable: pageBasedNotifierProvider.notifier,
contentBuilder: (data, widgetCount, endItemView) =>
ListView.builder(
key: const PageStorageKey<String>('page'),
itemCount: widgetCount,
itemBuilder: (context, index) {
// if the index is last, then
// return the end item view.
if (index == widgetCount - 1) {
return endItemView;
}

// Otherwise, build a list tile for each sample item.
return ListTile(
key: ValueKey(data.items[index].id),
title: Text(data.items[index].name),
subtitle: Text(data.items[index].id),
);
},
),
),
PagingHelperView(
provider: offsetBasedNotifierProvider,
futureRefreshable: offsetBasedNotifierProvider.future,
notifierRefreshable: offsetBasedNotifierProvider.notifier,
contentBuilder: (data, widgetCount, endItemView) =>
ListView.builder(
key: const PageStorageKey<String>('offset'),
itemCount: widgetCount,
itemBuilder: (context, index) {
// if the index is last, then
// return the end item view.
if (index == widgetCount - 1) {
return endItemView;
}

// Otherwise, build a list tile for each sample item.
return ListTile(
key: ValueKey(data.items[index].id),
title: Text(data.items[index].name),
subtitle: Text(data.items[index].id),
);
},
),
),
PagingHelperView(
provider: cursorBasedNotifierProvider,
futureRefreshable: cursorBasedNotifierProvider.future,
notifierRefreshable: cursorBasedNotifierProvider.notifier,
contentBuilder: (data, widgetCount, endItemView) =>
ListView.builder(
key: const PageStorageKey<String>('cursor'),
itemCount: widgetCount,
itemBuilder: (context, index) {
// if the index is last, then
// return the end item view.
if (index == widgetCount - 1) {
return endItemView;
}

// Otherwise, build a list tile for each sample item.
return ListTile(
key: ValueKey(data.items[index].id),
title: Text(data.items[index].name),
subtitle: Text(data.items[index].id),
);
},
),
),
],
),
),
);
}
}
63 changes: 63 additions & 0 deletions example/lib/ui/paging_method_screen.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import 'package:flutter/material.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';

part 'id_screen.g.dart';
part 'passing_args_screen.g.dart';

@riverpod
class IdNotifier extends _$IdNotifier
class PassingArgsNotifier extends _$PassingArgsNotifier
with CursorPagingNotifierMixin<SampleItem> {
@override
Future<CursorPagingData<SampleItem>> build({required String id}) =>
Expand All @@ -30,21 +30,21 @@ class IdNotifier extends _$IdNotifier
}
}

class IdScreen extends StatelessWidget {
const IdScreen._();
class PassingArgsScreen extends StatelessWidget {
const PassingArgsScreen._();

static Route<void> route() {
return MaterialPageRoute(
builder: (context) => const IdScreen._(),
builder: (context) => const PassingArgsScreen._(),
);
}

@override
Widget build(BuildContext context) {
final provider = idNotifierProvider(id: '1');
final provider = passingArgsNotifierProvider(id: '1');
return Scaffold(
appBar: AppBar(
title: const Text('Id Screen'),
title: const Text('Passing Args Sample'),
),
body: PagingHelperView(
provider: provider,
Expand Down
Loading

0 comments on commit 18a84a4

Please sign in to comment.