diff --git a/lib/application/game_codes/game_codes_bloc.dart b/lib/application/game_codes/game_codes_bloc.dart index 252dad245..61fc30dfe 100644 --- a/lib/application/game_codes/game_codes_bloc.dart +++ b/lib/application/game_codes/game_codes_bloc.dart @@ -4,6 +4,8 @@ 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/game_code_service.dart'; +import 'package:genshindb/domain/services/network_service.dart'; import 'package:genshindb/domain/services/telemetry_service.dart'; import 'package:meta/meta.dart'; @@ -16,12 +18,29 @@ const _initialState = GameCodesState.loaded(workingGameCodes: [], expiredGameCod class GameCodesBloc extends Bloc { final DataService _dataService; final TelemetryService _telemetryService; + final GameCodeService _gameCodeService; + final NetworkService _networkService; - GameCodesBloc(this._dataService, this._telemetryService) : super(_initialState); + GameCodesBloc(this._dataService, this._telemetryService, this._gameCodeService, this._networkService) : super(_initialState); @override Stream mapEventToState(GameCodesEvent event) async* { - final s = await event.when( + if (event is _Refresh) { + final isInternetAvailable = await _networkService.isInternetAvailable(); + if (!isInternetAvailable) { + yield state.copyWith.call(isInternetAvailable: false); + yield state.copyWith.call(isInternetAvailable: null); + return; + } + yield _initialState.copyWith.call(isBusy: true, workingGameCodes: [], expiredGameCodes: []); + final gameCodes = await _gameCodeService.getAllGameCodes(); + await _dataService.saveGameCodes(gameCodes); + + add(const GameCodesEvent.init()); + return; + } + + final s = await event.maybeWhen( init: () async { await _telemetryService.trackGameCodesOpened(); return _buildInitialState(); @@ -31,6 +50,7 @@ class GameCodesBloc extends Bloc { return _buildInitialState(); }, close: () async => _initialState, + orElse: () async => _initialState, ); yield s; diff --git a/lib/application/game_codes/game_codes_event.dart b/lib/application/game_codes/game_codes_event.dart index 272d05601..cf6cc1b3e 100644 --- a/lib/application/game_codes/game_codes_event.dart +++ b/lib/application/game_codes/game_codes_event.dart @@ -9,5 +9,7 @@ abstract class GameCodesEvent with _$GameCodesEvent { @required bool wasUsed, }) = _MarkAsUsed; + const factory GameCodesEvent.refresh() = _Refresh; + const factory GameCodesEvent.close() = _Close; } diff --git a/lib/application/game_codes/game_codes_state.dart b/lib/application/game_codes/game_codes_state.dart index d1110c109..411fd8396 100644 --- a/lib/application/game_codes/game_codes_state.dart +++ b/lib/application/game_codes/game_codes_state.dart @@ -5,5 +5,7 @@ abstract class GameCodesState with _$GameCodesState { const factory GameCodesState.loaded({ @required List workingGameCodes, @required List expiredGameCodes, + @Default(false) bool isBusy, + bool isInternetAvailable, }) = _Loaded; } diff --git a/lib/domain/assets.dart b/lib/domain/assets.dart index ef6b4052d..e059b4e85 100644 --- a/lib/domain/assets.dart +++ b/lib/domain/assets.dart @@ -8,7 +8,6 @@ class Assets { static String artifactsDbPath = '$dbPath/artifacts.json'; static String materialsDbPath = '$dbPath/materials.json'; static String elementsDbPath = '$dbPath/elements.json'; - static String gameCodesDbPath = '$dbPath/game_codes.json'; static String monstersDbPath = '$dbPath/monsters.json'; static String translationsBasePath = 'assets/i18n'; @@ -44,6 +43,7 @@ class Assets { //Others static String otherImgsBasePath = 'assets/others'; + static String noImageAvailablePath = '$othersBasePath/$noImageAvailableName'; //Monsters static String monstersImgsBasePath = 'assets/monsters'; diff --git a/lib/domain/services/data_service.dart b/lib/domain/services/data_service.dart index 02b10b502..d2419a8aa 100644 --- a/lib/domain/services/data_service.dart +++ b/lib/domain/services/data_service.dart @@ -68,7 +68,11 @@ abstract class DataService { List getAllGameCodes(); - List getAllUsedGameCodes(); + Future saveGameCodes(List items); + + Future saveGameCodeRewards(int gameCodeKey, List rewards); + + Future deleteAllGameCodeRewards(int gameCodeKey); Future markCodeAsUsed(String code, {bool wasUsed = true}); diff --git a/lib/domain/services/game_code_service.dart b/lib/domain/services/game_code_service.dart new file mode 100644 index 000000000..6396d4c6c --- /dev/null +++ b/lib/domain/services/game_code_service.dart @@ -0,0 +1,5 @@ +import 'package:genshindb/domain/models/models.dart'; + +abstract class GameCodeService { + Future> getAllGameCodes(); +} diff --git a/lib/domain/services/genshin_service.dart b/lib/domain/services/genshin_service.dart index f8ebdd19b..9ba9b3c99 100644 --- a/lib/domain/services/genshin_service.dart +++ b/lib/domain/services/genshin_service.dart @@ -8,7 +8,6 @@ abstract class GenshinService { Future initArtifacts(); Future initMaterials(); Future initElements(); - Future initGameCodes(); Future initMonsters(); Future initTranslations(AppLanguageType languageType); @@ -60,8 +59,6 @@ abstract class GenshinService { int getServerDay(AppServerResetTimeType type); DateTime getServerDate(AppServerResetTimeType type); - List getAllGameCodes(); - List getUpcomingKeys(); MonsterFileModel getMonster(String key); diff --git a/lib/domain/utils/date_utils.dart b/lib/domain/utils/date_utils.dart new file mode 100644 index 000000000..1649fa402 --- /dev/null +++ b/lib/domain/utils/date_utils.dart @@ -0,0 +1,25 @@ +import 'package:intl/intl.dart'; + +class DateUtils { + static const String defaultFormat = 'dd/MM/yyyy hh:mm:ss a'; + static const String twentyFourHoursFormat = 'dd/MM/yyyy HH:mm:ss'; + static const String dayMonthYearFormat = 'dd/MM/yyyy'; + + static String formatDate( + DateTime date, { + String locale, + String format = defaultFormat, + }) { + if (date == null) { + return 'N/A'; + } + final formatter = DateFormat(format, locale); + final formatted = formatter.format(date); + return formatted; + } + + static String formatDateMilitaryTime(DateTime date, {bool useTwentyFourHoursFormat = false}) { + final format = useTwentyFourHoursFormat ? twentyFourHoursFormat : defaultFormat; + return formatDate(date, format: format); + } +}