diff --git a/lib/app/router/app_router.g.dart b/lib/app/router/app_router.g.dart index 4913273..3dcf7eb 100644 --- a/lib/app/router/app_router.g.dart +++ b/lib/app/router/app_router.g.dart @@ -6,7 +6,7 @@ part of 'app_router.dart'; // RiverpodGenerator // ************************************************************************** -String _$goRouterHash() => r'ed545948f9448c0d6659482ef81dfa416e03e491'; +String _$goRouterHash() => r'7f07e84722afb99411c2c7b98a2a848b849c7cae'; /// See also [goRouter]. @ProviderFor(goRouter) diff --git a/lib/core/logger/provider_logger.dart b/lib/core/logger/provider_logger.dart new file mode 100644 index 0000000..e45c7b7 --- /dev/null +++ b/lib/core/logger/provider_logger.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; + +class ProviderLogger extends ProviderObserver { + // 로깅할 Provider + final observingProvider = [ + // 'currentTabTypeProvider', + // 'petMateSearchFilterProvider', + // 'petSosSearchFilterProvider', + ]; + + @override + void didAddProvider(ProviderBase provider, Object? value, + ProviderContainer container) { + super.didAddProvider(provider, value, container); + + if (observingProvider.contains(provider.name)) { + debugPrint('Provider added ::: ${provider.name}'); + } + } + + @override + void didDisposeProvider( + ProviderBase provider, ProviderContainer container) { + super.didDisposeProvider(provider, container); + + if (observingProvider.contains(provider.name)) { + debugPrint('Provider disposed ::: ${provider.name}'); + } + } + + @override + void didUpdateProvider(ProviderBase provider, Object? previousValue, + Object? newValue, ProviderContainer container) { + super.didUpdateProvider(provider, previousValue, newValue, container); + + if (observingProvider.contains(provider.name)) { + debugPrint( + 'Provider updated ::: ${provider.name} ::: ${previousValue.toString()} -> ${newValue.toString()}'); + } + } +} diff --git a/lib/core/pagination/pagination_response.dart b/lib/core/pagination/pagination_response.dart index c99cfdc..b1705c7 100644 --- a/lib/core/pagination/pagination_response.dart +++ b/lib/core/pagination/pagination_response.dart @@ -4,6 +4,7 @@ class PaginationResponse { required this.page, required this.size, required this.items, + required this.isLastPage, }); PaginationResponse.fromJson( @@ -13,27 +14,25 @@ class PaginationResponse { size = json['size'] as int, items = (json['items'] as List) .map((e) => fromJson.call(e)) - .toList(); + .toList(), + isLastPage = json['is_last_page'] as bool; final int page; final int size; final List items; + final bool isLastPage; @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is PaginationResponse && - other.items == items && - other.page == page && - other.size == size; - } + bool operator ==(Object other) => + identical(this, other) || + other is PaginationResponse && + runtimeType == other.runtimeType && + page == other.page && + size == other.size && + items == other.items && + isLastPage == other.isLastPage; @override - int get hashCode => items.hashCode ^ page.hashCode ^ size.hashCode; - - Map toJson() => { - 'page': page, - 'size': size, - }; + int get hashCode => + page.hashCode ^ size.hashCode ^ items.hashCode ^ isLastPage.hashCode; } diff --git a/lib/features/pet/domain/breeds_pagination_response.dart b/lib/features/pet/domain/breeds_pagination_response.dart index 9acf587..8802294 100644 --- a/lib/features/pet/domain/breeds_pagination_response.dart +++ b/lib/features/pet/domain/breeds_pagination_response.dart @@ -2,45 +2,15 @@ import 'package:pets_next_door_flutter/core/pagination/pagination_response.dart' import 'package:pets_next_door_flutter/features/pet/domain/breed.dart'; /// Metadata used when fetching movies with the paginated search API. -class BreedsPaginationResponse implements PaginationResponse { +class BreedsPaginationResponse extends PaginationResponse { BreedsPaginationResponse({ - required this.page, - required this.size, - required this.items, + required super.page, + required super.size, + required super.items, + required super.isLastPage, }); BreedsPaginationResponse.fromJson( Map json, - ) : page = json['page'] as int, - size = json['size'] as int, - items = (json['items'] as List) - .map((e) => Breed.fromJson(e)) - .toList(); - - @override - final int page; - - @override - final int size; - - @override - final List items; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is BreedsPaginationResponse && - other.page == page && - other.size == size; - } - - @override - int get hashCode => page.hashCode ^ size.hashCode; - - @override - Map toJson() { - // TODO: implement toJson - throw UnimplementedError(); - } + ) : super.fromJson(json, (e) => Breed.fromJson(e)); } diff --git a/lib/features/pet/repository/pet_repository.dart b/lib/features/pet/repository/pet_repository.dart index b7678df..a1450f9 100644 --- a/lib/features/pet/repository/pet_repository.dart +++ b/lib/features/pet/repository/pet_repository.dart @@ -1,10 +1,10 @@ import 'package:pets_next_door_flutter/core/utils/result.dart'; -import 'package:pets_next_door_flutter/features/pet/domain/breed.dart'; import 'package:pets_next_door_flutter/features/pet/domain/breeds_pagination_request.dart'; +import 'package:pets_next_door_flutter/features/pet/domain/breeds_pagination_response.dart'; import 'package:pets_next_door_flutter/features/pet/entities/pet_data_entity.dart'; abstract interface class PetRepository { - Future>> getBreeds({ + Future> getBreeds({ required BreedsPaginationRequest breedsPaginationRequest, }); diff --git a/lib/features/pet/repository/pet_repository_impl.dart b/lib/features/pet/repository/pet_repository_impl.dart index 7073961..6b10e38 100644 --- a/lib/features/pet/repository/pet_repository_impl.dart +++ b/lib/features/pet/repository/pet_repository_impl.dart @@ -1,7 +1,7 @@ import 'package:pets_next_door_flutter/core/utils/result.dart'; import 'package:pets_next_door_flutter/features/pet/data/remote/pet_remote_data_source.dart'; -import 'package:pets_next_door_flutter/features/pet/domain/breed.dart'; import 'package:pets_next_door_flutter/features/pet/domain/breeds_pagination_request.dart'; +import 'package:pets_next_door_flutter/features/pet/domain/breeds_pagination_response.dart'; import 'package:pets_next_door_flutter/features/pet/entities/pet_data_entity.dart'; import 'package:pets_next_door_flutter/features/pet/repository/pet_repository.dart'; @@ -13,12 +13,12 @@ final class PetRepositoryImpl implements PetRepository { final PetRemoteDataSource _petRemoteDataSource; @override - Future>> getBreeds( + Future> getBreeds( {required BreedsPaginationRequest breedsPaginationRequest}) async { try { final breedsData = await _petRemoteDataSource.getBreeds( breedsPaginationRequest: breedsPaginationRequest); - return Result.success(breedsData.items); + return Result.success(breedsData); } on Exception catch (e) { return Result.failure(e); } diff --git a/lib/features/pet/usecases/get_breeds_use_case.dart b/lib/features/pet/usecases/get_breeds_use_case.dart index 2f41681..a732898 100644 --- a/lib/features/pet/usecases/get_breeds_use_case.dart +++ b/lib/features/pet/usecases/get_breeds_use_case.dart @@ -1,6 +1,6 @@ import 'package:pets_next_door_flutter/core/utils/result.dart'; -import 'package:pets_next_door_flutter/features/pet/domain/breed.dart'; import 'package:pets_next_door_flutter/features/pet/domain/breeds_pagination_request.dart'; +import 'package:pets_next_door_flutter/features/pet/domain/breeds_pagination_response.dart'; import 'package:pets_next_door_flutter/features/pet/repository/pet_repository.dart'; final class GetBreedsUseCase { @@ -10,9 +10,10 @@ final class GetBreedsUseCase { final PetRepository _petRepository; - Future>> call({ + Future> call({ required BreedsPaginationRequest breedsPaginationRequest, }) async { - return _petRepository.getBreeds(breedsPaginationRequest: breedsPaginationRequest); + return _petRepository.getBreeds( + breedsPaginationRequest: breedsPaginationRequest); } -} \ No newline at end of file +} diff --git a/lib/features/sos/data/dto/author_dto.dart b/lib/features/sos/data/dto/author_dto.dart new file mode 100644 index 0000000..9160a95 --- /dev/null +++ b/lib/features/sos/data/dto/author_dto.dart @@ -0,0 +1,23 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'author_dto.g.dart'; + +/// 게시물 작성자 정보 dto +@JsonSerializable() +class AuthorDto { + final int id; + final String nickname; + final String? profileImageUrl; + + AuthorDto( + {required this.id, + required this.nickname, + required this.profileImageUrl}); + + factory AuthorDto.fromJson(Map json) => + _$AuthorDtoFromJson(json); + + Map toJson() => _$AuthorDtoToJson(this); +} diff --git a/lib/features/sos/data/dto/author_dto.g.dart b/lib/features/sos/data/dto/author_dto.g.dart new file mode 100644 index 0000000..987d8e7 --- /dev/null +++ b/lib/features/sos/data/dto/author_dto.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'author_dto.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AuthorDto _$AuthorDtoFromJson(Map json) => AuthorDto( + id: json['id'] as int, + nickname: json['nickname'] as String, + profileImageUrl: json['profileImageUrl'] as String?, + ); + +Map _$AuthorDtoToJson(AuthorDto instance) => { + 'id': instance.id, + 'nickname': instance.nickname, + 'profileImageUrl': instance.profileImageUrl, + }; diff --git a/lib/features/sos/data/dto/sos_pagination_response_dto.dart b/lib/features/sos/data/dto/sos_pagination_response_dto.dart index fca05e7..c26a0a9 100644 --- a/lib/features/sos/data/dto/sos_pagination_response_dto.dart +++ b/lib/features/sos/data/dto/sos_pagination_response_dto.dart @@ -2,44 +2,15 @@ import 'package:pets_next_door_flutter/core/pagination/pagination_response.dart' import 'package:pets_next_door_flutter/features/sos/data/dto/sos_post_dto.dart'; /// Metadata used when fetching movies with the paginated search API. -class SosPostPaginationResponseDto implements PaginationResponse { +class SosPostPaginationResponseDto extends PaginationResponse { SosPostPaginationResponseDto({ - required this.page, - required this.size, - required this.items, + required super.page, + required super.size, + required super.items, + required super.isLastPage, }); SosPostPaginationResponseDto.fromJson( Map json, - ) : page = json['page'] as int, - size = json['size'] as int, - items = (json['items'] as List) - .map((e) => SosPostDto.fromJson(e)) - .toList(); - - @override - final int page; - - @override - final int size; - - @override - final List items; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is SosPostPaginationResponseDto && - other.page == page && - other.size == size; - } - - @override - int get hashCode => page.hashCode ^ size.hashCode; - - @override - Map toJson() { - throw UnimplementedError(); - } + ) : super.fromJson(json, (e) => SosPostDto.fromJson(e)); } diff --git a/lib/features/sos/data/dto/sos_post_dto.dart b/lib/features/sos/data/dto/sos_post_dto.dart index 7c7b97a..7e3c114 100644 --- a/lib/features/sos/data/dto/sos_post_dto.dart +++ b/lib/features/sos/data/dto/sos_post_dto.dart @@ -3,6 +3,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:pets_next_door_flutter/features/media/data/dto/media_image_dto.dart'; import 'package:pets_next_door_flutter/features/pet/data/dto/pet_data_dto.dart'; +import 'package:pets_next_door_flutter/features/sos/data/dto/author_dto.dart'; import 'package:pets_next_door_flutter/features/sos/data/dto/sos_condition_dto.dart'; part 'sos_post_dto.g.dart'; @@ -29,11 +30,11 @@ class SosPostDto { SosPostDto({ required this.id, + required this.author, required this.conditions, required this.content, required this.media, required this.title, - required this.authorId, required this.dateStartAt, required this.dateEndAt, required this.thumbnailId, diff --git a/lib/features/sos/data/dto/sos_post_dto.g.dart b/lib/features/sos/data/dto/sos_post_dto.g.dart index c45be39..c8f6856 100644 --- a/lib/features/sos/data/dto/sos_post_dto.g.dart +++ b/lib/features/sos/data/dto/sos_post_dto.g.dart @@ -8,6 +8,7 @@ part of 'sos_post_dto.dart'; SosPostDto _$SosPostDtoFromJson(Map json) => SosPostDto( id: json['id'] as int, + author: AuthorDto.fromJson(json['author'] as Map), conditions: (json['conditions'] as List) .map((e) => SosConditionDto.fromJson(e as Map)) .toList(), @@ -16,7 +17,6 @@ SosPostDto _$SosPostDtoFromJson(Map json) => SosPostDto( .map((e) => MediaImageDto.fromJson(e as Map)) .toList(), title: json['title'] as String, - authorId: json['author_id'] as int, dateStartAt: json['date_start_at'] as String, dateEndAt: json['date_end_at'] as String, thumbnailId: json['thumbnail_id'] as int, diff --git a/lib/features/sos/repositories/sos_post_repository.dart b/lib/features/sos/repositories/sos_post_repository.dart index d289dcd..eb66b8c 100644 --- a/lib/features/sos/repositories/sos_post_repository.dart +++ b/lib/features/sos/repositories/sos_post_repository.dart @@ -1,8 +1,8 @@ import 'package:pets_next_door_flutter/core/utils/result.dart'; import 'package:pets_next_door_flutter/features/sos/data/dto/sos_pagination_request_dto.dart'; -import 'package:pets_next_door_flutter/features/sos/entities/sos_post_entity.dart'; +import 'package:pets_next_door_flutter/features/sos/data/dto/sos_pagination_response_dto.dart'; abstract interface class SosPostRepository { - Future>> getSosPosts( + Future> getSosPosts( SosPostPaginationRequestDto request); } diff --git a/lib/features/sos/repositories/sos_post_repository_impl.dart b/lib/features/sos/repositories/sos_post_repository_impl.dart index 728ed67..fadb01c 100644 --- a/lib/features/sos/repositories/sos_post_repository_impl.dart +++ b/lib/features/sos/repositories/sos_post_repository_impl.dart @@ -1,7 +1,7 @@ import 'package:pets_next_door_flutter/core/utils/result.dart'; import 'package:pets_next_door_flutter/features/sos/data/dto/sos_pagination_request_dto.dart'; +import 'package:pets_next_door_flutter/features/sos/data/dto/sos_pagination_response_dto.dart'; import 'package:pets_next_door_flutter/features/sos/data/remote/sos_post_remote_data_source.dart'; -import 'package:pets_next_door_flutter/features/sos/entities/sos_post_entity.dart'; import 'package:pets_next_door_flutter/features/sos/repositories/sos_post_repository.dart'; final class SosPostRepositoryImpl implements SosPostRepository { @@ -12,17 +12,13 @@ final class SosPostRepositoryImpl implements SosPostRepository { final SosPostRemoteDataSource _sosPostRemoteDataSource; @override - Future>> getSosPosts( + Future> getSosPosts( SosPostPaginationRequestDto request) async { try { final sosPostResponse = await _sosPostRemoteDataSource.getSosPosts(request); - return Result.success( - sosPostResponse.items - .map((postDto) => SosPostEntity.fromDto(postDto)) - .toList(), - ); + return Result.success(sosPostResponse); } on Exception catch (e) { return Result.failure(e); } diff --git a/lib/features/sos/usecases/get_sos_post_use_case.dart b/lib/features/sos/usecases/get_sos_post_use_case.dart index cea78d8..c2745f4 100644 --- a/lib/features/sos/usecases/get_sos_post_use_case.dart +++ b/lib/features/sos/usecases/get_sos_post_use_case.dart @@ -1,7 +1,7 @@ import 'package:pets_next_door_flutter/core/enums/sort_type_filter.enum.dart'; import 'package:pets_next_door_flutter/core/utils/result.dart'; import 'package:pets_next_door_flutter/features/sos/data/dto/sos_pagination_request_dto.dart'; -import 'package:pets_next_door_flutter/features/sos/entities/sos_post_entity.dart'; +import 'package:pets_next_door_flutter/features/sos/data/dto/sos_pagination_response_dto.dart'; import 'package:pets_next_door_flutter/features/sos/repositories/sos_post_repository.dart'; final class GetSosPostsUseCase { @@ -11,7 +11,7 @@ final class GetSosPostsUseCase { final SosPostRepository _sosPostRepository; - Future>> call({ + Future> call({ required int size, required int page, required SortTypeFilter sortType, diff --git a/lib/main_development.dart b/lib/main_development.dart index cb63183..c56cfb0 100644 --- a/lib/main_development.dart +++ b/lib/main_development.dart @@ -2,11 +2,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pets_next_door_flutter/app.dart'; import 'package:pets_next_door_flutter/app/env/flavors.dart'; +import 'package:pets_next_door_flutter/core/logger/provider_logger.dart'; Future main() async { Flavor.initialize(BuildType.development); await Flavor.instance.setup(); - runApp(const ProviderScope(child: App())); + runApp(ProviderScope(observers: [ProviderLogger()], child: App())); } diff --git a/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.dart b/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.dart index 27c0b98..63f0c4a 100644 --- a/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.dart +++ b/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.dart @@ -7,7 +7,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'breeds_paging_controller_provider.g.dart'; -const breedsPagingSize = 20; +const pagingSize = 20; @riverpod class BreedsPagingController extends _$BreedsPagingController { @@ -24,22 +24,20 @@ class BreedsPagingController extends _$BreedsPagingController { Future fetchPage(int pageKey) async { try { - final newBreeds = await getBreedsUseCase.call( + final newPage = await getBreedsUseCase.call( breedsPaginationRequest: new BreedsPaginationRequest( page: pageKey, - size: breedsPagingSize, + size: pagingSize, petType: ref.read(petStateProvider.notifier).state.petType!, ), ); - newBreeds.fold( - onSuccess: (breeds) { - final isLastPage = breeds.length < breedsPagingSize; - - if (isLastPage) { - state.appendLastPage(breeds); + newPage.fold( + onSuccess: (page) { + if (page.isLastPage) { + state.appendLastPage(page.items); } else { - state.appendPage(breeds, pageKey + 1); + state.appendPage(page.items, pageKey + 1); } }, onFailure: (e) => print('::: Fold Error ::: $e'), diff --git a/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.g.dart b/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.g.dart index 9cc79c3..a265200 100644 --- a/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.g.dart +++ b/lib/presentation/pages/pet/providers/breeds_paging_controller_provider.g.dart @@ -7,7 +7,7 @@ part of 'breeds_paging_controller_provider.dart'; // ************************************************************************** String _$breedsPagingControllerHash() => - r'f14f38dc38e0a32b977387e5ee90d9aaae12cd88'; + r'e3aed41da943c0dd2e40af94cc2ac47627812e9b'; /// See also [BreedsPagingController]. @ProviderFor(BreedsPagingController) diff --git a/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.dart b/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.dart index 1eb0e0c..efb7637 100644 --- a/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.dart +++ b/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.dart @@ -23,20 +23,21 @@ class SosPagingController extends _$SosPagingController { Future fetchPage(int pageKey) async { try { - final newPosts = await getSosPostUseCase.call( + final newPage = await getSosPostUseCase.call( size: _pagingSize, page: pageKey, sortType: ref.read(sosPostFilterProvider).sortFilter, ); - newPosts.fold( - onSuccess: (breeds) { - final isLastPage = breeds.length < _pagingSize; - - if (isLastPage) { - state.appendLastPage(breeds); + newPage.fold( + onSuccess: (page) { + final sosPostList = page.items + .map((sosPost) => SosPostEntity.fromDto(sosPost)) + .toList(); + if (page.isLastPage) { + state.appendLastPage(sosPostList); } else { - state.appendPage(breeds, pageKey + 1); + state.appendPage(sosPostList, pageKey + 1); } }, onFailure: (e) => print('::: Fold Error ::: $e'), diff --git a/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.g.dart b/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.g.dart index b8ad282..858beb9 100644 --- a/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.g.dart +++ b/lib/presentation/pages/sos/list/providers/sos_post_paging_controller_provider.g.dart @@ -7,7 +7,7 @@ part of 'sos_post_paging_controller_provider.dart'; // ************************************************************************** String _$sosPagingControllerHash() => - r'6548bf58e58b7f337411a2f5ef7cc8325c6c0738'; + r'd6261bcffde36ecb43f2ec1997d80a1bb0cc2575'; /// See also [SosPagingController]. @ProviderFor(SosPagingController)