diff --git a/lib/data/dtos/pokemon_dto.dart b/lib/data/dtos/pokemon_dto.dart index de8e84e..fcbf468 100644 --- a/lib/data/dtos/pokemon_dto.dart +++ b/lib/data/dtos/pokemon_dto.dart @@ -4,16 +4,12 @@ part 'pokemon_dto.g.dart'; @JsonSerializable(createToJson: false) class PokemonDto { - final List? results; - final int? count; - final String? next; - final String? previous; + final List? data; + final MetaDto? meta; const PokemonDto({ - this.results, - this.count, - this.next, - this.previous, + this.data, + this.meta, }); factory PokemonDto.fromJson(Map json) => _$PokemonDtoFromJson(json); @@ -21,46 +17,61 @@ class PokemonDto { @JsonSerializable(createToJson: false) class PokemonDataDto { + final String? id; final String? name; - final String? url; + final List? types; + final List? evolvesTo; + final List? abilities; + final PokemonImagesDto? images; const PokemonDataDto({ + this.id, this.name, - this.url, + this.types, + this.evolvesTo, + this.abilities, + this.images, }); factory PokemonDataDto.fromJson(Map json) => _$PokemonDataDtoFromJson(json); } @JsonSerializable(createToJson: false) -class PokemonDetailsDto { - final int? height; - final int? weight; - final List? abilities; - - const PokemonDetailsDto({ - this.height, - this.weight, - this.abilities, - }); - - factory PokemonDetailsDto.fromJson(Map json) => _$PokemonDetailsDtoFromJson(json); -} - -@JsonSerializable(createToJson: false) -class AbilityDto { - final AbilityDetailDto? ability; - - const AbilityDto({this.ability}); - - factory AbilityDto.fromJson(Map json) => _$AbilityDtoFromJson(json); -} - -@JsonSerializable(createToJson: false) -class AbilityDetailDto { +class PokemonAbilityDto { final String? name; + final String? text; + final String? type; - const AbilityDetailDto({this.name}); + const PokemonAbilityDto({this.name, this.text, this.type}); - factory AbilityDetailDto.fromJson(Map json) => _$AbilityDetailDtoFromJson(json); + factory PokemonAbilityDto.fromJson(Map json) => _$PokemonAbilityDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class PokemonImagesDto { + final String? large; + + const PokemonImagesDto({this.large}); + + factory PokemonImagesDto.fromJson(Map json) => _$PokemonImagesDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class MetaDto { + final PaginationDto? pagination; + + const MetaDto({this.pagination}); + + factory MetaDto.fromJson(Map json) => _$MetaDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class PaginationDto { + final int? current; + final int? next; + final int? last; + + const PaginationDto({this.current, this.next, this.last}); + + factory PaginationDto.fromJson(Map json) => _$PaginationDtoFromJson(json); } \ No newline at end of file diff --git a/lib/data/dtos/pokemon_dto.g.dart b/lib/data/dtos/pokemon_dto.g.dart index 7e7ce83..d5b37cf 100644 --- a/lib/data/dtos/pokemon_dto.g.dart +++ b/lib/data/dtos/pokemon_dto.g.dart @@ -7,36 +7,52 @@ part of 'pokemon_dto.dart'; // ************************************************************************** PokemonDto _$PokemonDtoFromJson(Map json) => PokemonDto( - results: (json['results'] as List?) + data: (json['data'] as List?) ?.map((e) => PokemonDataDto.fromJson(e as Map)) .toList(), - count: (json['count'] as num?)?.toInt(), - next: json['next'] as String?, - previous: json['previous'] as String?, + meta: json['meta'] == null + ? null + : MetaDto.fromJson(json['meta'] as Map), ); PokemonDataDto _$PokemonDataDtoFromJson(Map json) => PokemonDataDto( + id: json['id'] as String?, name: json['name'] as String?, - url: json['url'] as String?, - ); - -PokemonDetailsDto _$PokemonDetailsDtoFromJson(Map json) => - PokemonDetailsDto( - height: (json['height'] as num?)?.toInt(), - weight: (json['weight'] as num?)?.toInt(), - abilities: (json['abilities'] as List?) - ?.map((e) => AbilityDto.fromJson(e as Map)) + types: + (json['types'] as List?)?.map((e) => e as String).toList(), + evolvesTo: (json['evolvesTo'] as List?) + ?.map((e) => e as String) .toList(), - ); - -AbilityDto _$AbilityDtoFromJson(Map json) => AbilityDto( - ability: json['ability'] == null + abilities: (json['abilities'] as List?) + ?.map((e) => PokemonAbilityDto.fromJson(e as Map)) + .toList(), + images: json['images'] == null ? null - : AbilityDetailDto.fromJson(json['ability'] as Map), + : PokemonImagesDto.fromJson(json['images'] as Map), ); -AbilityDetailDto _$AbilityDetailDtoFromJson(Map json) => - AbilityDetailDto( +PokemonAbilityDto _$PokemonAbilityDtoFromJson(Map json) => + PokemonAbilityDto( name: json['name'] as String?, + text: json['text'] as String?, + type: json['type'] as String?, + ); + +PokemonImagesDto _$PokemonImagesDtoFromJson(Map json) => + PokemonImagesDto( + large: json['large'] as String?, + ); + +MetaDto _$MetaDtoFromJson(Map json) => MetaDto( + pagination: json['pagination'] == null + ? null + : PaginationDto.fromJson(json['pagination'] as Map), + ); + +PaginationDto _$PaginationDtoFromJson(Map json) => + PaginationDto( + current: (json['current'] as num?)?.toInt(), + next: (json['next'] as num?)?.toInt(), + last: (json['last'] as num?)?.toInt(), ); diff --git a/lib/data/mappers/pokemon_mapper.dart b/lib/data/mappers/pokemon_mapper.dart index 5b74a9b..22ddd16 100644 --- a/lib/data/mappers/pokemon_mapper.dart +++ b/lib/data/mappers/pokemon_mapper.dart @@ -1,34 +1,39 @@ import 'package:mobilki_lab1/data/dtos/pokemon_dto.dart'; import 'package:mobilki_lab1/domain/models/card.dart'; import 'package:mobilki_lab1/domain/models/home.dart'; +import 'package:flutter/material.dart'; const _imagePlaceholder = 'https://upload.wikimedia.org/wikipedia/en/archive/b/b1/20210811082420%21Portrait_placeholder.png'; extension PokemonDtoToModel on PokemonDto { HomeData toDomain() => HomeData( - data: results?.map((e) => e.toDomain()).toList(), - nextPage: next != null ? int.tryParse(next!.split('=')[1].split('&')[0]) : null, + data: data?.map((e) => e.toDomain()).toList(), + nextPage: meta?.pagination?.next, ); } extension PokemonDataDtoToModel on PokemonDataDto { - CardData toDomain() { - final id = url?.split('/')[6] ?? 'UNKNOWN'; - final imageUrl = 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/$id.png'; + CardData toDomain() => CardData( + name ?? 'UNKNOWN', + imageUrl: images?.large ?? _imagePlaceholder, + descriptionText: _makeDescriptionText(types, evolvesTo, abilities), + id: id, + ); - return CardData( - name ?? 'UNKNOWN', - imageUrl: imageUrl, - descriptionText: 'ID: $id', - id: id, - ); - } -} + String _makeDescriptionText( + List? types, + List? evolvesTo, + List? abilities, + ) { + final typeText = types != null && types.isNotEmpty ? 'Types: ${types.join(", ")}' : ''; + final evolvesToText = evolvesTo != null && evolvesTo.isNotEmpty ? 'Evolves To: ${evolvesTo.join(", ")}' : ''; + final abilitiesText = abilities != null && abilities.isNotEmpty ? 'Abilities: ${abilities.map((a) => a.name).join(", ")}' : ''; -extension PokemonDetailsDtoToModel on PokemonDetailsDto { - String toDescriptionText() { - final abilitiesText = abilities?.map((ability) => ability.ability?.name ?? 'UNKNOWN').join(', ') ?? 'UNKNOWN'; - return 'Height: ${height ?? 'UNKNOWN'} cm, Weight: ${weight ?? 'UNKNOWN'} kg, Abilities: $abilitiesText'; + return [ + typeText, + evolvesToText, + abilitiesText, + ].where((text) => text.isNotEmpty).join('\n'); } } \ No newline at end of file diff --git a/lib/data/repositories/pokemon_repository.dart b/lib/data/repositories/pokemon_repository.dart index 93a9daa..5fdf60c 100644 --- a/lib/data/repositories/pokemon_repository.dart +++ b/lib/data/repositories/pokemon_repository.dart @@ -5,33 +5,32 @@ import 'package:mobilki_lab1/data/repositories/api_interface.dart'; import 'package:mobilki_lab1/domain/models/home.dart'; import 'package:pretty_dio_logger/pretty_dio_logger.dart'; -class PokeRepository extends ApiInterface { +class PokemonRepository extends ApiInterface { static final Dio _dio = Dio() ..interceptors.add(PrettyDioLogger( requestHeader: true, requestBody: true, )); - static const String _baseUrl = 'https://pokeapi.co/api/v2'; + static const String _baseUrl = 'https://api.pokemontcg.io/v2'; @override Future loadData({ OnErrorCallback? onError, - String? q, // Добавляем параметр для поискового запроса + String? q, int page = 1, - int pageSize = 25, + int pageSize = 10, }) async { try { - final String url = '$_baseUrl/pokemon'; + final String url = '$_baseUrl/cards'; final Map queryParameters = { - 'offset': (page - 1) * pageSize, - 'limit': pageSize, + 'page': page, + 'pageSize': pageSize, }; - // Если есть поисковый запрос, добавляем его в параметры запроса - if (q != null && q.isNotEmpty) { - queryParameters['name'] = q; + if (q != null) { + queryParameters['q'] = 'name:$q*'; } final Response response = await _dio.get>( diff --git a/lib/main.dart b/lib/main.dart index 80d524a..68efc53 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -35,15 +35,15 @@ class MyApp extends StatelessWidget { colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), - home: RepositoryProvider( + home: RepositoryProvider( lazy: true, - create: (_) => PotterRepository(), + create: (_) => PokemonRepository(), child: BlocProvider( lazy: false, create: (context) => LikeBloc(), child: BlocProvider( lazy: false, - create: (context) => HomeBloc(context.read()), + create: (context) => HomeBloc(context.read()), child: const MyHomePage(title: 'Чубыкина Полина Павловна'), ), ), diff --git a/lib/presentation/home_page/bloc/bloc.dart b/lib/presentation/home_page/bloc/bloc.dart index 67f91da..83b6468 100644 --- a/lib/presentation/home_page/bloc/bloc.dart +++ b/lib/presentation/home_page/bloc/bloc.dart @@ -6,8 +6,8 @@ import 'package:mobilki_lab1/presentation/home_page/bloc/state.dart'; import '../../../data/repositories/pokemon_repository.dart'; class HomeBloc extends Bloc { - final PotterRepository repo; - // final PokeRepository repo; + // final PotterRepository repo; + final PokemonRepository repo; HomeBloc(this.repo) : super(const HomeState()) { on(_onLoadData); diff --git a/lib/presentation/home_page/home_page.dart b/lib/presentation/home_page/home_page.dart index bfa8895..bbaf75d 100644 --- a/lib/presentation/home_page/home_page.dart +++ b/lib/presentation/home_page/home_page.dart @@ -63,7 +63,7 @@ class BodyState extends State { } void _onNextPageListener() { - if (scrollController.offset > scrollController.position.maxScrollExtent) { + if (scrollController.offset >= scrollController.position.maxScrollExtent) { final bloc = context.read(); if (!bloc.state.isPaginationLoading) { bloc.add(HomeLoadDataEvent(