diff --git a/assets/icon.jpg b/assets/icon.jpg
new file mode 100644
index 0000000..9d71906
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/us.svg b/assets/svg/us.svg
new file mode 100644
index 0000000..f5a7a01
--- /dev/null
+++ b/assets/svg/us.svg
@@ -0,0 +1,34 @@
+
+
+
\ No newline at end of file
diff --git a/lib/components/locale/l10n/app_locale.dart b/lib/components/locale/l10n/app_locale.dart
index 5f646e6..1c601cd 100644
--- a/lib/components/locale/l10n/app_locale.dart
+++ b/lib/components/locale/l10n/app_locale.dart
@@ -8,6 +8,8 @@ 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)`.
///
@@ -80,8 +82,7 @@ abstract class AppLocale {
/// 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 =
- >[
+ static const List> localizationsDelegates = >[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
@@ -89,7 +90,10 @@ abstract class AppLocale {
];
/// A list of this localizations delegate's supported locales.
- static const List supportedLocales = [Locale('en'), Locale('ru')];
+ static const List supportedLocales = [
+ Locale('en'),
+ Locale('ru')
+ ];
/// No description provided for @search.
///
@@ -107,7 +111,7 @@ abstract class AppLocale {
///
/// In ru, this message translates to:
/// **'разонравился'**
- String get unliked;
+ String get disliked;
}
class _AppLocaleDelegate extends LocalizationsDelegate {
@@ -126,17 +130,18 @@ class _AppLocaleDelegate extends LocalizationsDelegate {
}
AppLocale lookupAppLocale(Locale locale) {
+
+
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
- case 'en':
- return AppLocaleEn();
- case 'ru':
- return AppLocaleRu();
+ 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.');
+ '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
index 90b81dd..e0f4211 100644
--- a/lib/components/locale/l10n/app_locale_en.dart
+++ b/lib/components/locale/l10n/app_locale_en.dart
@@ -1,5 +1,7 @@
import 'app_locale.dart';
+// ignore_for_file: type=lint
+
/// The translations for English (`en`).
class AppLocaleEn extends AppLocale {
AppLocaleEn([String locale = 'en']) : super(locale);
@@ -11,6 +13,5 @@ class AppLocaleEn extends AppLocale {
String get liked => 'liked!';
@override
- String get unliked => 'disliked';
-
+ String get disliked => 'разонравился';
}
diff --git a/lib/components/locale/l10n/app_locale_ru.dart b/lib/components/locale/l10n/app_locale_ru.dart
index 4d78b7f..e1485c0 100644
--- a/lib/components/locale/l10n/app_locale_ru.dart
+++ b/lib/components/locale/l10n/app_locale_ru.dart
@@ -1,5 +1,7 @@
import 'app_locale.dart';
+// ignore_for_file: type=lint
+
/// The translations for Russian (`ru`).
class AppLocaleRu extends AppLocale {
AppLocaleRu([String locale = 'ru']) : super(locale);
@@ -11,5 +13,5 @@ class AppLocaleRu extends AppLocale {
String get liked => 'понравился!';
@override
- String get unliked => 'разонравился';
+ String get disliked => 'разонравился';
}
diff --git a/lib/main.dart b/lib/main.dart
index f4b01ab..5075b12 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,9 +1,16 @@
+import 'dart:io';
+
import 'package:flutter/material.dart';
import 'package:flutter_app/data/repositories/manga_repository.dart';
import 'package:flutter_app/presentation/home_page/bloc/bloc.dart';
import 'package:flutter_app/presentation/home_page/home_page.dart';
+import 'package:flutter_app/presentation/like_bloc/like_bloc.dart';
+import 'package:flutter_app/presentation/locale_bloc/locale_bloc.dart';
+import 'package:flutter_app/presentation/locale_bloc/locale_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
+import 'components/locale/l10n/app_locale.dart';
+
void main() {
runApp(const MyApp());
}
@@ -14,27 +21,36 @@ class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
- return MaterialApp(
- title: 'Flutter Demo',
- theme: ThemeData(
- colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
- useMaterial3: true,
- ),
- home: RepositoryProvider(
- lazy: true,
- create: (_) => MangaRepository(),
- child: BlocProvider(
- lazy: false,
- create: (context) => HomeBloc(context.read()),
- child: const HomePage(),
- ),
- )
- );
+ return BlocProvider(
+ lazy: false,
+ create: (context) => LocaleBloc(Locale(Platform.localeName)),
+ child: BlocBuilder(
+ builder: (context, state) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ locale: state.currentLocale,
+ localizationsDelegates: AppLocale.localizationsDelegates,
+ supportedLocales: AppLocale.supportedLocales,
+ debugShowCheckedModeBanner: false,
+ theme: ThemeData(
+ colorScheme:
+ ColorScheme.fromSeed(seedColor: Colors.deepPurple),
+ useMaterial3: true,
+ ),
+ home: RepositoryProvider(
+ lazy: true,
+ create: (_) => MangaRepository(),
+ child: BlocProvider(
+ lazy: false,
+ create: (context) => LikeBloc(),
+ child: BlocProvider(
+ lazy: false,
+ create: (context) =>
+ HomeBloc(context.read()),
+ child: const HomePage(),
+ ),
+ )));
+ },
+ ));
}
}
-
-
-
-
-
-
diff --git a/lib/presentation/home_page/home_page.dart b/lib/presentation/home_page/home_page.dart
index d235b9f..9272309 100644
--- a/lib/presentation/home_page/home_page.dart
+++ b/lib/presentation/home_page/home_page.dart
@@ -2,7 +2,6 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/components/utils/debounce.dart';
import 'package:flutter_app/data/repositories/manga_repository.dart';
-import 'package:flutter_app/data/repositories/mock_repository.dart';
import 'package:flutter_app/presentation/details_page/details_page.dart';
import 'package:flutter_app/presentation/home_page/bloc/bloc.dart';
import 'package:flutter_app/presentation/home_page/bloc/events.dart';
@@ -10,6 +9,13 @@ import 'package:flutter_app/presentation/home_page/bloc/state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../domain/models/carddata.dart';
+import '../common/svg_objects.dart';
+import '../like_bloc/like_bloc.dart';
+import '../like_bloc/like_event.dart';
+import '../like_bloc/like_state.dart';
+import '../locale_bloc/locale_bloc.dart';
+import '../locale_bloc/locale_events.dart';
+import '../locale_bloc/locale_state.dart';
part 'card.dart';
@@ -45,8 +51,11 @@ class _BodyState extends State {
@override
void initState() {
+ SvgObjects.init();
+
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read().add(const HomeLoadDataEvent());
+ context.read().add(const LoadLikesEvent());
});
scrollController.addListener(_onNextPageListener);
@@ -74,7 +83,14 @@ class _BodyState extends State {
final MangaRepository repo = MangaRepository();
var data = MangaRepository().loadData();
- void _showSnackbar(BuildContext context, String title, bool isLiked) {
+ void _onLike(String? id, String title, bool isLiked) {
+ if (id != null) {
+ context.read().add(ChangeLikeEvent(id));
+ _showSnackBar(context, title, !isLiked);
+ }
+ }
+
+ void _showSnackBar(BuildContext context, String title, bool isLiked) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
@@ -114,31 +130,47 @@ class _BodyState extends State {
.read()
.add(HomeLoadDataEvent(search: search)));
})),
+ GestureDetector(
+ onTap: () =>
+ context.read().add(const ChangeLocaleEvent()),
+ child: SizedBox.square(
+ dimension: 50,
+ child: Padding(
+ padding: const EdgeInsets.only(right: 12),
+ child: BlocBuilder(
+ builder: (context, state) {
+ return state.currentLocale.languageCode == 'ru'
+ ? const SvgRu()
+ : const SvgUk();
+ },
+ ),
+ ),
+ ),
+ ),
BlocBuilder(
builder: (context, state) => state.isLoading
? CircularProgressIndicator()
- : Expanded(
- child: RefreshIndicator(
- onRefresh: _onRefresh,
- child: ListView.builder(
- controller: scrollController,
- padding: EdgeInsets.zero,
- itemCount: state.data?.data?.length ?? 0,
- itemBuilder: (context, index) {
- final data = state.data?.data?[index];
- return data != null
- ? _Card.fromData(
- data,
- onLike: (title, isLiked) =>
- _showSnackbar(
- context, title, isLiked),
- onTap: () =>
- _navToDetails(context, data),
- )
- : const SizedBox.shrink();
- }),
- ),
- )),
+ : BlocBuilder(
+ builder: (context, likeState) => Expanded(
+ child: RefreshIndicator(
+ onRefresh: _onRefresh,
+ child: ListView.builder(
+ controller: scrollController,
+ padding: EdgeInsets.zero,
+ itemCount: state.data?.data?.length ?? 0,
+ itemBuilder: (context, index) {
+ final data = state.data?.data?[index];
+ return data != null
+ ? _Card.fromData(
+ data,
+ onLike: _onLike,
+ onTap: () =>
+ _navToDetails(context, data),
+ )
+ : const SizedBox.shrink();
+ }),
+ ),
+ ))),
BlocBuilder(
builder: (context, state) => state.isPaginationLoading
? const CircularProgressIndicator()
diff --git a/pubspec.yaml b/pubspec.yaml
index 90d469f..bab3e71 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -47,7 +47,7 @@ dev_dependencies:
flutter_icons:
android: "ic_launcher"
ios: true
- image_path: "assets/launcher.jpeg"
+ image_path: "assets/icon.jpeg"
min_sdk_android: 21
flutter: