diff --git a/lib/application/bloc.dart b/lib/application/bloc.dart index 8bb91e598..8f097ad22 100644 --- a/lib/application/bloc.dart +++ b/lib/application/bloc.dart @@ -17,6 +17,7 @@ export 'main/main_bloc.dart'; export 'main_tab/main_tab_bloc.dart'; export 'material/material_bloc.dart'; export 'materials/materials_bloc.dart'; +export 'monsters/monsters_bloc.dart'; export 'settings/settings_bloc.dart'; export 'tierlist/tier_list_bloc.dart'; export 'today_materials/today_materials_bloc.dart'; diff --git a/lib/application/monsters/monsters_bloc.dart b/lib/application/monsters/monsters_bloc.dart new file mode 100644 index 000000000..01c231423 --- /dev/null +++ b/lib/application/monsters/monsters_bloc.dart @@ -0,0 +1,107 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:darq/darq.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:genshindb/domain/enums/enums.dart'; +import 'package:genshindb/domain/models/models.dart'; +import 'package:genshindb/domain/services/genshin_service.dart'; +import 'package:meta/meta.dart'; + +part 'monsters_bloc.freezed.dart'; +part 'monsters_event.dart'; +part 'monsters_state.dart'; + +class MonstersBloc extends Bloc { + final GenshinService _genshinService; + + _LoadedState get currentState => state as _LoadedState; + + MonstersBloc(this._genshinService) : super(const MonstersState.loading()); + + @override + Stream mapEventToState(MonstersEvent event) async* { + final s = event.map( + init: (e) => _buildInitialState(), + sortDirectionTypeChanged: (e) => currentState.copyWith.call(tempSortDirectionType: e.sortDirectionType), + typeChanged: (e) => currentState.copyWith.call(tempType: e.type), + filterTypeChanged: (e) => currentState.copyWith.call(tempFilterType: e.type), + searchChanged: (e) => _buildInitialState( + search: e.search, + type: currentState.type, + filterType: currentState.filterType, + sortDirectionType: currentState.sortDirectionType, + ), + applyFilterChanges: (_) => _buildInitialState( + search: currentState.search, + type: currentState.tempType, + filterType: currentState.tempFilterType, + sortDirectionType: currentState.tempSortDirectionType, + ), + cancelChanges: (_) => currentState.copyWith.call( + tempFilterType: currentState.filterType, + tempSortDirectionType: currentState.sortDirectionType, + tempType: currentState.type, + ), + close: (e) => currentState.copyWith.call(monsters: []), + ); + + yield s; + } + + MonstersState _buildInitialState({ + String search, + MonsterType type = MonsterType.all, + MonsterFilterType filterType = MonsterFilterType.name, + SortDirectionType sortDirectionType = SortDirectionType.asc, + }) { + final isLoaded = state is _LoadedState; + var data = _genshinService.getAllMonstersForCard(); + + if (!isLoaded) { + return MonstersState.loaded( + monsters: _sortData(data, filterType, sortDirectionType), + search: search, + type: type, + tempType: type, + filterType: filterType, + tempFilterType: filterType, + sortDirectionType: sortDirectionType, + tempSortDirectionType: sortDirectionType, + ); + } + + if (search != null && search.isNotEmpty) { + data = data.where((el) => el.name.toLowerCase().contains(search.toLowerCase())).toList(); + } + + if (type != MonsterType.all) { + data = data.where((el) => el.type == type).toList(); + } + + final s = currentState.copyWith.call( + monsters: _sortData(data, filterType, sortDirectionType), + search: search, + type: type, + tempType: type, + filterType: filterType, + tempFilterType: filterType, + sortDirectionType: sortDirectionType, + tempSortDirectionType: sortDirectionType, + ); + return s; + } + + List _sortData( + List data, + MonsterFilterType filterType, + SortDirectionType sortDirectionType, + ) { + switch (filterType) { + case MonsterFilterType.name: + return sortDirectionType == SortDirectionType.asc ? data.orderBy((el) => el.name).toList() : data.orderByDescending((el) => el.name).toList(); + default: + return data; + } + } +} diff --git a/lib/application/monsters/monsters_event.dart b/lib/application/monsters/monsters_event.dart new file mode 100644 index 000000000..2c717a40e --- /dev/null +++ b/lib/application/monsters/monsters_event.dart @@ -0,0 +1,18 @@ +part of 'monsters_bloc.dart'; + +@freezed +abstract class MonstersEvent implements _$MonstersEvent { + const factory MonstersEvent.init() = _Init; + const factory MonstersEvent.searchChanged({ + @required String search, + }) = _SearchChanged; + + const factory MonstersEvent.typeChanged(MonsterType type) = _TypeChanged; + const factory MonstersEvent.filterTypeChanged(MonsterFilterType type) = _FilterTypeChanged; + const factory MonstersEvent.applyFilterChanges() = _ApplyFilterChanges; + const factory MonstersEvent.sortDirectionTypeChanged(SortDirectionType sortDirectionType) = _SortDirectionTypeChanged; + + const factory MonstersEvent.cancelChanges() = _CancelChanges; + + const factory MonstersEvent.close() = _Close; +} diff --git a/lib/application/monsters/monsters_state.dart b/lib/application/monsters/monsters_state.dart new file mode 100644 index 000000000..4d12e70a3 --- /dev/null +++ b/lib/application/monsters/monsters_state.dart @@ -0,0 +1,17 @@ +part of 'monsters_bloc.dart'; + +@freezed +abstract class MonstersState implements _$MonstersState { + const factory MonstersState.loading() = _LoadingState; + + const factory MonstersState.loaded({ + @required List monsters, + String search, + @required MonsterFilterType filterType, + @required MonsterFilterType tempFilterType, + @required MonsterType type, + @required MonsterType tempType, + @required SortDirectionType sortDirectionType, + @required SortDirectionType tempSortDirectionType, + }) = _LoadedState; +}