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..54535ad 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..80aa327 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..defb0e4 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..328b546 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..c0bf4b3 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/icon.jpg b/assets/icon.jpg
new file mode 100644
index 0000000..34dc9ce
Binary files /dev/null and b/assets/icon.jpg differ
diff --git a/assets/svg/ru.svg b/assets/svg/ru.svg
new file mode 100644
index 0000000..ae12982
--- /dev/null
+++ b/assets/svg/ru.svg
@@ -0,0 +1,19 @@
+
+
+
\ No newline at end of file
diff --git a/assets/svg/uk.svg b/assets/svg/uk.svg
new file mode 100644
index 0000000..88e2211
--- /dev/null
+++ b/assets/svg/uk.svg
@@ -0,0 +1,23 @@
+
+
+
\ 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..1106903
--- /dev/null
+++ b/l10n/app_en.arb
@@ -0,0 +1,9 @@
+{
+ "@@locale": "en",
+
+ "search": "Search",
+ "liked": "You liked ",
+ "disliked": "You 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..f668c33
--- /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..9d9b340
--- /dev/null
+++ b/lib/components/extensions/context_x.dart
@@ -0,0 +1,6 @@
+import 'package:flutter/cupertino.dart';
+import '../locale/l10n/app_locale.dart';
+
+extension LocalContextX on BuildContext {
+ AppLocale get locale => AppLocale.of(this)!;
+}
diff --git a/lib/components/locale/l10n/app_locale.dart b/lib/components/locale/l10n/app_locale.dart
new file mode 100644
index 0000000..e79d953
--- /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..caf8f92
--- /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 => 'You liked ';
+
+ @override
+ String get disliked => 'You 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..aae8d98
--- /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..9645894
--- /dev/null
+++ b/lib/components/resources.g.dart
@@ -0,0 +1,10 @@
+/// Generate by [asset_generator](https://github.com/fluttercandies/flutter_asset_generator) library.
+/// PLEASE DO NOT EDIT MANUALLY.
+// ignore_for_file: constant_identifier_names
+class R {
+ const R._();
+
+ static const String ASSETS_SVG_RU_SVG = 'assets/svg/ru.svg';
+
+ static const String ASSETS_SVG_UK_SVG = 'assets/svg/uk.svg';
+}
diff --git a/lib/components/utils/debounce.dart b/lib/components/utils/debounce.dart
index 24e35af..bed72b6 100644
--- a/lib/components/utils/debounce.dart
+++ b/lib/components/utils/debounce.dart
@@ -9,13 +9,13 @@ class Debounce {
static final Debounce _instance = Debounce._();
static Timer? _timer;
- // если в течении 0.5 сек появится новый вызов (изменится текст в поле ввода)
+ // если в течении 1.5 сек появится новый вызов (изменится текст в поле ввода)
// то текущий вызов заменяется новым
- static void run (
- VoidCallback action, {
- Duration delay = const Duration(milliseconds: 500),
- }) {
+ static void run(
+ VoidCallback action, {
+ Duration delay = const Duration(milliseconds: 1500),
+ }) {
_timer?.cancel();
_timer = Timer(delay, action);
}
-}
\ No newline at end of file
+}
diff --git a/lib/data/dto/games_dto.dart b/lib/data/dto/games_dto.dart
index aa2e4a1..e868185 100644
--- a/lib/data/dto/games_dto.dart
+++ b/lib/data/dto/games_dto.dart
@@ -1,5 +1,5 @@
import 'package:json_annotation/json_annotation.dart';
-//автоматически сгенерился
+
part 'games_dto.g.dart';
// createToJson:false - указание, что сериализатор не нужен, нужен только десериализатор
@@ -8,18 +8,16 @@ class GamesDto {
@JsonKey(name: 'results')
final List? data;
- final int? current;
final int? next;
- // final int? previous;
- const GamesDto({this.data, this.current, this.next});
+ const GamesDto({this.data, this.next});
factory GamesDto.fromJson(Map json) => _$GamesDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
class GameDto {
- //для получения описания игры
+ //для получения описания игры + хранения лайков
@JsonKey(name: 'id')
final int? id;
@@ -27,7 +25,6 @@ class GameDto {
final String? description;
-
@JsonKey(name: 'background_image')
final String? image;
@@ -37,4 +34,4 @@ class GameDto {
const GameDto(this.id, this.name, this.description, this.image, this.date);
factory GameDto.fromJson(Map json) => _$GameDtoFromJson(json);
-}
\ No newline at end of file
+}
diff --git a/lib/data/dto/games_dto.g.dart b/lib/data/dto/games_dto.g.dart
index 1d3efd3..ee22d49 100644
--- a/lib/data/dto/games_dto.g.dart
+++ b/lib/data/dto/games_dto.g.dart
@@ -7,21 +7,16 @@ part of 'games_dto.dart';
// **************************************************************************
GamesDto _$GamesDtoFromJson(Map json) => GamesDto(
- data: (json['results'] as List?)
- ?.map((e) => GameDto.fromJson(e as Map))
- .toList(),
- current: getNextPageNumber(json['next']) != null ? getNextPageNumber(json['next'])! - 1 : null,
- next: getNextPageNumber(json['next']),
-);
+ data: (json['results'] as List?)?.map((e) => GameDto.fromJson(e as Map)).toList(),
+ next: getNextPageNumber(json['next']),
+ );
int? getNextPageNumber(String url) {
RegExp regExp = RegExp(r'page=(\d+)');
Match? match = regExp.firstMatch(url);
- String? number;
if (match != null) {
return int.parse(match.group(1)!);
}
- //по умолчанию след. = 2, т.е. тек. = 1
else {
return null;
}
diff --git a/lib/data/mappers/games_mapper.dart b/lib/data/mappers/games_mapper.dart
index ea1292c..b2c150b 100644
--- a/lib/data/mappers/games_mapper.dart
+++ b/lib/data/mappers/games_mapper.dart
@@ -1,27 +1,19 @@
import 'package:mobiles_labs_5th_semester/data/dto/games_dto.dart';
import 'package:mobiles_labs_5th_semester/domain/models/game.dart';
-import 'package:mobiles_labs_5th_semester/domain/models/page_of_games_home.dart';
+import 'package:mobiles_labs_5th_semester/domain/models/games.dart';
extension GamesDtoToModel on GamesDto {
- PageOfGames toDomain() => PageOfGames(
- data: data?.map((e) => e.toDomain()).toList(),
- nextPage: next);
+ Games toDomain() => Games(data: data?.map((e) => e.toDomain()).toList(), nextPage: next);
}
extension GameDtoToModel on GameDto {
- GameData toDomain() {
+ Game toDomain() {
// удаление HTML-тегов из описания
String cleanedDescription = description ?? '';
if (cleanedDescription.isNotEmpty) {
- cleanedDescription =
- cleanedDescription.replaceAll(RegExp(r'<[^>]*>'), '');
+ cleanedDescription = cleanedDescription.replaceAll(RegExp(r'<[^>]*>'), '');
}
- // return GameData(name: name ?? 'Неизвестная игра', price: 100, image: image?.originalUrl, description: cleanedDescription);
- return GameData(
- id: id,
- name: name ?? 'Неизвестная игра',
- date: DateTime.parse(date ?? '2000-01-01'),
- image: image,
- description: cleanedDescription);
+
+ return Game(id: id, name: name ?? 'Неизвестная игра', date: DateTime.parse(date ?? '2000-01-01'), image: image, description: cleanedDescription);
}
}
diff --git a/lib/data/repositories/api_interface.dart b/lib/data/repositories/api_interface.dart
index 67303b5..8dfee61 100644
--- a/lib/data/repositories/api_interface.dart
+++ b/lib/data/repositories/api_interface.dart
@@ -1,8 +1,7 @@
-import 'package:mobiles_labs_5th_semester/domain/models/game.dart';
-import 'package:mobiles_labs_5th_semester/domain/models/page_of_games_home.dart';
+import 'package:mobiles_labs_5th_semester/domain/models/games.dart';
typedef OnErrorCallback = void Function(String? error);
abstract class ApiInterface {
- Future loadData({OnErrorCallback? onError});
-}
\ No newline at end of file
+ Future loadData({OnErrorCallback? onError});
+}
diff --git a/lib/data/repositories/games_repository.dart b/lib/data/repositories/games_repository.dart
index d8c7120..50d610e 100644
--- a/lib/data/repositories/games_repository.dart
+++ b/lib/data/repositories/games_repository.dart
@@ -5,8 +5,7 @@ import 'package:dio/dio.dart';
import 'package:mobiles_labs_5th_semester/domain/models/game.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
-import '../../domain/models/page_of_games_home.dart';
-
+import '../../domain/models/games.dart';
class GamesRepository extends ApiInterface {
// Для обращения к api, с удобным выводом в консоль
@@ -18,9 +17,8 @@ class GamesRepository extends ApiInterface {
static const String _baseUrl = 'https://api.rawg.io';
-
@override
- Future loadData({OnErrorCallback? onError, String? q, int page = 1, int pageSize = 10}) async {
+ Future loadData({OnErrorCallback? onError, String? q, int page = 1, int pageSize = 10}) async {
try {
String url = '$_baseUrl/api/games?key=793f3ef5bdb64d128bebbb6e68ab89bd&format=json&platforms=4';
url += '&page=$page';
@@ -34,17 +32,16 @@ class GamesRepository extends ApiInterface {
final GamesDto gamesDto = GamesDto.fromJson(response.data as Map);
- final PageOfGames? data = gamesDto.toDomain();
+ final Games? data = gamesDto.toDomain();
return data;
- }
- on DioException catch (e) {
+ } on DioException catch (e) {
onError?.call(e.error?.toString());
return null;
}
}
- Future loadGameData(int? id) async {
+ Future loadGameData(int? id) async {
try {
String url = '$_baseUrl/api/games/${id.toString()}?key=793f3ef5bdb64d128bebbb6e68ab89bd&format=json';
@@ -52,11 +49,10 @@ class GamesRepository extends ApiInterface {
final GameDto gameDto = GameDto.fromJson(response.data as Map);
- final GameData data = gameDto.toDomain();
+ final Game data = gameDto.toDomain();
return data;
- }
- on DioException catch (e) {
+ } on DioException catch (e) {
return null;
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/data/repositories/mock_repository.dart b/lib/data/repositories/mock_repository.dart
deleted file mode 100644
index a2c788d..0000000
--- a/lib/data/repositories/mock_repository.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// import 'package:flutter/material.dart';
-// import 'package:mobiles_labs_5th_semester/data/repositories/api_interface.dart';
-// import 'package:mobiles_labs_5th_semester/domain/models/game.dart';
-//
-// //реализация apiInterface
-// //"фейковые" данные, которые подходят
-// class MockRepository extends ApiInterface {
-// @override
-// Future?> loadData(String? q) async {
-// return [
-// GameData(
-// name: 'Late Shift',
-// //price: 399,
-// date: DateTime(2016, 20, 02),
-// description: 'Late Shift - криминальный FMV-триллер с невероятно высокими ставками. Вы окажетесь в эпицентре лондонского ограбления и выберете своё приключение в интерактивном кинофильме с меняющейся историей, ведущей к одной из семи концовок. Ваши решения определяют вас.',
-// image:
-// 'https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/584980/capsule_616x353.jpg?t=1697110140'),
-// GameData(
-// name: 'Dark Nights with Poe & Munro',
-// //price: 450,
-// date: DateTime(2019, 05, 05),
-// description: 'Проведите местных радиоведущих По и Манро через шесть похожих на короткометражки эпизодов сверъестественной странности и обжигающего сюжета. От создателей The Infectious Madness of Doctor Dekker и The Shapeshifting Detective.',
-// image:
-// 'https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1098170/capsule_616x353.jpg?t=1725541685'),
-// GameData(
-// date: DateTime(1900, 20, 02),
-// name: 'Неизвестная игра',
-// //price: 999,
-//
-// )
-// ];
-// }
-// }
\ No newline at end of file
diff --git a/lib/domain/models/game.dart b/lib/domain/models/game.dart
index 1a866a2..0995d01 100644
--- a/lib/domain/models/game.dart
+++ b/lib/domain/models/game.dart
@@ -1,18 +1,14 @@
-class GameData {
+class Game {
final int? id;
final String name;
- //final int price;
final DateTime date;
final String? image;
- //Описание игры
final String? description;
- GameData(
- { this.id,
- required this.name,
- //required this.price,
- required this.date,
- this.description,
- this.image =
- 'https://parpol.ru/wp-content/uploads/2019/09/placeholder.png'});
-}
\ No newline at end of file
+ Game(
+ {required this.id,
+ required this.name,
+ required this.date,
+ this.description,
+ this.image = 'https://parpol.ru/wp-content/uploads/2019/09/placeholder.png'});
+}
diff --git a/lib/domain/models/games.dart b/lib/domain/models/games.dart
new file mode 100644
index 0000000..a7d1c07
--- /dev/null
+++ b/lib/domain/models/games.dart
@@ -0,0 +1,7 @@
+import 'package:mobiles_labs_5th_semester/domain/models/game.dart';
+
+class Games {
+ final List? data;
+ final int? nextPage;
+ Games({this.data, this.nextPage});
+}
diff --git a/lib/domain/models/page_of_games_home.dart b/lib/domain/models/page_of_games_home.dart
deleted file mode 100644
index adcdb9b..0000000
--- a/lib/domain/models/page_of_games_home.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-import 'package:mobiles_labs_5th_semester/domain/models/game.dart';
-
-class PageOfGames {
- final List? data;
- final int? nextPage;
- //final int? prevPage;
- PageOfGames({this.data, this.nextPage});
-}
\ No newline at end of file
diff --git a/lib/main.dart b/lib/main.dart
index 8a069e5..2cb92aa 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -2,7 +2,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mobiles_labs_5th_semester/data/repositories/games_repository.dart';
import 'package:mobiles_labs_5th_semester/presentation/home_page/bloc/bloc.dart';
+import 'package:mobiles_labs_5th_semester/presentation/like_bloc/like_bloc.dart';
+import 'package:mobiles_labs_5th_semester/presentation/locale_bloc/locale_bloc.dart';
+import 'package:mobiles_labs_5th_semester/presentation/locale_bloc/locale_state.dart';
+import 'components/locale/l10n/app_locale.dart';
import 'presentation/home_page/home_page.dart';
void main() {
@@ -14,23 +18,31 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return MaterialApp(
- title: 'Flutter Demo',
- debugShowCheckedModeBanner: false,
- home: RepositoryProvider(
- //репозиторий будет создан только тогда, когда будет запрошен, а не сразу при создании виджета
- lazy: true,
- create: (_) => GamesRepository(),
- child: BlocProvider(
- //bloc будет создан сразу при создании виджета
- lazy: false,
- //context нужен, чтобы суметь обратиться к провайдеру, кот. выше по дереву
- create: (context) => HomeBloc(context.read()),
- child: const HomePage(title: 'Чернышев Георгий Янович'),
- ),
- )
- );
+ return BlocProvider(
+ lazy: false,
+ create: (context) => LocaleBloc(Locale('ru')),
+ child: BlocBuilder(builder: (context, state) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ locale: state.currentLocale,
+ localizationsDelegates: AppLocale.localizationsDelegates,
+ supportedLocales: AppLocale.supportedLocales,
+ debugShowCheckedModeBanner: false,
+ home: RepositoryProvider(
+ //репозиторий будет создан только тогда, когда будет запрошен, а не сразу при создании виджета
+ lazy: true,
+ create: (_) => GamesRepository(),
+ child: BlocProvider(
+ lazy: false,
+ create: (context) => LikeBloc(),
+ child: BlocProvider(
+ //bloc будет создан сразу при создании виджета
+ lazy: false,
+ //context нужен, чтобы суметь обратиться к провайдеру, кот. выше по дереву
+ create: (context) => HomeBloc(context.read()),
+ child: const HomePage(title: 'неSteam'),
+ ),
+ )));
+ }));
}
}
-
-
diff --git a/lib/presentation/common/svg_objects.dart b/lib/presentation/common/svg_objects.dart
new file mode 100644
index 0000000..ca7daa2
--- /dev/null
+++ b/lib/presentation/common/svg_objects.dart
@@ -0,0 +1,34 @@
+import 'package:flutter/widgets.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:mobiles_labs_5th_semester/components/resources.g.dart';
+
+abstract class SvgObjects {
+ static void init() {
+ final pics = [
+ R.ASSETS_SVG_RU_SVG,
+ R.ASSETS_SVG_UK_SVG,
+ ];
+ for (final String p in pics) {
+ final loader = SvgAssetLoader(p);
+ svg.cache.putIfAbsent(loader.cacheKey(null), () => loader.loadBytes(null));
+ }
+ }
+}
+
+class SvgRu extends StatelessWidget {
+ const SvgRu({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return SvgPicture.asset(R.ASSETS_SVG_RU_SVG);
+ }
+}
+
+class SvgUk extends StatelessWidget {
+ const SvgUk({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return SvgPicture.asset(R.ASSETS_SVG_UK_SVG);
+ }
+}
diff --git a/lib/presentation/details_page/bloc/state.dart b/lib/presentation/details_page/bloc/state.dart
index 4efaeea..4e1a0d8 100644
--- a/lib/presentation/details_page/bloc/state.dart
+++ b/lib/presentation/details_page/bloc/state.dart
@@ -1,13 +1,14 @@
+import 'package:copy_with_extension/copy_with_extension.dart';
import 'package:equatable/equatable.dart';
import '../../../domain/models/game.dart';
-import 'package:copy_with_extension/copy_with_extension.dart';
+
part 'state.g.dart';
@CopyWith()
class GameDetailsState extends Equatable {
- final GameData? gameData;
+ final Game? gameData;
const GameDetailsState({this.gameData});
@override
List