diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
index db77bb4..b3fdbd0 100644
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
index 17987b7..b6f2385 100644
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 09d4391..d4400a0 100644
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index d5f1c8d..5830471 100644
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 4d6372e..6676853 100644
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/assets/sekiroicon.jpg b/assets/sekiroicon.jpg
new file mode 100644
index 0000000..e5f4083
Binary files /dev/null and b/assets/sekiroicon.jpg differ
diff --git a/assets/sekiroicon.png b/assets/sekiroicon.png
deleted file mode 100644
index d6d3625..0000000
Binary files a/assets/sekiroicon.png and /dev/null differ
diff --git a/assets/svg/ru.svg b/assets/svg/ru.svg
new file mode 100644
index 0000000..9c0cc49
--- /dev/null
+++ b/assets/svg/ru.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/svg/uk.svg b/assets/svg/uk.svg
new file mode 100644
index 0000000..f87fdb0
--- /dev/null
+++ b/assets/svg/uk.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/l10n.yaml b/l10n.yaml
new file mode 100644
index 0000000..d26d702
--- /dev/null
+++ b/l10n.yaml
@@ -0,0 +1,6 @@
+arb-dir: l10n
+template-arb-file: app_ru.arb
+output-localization-file: app_locale.dart
+output-dir: lib/components/locale/l10n
+output-class: AppLocale
+synthetic-package: false
\ No newline at end of file
diff --git a/l10n/app_en.arb b/l10n/app_en.arb
new file mode 100644
index 0000000..acf0a55
--- /dev/null
+++ b/l10n/app_en.arb
@@ -0,0 +1,9 @@
+{
+ "@@locale": "en",
+
+ "search": "Search",
+ "liked": "liked!",
+ "disliked": "disliked",
+
+ "arbEnding": "Чтобы не забыть про отсутствие запятой :)"
+}
\ No newline at end of file
diff --git a/l10n/app_ru.arb b/l10n/app_ru.arb
new file mode 100644
index 0000000..b823375
--- /dev/null
+++ b/l10n/app_ru.arb
@@ -0,0 +1,9 @@
+{
+ "@@locale": "ru",
+
+ "search": "Поиск",
+ "liked": "понравился!",
+ "disliked": "разонравился",
+
+ "arbEnding": "Чтобы не забыть про отсутствие запятой :)"
+}
\ No newline at end of file
diff --git a/lib/components/extensions/context_x.dart b/lib/components/extensions/context_x.dart
new file mode 100644
index 0000000..2d80393
--- /dev/null
+++ b/lib/components/extensions/context_x.dart
@@ -0,0 +1,6 @@
+import 'package:flutter/cupertino.dart';
+import 'package:pmu_labs/components/locale/l10n/app_locale.dart';
+
+extension LocalContextX on BuildContext{
+ AppLocale get locale => AppLocale.of(this)!;
+}
\ No newline at end of file
diff --git a/lib/components/locale/l10n/app_locale.dart b/lib/components/locale/l10n/app_locale.dart
new file mode 100644
index 0000000..1a23eb7
--- /dev/null
+++ b/lib/components/locale/l10n/app_locale.dart
@@ -0,0 +1,153 @@
+import 'dart:async';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_localizations/flutter_localizations.dart';
+import 'package:intl/intl.dart' as intl;
+
+import 'app_locale_en.dart';
+import 'app_locale_ru.dart';
+
+// ignore_for_file: type=lint
+
+/// Callers can lookup localized strings with an instance of AppLocale
+/// returned by `AppLocale.of(context)`.
+///
+/// Applications need to include `AppLocale.delegate()` in their app's
+/// `localizationDelegates` list, and the locales they support in the app's
+/// `supportedLocales` list. For example:
+///
+/// ```dart
+/// import 'l10n/app_locale.dart';
+///
+/// return MaterialApp(
+/// localizationsDelegates: AppLocale.localizationsDelegates,
+/// supportedLocales: AppLocale.supportedLocales,
+/// home: MyApplicationHome(),
+/// );
+/// ```
+///
+/// ## Update pubspec.yaml
+///
+/// Please make sure to update your pubspec.yaml to include the following
+/// packages:
+///
+/// ```yaml
+/// dependencies:
+/// # Internationalization support.
+/// flutter_localizations:
+/// sdk: flutter
+/// intl: any # Use the pinned version from flutter_localizations
+///
+/// # Rest of dependencies
+/// ```
+///
+/// ## iOS Applications
+///
+/// iOS applications define key application metadata, including supported
+/// locales, in an Info.plist file that is built into the application bundle.
+/// To configure the locales supported by your app, you’ll need to edit this
+/// file.
+///
+/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
+/// Then, in the Project Navigator, open the Info.plist file under the Runner
+/// project’s Runner folder.
+///
+/// Next, select the Information Property List item, select Add Item from the
+/// Editor menu, then select Localizations from the pop-up menu.
+///
+/// Select and expand the newly-created Localizations item then, for each
+/// locale your application supports, add a new item and select the locale
+/// you wish to add from the pop-up menu in the Value field. This list should
+/// be consistent with the languages listed in the AppLocale.supportedLocales
+/// property.
+abstract class AppLocale {
+ AppLocale(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
+
+ final String localeName;
+
+ static AppLocale? of(BuildContext context) {
+ return Localizations.of(context, AppLocale);
+ }
+
+ static const LocalizationsDelegate delegate = _AppLocaleDelegate();
+
+ /// A list of this localizations delegate along with the default localizations
+ /// delegates.
+ ///
+ /// Returns a list of localizations delegates containing this delegate along with
+ /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
+ /// and GlobalWidgetsLocalizations.delegate.
+ ///
+ /// Additional delegates can be added by appending to this list in
+ /// MaterialApp. This list does not have to be used at all if a custom list
+ /// of delegates is preferred or required.
+ static const List> localizationsDelegates = >[
+ delegate,
+ GlobalMaterialLocalizations.delegate,
+ GlobalCupertinoLocalizations.delegate,
+ GlobalWidgetsLocalizations.delegate,
+ ];
+
+ /// A list of this localizations delegate's supported locales.
+ static const List supportedLocales = [
+ Locale('en'),
+ Locale('ru')
+ ];
+
+ /// No description provided for @search.
+ ///
+ /// In ru, this message translates to:
+ /// **'Поиск'**
+ String get search;
+
+ /// No description provided for @liked.
+ ///
+ /// In ru, this message translates to:
+ /// **'понравился!'**
+ String get liked;
+
+ /// No description provided for @disliked.
+ ///
+ /// In ru, this message translates to:
+ /// **'разонравился'**
+ String get disliked;
+
+ /// No description provided for @arbEnding.
+ ///
+ /// In ru, this message translates to:
+ /// **'Чтобы не забыть про отсутствие запятой :)'**
+ String get arbEnding;
+}
+
+class _AppLocaleDelegate extends LocalizationsDelegate {
+ const _AppLocaleDelegate();
+
+ @override
+ Future load(Locale locale) {
+ return SynchronousFuture(lookupAppLocale(locale));
+ }
+
+ @override
+ bool isSupported(Locale locale) => ['en', 'ru'].contains(locale.languageCode);
+
+ @override
+ bool shouldReload(_AppLocaleDelegate old) => false;
+}
+
+AppLocale lookupAppLocale(Locale locale) {
+
+
+ // Lookup logic when only language code is specified.
+ switch (locale.languageCode) {
+ case 'en': return AppLocaleEn();
+ case 'ru': return AppLocaleRu();
+ }
+
+ throw FlutterError(
+ 'AppLocale.delegate failed to load unsupported locale "$locale". This is likely '
+ 'an issue with the localizations generation tool. Please file an issue '
+ 'on GitHub with a reproducible sample app and the gen-l10n configuration '
+ 'that was used.'
+ );
+}
diff --git a/lib/components/locale/l10n/app_locale_en.dart b/lib/components/locale/l10n/app_locale_en.dart
new file mode 100644
index 0000000..8f9dc19
--- /dev/null
+++ b/lib/components/locale/l10n/app_locale_en.dart
@@ -0,0 +1,20 @@
+import 'app_locale.dart';
+
+// ignore_for_file: type=lint
+
+/// The translations for English (`en`).
+class AppLocaleEn extends AppLocale {
+ AppLocaleEn([String locale = 'en']) : super(locale);
+
+ @override
+ String get search => 'Search';
+
+ @override
+ String get liked => 'liked!';
+
+ @override
+ String get disliked => 'disliked';
+
+ @override
+ String get arbEnding => 'Чтобы не забыть про отсутствие запятой :)';
+}
diff --git a/lib/components/locale/l10n/app_locale_ru.dart b/lib/components/locale/l10n/app_locale_ru.dart
new file mode 100644
index 0000000..4685a92
--- /dev/null
+++ b/lib/components/locale/l10n/app_locale_ru.dart
@@ -0,0 +1,20 @@
+import 'app_locale.dart';
+
+// ignore_for_file: type=lint
+
+/// The translations for Russian (`ru`).
+class AppLocaleRu extends AppLocale {
+ AppLocaleRu([String locale = 'ru']) : super(locale);
+
+ @override
+ String get search => 'Поиск';
+
+ @override
+ String get liked => 'понравился!';
+
+ @override
+ String get disliked => 'разонравился';
+
+ @override
+ String get arbEnding => 'Чтобы не забыть про отсутствие запятой :)';
+}
diff --git a/lib/components/resources.g.dart b/lib/components/resources.g.dart
new file mode 100644
index 0000000..5270ada
--- /dev/null
+++ b/lib/components/resources.g.dart
@@ -0,0 +1,12 @@
+/// Generate by [flutter_assets_generator](https://github.com/goodswifter/flutter_assets_generator) library.
+///
+/// PLEASE DO NOT EDIT MANUALLY.
+class R {
+ const R._();
+
+ /// 
+ static const String assetsSvgRuSvg = 'assets/svg/ru.svg';
+
+ /// 
+ static const String assetsSvgUkSvg = 'assets/svg/uk.svg';
+}
diff --git a/lib/data/dtos/bosses_dto.dart b/lib/data/dtos/bosses_dto.dart
index e3851ef..ea868d0 100644
--- a/lib/data/dtos/bosses_dto.dart
+++ b/lib/data/dtos/bosses_dto.dart
@@ -2,14 +2,14 @@ import 'package:json_annotation/json_annotation.dart';
part 'bosses_dto.g.dart';
@JsonSerializable(createToJson: false)
-class BossesDto{
+class BossesDto {
final List? data;
const BossesDto({this.data});
factory BossesDto.fromJson(Map json) => _$BossesDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
-class BossesDataDto{
+class BossesDataDto {
final String? id;
final String? type;
final BossAttributesDataDto? attributes;
@@ -20,12 +20,14 @@ class BossesDataDto{
}
@JsonSerializable(createToJson: false)
-class BossAttributesDataDto{
+class BossAttributesDataDto {
+ final String? id;
final String? title;
final String? imageUrl;
final String? description;
- const BossAttributesDataDto({this.title, this.imageUrl, this.description});
+ const BossAttributesDataDto({this.id,this.title, this.imageUrl, this.description});
- factory BossAttributesDataDto.fromJson(Map json) => _$BossAttributesDataDtoFromJson(json);
-}
\ No newline at end of file
+ factory BossAttributesDataDto.fromJson(Map json) =>
+ _$BossAttributesDataDtoFromJson(json);
+}
diff --git a/lib/data/dtos/bosses_dto.g.dart b/lib/data/dtos/bosses_dto.g.dart
index f1c4b55..a85586c 100644
--- a/lib/data/dtos/bosses_dto.g.dart
+++ b/lib/data/dtos/bosses_dto.g.dart
@@ -26,6 +26,7 @@ BossesDataDto _$BossesDataDtoFromJson(Map json) =>
BossAttributesDataDto _$BossAttributesDataDtoFromJson(
Map json) =>
BossAttributesDataDto(
+ id: json['id'] as String?,
title: json['title'] as String?,
imageUrl: json['imageUrl'] as String?,
description: json['description'] as String?,
diff --git a/lib/data/mappers/bosses_mapper.dart b/lib/data/mappers/bosses_mapper.dart
index 531f90e..aff57e8 100644
--- a/lib/data/mappers/bosses_mapper.dart
+++ b/lib/data/mappers/bosses_mapper.dart
@@ -4,8 +4,9 @@ import 'package:pmu_labs/domain/models/card.dart';
extension BossDataDtoToModel on BossAttributesDataDto {
CardData toDomain() => CardData(
title ?? 'UNKNOWN',
+ id: id ?? 'UNKNOWN',
descriptionText: 'Открыть', //attributes?.description,
- gameDesc: description,//attributes?.drop,
+ gameDesc: description, //attributes?.drop,
imageUrl: imageUrl,
);
}
diff --git a/lib/data/repositories/api_interface.dart b/lib/data/repositories/api_interface.dart
index 038c22c..38ead3f 100644
--- a/lib/data/repositories/api_interface.dart
+++ b/lib/data/repositories/api_interface.dart
@@ -2,6 +2,6 @@ import 'package:pmu_labs/domain/models/card.dart';
typedef OnErrorCallback = void Function(String? error);
-abstract class ApiInterface{
+abstract class ApiInterface {
Future?> loadData();
-}
\ No newline at end of file
+}
diff --git a/lib/data/repositories/bosses_repository.dart b/lib/data/repositories/bosses_repository.dart
index 9afef6a..3ab2a91 100644
--- a/lib/data/repositories/bosses_repository.dart
+++ b/lib/data/repositories/bosses_repository.dart
@@ -13,11 +13,13 @@ Map transformJsonToBossesDtoFormat(
final title = boss['title'] as String;
final imageUrl = boss['original']?['source'] as String? ?? '';
final description = descs.firstWhere((desc) => desc.$1 == title).$2;
+ final id = boss['pageid'].toString();
return {
'title': title,
'imageUrl': imageUrl,
'description': description,
+ 'id': id,
};
}).toList();
@@ -33,7 +35,7 @@ void removeByTitle(Map map, String title) {
});
}
-void getBySearch(Map map, String? title){
+void getBySearch(Map map, String? title) {
map.removeWhere((key, value) {
return value is Map && value['title'] != title;
});
@@ -49,30 +51,31 @@ class BossesRepository extends ApiInterface {
static const String _baseUrl = 'https://sekiro.fandom.com/ru/api.php';
@override
- Future?> loadData({OnErrorCallback? onError,String? q,}) async {
+ Future?> loadData({
+ OnErrorCallback? onError,
+ String? q,
+ }) async {
try {
String url = '';
- if(q != null && q != ""){
- url ='$_baseUrl?action=query&titles=$q&prop=pageimages&piprop=original&format=json&origin=*';
- }else{
+ if (q != null && q != "") {
+ url =
+ '$_baseUrl?action=query&titles=$q&prop=pageimages&piprop=original&format=json&origin=*';
+ } else {
url =
'$_baseUrl?action=query&generator=categorymembers&gcmtitle=Category:Боссы&gcmnamespace=0&gcmlimit=50&prop=pageimages&piprop=original&format=json&origin=*';
}
+ final List? data;
+ BossesDto dto;
- final Response response = await _dio.get