что что делается
This commit is contained in:
parent
b7013f4e2a
commit
0861ab4e91
@ -3,62 +3,67 @@ import 'package:json_annotation/json_annotation.dart';
|
||||
part 'pokemon_dto.g.dart';
|
||||
|
||||
@JsonSerializable(createToJson: false)
|
||||
class PokemonDto {
|
||||
final List<PokemonDataDto>? data;
|
||||
final MetaDto? meta;
|
||||
class PokemonListDto {
|
||||
final int? count;
|
||||
final String? next;
|
||||
final String? previous;
|
||||
final List<PokemonDto>? results;
|
||||
|
||||
const PokemonDto({
|
||||
this.data,
|
||||
this.meta,
|
||||
const PokemonListDto({
|
||||
this.count,
|
||||
this.next,
|
||||
this.previous,
|
||||
this.results,
|
||||
});
|
||||
|
||||
factory PokemonListDto.fromJson(Map<String, dynamic> json) => _$PokemonListDtoFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(createToJson: false)
|
||||
class PokemonDto {
|
||||
final String? name;
|
||||
final String? url;
|
||||
|
||||
const PokemonDto({this.name, this.url});
|
||||
|
||||
factory PokemonDto.fromJson(Map<String, dynamic> json) => _$PokemonDtoFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(createToJson: false)
|
||||
class PokemonDataDto {
|
||||
class PokemonDetailsDto {
|
||||
@JsonKey(fromJson: _idFromJson)
|
||||
final String? id;
|
||||
final String? type;
|
||||
final PokemonAttributesDataDto? attributes;
|
||||
|
||||
const PokemonDataDto({this.id, this.type, this.attributes});
|
||||
|
||||
factory PokemonDataDto.fromJson(Map<String, dynamic> json) => _$PokemonDataDtoFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(createToJson: false)
|
||||
class PokemonAttributesDataDto {
|
||||
final String? name;
|
||||
final String? height;
|
||||
final String? weight;
|
||||
final String? image;
|
||||
final int? height;
|
||||
final int? weight;
|
||||
final SpritesDto? sprites;
|
||||
|
||||
const PokemonAttributesDataDto({
|
||||
const PokemonDetailsDto({
|
||||
this.id,
|
||||
this.name,
|
||||
this.height,
|
||||
this.weight,
|
||||
this.image,
|
||||
this.sprites,
|
||||
});
|
||||
|
||||
factory PokemonAttributesDataDto.fromJson(Map<String, dynamic> json) => _$PokemonAttributesDataDtoFromJson(json);
|
||||
factory PokemonDetailsDto.fromJson(Map<String, dynamic> json) => _$PokemonDetailsDtoFromJson(json);
|
||||
|
||||
static String? _idFromJson(dynamic id) {
|
||||
if (id is int) {
|
||||
return id.toString();
|
||||
} else if (id is String) {
|
||||
return id;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsonSerializable(createToJson: false)
|
||||
class MetaDto {
|
||||
final PaginationDto? pagination;
|
||||
class SpritesDto {
|
||||
final String? frontDefault;
|
||||
|
||||
const MetaDto({this.pagination});
|
||||
const SpritesDto({this.frontDefault});
|
||||
|
||||
factory MetaDto.fromJson(Map<String, dynamic> 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<String, dynamic> json) => _$PaginationDtoFromJson(json);
|
||||
factory SpritesDto.fromJson(Map<String, dynamic> json) => _$SpritesDtoFromJson(json);
|
||||
}
|
@ -7,42 +7,32 @@ part of 'pokemon_dto.dart';
|
||||
// **************************************************************************
|
||||
|
||||
PokemonDto _$PokemonDtoFromJson(Map<String, dynamic> json) => PokemonDto(
|
||||
data: (json['data'] as List<dynamic>?)
|
||||
results: (json['results'] as List<dynamic>?)
|
||||
?.map((e) => PokemonDataDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
meta: json['meta'] == null
|
||||
? null
|
||||
: MetaDto.fromJson(json['meta'] as Map<String, dynamic>),
|
||||
count: (json['count'] as num?)?.toInt(),
|
||||
next: json['next'] as String?,
|
||||
previous: json['previous'] as String?,
|
||||
);
|
||||
|
||||
PokemonDataDto _$PokemonDataDtoFromJson(Map<String, dynamic> json) =>
|
||||
PokemonDataDto(
|
||||
id: json['id'] as String?,
|
||||
type: json['type'] as String?,
|
||||
name: json['name'] as String?,
|
||||
attributes: json['attributes'] == null
|
||||
? null
|
||||
: PokemonAttributesDataDto.fromJson(
|
||||
: PokemonAttributesDto.fromJson(
|
||||
json['attributes'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
PokemonAttributesDataDto _$PokemonAttributesDataDtoFromJson(
|
||||
PokemonAttributesDto _$PokemonAttributesDtoFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
PokemonAttributesDataDto(
|
||||
name: json['name'] as String?,
|
||||
height: json['height'] as String?,
|
||||
weight: json['weight'] as String?,
|
||||
PokemonAttributesDto(
|
||||
type: json['type'] as String?,
|
||||
height: (json['height'] as num?)?.toInt(),
|
||||
weight: (json['weight'] as num?)?.toInt(),
|
||||
abilities: (json['abilities'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList(),
|
||||
image: json['image'] as String?,
|
||||
);
|
||||
|
||||
MetaDto _$MetaDtoFromJson(Map<String, dynamic> json) => MetaDto(
|
||||
pagination: json['pagination'] == null
|
||||
? null
|
||||
: PaginationDto.fromJson(json['pagination'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
PaginationDto _$PaginationDtoFromJson(Map<String, dynamic> json) =>
|
||||
PaginationDto(
|
||||
current: (json['current'] as num?)?.toInt(),
|
||||
next: (json['next'] as num?)?.toInt(),
|
||||
last: (json['last'] as num?)?.toInt(),
|
||||
);
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
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';
|
||||
@ -5,22 +6,33 @@ import 'package:mobilki_lab1/domain/models/home.dart';
|
||||
const _imagePlaceholder =
|
||||
'https://upload.wikimedia.org/wikipedia/en/archive/b/b1/20210811082420%21Portrait_placeholder.png';
|
||||
|
||||
extension PokemonDtoToModel on PokemonDto {
|
||||
extension PokemonListDtoToModel on PokemonListDto {
|
||||
HomeData toDomain() => HomeData(
|
||||
data: data?.map((e) => e.toDomain()).toList(),
|
||||
nextPage: meta?.pagination?.next,
|
||||
data: results?.map((e) => e.toDomain()).toList(),
|
||||
nextPage: next != null ? int.tryParse(next!.split('?')[1].split('=')[1]) : null,
|
||||
);
|
||||
}
|
||||
|
||||
extension PokemonDataDtoToModel on PokemonDataDto {
|
||||
extension PokemonDtoToModel on PokemonDto {
|
||||
CardData toDomain() => CardData(
|
||||
attributes?.name ?? 'UNKNOWN',
|
||||
imageUrl: attributes?.image ?? _imagePlaceholder,
|
||||
descriptionText: _makeDescriptionText(attributes?.height, attributes?.weight),
|
||||
name ?? 'UNKNOWN',
|
||||
descriptionText: '', // Здесь можно добавить описание, если оно есть
|
||||
imageUrl: _imagePlaceholder, // Здесь нужно добавить логику для получения URL изображения
|
||||
id: null, // Здесь можно добавить логику для получения ID
|
||||
icon: Icons.catching_pokemon, // Используем стандартную иконку
|
||||
);
|
||||
}
|
||||
|
||||
extension PokemonDetailsDtoToModel on PokemonDetailsDto {
|
||||
CardData toDomain() => CardData(
|
||||
name ?? 'UNKNOWN',
|
||||
descriptionText: _makeDescriptionText(height, weight),
|
||||
imageUrl: sprites?.frontDefault ?? _imagePlaceholder,
|
||||
id: id,
|
||||
icon: Icons.catching_pokemon, // Используем стандартную иконку
|
||||
);
|
||||
|
||||
String _makeDescriptionText(String? height, String? weight) {
|
||||
String _makeDescriptionText(int? height, int? weight) {
|
||||
return height != null && weight != null
|
||||
? 'Height: $height, Weight: $weight'
|
||||
: height != null
|
||||
|
@ -2,12 +2,12 @@ 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:mobilki_lab1/domain/models/home.dart';
|
||||
import 'package:mobilki_lab1/presentation/home_page/bloc/events.dart';
|
||||
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
||||
|
||||
class PokemonRepository extends ApiInterface {
|
||||
import '../../domain/models/card.dart';
|
||||
|
||||
class PokeRepository extends ApiInterface {
|
||||
static final Dio _dio = Dio()
|
||||
..interceptors.add(PrettyDioLogger(
|
||||
requestHeader: true,
|
||||
@ -29,18 +29,61 @@ class PokemonRepository extends ApiInterface {
|
||||
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(
|
||||
url,
|
||||
queryParameters: {
|
||||
'filter[name_cont]': q,
|
||||
'page[number]': page,
|
||||
'page[size]': pageSize,
|
||||
'offset': (page - 1) * pageSize,
|
||||
'limit': pageSize,
|
||||
},
|
||||
);
|
||||
|
||||
final PokemonDto dto = PokemonDto.fromJson(response.data as Map<String, dynamic>);
|
||||
final HomeData data = dto.toDomain();
|
||||
return data;
|
||||
final PokemonListDto dto = PokemonListDto.fromJson(response.data as Map<String, dynamic>);
|
||||
final List<PokemonDto>? pokemonList = dto.results;
|
||||
|
||||
if (pokemonList != null) {
|
||||
final List<CardData> cards = await Future.wait(pokemonList.map((pokemon) async {
|
||||
final PokemonDetailsDto detailsDto = await loadPokemonDetails(pokemon.url!);
|
||||
return detailsDto.toDomain();
|
||||
}));
|
||||
|
||||
return HomeData(
|
||||
data: cards,
|
||||
nextPage: dto.next,
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
} on DioException catch (e) {
|
||||
onError?.call(e.error?.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<HomeData?> loadNextPage(String nextPageUrl, {OnErrorCallback? onError}) async {
|
||||
try {
|
||||
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(nextPageUrl);
|
||||
|
||||
final PokemonListDto dto = PokemonListDto.fromJson(response.data as Map<String, dynamic>);
|
||||
final List<PokemonDto>? pokemonList = dto.results;
|
||||
|
||||
if (pokemonList != null) {
|
||||
final List<CardData> cards = await Future.wait(pokemonList.map((pokemon) async {
|
||||
final PokemonDetailsDto detailsDto = await loadPokemonDetails(pokemon.url!);
|
||||
return detailsDto.toDomain();
|
||||
}));
|
||||
|
||||
return HomeData(
|
||||
data: cards,
|
||||
nextPage: dto.next,
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
} on DioException catch (e) {
|
||||
onError?.call(e.error?.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<PokemonDetailsDto> loadPokemonDetails(String url) async {
|
||||
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(url);
|
||||
return PokemonDetailsDto.fromJson(response.data as Map<String, dynamic>);
|
||||
}
|
||||
}
|
@ -35,15 +35,15 @@ class MyApp extends StatelessWidget {
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: RepositoryProvider<PokemonRepository>(
|
||||
home: RepositoryProvider<PokeRepository>(
|
||||
lazy: true,
|
||||
create: (_) => PokemonRepository(),
|
||||
create: (_) => PokeRepository(),
|
||||
child: BlocProvider<LikeBloc>(
|
||||
lazy: false,
|
||||
create: (context) => LikeBloc(),
|
||||
child: BlocProvider<HomeBloc>(
|
||||
lazy: false,
|
||||
create: (context) => HomeBloc(context.read<PokemonRepository>()),
|
||||
create: (context) => HomeBloc(context.read<PokeRepository>()),
|
||||
child: const MyHomePage(title: 'Чубыкина Полина Павловна'),
|
||||
),
|
||||
),
|
||||
|
@ -6,7 +6,7 @@ import 'package:mobilki_lab1/presentation/home_page/bloc/state.dart';
|
||||
|
||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
//final PotterRepository repo;
|
||||
final PokemonRepository repo;
|
||||
final PokeRepository repo;
|
||||
|
||||
HomeBloc(this.repo) : super(const HomeState()) {
|
||||
on<HomeLoadDataEvent>(_onLoadData);
|
||||
|
@ -63,7 +63,7 @@ class BodyState extends State<Body> {
|
||||
}
|
||||
|
||||
void _onNextPageListener() {
|
||||
if (scrollController.offset > scrollController.position.maxScrollExtent) {
|
||||
if (scrollController.offset >= scrollController.position.maxScrollExtent) {
|
||||
final bloc = context.read<HomeBloc>();
|
||||
if (!bloc.state.isPaginationLoading) {
|
||||
bloc.add(HomeLoadDataEvent(
|
||||
|
Loading…
Reference in New Issue
Block a user