вроде всё кроме иконки
This commit is contained in:
parent
753419dbf3
commit
aececde5c2
@ -2,9 +2,12 @@
|
||||
"@@locale" : "en",
|
||||
|
||||
"search": "Search",
|
||||
"liked": "liked!",
|
||||
"disliked": "disliked :<",
|
||||
"liked": "liked",
|
||||
"disliked": "disliked",
|
||||
"heroDetailsTitle": "Hero Details",
|
||||
"heroListTitle": "Hero List",
|
||||
"noHeroesAvailable": "no heroes available",
|
||||
"noHeroesFound": "no heroes found",
|
||||
"heroNoImage": "No image available",
|
||||
"heroNoDescription": "No description available",
|
||||
|
||||
|
@ -2,10 +2,13 @@
|
||||
"@@locale" : "ru",
|
||||
|
||||
"search": "Поиск",
|
||||
"liked": "нравится!",
|
||||
"disliked": "не нравится :<",
|
||||
"liked": "нравится",
|
||||
"disliked": "больше не нравится",
|
||||
"heroListTitle": "Список героев",
|
||||
"heroDetailsTitle": "Детали героя",
|
||||
"heroNoImage": "Изображение недоступно",
|
||||
"noHeroesAvailable": "Нет доступных героев",
|
||||
"noHeroesFound": "Герои не найдены",
|
||||
"heroNoDescription": "Описание отсутствует",
|
||||
|
||||
"arbEnding": "ЗАПЯТАЯ"
|
||||
|
@ -104,15 +104,21 @@ abstract class AppLocale {
|
||||
/// 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 @heroListTitle.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Список героев'**
|
||||
String get heroListTitle;
|
||||
|
||||
/// No description provided for @heroDetailsTitle.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
@ -125,6 +131,18 @@ abstract class AppLocale {
|
||||
/// **'Изображение недоступно'**
|
||||
String get heroNoImage;
|
||||
|
||||
/// No description provided for @noHeroesAvailable.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Нет доступных героев'**
|
||||
String get noHeroesAvailable;
|
||||
|
||||
/// No description provided for @noHeroesFound.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
/// **'Герои не найдены'**
|
||||
String get noHeroesFound;
|
||||
|
||||
/// No description provided for @heroNoDescription.
|
||||
///
|
||||
/// In ru, this message translates to:
|
||||
|
@ -10,10 +10,13 @@ class AppLocaleEn extends AppLocale {
|
||||
String get search => 'Search';
|
||||
|
||||
@override
|
||||
String get liked => 'liked!';
|
||||
String get liked => 'liked';
|
||||
|
||||
@override
|
||||
String get disliked => 'disliked :<';
|
||||
String get disliked => 'disliked';
|
||||
|
||||
@override
|
||||
String get heroListTitle => 'Hero List';
|
||||
|
||||
@override
|
||||
String get heroDetailsTitle => 'Hero Details';
|
||||
@ -21,6 +24,12 @@ class AppLocaleEn extends AppLocale {
|
||||
@override
|
||||
String get heroNoImage => 'No image available';
|
||||
|
||||
@override
|
||||
String get noHeroesAvailable => 'no heroes available';
|
||||
|
||||
@override
|
||||
String get noHeroesFound => 'no heroes found';
|
||||
|
||||
@override
|
||||
String get heroNoDescription => 'No description available';
|
||||
|
||||
|
@ -10,10 +10,13 @@ class AppLocaleRu extends AppLocale {
|
||||
String get search => 'Поиск';
|
||||
|
||||
@override
|
||||
String get liked => 'нравится!';
|
||||
String get liked => 'нравится';
|
||||
|
||||
@override
|
||||
String get disliked => 'не нравится :<';
|
||||
String get disliked => 'больше не нравится';
|
||||
|
||||
@override
|
||||
String get heroListTitle => 'Список героев';
|
||||
|
||||
@override
|
||||
String get heroDetailsTitle => 'Детали героя';
|
||||
@ -21,6 +24,12 @@ class AppLocaleRu extends AppLocale {
|
||||
@override
|
||||
String get heroNoImage => 'Изображение недоступно';
|
||||
|
||||
@override
|
||||
String get noHeroesAvailable => 'Нет доступных героев';
|
||||
|
||||
@override
|
||||
String get noHeroesFound => 'Герои не найдены';
|
||||
|
||||
@override
|
||||
String get heroNoDescription => 'Описание отсутствует';
|
||||
|
||||
|
@ -13,9 +13,10 @@ class HeroListScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final locale = AppLocale.of(context)!; // Получаем текущую локализацию
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Heroes'),
|
||||
title: Text(locale.heroListTitle),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.language),
|
||||
@ -50,35 +51,46 @@ class HeroListScreen extends StatelessWidget {
|
||||
if (searchState is HeroSearchLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (searchState is HeroSearchLoaded) {
|
||||
return ListView.builder(
|
||||
itemCount: searchState.heroes.length,
|
||||
itemBuilder: (context, index) {
|
||||
return HeroCard(hero: searchState.heroes[index]);
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
// Обновляем список героев
|
||||
context.read<HeroListBloc>().add(FetchHeroes());
|
||||
},
|
||||
child: ListView.builder(
|
||||
itemCount: searchState.heroes.length,
|
||||
itemBuilder: (context, index) {
|
||||
return HeroCard(hero: searchState.heroes[index]);
|
||||
},
|
||||
),
|
||||
);
|
||||
} else if (searchState is HeroSearchError) {
|
||||
return Center(child: Text('Error: ${searchState.message}'));
|
||||
} else if (searchState is HeroSearchInitial) {
|
||||
// Если поисковый запрос пустой, показываем полный список героев
|
||||
return BlocBuilder<HeroListBloc, HeroListState>(
|
||||
builder: (context, listState) {
|
||||
if (listState is HeroListLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (listState is HeroListLoaded) {
|
||||
return ListView.builder(
|
||||
itemCount: listState.heroes.length,
|
||||
itemBuilder: (context, index) {
|
||||
return HeroCard(hero: listState.heroes[index]);
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
// Выполняем новый запрос к API
|
||||
context.read<HeroListBloc>().add(FetchHeroes());
|
||||
},
|
||||
child: ListView.builder(
|
||||
itemCount: listState.heroes.length,
|
||||
itemBuilder: (context, index) {
|
||||
return HeroCard(hero: listState.heroes[index]);
|
||||
},
|
||||
),
|
||||
);
|
||||
} else if (listState is HeroListError) {
|
||||
return Center(child: Text('Error: ${listState.message}'));
|
||||
}
|
||||
return const Center(child: Text('No heroes available.'));
|
||||
return Center(child: Text(locale.noHeroesAvailable));
|
||||
},
|
||||
);
|
||||
}
|
||||
return const Center(child: Text('No heroes found.'));
|
||||
return Center(child: Text(locale.noHeroesFound));
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import '../../data/dtos/hero_dto.dart';
|
||||
import '../components/screens/hero_detail_screen.dart';
|
||||
import '../services/like_service.dart';
|
||||
import '../../Components/locale/l10n/app_locale.dart';
|
||||
|
||||
class HeroCard extends StatefulWidget {
|
||||
final HeroDto hero;
|
||||
@ -30,14 +31,28 @@ class _HeroCardState extends State<HeroCard> {
|
||||
}
|
||||
|
||||
Future<void> _toggleLike() async {
|
||||
final locale = AppLocale.of(context)!; // Получаем текущую локализацию
|
||||
String message;
|
||||
|
||||
if (_isLiked) {
|
||||
await _likeService.unlikeHero(widget.hero.id);
|
||||
message = '${locale.disliked} ${widget.hero.name}';
|
||||
} else {
|
||||
await _likeService.likeHero(widget.hero.id);
|
||||
message = '${locale.liked} ${widget.hero.name}';
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isLiked = !_isLiked;
|
||||
});
|
||||
|
||||
// Отображение Snackbar с локализованным сообщением
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -46,14 +61,14 @@ class _HeroCardState extends State<HeroCard> {
|
||||
child: ListTile(
|
||||
leading: widget.hero.portraitUrl != null
|
||||
? Image.network(widget.hero.portraitUrl!)
|
||||
: Icon(Icons.image),
|
||||
: const Icon(Icons.image),
|
||||
title: Text(widget.hero.name),
|
||||
trailing: IconButton(
|
||||
icon: Icon(
|
||||
_isLiked ? Icons.favorite : Icons.favorite_border,
|
||||
color: _isLiked ? Colors.red : null,
|
||||
),
|
||||
onPressed: _toggleLike,
|
||||
onPressed: _toggleLike, // Вызываем метод с Snackbar
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
|
Loading…
Reference in New Issue
Block a user