import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'bloc/bloc.dart'; import 'bloc/events.dart'; import 'bloc/state.dart'; import 'package:dio/dio.dart'; import 'components/locale/l10n/app_locale.dart'; import 'pages/character_detail_page.dart'; import 'package:identity/data/repositories/character_repository.dart'; import 'character_search_delegate.dart'; import 'package:identity/data/mappers/character_mapper.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // Load saved language preference final prefs = await SharedPreferences.getInstance(); final savedLocale = prefs.getString('locale') ?? 'en'; runApp( MultiBlocProvider( providers: [ BlocProvider( create: (_) => HomeBloc(CharacterRepository(Dio())), ), BlocProvider( create: (_) => DebouncedSearchCubit(), ), ], child: MyApp(savedLocale: savedLocale), ), ); } class MyApp extends StatefulWidget { final String savedLocale; const MyApp({required this.savedLocale, super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { late Locale _locale; @override void initState() { super.initState(); _locale = Locale(widget.savedLocale); } void _changeLanguage(String languageCode) async { setState(() { _locale = Locale(languageCode); }); // Save selected language to preferences final prefs = await SharedPreferences.getInstance(); prefs.setString('locale', languageCode); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, localizationsDelegates: AppLocale.localizationsDelegates, supportedLocales: AppLocale.supportedLocales, locale: _locale, localeResolutionCallback: (locale, supportedLocales) { return supportedLocales.contains(locale) ? locale : const Locale('en'); }, home: MyHomePage( onLanguageChanged: _changeLanguage, ), ); } } class MyHomePage extends StatelessWidget { final Function(String) onLanguageChanged; const MyHomePage({ required this.onLanguageChanged, super.key, }); @override Widget build(BuildContext context) { context.read().add(HomeLoadDataEvent()); final appTitle = AppLocale.of(context)?.appTitle ?? 'Default Title'; return Scaffold( appBar: AppBar( title: Text(appTitle), actions: [ IconButton( icon: const Icon(Icons.language), onPressed: () { // Переключение между языками final currentLocale = Localizations.localeOf(context).languageCode; final newLocale = currentLocale == 'en' ? 'ru' : 'en'; onLanguageChanged(newLocale); }, ), IconButton( icon: const Icon(Icons.refresh), onPressed: () { // Отправляем событие для обновления данных context.read().add(HomeLoadDataEvent()); }, ), IconButton( icon: const Icon(Icons.search), onPressed: () { final characters = context.read().state.characters; final suggestions = characters.map((e) => e.name).toList(); showSearch( context: context, delegate: CharacterSearchDelegate(suggestions), ); }, ), ], ), body: BlocBuilder( builder: (context, state) { if (state.status == HomeStatus.loading) { return const Center(child: CircularProgressIndicator()); } else if (state.status == HomeStatus.error) { return Center( child: Text(AppLocale.of(context)?.errorMessage(state.errorMessage) ?? 'Error')); } else if (state.status == HomeStatus.loaded) { final characters = state.characters; return ListView.builder( itemCount: characters.length, itemBuilder: (context, index) { final characterDTO = characters[index]; return StatefulBuilder( builder: (context, setState) { return ListTile( leading: SizedBox( width: 40, child: Image.network(characterDTO.imageUrl, width: 50, height: 50), ), title: Text(characterDTO.name), subtitle: Text(characterDTO.typeString), trailing: IconButton( icon: Icon( characterDTO.isLiked ? Icons.favorite : Icons.favorite_border, color: characterDTO.isLiked ? Colors.red : Colors.grey, ), onPressed: () { setState(() { characterDTO.isLiked = !characterDTO.isLiked; }); final message = characterDTO.isLiked ? (AppLocale.of(context)?.likeMessage(characterDTO.name) ?? 'Понравился персонаж') : (AppLocale.of(context)?.unlikeMessage(characterDTO.name) ?? 'Персонаж больше не понравился'); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(message), duration: const Duration(seconds: 1), ), ); }, ), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => CharacterDetailPage( characterDTO: CharacterMapper.toDTO(characterDTO), // Используем метод toDTO() ), ), ); }, ); }, ); }, ); } else { return Center(child: Text(AppLocale.of(context)?.noData ?? 'No Data')); } }, ), ); } }