Skip to content

Commit

Permalink
Merge pull request #365 from yumemi-inc/improve/GH-303/extract_pagina…
Browse files Browse the repository at this point in the history
…tion_package

[Improve]: ページネーション関連の実装を utils/pagination パッケージに切り出す
  • Loading branch information
blendthink authored Jan 17, 2025
2 parents 4f2e63a + 486bc2c commit 0dfbc1d
Show file tree
Hide file tree
Showing 27 changed files with 853 additions and 32 deletions.
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ labels:
files:
- packages/samples/github_repository/.+

- label: "@packages/utils/pagination"
files:
- packages/utils/pagination/.+

- label: "@apps/website"
files:
- apps/website/.+
4 changes: 4 additions & 0 deletions .github/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@
description: packages samples github_repository package
from_name: "@packages/features/github_repository"

- name: "@packages/utils/pagination"
color: 5d7dbc
description: packages utils pagination package

- name: "@apps/website"
color: 3b4ff2
description: apps website package
1 change: 0 additions & 1 deletion packages/cores/core/lib/extension/async_value.dart

This file was deleted.

2 changes: 0 additions & 2 deletions packages/cores/core/lib/pagination.dart

This file was deleted.

1 change: 0 additions & 1 deletion packages/cores/core/lib/ui.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export 'src/ui/util/common_paging_view.dart';
export 'src/ui/util/snack_bar_manager.dart';
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:cores_core/exception.dart';
import 'package:cores_core/ui.dart';
import 'dart:async';

import 'package:cores_designsystem/components.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
Expand All @@ -8,6 +8,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:samples_github_repository/src/data/provider/scroll_notifier.dart';
import 'package:samples_github_repository/src/domain/model/github_repository.dart';
import 'package:samples_github_repository/src/ui/provider/github_repository_list_notifier.dart';
import 'package:utils_pagination/ui.dart';

part 'github_repository_list_page.g.dart';

Expand Down Expand Up @@ -69,7 +70,22 @@ class GitHubRepositoryListPage extends HookConsumerWidget {
);
},
),
onError: ref.read(appExceptionNotifierProvider.notifier).notify,
onError: (e) => unawaited(
showDialog<void>(
context: context,
builder: (_) {
return AlertDialog(
title: Text(e.message),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Close'),
),
],
);
},
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:cores_core/pagination.dart';
import 'package:cores_core/exception.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:samples_github_repository/src/data/provider/repository.dart';
import 'package:samples_github_repository/src/domain/model/github_repository.dart';
import 'package:utils_pagination/exception.dart';
import 'package:utils_pagination/model.dart';
import 'package:utils_pagination/provider.dart';

final pageBasedGitHubRepositoryNotifierProvider = AsyncNotifierProvider
.autoDispose<PageBasedGitHubRepositoryNotifier, GitHubRepositoryPageState>(
Expand All @@ -16,13 +19,26 @@ class PageBasedGitHubRepositoryNotifier
Future<PageBasedFetchResult<GitHubRepository>> fetch({
required int page,
}) async {
final res =
await ref.read(listOrganizationRepositoriesProvider(page: page).future);
ref.keepAlive();
return PageBasedFetchResult(
items: res.items,
hasMore: res.hasMore,
);
try {
final res = await ref
.read(listOrganizationRepositoriesProvider(page: page).future);
ref.keepAlive();
return PageBasedFetchResult(
items: res.items,
hasMore: res.hasMore,
);
} on AppException catch (e) {
switch (e) {
case ClientNetworkException():
throw PagingClientNetworkException(e.message);
case ServerNetworkException():
throw PagingServerNetworkException(e.message);
case UnknownNetworkException():
throw const PagingUnknownNetworkException();
case UnknownException():
throw const PagingUnknownException();
}
}
}

@override
Expand Down
7 changes: 7 additions & 0 deletions packages/samples/github_repository/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
utils_pagination:
dependency: "direct main"
description:
path: "../../utils/pagination"
relative: true
source: path
version: "0.0.1"
uuid:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions packages/samples/github_repository/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ dependencies:
hooks_riverpod: ^2.5.1
json_annotation: ^4.9.0
riverpod_annotation: ^2.6.1
utils_pagination:
path: ../../utils/pagination

dev_dependencies:
build_runner: ^2.4.14
Expand Down
32 changes: 32 additions & 0 deletions packages/utils/pagination/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
build/
.flutter-plugins
.flutter-plugins-dependencies

# Melos related
/pubspec_overrides.yaml
10 changes: 10 additions & 0 deletions packages/utils/pagination/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "2e9cb0aa71a386a91f73f7088d115c0d96654829"
channel: "stable"

project_type: package
1 change: 1 addition & 0 deletions packages/utils/pagination/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# utils_pagination package
6 changes: 6 additions & 0 deletions packages/utils/pagination/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include: package:yumemi_lints/flutter/3.24/recommended.yaml

analyzer:
plugins:
# https://riverpod.dev/docs/introduction/getting_started#enabling-riverpod_lintcustom_lint
- custom_lint
15 changes: 15 additions & 0 deletions packages/utils/pagination/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
targets:
$default:
builders:
freezed:
# /~https://github.com/dart-lang/build/blob/master/docs/faq.md#how-do-i-avoid-running-builders-on-unnecessary-inputs
generate_for:
include:
- lib/src/{model,**/model}/**.dart
# /~https://github.com/dart-lang/source_gen#ignore_for_file
source_gen:combining_builder:
options:
ignore_for_file:
- type=lint
- duplicate_ignore
- deprecated_member_use
1 change: 1 addition & 0 deletions packages/utils/pagination/lib/exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'src/exception/paging_exception.dart';
1 change: 1 addition & 0 deletions packages/utils/pagination/lib/model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'src/model/paging_data.dart';
1 change: 1 addition & 0 deletions packages/utils/pagination/lib/provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'src/provider/paging_async_notifier.dart';
26 changes: 26 additions & 0 deletions packages/utils/pagination/lib/src/exception/paging_exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
sealed class PagingException implements Exception {
const PagingException(this.message);

final String message;
}

sealed class PagingNetworkException extends PagingException {
const PagingNetworkException(super.message);
}

final class PagingClientNetworkException extends PagingNetworkException {
const PagingClientNetworkException(super.message);
}

final class PagingServerNetworkException extends PagingNetworkException {
const PagingServerNetworkException(super.message);
}

final class PagingUnknownNetworkException extends PagingNetworkException {
const PagingUnknownNetworkException()
: super('Unknown network error occurred');
}

final class PagingUnknownException extends PagingException {
const PagingUnknownException() : super('Unknown error occurred');
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:async';

import 'package:cores_core/extension/async_value.dart';
import 'package:cores_core/src/pagination/model/paging_data.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:utils_pagination/src/extension/async_value.dart';
import 'package:utils_pagination/src/model/paging_data.dart';

/// An abstract notifier for paging logic, handling asynchronous data fetching
/// and state management.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import 'package:cores_core/exception.dart';
import 'package:cores_core/extension/async_value.dart';
import 'package:cores_core/src/pagination/model/paging_data.dart';
import 'package:cores_core/src/pagination/provider/paging_async_notifier.dart';
import 'package:cores_core/src/util/logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:utils_pagination/model.dart';
import 'package:utils_pagination/provider.dart';
import 'package:utils_pagination/src/exception/paging_exception.dart';
import 'package:utils_pagination/src/extension/async_value.dart';

import 'package:visibility_detector/visibility_detector.dart';

Expand Down Expand Up @@ -46,7 +45,7 @@ class CommonPagingView<N extends PagingAsyncNotifier<D, T>,
const CommonPagingView({
required AutoDisposeAsyncNotifierProvider<N, D> provider,
required Widget Function(D data, Widget? endItem) contentBuilder,
required void Function(AppException e) onError,
required void Function(PagingException e) onError,
super.key,
}) : _contentBuilder = contentBuilder,
_provider = provider,
Expand All @@ -62,7 +61,7 @@ class CommonPagingView<N extends PagingAsyncNotifier<D, T>,
/// adding a special widget at that position.
final Widget Function(D data, Widget? endItem) _contentBuilder;

final void Function(AppException e) _onError;
final void Function(PagingException e) _onError;

Widget? _endItem(
D data,
Expand Down Expand Up @@ -96,17 +95,10 @@ class CommonPagingView<N extends PagingAsyncNotifier<D, T>,
(_, next) {
if (!next.isLoading && next.hasError) {
final error = next.error;
if (error is AppException) {
if (error is PagingException) {
_onError(error);
return;
}
// AppException is expected, so this should never be reached.
logger.shout(
'Unexpected error type encountered: $error - '
'This indicates a need to revise exception handling to ensure only '
'AppException is thrown. Please review exception handling '
'practices and modify as necessary.',
);
}
},
);
Expand Down
1 change: 1 addition & 0 deletions packages/utils/pagination/lib/ui.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'src/ui/common_paging_view.dart';
Loading

0 comments on commit 0dfbc1d

Please sign in to comment.