Skip to content

Commit

Permalink
When anything changes in the tier list, it gets saved into db
Browse files Browse the repository at this point in the history
  • Loading branch information
Wolfteam committed Mar 30, 2021
1 parent 32f6730 commit 530f20b
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 108 deletions.
62 changes: 42 additions & 20 deletions lib/application/tierlist/tier_list_bloc.dart
Expand Up @@ -3,6 +3,7 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:genshindb/domain/models/models.dart';
import 'package:genshindb/domain/services/data_service.dart';
import 'package:genshindb/domain/services/genshin_service.dart';
import 'package:genshindb/domain/services/logging_service.dart';
import 'package:genshindb/domain/services/telemetry_service.dart';
Expand All @@ -12,8 +13,11 @@ part 'tier_list_bloc.freezed.dart';
part 'tier_list_event.dart';
part 'tier_list_state.dart';

const _initialState = TierListState.loaded(rows: [], charsAvailable: [], readyToSave: false);

class TierListBloc extends Bloc<TierListEvent, TierListState> {
final GenshinService _genshinService;
final DataService _dataService;
final TelemetryService _telemetryService;
final LoggingService _loggingService;
final List<int> defaultColors = [
Expand All @@ -26,16 +30,12 @@ class TierListBloc extends Bloc<TierListEvent, TierListState> {

_LoadedState get currentState => state as _LoadedState;

TierListBloc(this._genshinService, this._telemetryService, this._loggingService) : super(const TierListState.loading());
TierListBloc(this._genshinService, this._dataService, this._telemetryService, this._loggingService) : super(_initialState);

@override
Stream<TierListState> mapEventToState(TierListEvent event) async* {
if (event is _Init) {
yield const TierListState.loading();
}

final s = await event.map(
init: (_) async => _init(),
init: (e) async => _init(e.reset),
rowTextChanged: (e) async => _rowTextChanged(e.index, e.newValue),
rowPositionChanged: (e) async => _rowPositionChanged(e.index, e.newIndex),
rowColorChanged: (e) async => _rowColorChanged(e.index, e.newColor),
Expand All @@ -55,83 +55,106 @@ class TierListBloc extends Bloc<TierListEvent, TierListState> {

return currentState;
},
close: (e) async => _initialState,
);

yield s;
}

Future<TierListState> _init() async {
Future<TierListState> _init(bool reset) async {
await _telemetryService.trackTierListOpened();
if (reset) {
await _dataService.deleteTierList();
}

final tierList = _dataService.getTierList();
final defaultTierList = _genshinService.getDefaultCharacterTierList(defaultColors);
return TierListState.loaded(rows: defaultTierList, charsAvailable: [], readyToSave: false);
if (tierList.isEmpty) {
return TierListState.loaded(rows: defaultTierList, charsAvailable: [], readyToSave: false);
}

final usedCharImgs = tierList.expand((el) => el.charImgs).toList();
final availableChars = defaultTierList.expand((el) => el.charImgs).where((el) => !usedCharImgs.contains(el)).toList();
return TierListState.loaded(rows: tierList, charsAvailable: availableChars, readyToSave: false);
}

TierListState _rowTextChanged(int index, String newValue) {
Future<TierListState> _rowTextChanged(int index, String newValue) async {
final updated = currentState.rows.elementAt(index).copyWith.call(tierText: newValue);
final rows = _updateRows(updated, index, index);
await _dataService.saveTierList(rows);
return currentState.copyWith.call(rows: rows);
}

TierListState _rowPositionChanged(int index, int newIndex) {
Future<TierListState> _rowPositionChanged(int index, int newIndex) async {
final updated = currentState.rows.elementAt(index);
final rows = _updateRows(updated, newIndex, index);
await _dataService.saveTierList(rows);
return currentState.copyWith.call(rows: rows);
}

TierListState _rowColorChanged(int index, int newColor) {
Future<TierListState> _rowColorChanged(int index, int newColor) async {
final updated = currentState.rows.elementAt(index).copyWith.call(tierColor: newColor);
final rows = _updateRows(updated, index, index);
await _dataService.saveTierList(rows);
return currentState.copyWith.call(rows: rows);
}

TierListState _addNewRow(int index, bool above) {
Future<TierListState> _addNewRow(int index, bool above) async {
final colorsCopy = [...defaultColors];
final color = (colorsCopy..shuffle()).first;
final newIndex = above ? index : index + 1;

final newRow = TierListRowModel.row(tierText: (currentState.rows.length + 1).toString(), tierColor: color, charImgs: []);
final rows = [...currentState.rows];
rows.insert(newIndex, newRow);
await _dataService.saveTierList(rows);
return currentState.copyWith.call(rows: rows);
}

TierListState _deleteRow(int index) {
Future<TierListState> _deleteRow(int index) async {
if (currentState.rows.length == 1) {
return currentState;
}
final rows = [...currentState.rows];
final row = rows.elementAt(index);
final chars = _updateAvailableChars([...currentState.charsAvailable, ...row.charImgs], []);
rows.removeAt(index);
await _dataService.saveTierList(rows);
return currentState.copyWith.call(rows: rows, charsAvailable: chars);
}

TierListState _clearRow(int index) {
Future<TierListState> _clearRow(int index) async {
final row = currentState.rows.elementAt(index);
final updated = row.copyWith.call(charImgs: []);
final rows = _updateRows(updated, index, index);
final chars = _updateAvailableChars([...currentState.charsAvailable, ...row.charImgs], []);
await _dataService.saveTierList(rows);
return currentState.copyWith.call(rows: rows, charsAvailable: chars);
}

TierListState _clearAllRows() {
Future<TierListState> _clearAllRows() async {
final chars = _updateAvailableChars(_genshinService.getDefaultCharacterTierList(defaultColors).expand((row) => row.charImgs).toList(), []);
final updatedRows = currentState.rows.map((row) => row.copyWith.call(charImgs: [])).toList();
await _dataService.saveTierList(updatedRows);
return currentState.copyWith.call(rows: updatedRows, charsAvailable: chars, readyToSave: false);
}

TierListState _addCharacterToRow(int index, String charImg) {
Future<TierListState> _addCharacterToRow(int index, String charImg) async {
final row = currentState.rows.elementAt(index);
final updated = row.copyWith.call(charImgs: [...row.charImgs, charImg]);
final updatedChars = _updateAvailableChars(currentState.charsAvailable, [charImg]);
return currentState.copyWith.call(rows: _updateRows(updated, index, index), charsAvailable: updatedChars);
final updatedRows = _updateRows(updated, index, index);
await _dataService.saveTierList(updatedRows);
return currentState.copyWith.call(rows: updatedRows, charsAvailable: updatedChars);
}

TierListState _deleteCharacterFromRow(int index, String charImg) {
Future<TierListState> _deleteCharacterFromRow(int index, String charImg) async {
final row = currentState.rows.elementAt(index);
final updated = row.copyWith.call(charImgs: row.charImgs.where((img) => img != charImg).toList());
final updatedChars = _updateAvailableChars([...currentState.charsAvailable, charImg], []);
return currentState.copyWith.call(rows: _updateRows(updated, index, index), charsAvailable: updatedChars, readyToSave: false);
final updatedRows = _updateRows(updated, index, index);
await _dataService.saveTierList(updatedRows);
return currentState.copyWith.call(rows: updatedRows, charsAvailable: updatedChars, readyToSave: false);
}

List<TierListRowModel> _updateRows(TierListRowModel updated, int newIndex, int excludeIndex) {
Expand All @@ -150,7 +173,6 @@ class TierListBloc extends Bloc<TierListEvent, TierListState> {
}

rows.insert(newIndex, updated);
// rows.sort((x, y) => x.index - y.index);
return rows;
}

Expand Down
6 changes: 5 additions & 1 deletion lib/application/tierlist/tier_list_event.dart
Expand Up @@ -2,7 +2,9 @@ part of 'tier_list_bloc.dart';

@freezed
abstract class TierListEvent with _$TierListEvent {
const factory TierListEvent.init() = _Init;
const factory TierListEvent.init({
@Default(false) bool reset,
}) = _Init;

const factory TierListEvent.rowTextChanged({
@required int index,
Expand Down Expand Up @@ -51,4 +53,6 @@ abstract class TierListEvent with _$TierListEvent {
dynamic ex,
StackTrace trace,
}) = _ScreenshotTaken;

const factory TierListEvent.close() = _Close;
}
2 changes: 0 additions & 2 deletions lib/application/tierlist/tier_list_state.dart
Expand Up @@ -2,8 +2,6 @@ part of 'tier_list_bloc.dart';

@freezed
abstract class TierListState with _$TierListState {
const factory TierListState.loading() = _LoadingState;

const factory TierListState.loaded({
@required List<TierListRowModel> rows,
@required List<String> charsAvailable,
Expand Down
1 change: 1 addition & 0 deletions lib/domain/models/entities.dart
Expand Up @@ -4,3 +4,4 @@ export 'entities/calculator/calculator_session.dart';
export 'entities/game_code/used_game_code.dart';
export 'entities/inventory/inventory_item.dart';
export 'entities/inventory/inventory_used_item.dart';
export 'entities/tierlist/tierlist_item.dart';
20 changes: 20 additions & 0 deletions lib/domain/models/entities/tierlist/tierlist_item.dart
@@ -0,0 +1,20 @@
import 'package:hive/hive.dart';

part 'tierlist_item.g.dart';

@HiveType(typeId: 7)
class TierListItem extends HiveObject {
@HiveField(0)
final String text;

@HiveField(1)
final int color;

@HiveField(2)
final int position;

@HiveField(3)
final List<String> charsImgs;

TierListItem(this.text, this.color, this.position, this.charsImgs);
}
6 changes: 6 additions & 0 deletions lib/domain/services/data_service.dart
Expand Up @@ -63,4 +63,10 @@ abstract class DataService {
List<String> getAllUsedGameCodes();

Future<void> markCodeAsUsed(String code, {bool wasUsed = true});

List<TierListRowModel> getTierList();

Future<void> saveTierList(List<TierListRowModel> tierList);

Future<void> deleteTierList();
}
23 changes: 23 additions & 0 deletions lib/infrastructure/data_service.dart
Expand Up @@ -2,6 +2,7 @@ import 'package:genshindb/domain/app_constants.dart';
import 'package:genshindb/domain/assets.dart';
import 'package:genshindb/domain/enums/enums.dart';
import 'package:genshindb/domain/enums/item_type.dart';
import 'package:genshindb/domain/extensions/iterable_extensions.dart';
import 'package:genshindb/domain/extensions/string_extensions.dart';
import 'package:genshindb/domain/models/entities.dart';
import 'package:genshindb/domain/models/models.dart';
Expand All @@ -20,6 +21,7 @@ class DataServiceImpl implements DataService {
Box<InventoryItem> _inventoryBox;
Box<InventoryUsedItem> _inventoryUsedItemsBox;
Box<UsedGameCode> _usedGameCodesBox;
Box<TierListItem> _tierListBox;

DataServiceImpl(this._genshinService, this._calculatorService);

Expand All @@ -32,6 +34,7 @@ class DataServiceImpl implements DataService {
_inventoryBox = await Hive.openBox<InventoryItem>('inventory');
_inventoryUsedItemsBox = await Hive.openBox<InventoryUsedItem>('inventoryUsedItems');
_usedGameCodesBox = await Hive.openBox<UsedGameCode>('usedGameCodes');
_tierListBox = await Hive.openBox<TierListItem>('tierList');
}

@override
Expand Down Expand Up @@ -375,13 +378,33 @@ class DataServiceImpl implements DataService {
}
}

@override
List<TierListRowModel> getTierList() {
final values = _tierListBox.values.toList()..sort((x, y) => x.position.compareTo(y.position));
return values.map((e) => TierListRowModel.row(tierText: e.text, charImgs: e.charsImgs, tierColor: e.color)).toList();
}

@override
Future<void> saveTierList(List<TierListRowModel> tierList) async {
await deleteTierList();
final toSave = tierList.mapIndex((e, i) => TierListItem(e.tierText, e.tierColor, i, e.charImgs)).toList();
await _tierListBox.addAll(toSave);
}

@override
Future<void> deleteTierList() async {
final keys = _tierListBox.values.map((e) => e.key);
await _tierListBox.deleteAll(keys);
}

void _registerAdapters() {
Hive.registerAdapter(CalculatorCharacterSkillAdapter());
Hive.registerAdapter(CalculatorItemAdapter());
Hive.registerAdapter(CalculatorSessionAdapter());
Hive.registerAdapter(InventoryItemAdapter());
Hive.registerAdapter(InventoryUsedItemAdapter());
Hive.registerAdapter(UsedGameCodeAdapter());
Hive.registerAdapter(TierListItemAdapter());
}

ItemAscensionMaterials _buildForCharacter(CalculatorItem item, {int calculatorItemKey, bool includeInventory = false}) {
Expand Down
3 changes: 2 additions & 1 deletion lib/main.dart
Expand Up @@ -159,9 +159,10 @@ class MyApp extends StatelessWidget {
BlocProvider(
create: (_) {
final genshinService = getIt<GenshinService>();
final dataService = getIt<DataService>();
final telemetryService = getIt<TelemetryService>();
final loggingService = getIt<LoggingService>();
return TierListBloc(genshinService, telemetryService, loggingService);
return TierListBloc(genshinService, dataService, telemetryService, loggingService);
},
),
BlocProvider(
Expand Down
2 changes: 2 additions & 0 deletions lib/presentation/home/widgets/sliver_tierlist_card.dart
Expand Up @@ -30,5 +30,7 @@ class SliverTierList extends StatelessWidget {
context.read<TierListBloc>().add(const TierListEvent.init());
final route = MaterialPageRoute(builder: (c) => TierListPage());
await Navigator.push(context, route);
await route.completed;
context.read<TierListBloc>().add(const TierListEvent.close());
}
}

0 comments on commit 530f20b

Please sign in to comment.