lab7 done :)
This commit is contained in:
parent
2d49ce9f8c
commit
5c9ef6476c
@ -1,13 +1,13 @@
|
||||
{
|
||||
"@@locale": "en",
|
||||
|
||||
"title": "Quotes"
|
||||
"title": "Quotes",
|
||||
"search_word": "Search by word",
|
||||
"search_author": "Search by author",
|
||||
"liked": "Like :)",
|
||||
"disliked": "Dislike :(",
|
||||
"error": "Error :C"
|
||||
"details": "Details of quote"
|
||||
"error": "Error :C",
|
||||
"details": "Details of quote",
|
||||
|
||||
"arbEnding": ""
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
{
|
||||
"@@locale": "ru",
|
||||
|
||||
"search": "Поиск",
|
||||
"liked": "Круто :)",
|
||||
"disliked": "Не круто :с",
|
||||
"title": "Цитаты",
|
||||
"search_word": "Поиск по слову",
|
||||
"search_author": "Поиск по автору",
|
||||
"liked": "Лайк :)",
|
||||
"disliked": "Дизлайк :(",
|
||||
"error": "Ошибка :C",
|
||||
"details": "Детали цитаты",
|
||||
|
||||
"arbEnding": ""
|
||||
}
|
||||
|
@ -95,24 +95,48 @@ abstract class AppLocale {
|
||||
Locale('ru')
|
||||
];
|
||||
|
||||
/// No description provided for @search.
|
||||
/// No description provided for @title.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Поиск'**
|
||||
String get search;
|
||||
/// **'Цитаты'**
|
||||
String get title;
|
||||
|
||||
/// No description provided for @search_word.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Поиск по слову'**
|
||||
String get search_word;
|
||||
|
||||
/// No description provided for @search_author.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Поиск по автору'**
|
||||
String get search_author;
|
||||
|
||||
/// 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 @error.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Ошибка :C'**
|
||||
String get error;
|
||||
|
||||
/// No description provided for @details.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Детали цитаты'**
|
||||
String get details;
|
||||
|
||||
/// No description provided for @arbEnding.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
|
@ -7,7 +7,13 @@ class AppLocaleEn extends AppLocale {
|
||||
AppLocaleEn([String locale = 'en']) : super(locale);
|
||||
|
||||
@override
|
||||
String get search => 'Поиск';
|
||||
String get title => 'Quotes';
|
||||
|
||||
@override
|
||||
String get search_word => 'Search by word';
|
||||
|
||||
@override
|
||||
String get search_author => 'Search by author';
|
||||
|
||||
@override
|
||||
String get liked => 'Like :)';
|
||||
@ -15,6 +21,12 @@ class AppLocaleEn extends AppLocale {
|
||||
@override
|
||||
String get disliked => 'Dislike :(';
|
||||
|
||||
@override
|
||||
String get error => 'Error :C';
|
||||
|
||||
@override
|
||||
String get details => 'Details of quote';
|
||||
|
||||
@override
|
||||
String get arbEnding => '';
|
||||
}
|
||||
|
@ -7,13 +7,25 @@ class AppLocaleRu extends AppLocale {
|
||||
AppLocaleRu([String locale = 'ru']) : super(locale);
|
||||
|
||||
@override
|
||||
String get search => 'Поиск';
|
||||
String get title => 'Цитаты';
|
||||
|
||||
@override
|
||||
String get liked => 'Круто :)';
|
||||
String get search_word => 'Поиск по слову';
|
||||
|
||||
@override
|
||||
String get disliked => 'Не круто :с';
|
||||
String get search_author => 'Поиск по автору';
|
||||
|
||||
@override
|
||||
String get liked => 'Лайк :)';
|
||||
|
||||
@override
|
||||
String get disliked => 'Дизлайк :(';
|
||||
|
||||
@override
|
||||
String get error => 'Ошибка :C';
|
||||
|
||||
@override
|
||||
String get details => 'Детали цитаты';
|
||||
|
||||
@override
|
||||
String get arbEnding => '';
|
||||
|
@ -10,6 +10,7 @@ import 'components/locale/l10n/app_locale.dart';
|
||||
import 'data/repositories/quotes_repository.dart';
|
||||
import '/presentation/home_page/bloc/bloc.dart';
|
||||
import '/presentation/home_page/home_page.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
@ -21,35 +22,32 @@ class MyApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider<LocaleBloc>(
|
||||
lazy: false,
|
||||
create:(context) => LocaleBloc(Locale(Platform.localeName)),
|
||||
child: BlocBuilder<LocaleBloc, LocaleState>(
|
||||
builder: (context, state) {
|
||||
return MaterialApp(
|
||||
title: 'Цитаты',
|
||||
locale: state.currentLocale,
|
||||
localizationsDelegates: AppLocale.localizationsDelegates,
|
||||
supportedLocales: AppLocale.supportedLocales,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: RepositoryProvider<QuotesRepository>(
|
||||
lazy: true,
|
||||
create: (_) => QuotesRepository(),
|
||||
child: BlocProvider<LikeBloc>(
|
||||
create: (context) => LocaleBloc(Locale(Platform.localeName)),
|
||||
child: BlocBuilder<LocaleBloc, LocaleState>(builder: (context, state) {
|
||||
return MaterialApp(
|
||||
title: 'Цитаты',
|
||||
locale: state.currentLocale,
|
||||
localizationsDelegates: AppLocale.localizationsDelegates,
|
||||
supportedLocales: AppLocale.supportedLocales,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: RepositoryProvider<QuotesRepository>(
|
||||
lazy: true,
|
||||
create: (_) => QuotesRepository(),
|
||||
child: BlocProvider<LikeBloc>(
|
||||
lazy: false,
|
||||
create: (context) => LikeBloc(), // Add LikeBloc here
|
||||
child: BlocProvider<HomeBloc>(
|
||||
lazy: false,
|
||||
create: (context) => LikeBloc(), // Add LikeBloc here
|
||||
child: BlocProvider<HomeBloc>(
|
||||
lazy: false,
|
||||
create: (context) => HomeBloc(context.read<QuotesRepository>()),
|
||||
child: const MyHomePage(title: "Цитаты"),
|
||||
),
|
||||
create: (context) => HomeBloc(context.read<QuotesRepository>()),
|
||||
child: const MyHomePage(title: '',),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pmu_flutter_labs/components/extensions/context_x.dart';
|
||||
import '../../domain/quote.dart';
|
||||
import 'home_page.dart';
|
||||
|
||||
@ -28,8 +29,7 @@ class QuoteCard extends StatelessWidget {
|
||||
child: Image.network(
|
||||
quote.imagePath,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.error, color: Colors.red),
|
||||
errorBuilder: (_, __, ___) => const Icon(Icons.error, color: Colors.red),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
@ -57,7 +57,6 @@ class QuoteCard extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class QuoteDetailScreen extends StatelessWidget {
|
||||
final Quote quote;
|
||||
|
||||
@ -67,7 +66,7 @@ class QuoteDetailScreen extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Детали цитаты'),
|
||||
title: Text(context.locale.details),
|
||||
),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
@ -78,8 +77,7 @@ class QuoteDetailScreen extends StatelessWidget {
|
||||
Image.network(
|
||||
quote.imagePath,
|
||||
height: 150,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.error, color: Colors.red),
|
||||
errorBuilder: (_, __, ___) => const Icon(Icons.error, color: Colors.red),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
@ -98,4 +96,4 @@ class QuoteDetailScreen extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,17 +27,15 @@ class MyHomePage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
HomeBloc(QuotesRepository())..add(const HomeLoadDataEvent()),
|
||||
create: (context) => HomeBloc(QuotesRepository())..add(const HomeLoadDataEvent()),
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(title),
|
||||
Text(context.locale.title),
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
context.read<LocaleBloc>().add(const ChangeLocaleEvent()),
|
||||
onTap: () => context.read<LocaleBloc>().add(const ChangeLocaleEvent()),
|
||||
child: SizedBox.square(
|
||||
dimension: 50,
|
||||
child: Padding(
|
||||
@ -125,7 +123,7 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
decoration: InputDecoration(
|
||||
labelText: context.locale.search,
|
||||
labelText: context.locale.search_word,
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
),
|
||||
),
|
||||
@ -135,7 +133,7 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
child: TextField(
|
||||
controller: authorController,
|
||||
decoration: InputDecoration(
|
||||
labelText: context.locale.search,
|
||||
labelText: context.locale.search_author,
|
||||
prefixIcon: const Icon(Icons.person),
|
||||
),
|
||||
),
|
||||
@ -148,22 +146,17 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
: FutureBuilder<List<Quote>?>(
|
||||
future: state.data,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState ==
|
||||
ConnectionState.waiting) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator());
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text('Ошибка: ${snapshot.error}'));
|
||||
return Center(child: Text('${context.locale.error}: ${snapshot.error}'));
|
||||
}
|
||||
if (snapshot.data == null ||
|
||||
snapshot.data!.isEmpty) {
|
||||
return const Center(
|
||||
if (snapshot.data == null || snapshot.data!.isEmpty) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Нет цитат для отображения.',
|
||||
style: TextStyle(
|
||||
fontSize: 18, color: Colors.grey),
|
||||
context.locale.error,
|
||||
style: const TextStyle(fontSize: 18, color: Colors.grey),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -188,9 +181,8 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
quote: quote,
|
||||
isLiked: isLiked,
|
||||
onFavoriteToggle: () {
|
||||
context
|
||||
.read<LikeBloc>()
|
||||
.add(ChangeLikeEvent(quote.id));
|
||||
context.read<LikeBloc>().add(ChangeLikeEvent(quote.id));
|
||||
_showSnackbar(context, !isLiked);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -33,4 +33,4 @@ class LikeBloc extends Bloc<LikeEvent, LikeState> {
|
||||
|
||||
emit(state.copyWith(likedIds: updatedList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,4 @@ class LoadLikesEvent extends LikeEvent {
|
||||
class ChangeLikeEvent extends LikeEvent {
|
||||
final String id;
|
||||
const ChangeLikeEvent(this.id);
|
||||
}
|
||||
}
|
||||
|
@ -11,4 +11,4 @@ class LikeState extends Equatable {
|
||||
|
||||
@override
|
||||
List<Object?> get props => [likedIds];
|
||||
}
|
||||
}
|
||||
|
@ -14,4 +14,4 @@ class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
|
||||
.firstWhere((e) => e.languageCode != state.currentLocale.languageCode);
|
||||
emit(state.copyWith(currentLocale: toChange));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,4 +4,4 @@ abstract class LocaleEvent {
|
||||
|
||||
class ChangeLocaleEvent extends LocaleEvent {
|
||||
const ChangeLocaleEvent();
|
||||
}
|
||||
}
|
||||
|
@ -12,4 +12,4 @@ class LocaleState extends Equatable {
|
||||
|
||||
@override
|
||||
List<Object?> get props => [currentLocale];
|
||||
}
|
||||
}
|
||||
|
56
lib/presentation/locale_bloc/locale_state.g.dart
Normal file
56
lib/presentation/locale_bloc/locale_state.g.dart
Normal file
@ -0,0 +1,56 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'locale_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// CopyWithGenerator
|
||||
// **************************************************************************
|
||||
|
||||
abstract class _$LocaleStateCWProxy {
|
||||
LocaleState currentLocale(Locale currentLocale);
|
||||
|
||||
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `LocaleState(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
|
||||
///
|
||||
/// Usage
|
||||
/// ```dart
|
||||
/// LocaleState(...).copyWith(id: 12, name: "My name")
|
||||
/// ````
|
||||
LocaleState call({
|
||||
Locale currentLocale,
|
||||
});
|
||||
}
|
||||
|
||||
/// Proxy class for `copyWith` functionality. This is a callable class and can be used as follows: `instanceOfLocaleState.copyWith(...)`. Additionally contains functions for specific fields e.g. `instanceOfLocaleState.copyWith.fieldName(...)`
|
||||
class _$LocaleStateCWProxyImpl implements _$LocaleStateCWProxy {
|
||||
const _$LocaleStateCWProxyImpl(this._value);
|
||||
|
||||
final LocaleState _value;
|
||||
|
||||
@override
|
||||
LocaleState currentLocale(Locale currentLocale) => this(currentLocale: currentLocale);
|
||||
|
||||
@override
|
||||
|
||||
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `LocaleState(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
|
||||
///
|
||||
/// Usage
|
||||
/// ```dart
|
||||
/// LocaleState(...).copyWith(id: 12, name: "My name")
|
||||
/// ````
|
||||
LocaleState call({
|
||||
Object? currentLocale = const $CopyWithPlaceholder(),
|
||||
}) {
|
||||
return LocaleState(
|
||||
currentLocale: currentLocale == const $CopyWithPlaceholder()
|
||||
? _value.currentLocale
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: currentLocale as Locale,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension $LocaleStateCopyWith on LocaleState {
|
||||
/// Returns a callable class that can be used as follows: `instanceOfLocaleState.copyWith(...)` or like so:`instanceOfLocaleState.copyWith.fieldName(...)`.
|
||||
// ignore: library_private_types_in_public_api
|
||||
_$LocaleStateCWProxy get copyWith => _$LocaleStateCWProxyImpl(this);
|
||||
}
|
Loading…
Reference in New Issue
Block a user