Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Application] Created multiple chart blocs.
- Loading branch information
Showing
17 changed files
with
315 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
lib/application/charts/birthdays/chart_birthdays_bloc.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import 'package:bloc/bloc.dart'; | ||
import 'package:freezed_annotation/freezed_annotation.dart'; | ||
import 'package:shiori/domain/models/models.dart'; | ||
import 'package:shiori/domain/services/genshin_service.dart'; | ||
|
||
part 'chart_birthdays_bloc.freezed.dart'; | ||
part 'chart_birthdays_event.dart'; | ||
part 'chart_birthdays_state.dart'; | ||
|
||
class ChartBirthdaysBloc extends Bloc<ChartBirthdaysEvent, ChartBirthdaysState> { | ||
final GenshinService _genshinService; | ||
|
||
ChartBirthdaysBloc(this._genshinService) : super(const ChartBirthdaysState.loading()); | ||
|
||
@override | ||
Stream<ChartBirthdaysState> mapEventToState(ChartBirthdaysEvent event) async* { | ||
final s = await event.map( | ||
init: (e) async => _init(), | ||
); | ||
|
||
yield s; | ||
} | ||
|
||
Future<ChartBirthdaysState> _init() async { | ||
final birthdays = _genshinService.getCharacterBirthdaysForCharts(); | ||
return ChartBirthdaysState.initial(birthdays: birthdays); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
part of 'chart_birthdays_bloc.dart'; | ||
|
||
@freezed | ||
class ChartBirthdaysEvent with _$ChartBirthdaysEvent { | ||
const factory ChartBirthdaysEvent.init() = _Init; | ||
} |
10 changes: 10 additions & 0 deletions
10
lib/application/charts/birthdays/chart_birthdays_state.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
part of 'chart_birthdays_bloc.dart'; | ||
|
||
@freezed | ||
class ChartBirthdaysState with _$ChartBirthdaysState { | ||
const factory ChartBirthdaysState.loading() = _LoadingState; | ||
|
||
const factory ChartBirthdaysState.initial({ | ||
required List<ChartBirthdayMonthModel> birthdays, | ||
}) = _LoadedState; | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
156 changes: 156 additions & 0 deletions
156
lib/application/charts/elements/chart_elements_bloc.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
import 'package:bloc/bloc.dart'; | ||
import 'package:freezed_annotation/freezed_annotation.dart'; | ||
import 'package:shiori/domain/app_constants.dart'; | ||
import 'package:shiori/domain/enums/enums.dart'; | ||
import 'package:shiori/domain/extensions/double_extensions.dart'; | ||
import 'package:shiori/domain/models/models.dart'; | ||
import 'package:shiori/domain/services/genshin_service.dart'; | ||
|
||
part 'chart_elements_bloc.freezed.dart'; | ||
part 'chart_elements_event.dart'; | ||
part 'chart_elements_state.dart'; | ||
|
||
class ChartElementsBloc extends Bloc<ChartElementsEvent, ChartElementsState> { | ||
final GenshinService _genshinService; | ||
final List<double> versions; | ||
|
||
ChartElementsBloc(this._genshinService) | ||
: versions = _genshinService.getBannerHistoryVersions(SortDirectionType.asc), | ||
super(const ChartElementsState.loading()); | ||
|
||
@override | ||
Stream<ChartElementsState> mapEventToState(ChartElementsEvent event) async* { | ||
final s = event.map( | ||
init: (e) => _init(e.maxNumberOfColumns), | ||
elementSelected: (e) => state.maybeMap( | ||
loaded: (state) => _elementSelectionChanged(state, e.type), | ||
orElse: () => throw Exception('Invalid state'), | ||
), | ||
goToNextPage: (e) => state.maybeMap( | ||
loaded: _goToNextPage, | ||
orElse: () => throw Exception('Invalid state'), | ||
), | ||
goToPreviousPage: (e) => state.maybeMap( | ||
loaded: _goToPreviousPage, | ||
orElse: () => throw Exception('Invalid state'), | ||
), | ||
goToFirstPage: (e) => state.maybeMap( | ||
loaded: (state) => _goToFirstOrLastPage(state, true), | ||
orElse: () => throw Exception('Invalid state'), | ||
), | ||
goToLastPage: (e) => state.maybeMap( | ||
loaded: (state) => _goToFirstOrLastPage(state, false), | ||
orElse: () => throw Exception('Invalid state'), | ||
), | ||
); | ||
|
||
yield s; | ||
} | ||
|
||
//Some versions were skipped (e.g: 1.7, 1.8, 1.9), that's why we use this function | ||
//to determine if the version can be skipped or no | ||
bool isValidVersion(double value) { | ||
return versions.contains(value.truncateToDecimalPlaces()); | ||
} | ||
|
||
ChartElementsState _init(int maxNumberOfColumns) { | ||
final firstVersion = versions.first; | ||
final lastVersion = versions.first + (maxNumberOfColumns / 10); | ||
final elements = _genshinService.getElementsForCharts(firstVersion, lastVersion); | ||
return ChartElementsState.loaded( | ||
maxNumberOfColumns: maxNumberOfColumns, | ||
firstVersion: firstVersion, | ||
lastVersion: lastVersion, | ||
elements: elements, | ||
filteredElements: elements, | ||
canGoToFirstPage: _canGoToFirstPage(firstVersion), | ||
canGoToLastPage: _canGoToLastPage(firstVersion), | ||
canGoToNextPage: _canGoToNextPage(firstVersion), | ||
canGoToPreviousPage: _canGoToPreviousPage(firstVersion), | ||
); | ||
} | ||
|
||
ChartElementsState _elementSelectionChanged(_InitialState state, ElementType type) { | ||
final selectedTypes = [...state.selectedElementTypes]; | ||
if (selectedTypes.contains(type)) { | ||
selectedTypes.remove(type); | ||
} else { | ||
selectedTypes.add(type); | ||
} | ||
|
||
return state.copyWith(selectedElementTypes: selectedTypes, filteredElements: _getFilteredElements(state.elements, selectedTypes)); | ||
} | ||
|
||
List<ChartElementItemModel> _getFilteredElements(List<ChartElementItemModel> elements, List<ElementType> selectedTypes) => | ||
selectedTypes.isEmpty ? elements : elements.where((el) => selectedTypes.contains(el.type)).toList(); | ||
|
||
double _getStep(_InitialState state) => state.maxNumberOfColumns * gameVersionIncrementsBy; | ||
|
||
ChartElementsState _goToFirstOrLastPage(_InitialState state, bool toFirstPage) { | ||
final firstVersion = versions.first; | ||
if (toFirstPage) { | ||
return _newVersionChanged(state, firstVersion); | ||
} | ||
|
||
final possibleVersionA = (firstVersion + _getStep(state)).truncateToDecimalPlaces(); | ||
final possibleVersionB = (versions.last - _getStep(state)).truncateToDecimalPlaces(); | ||
if (possibleVersionA > possibleVersionB && possibleVersionB > firstVersion) { | ||
return _newVersionChanged(state, possibleVersionB); | ||
} | ||
return _newVersionChanged(state, possibleVersionA); | ||
} | ||
|
||
ChartElementsState _goToNextPage(_InitialState state) { | ||
if (!_canGoToNextPage(state.firstVersion)) { | ||
throw Exception('Cannot go to the next page'); | ||
} | ||
final newVersion = (state.firstVersion + gameVersionIncrementsBy).truncateToDecimalPlaces(); | ||
return _newVersionChanged(state, newVersion); | ||
} | ||
|
||
ChartElementsState _goToPreviousPage(_InitialState state) { | ||
if (!_canGoToPreviousPage(state.firstVersion)) { | ||
throw Exception('Cannot go to the previous page'); | ||
} | ||
final newVersion = (state.firstVersion - gameVersionIncrementsBy).truncateToDecimalPlaces(); | ||
return _newVersionChanged(state, newVersion); | ||
} | ||
|
||
ChartElementsState _newVersionChanged(_InitialState state, double newFirstVersion) { | ||
final step = _getStep(state); | ||
double newLastVersion = (newFirstVersion + step).truncateToDecimalPlaces(); | ||
|
||
if (newLastVersion > versions.last) { | ||
newLastVersion = versions.last; | ||
} | ||
if (newFirstVersion < versions.first) { | ||
throw Exception('First version = $newFirstVersion cannot be greater than = ${versions.first}'); | ||
} | ||
|
||
if (newLastVersion > versions.last) { | ||
throw Exception('Last version = $newLastVersion cannot be greater than = ${versions.last}'); | ||
} | ||
|
||
assert(newFirstVersion != newLastVersion, 'New and last version cannot be equal'); | ||
|
||
final elements = _genshinService.getElementsForCharts(newFirstVersion, newLastVersion); | ||
return state.copyWith( | ||
elements: elements, | ||
filteredElements: _getFilteredElements(elements, state.selectedElementTypes), | ||
firstVersion: newFirstVersion, | ||
lastVersion: newLastVersion, | ||
canGoToFirstPage: _canGoToFirstPage(newFirstVersion), | ||
canGoToLastPage: _canGoToLastPage(newLastVersion), | ||
canGoToNextPage: _canGoToNextPage(newFirstVersion) && _canGoToLastPage(newLastVersion), | ||
canGoToPreviousPage: _canGoToPreviousPage(newFirstVersion) && _canGoToFirstPage(newFirstVersion), | ||
); | ||
} | ||
|
||
bool _canGoToFirstPage(double version) => version > versions.first; | ||
|
||
bool _canGoToNextPage(double version) => version + gameVersionIncrementsBy <= versions.last; | ||
|
||
bool _canGoToPreviousPage(double version) => version - gameVersionIncrementsBy >= versions.first; | ||
|
||
bool _canGoToLastPage(double version) => version < versions.last; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
part of 'chart_elements_bloc.dart'; | ||
|
||
@freezed | ||
class ChartElementsEvent with _$ChartElementsEvent { | ||
const factory ChartElementsEvent.init({ | ||
required int maxNumberOfColumns, | ||
}) = _Init; | ||
|
||
const factory ChartElementsEvent.elementSelected({ | ||
required ElementType type, | ||
}) = _ElementSelected; | ||
|
||
const factory ChartElementsEvent.goToNextPage() = _GoToNextPage; | ||
|
||
const factory ChartElementsEvent.goToPreviousPage() = _GoToPreviousPage; | ||
|
||
const factory ChartElementsEvent.goToFirstPage() = _GoToFirstPage; | ||
|
||
const factory ChartElementsEvent.goToLastPage() = _GoToLastPage; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
part of 'chart_elements_bloc.dart'; | ||
|
||
@freezed | ||
class ChartElementsState with _$ChartElementsState { | ||
const factory ChartElementsState.loading() = _LoadingState; | ||
|
||
const factory ChartElementsState.loaded({ | ||
required int maxNumberOfColumns, | ||
required double firstVersion, | ||
required double lastVersion, | ||
required List<ChartElementItemModel> elements, | ||
required List<ChartElementItemModel> filteredElements, | ||
required bool canGoToFirstPage, | ||
required bool canGoToNextPage, | ||
required bool canGoToPreviousPage, | ||
required bool canGoToLastPage, | ||
@Default(<ElementType>[]) List<ElementType> selectedElementTypes, | ||
}) = _InitialState; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import 'package:bloc/bloc.dart'; | ||
import 'package:freezed_annotation/freezed_annotation.dart'; | ||
import 'package:shiori/domain/enums/enums.dart'; | ||
import 'package:shiori/domain/models/models.dart'; | ||
import 'package:shiori/domain/services/genshin_service.dart'; | ||
import 'package:shiori/domain/services/telemetry_service.dart'; | ||
|
||
part 'chart_tops_bloc.freezed.dart'; | ||
part 'chart_tops_event.dart'; | ||
part 'chart_tops_state.dart'; | ||
|
||
class ChartTopsBloc extends Bloc<ChartTopsEvent, ChartTopsState> { | ||
final GenshinService _genshinService; | ||
final TelemetryService _telemetryService; | ||
|
||
ChartTopsBloc(this._genshinService, this._telemetryService) : super(const ChartTopsState.loading()); | ||
|
||
@override | ||
Stream<ChartTopsState> mapEventToState(ChartTopsEvent event) async* { | ||
final s = await event.map( | ||
init: (e) async => _init(), | ||
); | ||
|
||
yield s; | ||
} | ||
|
||
Future<ChartTopsState> _init() async { | ||
await _telemetryService.trackChartsOpened(); | ||
final tops = [ | ||
..._genshinService.getTopCharts(ChartType.topFiveStarCharacterMostReruns), | ||
..._genshinService.getTopCharts(ChartType.topFiveStarCharacterLeastReruns), | ||
..._genshinService.getTopCharts(ChartType.topFiveStarWeaponMostReruns), | ||
..._genshinService.getTopCharts(ChartType.topFiveStarWeaponLeastReruns), | ||
..._genshinService.getTopCharts(ChartType.topFourStarCharacterMostReruns), | ||
..._genshinService.getTopCharts(ChartType.topFourStarCharacterLeastReruns), | ||
..._genshinService.getTopCharts(ChartType.topFourStarWeaponMostReruns), | ||
..._genshinService.getTopCharts(ChartType.topFourStarWeaponLeastReruns), | ||
]; | ||
return ChartTopsState.loaded(tops: tops); | ||
} | ||
} |
Oops, something went wrong.