CourseWork
This commit is contained in:
parent
b6ad2dee53
commit
abbb4d65ef
@ -2,6 +2,7 @@
|
|||||||
"@@locale": "en",
|
"@@locale": "en",
|
||||||
|
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
|
"title": "Sekiro bosses",
|
||||||
"liked": "liked!",
|
"liked": "liked!",
|
||||||
"disliked": "disliked",
|
"disliked": "disliked",
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"@@locale": "ru",
|
"@@locale": "ru",
|
||||||
|
|
||||||
"search": "Поиск",
|
"search": "Поиск",
|
||||||
|
"title": "Боссы Sekiro",
|
||||||
"liked": "понравился!",
|
"liked": "понравился!",
|
||||||
"disliked": "разонравился",
|
"disliked": "разонравился",
|
||||||
|
|
||||||
|
@ -101,6 +101,12 @@ abstract class AppLocale {
|
|||||||
/// **'Поиск'**
|
/// **'Поиск'**
|
||||||
String get search;
|
String get search;
|
||||||
|
|
||||||
|
/// No description provided for @title.
|
||||||
|
///
|
||||||
|
/// In ru, this message translates to:
|
||||||
|
/// **'Боссы Sekiro'**
|
||||||
|
String get title;
|
||||||
|
|
||||||
/// No description provided for @liked.
|
/// No description provided for @liked.
|
||||||
///
|
///
|
||||||
/// In ru, this message translates to:
|
/// In ru, this message translates to:
|
||||||
|
@ -9,6 +9,9 @@ class AppLocaleEn extends AppLocale {
|
|||||||
@override
|
@override
|
||||||
String get search => 'Search';
|
String get search => 'Search';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get title => 'Sekiro bosses';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get liked => 'liked!';
|
String get liked => 'liked!';
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@ class AppLocaleRu extends AppLocale {
|
|||||||
@override
|
@override
|
||||||
String get search => 'Поиск';
|
String get search => 'Поиск';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get title => 'Боссы Sekiro';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get liked => 'понравился!';
|
String get liked => 'понравился!';
|
||||||
|
|
||||||
|
@ -8,17 +8,6 @@ class BossesDto {
|
|||||||
factory BossesDto.fromJson(Map<String, dynamic> json) => _$BossesDtoFromJson(json);
|
factory BossesDto.fromJson(Map<String, dynamic> json) => _$BossesDtoFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonSerializable(createToJson: false)
|
|
||||||
class BossesDataDto {
|
|
||||||
final String? id;
|
|
||||||
final String? type;
|
|
||||||
final BossAttributesDataDto? attributes;
|
|
||||||
|
|
||||||
const BossesDataDto({this.id, this.type, this.attributes});
|
|
||||||
|
|
||||||
factory BossesDataDto.fromJson(Map<String, dynamic> json) => _$BossesDataDtoFromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonSerializable(createToJson: false)
|
@JsonSerializable(createToJson: false)
|
||||||
class BossAttributesDataDto {
|
class BossAttributesDataDto {
|
||||||
final String? id;
|
final String? id;
|
||||||
|
@ -13,16 +13,6 @@ BossesDto _$BossesDtoFromJson(Map<String, dynamic> json) => BossesDto(
|
|||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
BossesDataDto _$BossesDataDtoFromJson(Map<String, dynamic> json) =>
|
|
||||||
BossesDataDto(
|
|
||||||
id: json['id'] as String?,
|
|
||||||
type: json['type'] as String?,
|
|
||||||
attributes: json['attributes'] == null
|
|
||||||
? null
|
|
||||||
: BossAttributesDataDto.fromJson(
|
|
||||||
json['attributes'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
BossAttributesDataDto _$BossAttributesDataDtoFromJson(
|
BossAttributesDataDto _$BossAttributesDataDtoFromJson(
|
||||||
Map<String, dynamic> json) =>
|
Map<String, dynamic> json) =>
|
||||||
BossAttributesDataDto(
|
BossAttributesDataDto(
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'package:pmu_labs/data/dtos/bosses_dto.dart';
|
import 'package:pmu_labs/data/dtos/bosses_dto.dart';
|
||||||
import 'package:pmu_labs/domain/models/card.dart';
|
import 'package:pmu_labs/domain/models/card_data.dart';
|
||||||
|
|
||||||
|
import '../../domain/models/home_data.dart';
|
||||||
|
|
||||||
extension BossDataDtoToModel on BossAttributesDataDto {
|
extension BossDataDtoToModel on BossAttributesDataDto {
|
||||||
CardData toDomain() => CardData(
|
CardData toDomain() => CardData(
|
||||||
@ -10,3 +12,8 @@ extension BossDataDtoToModel on BossAttributesDataDto {
|
|||||||
imageUrl: imageUrl,
|
imageUrl: imageUrl,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
extension BossDtoToModel on BossesDto {
|
||||||
|
HomeData toDomain() => HomeData(
|
||||||
|
data: data?.map((e) => e.toDomain()).toList(),
|
||||||
|
);
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:pmu_labs/domain/models/card.dart';
|
import 'package:pmu_labs/domain/models/home_data.dart';
|
||||||
|
|
||||||
typedef OnErrorCallback = void Function(String? error);
|
typedef OnErrorCallback = void Function(String? error);
|
||||||
|
|
||||||
abstract class ApiInterface {
|
abstract class ApiInterface {
|
||||||
Future<List<CardData>?> loadData();
|
Future<HomeData?> loadData();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:pmu_labs/data/dtos/bosses_dto.dart';
|
import 'package:pmu_labs/data/dtos/bosses_dto.dart';
|
||||||
import 'package:pmu_labs/data/mappers/bosses_mapper.dart';
|
import 'package:pmu_labs/data/mappers/bosses_mapper.dart';
|
||||||
import 'package:pmu_labs/domain/models/card.dart';
|
import 'package:pmu_labs/domain/models/card_data.dart';
|
||||||
|
import 'package:pmu_labs/domain/models/home_data.dart';
|
||||||
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
||||||
import 'package:html/parser.dart' as html;
|
import 'package:html/parser.dart' as html;
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ class BossesRepository extends ApiInterface {
|
|||||||
static const String _baseUrl = 'https://sekiro.fandom.com/ru/api.php';
|
static const String _baseUrl = 'https://sekiro.fandom.com/ru/api.php';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<CardData>?> loadData({
|
Future<HomeData?> loadData({
|
||||||
OnErrorCallback? onError,
|
OnErrorCallback? onError,
|
||||||
String? q,
|
String? q,
|
||||||
}) async {
|
}) async {
|
||||||
@ -64,7 +65,7 @@ class BossesRepository extends ApiInterface {
|
|||||||
url =
|
url =
|
||||||
'$_baseUrl?action=query&generator=categorymembers&gcmtitle=Category:Боссы&gcmnamespace=0&gcmlimit=50&prop=pageimages&piprop=original&format=json&origin=*';
|
'$_baseUrl?action=query&generator=categorymembers&gcmtitle=Category:Боссы&gcmnamespace=0&gcmlimit=50&prop=pageimages&piprop=original&format=json&origin=*';
|
||||||
}
|
}
|
||||||
final List<CardData>? data;
|
final HomeData? data;
|
||||||
BossesDto dto;
|
BossesDto dto;
|
||||||
|
|
||||||
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(url);
|
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(url);
|
||||||
@ -74,15 +75,21 @@ class BossesRepository extends ApiInterface {
|
|||||||
|
|
||||||
List<(String, String)> descs = [];
|
List<(String, String)> descs = [];
|
||||||
|
|
||||||
for (var boss in pages.values) {
|
|
||||||
final Response<dynamic> respDesc = await _dio.get<Map<dynamic, dynamic>>(
|
final Response<dynamic> respDesc = await _dio.get<Map<dynamic, dynamic>>(
|
||||||
'https://sekiro.fandom.com/ru/api.php?action=parse&page=${boss['title']}&prop=text§ion=1&format=json');
|
'https://sekiro.fandom.com/ru/api.php?action=query&generator=categorymembers&gcmtitle=Category:Боссы&gcmnamespace=0&gcmlimit=50&prop=revisions&rvprop=content&format=json&origin=*');
|
||||||
final htmlContent = respDesc.data['parse']['text']['*'];
|
|
||||||
var doc = html.parse(htmlContent);
|
for (var boss in pages.values) {
|
||||||
final String text = doc.body?.text as String;
|
final htmlContent = respDesc.data['query']['pages']['${boss['pageid']}']['revisions'][0]['*'];
|
||||||
descs.add((boss['title'], text));
|
var document = html.parse(htmlContent);
|
||||||
|
String text = document.body?.text ?? '';
|
||||||
|
text = text.split("==Галерея==")[0];
|
||||||
|
text = text.split("== Галерея ==")[0];
|
||||||
|
text = text.replaceAll(RegExp(r'\{[^\}]*\}'), '');
|
||||||
|
descs.add((boss['title'], text.trim()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final transData = transformJsonToBossesDtoFormat(pages, descs);
|
final transData = transformJsonToBossesDtoFormat(pages, descs);
|
||||||
dto = BossesDto.fromJson(transData);
|
dto = BossesDto.fromJson(transData);
|
||||||
if (q != null && q != "") {
|
if (q != null && q != "") {
|
||||||
@ -92,10 +99,7 @@ class BossesRepository extends ApiInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
data = dto.data?.map((e) => e.toDomain()).toList();
|
data = dto.toDomain();
|
||||||
//for(int i = 0; i<data!.length;i++){
|
|
||||||
//data[i].id = i.toString();
|
|
||||||
//}
|
|
||||||
return data;
|
return data;
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
onError?.call(e.error?.toString());
|
onError?.call(e.error?.toString());
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
import 'package:pmu_labs/data/repositories/api_interface.dart';
|
|
||||||
|
|
||||||
import '../../domain/models/card.dart';
|
|
||||||
|
|
||||||
class MockRepository extends ApiInterface {
|
|
||||||
@override
|
|
||||||
Future<List<CardData>?> loadData() async {
|
|
||||||
return [
|
|
||||||
CardData('Warhammer 40000:Space Marine 2',
|
|
||||||
descriptionText: 'Читать новость',
|
|
||||||
id: '1',
|
|
||||||
imageUrl:
|
|
||||||
'https://news.xbox.com/en-us/wp-content/uploads/sites/2/2021/12/SpaceMarine2_TemporaryArtwork_4K_logo.jpg',
|
|
||||||
gameDesc: 'Обретите сверхчеловеческую мощь космодесантника. Пустите в ход смертоносные навыки и разрушительное оружие, чтобы ' +
|
|
||||||
' истребить безжалостных тиранидов. Защитите Империум в ярких одиночных боях или многопользовательских режимах с ' +
|
|
||||||
'видом от третьего лица. В продолжении экшена 2011 года Space Marine вам предстоит сразиться с врагами человечества и' +
|
|
||||||
' вновь доказать ему свою преданность в роли лейтенанта Деметрия Тита, который вернулся в ряды Ультрамаринов. Дайте отпор ' +
|
|
||||||
'ужасам Галактики в эпических боях сразу на нескольких планетах. Раскройте мрачные секреты и отбросьте тень вечной ночи.'),
|
|
||||||
CardData('Risk of rain 2',
|
|
||||||
descriptionText: 'Читать новость',
|
|
||||||
id: '2',
|
|
||||||
imageUrl: 'https://digiseller.mycdn.ink/preview/990130/p1_3675944_49000546.jpg',
|
|
||||||
gameDesc: 'Вас ожидает более тысячи созданных вручную областей. Каждая из них кишит смертельно опасными монстрами и огромными боссами,' +
|
|
||||||
' стремящимися оборвать вашу жизнь. Дойдите до финального босса и выберитесь с планеты, либо продолжите своё приключение,' +
|
|
||||||
' чтобы выяснить, как долго вы сможете продержаться. Благодаря умной системе повышения уровня ваша сила и сила ваших врагов будет постоянно расти во время игры.'),
|
|
||||||
CardData('Yakuza 0',
|
|
||||||
descriptionText: 'Читать новость',
|
|
||||||
id: '3',
|
|
||||||
imageUrl:
|
|
||||||
'https://avatars.mds.yandex.net/get-marketpic/1588570/pic3d2a9b85ee47202578aac1bb1f97fcc0/orig',
|
|
||||||
gameDesc: 'В декабре 1988 года двое героев из мира якудза — Кадзума Кирю (молодой якудза низшего ранга из региона Канто)' +
|
|
||||||
' и Горо Мадзима (менеджер кабаре, бывший якудза из региона Кансай, изгнанный из клана, но желающий во что бы' +
|
|
||||||
' то ни стало вернуться) — оказываются втянуты в борьбу за небольшой «пустой участок» земли в центре района Камуротё,' +
|
|
||||||
' который притягивает преступные силы со всей Японии.Сюжетная линия игры разбита на 2 линии, которые косвенно пересекаются по ходу истории'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
6
lib/domain/models/home_data.dart
Normal file
6
lib/domain/models/home_data.dart
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import 'package:pmu_labs/domain/models/card_data.dart';
|
||||||
|
|
||||||
|
class HomeData {
|
||||||
|
final List<CardData>? data;
|
||||||
|
HomeData({this.data});
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pmu_labs/domain/models/card.dart';
|
import 'package:pmu_labs/domain/models/card_data.dart';
|
||||||
|
|
||||||
class DetailsPage extends StatelessWidget {
|
class DetailsPage extends StatelessWidget {
|
||||||
final CardData data;
|
final CardData data;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:pmu_labs/domain/models/card.dart';
|
import 'package:pmu_labs/domain/models/card_data.dart';
|
||||||
|
import 'package:pmu_labs/domain/models/home_data.dart';
|
||||||
|
|
||||||
class HomeState extends Equatable {
|
class HomeState extends Equatable {
|
||||||
final List<CardData>? data;
|
final HomeData? data;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final String? error;
|
final String? error;
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ class HomeState extends Equatable {
|
|||||||
});
|
});
|
||||||
|
|
||||||
HomeState copyWith({
|
HomeState copyWith({
|
||||||
List<CardData>? data,
|
HomeData? data,
|
||||||
bool? isLoading,
|
bool? isLoading,
|
||||||
String? error,
|
String? error,
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -14,7 +14,7 @@ import 'package:pmu_labs/presentation/locale_bloc/locale_events.dart';
|
|||||||
import 'package:pmu_labs/presentation/locale_bloc/locale_state.dart';
|
import 'package:pmu_labs/presentation/locale_bloc/locale_state.dart';
|
||||||
|
|
||||||
import '../../components/utils/debounce.dart';
|
import '../../components/utils/debounce.dart';
|
||||||
import '../../domain/models/card.dart';
|
import '../../domain/models/card_data.dart';
|
||||||
import '../like_bloc/like_event.dart';
|
import '../like_bloc/like_event.dart';
|
||||||
|
|
||||||
part 'card.dart';
|
part 'card.dart';
|
||||||
@ -36,7 +36,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: _color,
|
backgroundColor: _color,
|
||||||
title: Text(widget.title),
|
title: Text(context.locale.title),
|
||||||
),
|
),
|
||||||
body: const Body(),
|
body: const Body(),
|
||||||
);
|
);
|
||||||
@ -140,9 +140,9 @@ class _BodyState extends State<Body> {
|
|||||||
onRefresh: _onRefresh,
|
onRefresh: _onRefresh,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
itemCount: state.data?.length ?? 0,
|
itemCount: state.data?.data?.length ?? 0,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final data = state.data?[index];
|
final data = state.data?.data?[index];
|
||||||
return data != null
|
return data != null
|
||||||
? _Card.fromData(
|
? _Card.fromData(
|
||||||
data,
|
data,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user