From 8e74f46465682f5249936a579700181557e7dc0f Mon Sep 17 00:00:00 2001 From: ohwhylin Date: Mon, 14 Oct 2024 21:25:43 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BA=D0=BE=D0=BB=20=D1=81?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BA=D0=B5=D0=BC=D0=BE=D0=BD=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/dtos/pokemon_dto.dart | 57 +++++++++++++++++++ lib/data/dtos/pokemon_dto.g.dart | 35 ++++++++++++ lib/data/mappers/pokemon_mapper.dart | 17 ++++++ lib/data/repositories/pokemon_repository.dart | 43 ++++++++++++++ lib/presentation/home_page/home_page.dart | 6 +- 5 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 lib/data/dtos/pokemon_dto.dart create mode 100644 lib/data/dtos/pokemon_dto.g.dart create mode 100644 lib/data/mappers/pokemon_mapper.dart create mode 100644 lib/data/repositories/pokemon_repository.dart diff --git a/lib/data/dtos/pokemon_dto.dart b/lib/data/dtos/pokemon_dto.dart new file mode 100644 index 0000000..feead9f --- /dev/null +++ b/lib/data/dtos/pokemon_dto.dart @@ -0,0 +1,57 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'pokemon_dto.g.dart'; + +@JsonSerializable(createToJson: false) +class PokemonDto { + final int id; + final String name; + final List types; + final PokemonSpritesDto sprites; + + const PokemonDto({ + required this.id, + required this.name, + required this.types, + required this.sprites, + }); + + factory PokemonDto.fromJson(Map json) => _$PokemonDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class PokemonTypeDto { + final int slot; + final PokemonTypeDetailDto type; + + const PokemonTypeDto({ + required this.slot, + required this.type, + }); + + factory PokemonTypeDto.fromJson(Map json) => _$PokemonTypeDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class PokemonTypeDetailDto { + final String name; + final String url; + + const PokemonTypeDetailDto({ + required this.name, + required this.url, + }); + + factory PokemonTypeDetailDto.fromJson(Map json) => _$PokemonTypeDetailDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class PokemonSpritesDto { + final String front_default; + + const PokemonSpritesDto({ + required this.front_default, + }); + + factory PokemonSpritesDto.fromJson(Map json) => _$PokemonSpritesDtoFromJson(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 new file mode 100644 index 0000000..849e083 --- /dev/null +++ b/lib/data/dtos/pokemon_dto.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pokemon_dto.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PokemonDto _$PokemonDtoFromJson(Map json) => PokemonDto( + id: (json['id'] as num).toInt(), + name: json['name'] as String, + types: (json['types'] as List) + .map((e) => PokemonTypeDto.fromJson(e as Map)) + .toList(), + sprites: + PokemonSpritesDto.fromJson(json['sprites'] as Map), + ); + +PokemonTypeDto _$PokemonTypeDtoFromJson(Map json) => + PokemonTypeDto( + slot: (json['slot'] as num).toInt(), + type: PokemonTypeDetailDto.fromJson(json['type'] as Map), + ); + +PokemonTypeDetailDto _$PokemonTypeDetailDtoFromJson( + Map json) => + PokemonTypeDetailDto( + name: json['name'] as String, + url: json['url'] as String, + ); + +PokemonSpritesDto _$PokemonSpritesDtoFromJson(Map json) => + PokemonSpritesDto( + front_default: json['front_default'] as String, + ); diff --git a/lib/data/mappers/pokemon_mapper.dart b/lib/data/mappers/pokemon_mapper.dart new file mode 100644 index 0000000..84fe142 --- /dev/null +++ b/lib/data/mappers/pokemon_mapper.dart @@ -0,0 +1,17 @@ +import 'package:mobilki_lab1/data/dtos/pokemon_dto.dart'; +import 'package:mobilki_lab1/domain/models/card.dart'; + +const _imagePlaceholder = + 'https://upload.wikimedia.org/wikipedia/en/archive/b/b1/20210811082420%21Portrait_placeholder.png'; + +extension PokemonDtoToModel on PokemonDto { + CardData toDomain() => CardData( + name, + imageUrl: sprites.front_default ?? _imagePlaceholder, + descriptionText: _makeDescriptionText(types), + ); + + String _makeDescriptionText(List types) { + return 'Types: ${types.map((type) => type.type.name).join(', ')}'; + } +} \ No newline at end of file diff --git a/lib/data/repositories/pokemon_repository.dart b/lib/data/repositories/pokemon_repository.dart new file mode 100644 index 0000000..844f6ab --- /dev/null +++ b/lib/data/repositories/pokemon_repository.dart @@ -0,0 +1,43 @@ +import 'package:dio/dio.dart'; +import 'package:mobilki_lab1/data/dtos/pokemon_dto.dart'; +import 'package:mobilki_lab1/data/mappers/pokemon_mapper.dart'; +import 'package:mobilki_lab1/data/repositories/api_interface.dart'; +import 'package:mobilki_lab1/domain/models/card.dart'; +import 'package:pretty_dio_logger/pretty_dio_logger.dart'; + +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'; + + @override + Future?> loadData({String? q, OnErrorCallback? onError}) async { + try { + final String url = '$_baseUrl/pokemon'; + + final Response response = await _dio.get>( + url, + queryParameters: q != null ? {'name': q} : null, + ); + + final List results = response.data['results'] as List; + final List data = []; + + for (final result in results) { + final String pokemonUrl = result['url'] as String; + final Response pokemonResponse = await _dio.get>(pokemonUrl); + final PokemonDto pokemonDto = PokemonDto.fromJson(pokemonResponse.data as Map); + data.add(pokemonDto.toDomain()); + } + + return data; + } on DioException catch (e) { + onError?.call(e.response?.statusMessage); + return null; + } + } +} \ No newline at end of file diff --git a/lib/presentation/home_page/home_page.dart b/lib/presentation/home_page/home_page.dart index d5f4cc5..9e9ce3d 100644 --- a/lib/presentation/home_page/home_page.dart +++ b/lib/presentation/home_page/home_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mobilki_lab1/data/repositories/potter_repository.dart'; +import 'package:mobilki_lab1/data/repositories/pokemon_repository.dart'; import 'package:mobilki_lab1/domain/models/card.dart'; import 'package:mobilki_lab1/presentation/details_page/details_page.dart'; @@ -33,7 +34,8 @@ class _BodyState extends State { final searchController = TextEditingController(); late Future?> data; - final repo = PotterRepository(); + final repo = PokemonRepository(); + //final repo = PotterRepository(); @override void initState() { @@ -97,7 +99,7 @@ class _BodyState extends State { WidgetsBinding.instance.addPostFrameCallback((_) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text( - '$title ${isLiked ? 'liked!' : 'disliked :('}', + '${isLiked ? 'Вам понравился $title!' : 'Вам больше не нравится $title :('}', style: Theme.of(context).textTheme.bodyLarge, ), backgroundColor: Colors.orangeAccent,