diff --git a/lib/Presentation/home_page/bloc/state.g.dart b/lib/Presentation/home_page/bloc/state.g.dart index 258a914..114ac25 100644 --- a/lib/Presentation/home_page/bloc/state.g.dart +++ b/lib/Presentation/home_page/bloc/state.g.dart @@ -72,7 +72,8 @@ class _$HomeStateCWProxyImpl implements _$HomeStateCWProxy { // ignore: cast_nullable_to_non_nullable : isLoading as bool, isPaginationLoading: - isPaginationLoading == const $CopyWithPlaceholder() || isPaginationLoading == null + isPaginationLoading == const $CopyWithPlaceholder() || + isPaginationLoading == null ? _value.isPaginationLoading // ignore: cast_nullable_to_non_nullable : isPaginationLoading as bool, diff --git a/lib/Presentation/home_page/home_page.dart b/lib/Presentation/home_page/home_page.dart index f48e881..138d0e5 100644 --- a/lib/Presentation/home_page/home_page.dart +++ b/lib/Presentation/home_page/home_page.dart @@ -1,9 +1,13 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:labs_petrushin/Presentation/common/svg_objects.dart'; import 'package:labs_petrushin/Presentation/home_page/bloc/bloc.dart'; import 'package:labs_petrushin/Presentation/home_page/bloc/events.dart'; import 'package:labs_petrushin/Presentation/home_page/bloc/state.dart'; +import 'package:labs_petrushin/Presentation/locale_bloc/locale_bloc.dart'; +import 'package:labs_petrushin/Presentation/locale_bloc/locale_events.dart'; +import 'package:labs_petrushin/Presentation/locale_bloc/locale_state.dart'; import 'package:labs_petrushin/components/extensions/context_x.dart'; import '../../Presentation/detailPage.dart'; import '../../components/util/Debounce.dart'; @@ -77,11 +81,28 @@ class BodyState extends State { padding: const EdgeInsets.all(12), child: CupertinoSearchTextField( controller: searchController, + placeholder: context.locale.search, onChanged: (search) { Debounce.run(() => context.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.error != null ? Text( diff --git a/lib/Presentation/locale_bloc/locale_bloc.dart b/lib/Presentation/locale_bloc/locale_bloc.dart new file mode 100644 index 0000000..8f8b1df --- /dev/null +++ b/lib/Presentation/locale_bloc/locale_bloc.dart @@ -0,0 +1,19 @@ +import 'dart:async'; +import 'dart:ui'; + +import 'package:labs_petrushin/components/locale/l10n/app_locale.dart'; +import 'package:labs_petrushin/Presentation/locale_bloc/locale_events.dart'; +import 'package:labs_petrushin/Presentation/locale_bloc/locale_state.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class LocaleBloc extends Bloc { + LocaleBloc(Locale defaultLocale) : super(LocaleState(currentLocale: defaultLocale)) { + on(_onChangeLocale); + } + + FutureOr _onChangeLocale(ChangeLocaleEvent event, Emitter emit) async { + final toChange = AppLocale.supportedLocales + .firstWhere((e) => e.languageCode != state.currentLocale.languageCode); + emit(state.copyWith(currentLocale: toChange)); + } +} \ No newline at end of file diff --git a/lib/Presentation/locale_bloc/locale_events.dart b/lib/Presentation/locale_bloc/locale_events.dart new file mode 100644 index 0000000..f345ef9 --- /dev/null +++ b/lib/Presentation/locale_bloc/locale_events.dart @@ -0,0 +1,7 @@ +abstract class LocaleEvent { + const LocaleEvent(); +} + +class ChangeLocaleEvent extends LocaleEvent { + const ChangeLocaleEvent(); +} \ No newline at end of file diff --git a/lib/Presentation/locale_bloc/locale_state.dart b/lib/Presentation/locale_bloc/locale_state.dart new file mode 100644 index 0000000..9c26abe --- /dev/null +++ b/lib/Presentation/locale_bloc/locale_state.dart @@ -0,0 +1,15 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:copy_with_extension/copy_with_extension.dart'; + +part 'locale_state.g.dart'; + +@CopyWith() +class LocaleState extends Equatable { + final Locale currentLocale; + + const LocaleState({required this.currentLocale}); + + @override + List get props => [currentLocale]; +} \ No newline at end of file diff --git a/lib/Presentation/locale_bloc/locale_state.g.dart b/lib/Presentation/locale_bloc/locale_state.g.dart new file mode 100644 index 0000000..e374db6 --- /dev/null +++ b/lib/Presentation/locale_bloc/locale_state.g.dart @@ -0,0 +1,58 @@ +// 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() || currentLocale == null + ? _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); +} diff --git a/lib/Presentation/main.dart b/lib/Presentation/main.dart index e300647..736deb0 100644 --- a/lib/Presentation/main.dart +++ b/lib/Presentation/main.dart @@ -1,5 +1,9 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:labs_petrushin/Presentation/home_page/bloc/bloc.dart'; +import 'package:labs_petrushin/Presentation/locale_bloc/locale_bloc.dart'; +import 'package:labs_petrushin/Presentation/locale_bloc/locale_state.dart'; import 'package:labs_petrushin/components/locale/l10n/app_locale.dart'; import 'package:labs_petrushin/repositories/food_repository.dart'; import 'home_page/home_page.dart'; @@ -14,24 +18,33 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Petrushin demo', - localizationsDelegates: AppLocale.localizationsDelegates, - supportedLocales: AppLocale.supportedLocales, - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.red), - useMaterial3: true, - ), - home: RepositoryProvider( - lazy: true, - create: (_) => FoodRepository(), - child: BlocProvider( - lazy: false, - create: (context) => HomeBloc(context.read()), - child: const MyHomePage( - title: 'Петрушин Егор Александрович', + return BlocProvider( + lazy: false, + create: (context) => LocaleBloc(Locale(Platform.localeName)), + child: BlocBuilder( + builder: (context, state) { + return MaterialApp( + title: 'Petrushin demo', + locale: state.currentLocale, + localizationsDelegates: AppLocale.localizationsDelegates, + supportedLocales: AppLocale.supportedLocales, + debugShowCheckedModeBanner: false, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.red), + useMaterial3: true, ), - ))); + home: RepositoryProvider( + lazy: true, + create: (_) => FoodRepository(), + child: BlocProvider( + lazy: false, + create: (context) => HomeBloc(context.read()), + child: const MyHomePage( + title: 'Петрушин Егор Александрович', + ), + ))); + } + ), + ); } }