2024-12-10 13:04:11 +04:00
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
|
import 'events.dart';
|
|
|
|
|
import 'state.dart';
|
2024-12-21 20:38:35 +04:00
|
|
|
|
import '../domain/models/character.dart';
|
2024-12-10 13:04:11 +04:00
|
|
|
|
import 'dart:async';
|
2024-12-21 20:38:35 +04:00
|
|
|
|
import 'package:identity/data/repositories/character_repository.dart';
|
|
|
|
|
import 'package:identity/data/dtos/character_dto.dart';
|
|
|
|
|
import 'package:identity/data/mappers/character_mapper.dart';
|
|
|
|
|
|
2024-12-10 13:04:11 +04:00
|
|
|
|
|
|
|
|
|
class DebouncedSearchCubit extends Cubit<String> {
|
|
|
|
|
DebouncedSearchCubit() : super('');
|
|
|
|
|
|
|
|
|
|
Timer? _debounce;
|
|
|
|
|
|
|
|
|
|
// Метод для обновления поиска с задержкой
|
|
|
|
|
void search(String query) {
|
|
|
|
|
if (_debounce?.isActive ?? false) _debounce?.cancel();
|
|
|
|
|
_debounce = Timer(const Duration(milliseconds: 500), () {
|
|
|
|
|
emit(query);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> close() {
|
|
|
|
|
_debounce?.cancel();
|
|
|
|
|
return super.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-17 14:28:23 +04:00
|
|
|
|
|
2024-12-10 13:04:11 +04:00
|
|
|
|
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
2024-12-21 20:38:35 +04:00
|
|
|
|
final CharacterRepository characterService;
|
2024-12-10 13:04:11 +04:00
|
|
|
|
|
|
|
|
|
HomeBloc(this.characterService) : super(const HomeState()) {
|
|
|
|
|
on<HomeLoadDataEvent>(_onLoadData);
|
2024-12-21 20:38:35 +04:00
|
|
|
|
on<HomeSearchEvent>(_onSearchCharacters);
|
2024-12-10 13:04:11 +04:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-17 14:28:23 +04:00
|
|
|
|
// Загрузка данных
|
2024-12-10 13:04:11 +04:00
|
|
|
|
Future<void> _onLoadData(HomeLoadDataEvent event, Emitter<HomeState> emit) async {
|
|
|
|
|
emit(state.copyWith(status: HomeStatus.loading));
|
|
|
|
|
|
|
|
|
|
try {
|
2024-12-21 20:38:35 +04:00
|
|
|
|
// Получаем список объектов Character
|
|
|
|
|
final characters = await characterService.loadData(searchQuery: event.searchQuery);
|
|
|
|
|
if (characters != null) {
|
|
|
|
|
// Преобразуем список Character в список CharacterDTO с помощью маппера
|
|
|
|
|
final charactersAsDTO = characters.map((character) => CharacterMapper.toDTO(character)).toList();
|
2024-12-10 13:41:28 +04:00
|
|
|
|
|
2024-12-21 20:38:35 +04:00
|
|
|
|
// Преобразуем обратно в List<Character>
|
|
|
|
|
final charactersAsModel = charactersAsDTO.map((dto) => CharacterMapper.fromDTO(dto)).toList();
|
2024-12-10 13:41:28 +04:00
|
|
|
|
|
2024-12-21 20:38:35 +04:00
|
|
|
|
emit(state.copyWith(status: HomeStatus.loaded, characters: charactersAsModel));
|
|
|
|
|
} else {
|
|
|
|
|
emit(state.copyWith(status: HomeStatus.error, errorMessage: "Failed to load characters."));
|
|
|
|
|
}
|
2024-12-10 13:04:11 +04:00
|
|
|
|
} catch (e) {
|
|
|
|
|
print('Error: $e');
|
|
|
|
|
emit(state.copyWith(status: HomeStatus.error, errorMessage: e.toString()));
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-10 13:41:28 +04:00
|
|
|
|
|
2024-12-21 20:38:35 +04:00
|
|
|
|
|
|
|
|
|
|
2024-12-17 14:28:23 +04:00
|
|
|
|
// Логика поиска
|
|
|
|
|
void _onSearchCharacters(HomeSearchEvent event, Emitter<HomeState> emit) {
|
|
|
|
|
final query = event.query.toLowerCase();
|
2024-12-10 13:41:28 +04:00
|
|
|
|
|
2024-12-17 14:28:23 +04:00
|
|
|
|
// Фильтруем данные по запросу
|
|
|
|
|
final filteredCharacters = state.characters
|
2024-12-21 20:38:35 +04:00
|
|
|
|
.where((character) => character.name?.toLowerCase().contains(query) ?? false)
|
2024-12-17 14:28:23 +04:00
|
|
|
|
.toList();
|
2024-12-10 13:04:11 +04:00
|
|
|
|
|
2024-12-17 14:28:23 +04:00
|
|
|
|
// Обновляем состояние с отфильтрованными данными
|
|
|
|
|
emit(state.copyWith(status: HomeStatus.loaded, characters: filteredCharacters));
|
|
|
|
|
}
|
|
|
|
|
}
|