эмулятор сломался...

This commit is contained in:
bulatova_karina 2024-11-18 13:20:06 +04:00
parent d1ca8bb4b0
commit 9ea4019641
5 changed files with 174 additions and 4 deletions

View File

@ -0,0 +1,42 @@
import 'package:json_annotation/json_annotation.dart';
part 'films_dto.g.dart';
@JsonSerializable(createToJson: false)
class FilmsDto {
final int total;
final List<FilmDataDto> items;
const FilmsDto({
required this.total,
required this.items,
});
factory FilmsDto.fromJson(Map<String, dynamic> json) => _$FilmsDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
class FilmDataDto {
final String nameRu;
final int year;
final List<GenreDto> genres;
final String posterUrl;
const FilmDataDto({
required this.nameRu,
required this.year,
required this.genres,
required this.posterUrl,
});
factory FilmDataDto.fromJson(Map<String, dynamic> json) => _$FilmDataDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
class GenreDto {
final String genre;
const GenreDto({required this.genre});
factory GenreDto.fromJson(Map<String, dynamic> json) => _$GenreDtoFromJson(json);
}

View File

@ -0,0 +1,31 @@
import 'package:project1/data/dtos/films_dto.dart';
import 'package:project1/domain/models/card.dart';
import 'package:project1/domain/models/home.dart';
const _imagePlaceholder =
'https://upload.wikimedia.org/wikipedia/en/archive/b/b1/20210811082420%21Portrait_placeholder.png';
extension FilmsDtoToModel on FilmsDto {
HomeData toDomain() => HomeData(
data: items.map((e) => e.toDomain()).toList(),
nextPage: null, // Если нужно добавить поддержку пагинации, нужно будет добавить соответствующие поля в HomeData
);
}
extension FilmDataDtoToModel on FilmDataDto {
CardData toDomain() => CardData(
nameRu,
imageUrl: posterUrl ?? _imagePlaceholder,
descriptionText: _makeDescriptionText(year, genres),
);
String _makeDescriptionText(int? year, List<GenreDto> genres) {
final yearText = year != null ? 'Год выхода: $year\n' : '';
final genresText = genres.isNotEmpty ? 'Жанр: ${genres.map((g) => g.genre).join(', ')}' : '';
return [yearText, genresText].where((s) => s.isNotEmpty).join();
}
}
extension GenreDtoToModel on GenreDto {
String toDomain() => genre;
}

View File

@ -0,0 +1,94 @@
import 'package:dio/dio.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'package:project1/data/dtos/films_dto.dart';
import 'package:project1/data/mappers/films_mapper.dart';
import 'package:project1/domain/models/home.dart';
typedef OnErrorCallback = void Function(String? error);
class FilmsRepository {
static final Dio _dio = Dio()
..interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
));
static const String _baseUrl = 'https://kinopoiskapiunofficial.tech';
static const String _apiKey = '67c830e4-b979-48ba-903d-a00c8f96fd4b';
Future<HomeData?> loadData({
OnErrorCallback? onError,
String? q,
int page = 1,
int pageSize = 7,
}) async {
try {
String url = '$_baseUrl/api/v2.2/films/premieres';
if (q != null && q.isNotEmpty) {
url = '$_baseUrl/api/v2.1/films/search-by-keyword';
}
final List<String> months = [
'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE',
'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER'
];
final List<FilmDataDto> allFilms = [];
for (final month in months) {
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(
url,
queryParameters: {
'year': DateTime.now().year,
'month': month,
'keyword': q,
'page': page,
'pageSize': pageSize,
},
options: Options(
headers: {
'X-API-KEY': _apiKey,
'Content-Type': 'application/json',
},
),
);
final FilmsDto dto = FilmsDto.fromJson(response.data as Map<String, dynamic>);
allFilms.addAll(dto.items);
}
final HomeData data = HomeData(
data: allFilms.map((e) => e.toDomain()).toList(),
nextPage: page + 1, // Увеличиваем номер страницы для следующего запроса
);
return data;
} on DioException catch (e) {
onError?.call(e.error?.toString());
return null;
}
}
Future<FilmDataDto?> getFilmById(int filmId) async {
try {
final String url = '$_baseUrl/api/v2.2/films/$filmId';
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(
url,
options: Options(
headers: {
'X-API-KEY': _apiKey,
'Content-Type': 'application/json',
},
),
);
final FilmDataDto dto = FilmDataDto.fromJson(response.data as Map<String, dynamic>);
return dto;
} on DioException catch (e) {
print('Request failed with error: ${e.error}');
return null;
}
}
}

View File

@ -8,6 +8,7 @@ import 'package:project1/presentation/like_bloc/like_bloc.dart';
import 'package:project1/presentation/locale_bloc/locale_bloc.dart';
import 'package:project1/presentation/locale_bloc/locale_state.dart';
import 'components/locale/l10n/app_locale.dart';
import 'data/repositories/films_repository.dart';
import 'data/repositories/potter_repository.dart';
void main() {
@ -34,15 +35,15 @@ class MyApp extends StatelessWidget {
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: RepositoryProvider<PotterRepository>(
home: RepositoryProvider<FilmsRepository>(
lazy: true,
create: (_) => PotterRepository(),
create: (_) => FilmsRepository(),
child: BlocProvider<LikeBloc>(
lazy: false,
create: (context) => LikeBloc(),
child: BlocProvider<HomeBloc>(
lazy: false,
create: (context) => HomeBloc(context.read<PotterRepository>()),
create: (context) => HomeBloc(context.read<FilmsRepository>()),
child: const MyHomePage(title: 'Булатова Карина Раилевна'),
),
),

View File

@ -3,8 +3,10 @@ import 'package:project1/data/repositories/potter_repository.dart';
import 'package:project1/presentation/home_page/bloc/events.dart';
import 'package:project1/presentation/home_page/bloc/state.dart';
import '../../../data/repositories/films_repository.dart';
class HomeBloc extends Bloc<HomeEvent, HomeState> {
final PotterRepository repo;
final FilmsRepository repo;
HomeBloc(this.repo) : super(const HomeState()) {
on<HomeLoadDataEvent>(_onLoadData);