Skip to content

Commit

Permalink
Added an option to prompt for a double back to close the app
Browse files Browse the repository at this point in the history
  • Loading branch information
Wolfteam committed Apr 4, 2021
1 parent d0d635b commit f6a036b
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 22 deletions.
7 changes: 7 additions & 0 deletions lib/application/settings/settings_bloc.dart
Expand Up @@ -38,6 +38,7 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
showCharacterDetails: settings.showCharacterDetails,
showWeaponDetails: settings.showWeaponDetails,
serverResetTime: settings.serverResetTime,
doubleBackToClose: settings.doubleBackToClose,
);
},
themeChanged: (event) async {
Expand Down Expand Up @@ -68,8 +69,14 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
_homeBloc.add(const HomeEvent.init());
return currentState.copyWith.call(serverResetTime: event.newValue);
},
doubleBackToCloseChanged: (event) async {
_settingsService.doubleBackToClose = event.newValue;
return currentState.copyWith.call(doubleBackToClose: event.newValue);
},
);

yield s;
}

bool doubleBackToClose() => _settingsService.doubleBackToClose;
}
5 changes: 5 additions & 0 deletions lib/application/settings/settings_event.dart
Expand Up @@ -3,6 +3,7 @@ part of 'settings_bloc.dart';
@freezed
abstract class SettingsEvent with _$SettingsEvent {
const factory SettingsEvent.init() = _Init;

const factory SettingsEvent.themeChanged({
@required AppThemeType newValue,
}) = _ThemeChanged;
Expand All @@ -26,4 +27,8 @@ abstract class SettingsEvent with _$SettingsEvent {
const factory SettingsEvent.serverResetTimeChanged({
@required AppServerResetTimeType newValue,
}) = _ServerResetTimeChanged;

const factory SettingsEvent.doubleBackToCloseChanged({
@required bool newValue,
}) = _DoubleBackToCloseChanged;
}
1 change: 1 addition & 0 deletions lib/application/settings/settings_state.dart
Expand Up @@ -11,5 +11,6 @@ abstract class SettingsState with _$SettingsState {
@required bool showCharacterDetails,
@required bool showWeaponDetails,
@required AppServerResetTimeType serverResetTime,
@required bool doubleBackToClose,
}) = _LoadedState;
}
1 change: 1 addition & 0 deletions lib/domain/models/settings/app_settings.dart
Expand Up @@ -18,6 +18,7 @@ abstract class AppSettings implements _$AppSettings {
@required bool showWeaponDetails,
@required bool isFirstInstall,
@required AppServerResetTimeType serverResetTime,
@required bool doubleBackToClose,
}) = _AppSettings;
const AppSettings._();

Expand Down
3 changes: 3 additions & 0 deletions lib/domain/services/settings_service.dart
Expand Up @@ -25,5 +25,8 @@ abstract class SettingsService {
AppServerResetTimeType get serverResetTime;
set serverResetTime(AppServerResetTimeType time);

bool get doubleBackToClose;
set doubleBackToClose(bool value);

Future<void> init();
}
13 changes: 13 additions & 0 deletions lib/infrastructure/settings_service.dart
Expand Up @@ -14,6 +14,7 @@ class SettingsServiceImpl extends SettingsService {
final _showCharacterDetailsKey = 'ShowCharacterDetailsKey';
final _showWeaponDetailsKey = 'ShowWeaponDetailsKey';
final _serverResetTimeKey = 'ServerResetTimeKey';
final _doubleBackToCloseKey = 'DoubleBackToCloseKey';

bool _initialized = false;

Expand Down Expand Up @@ -62,6 +63,12 @@ class SettingsServiceImpl extends SettingsService {
@override
set serverResetTime(AppServerResetTimeType time) => _prefs.setInt(_serverResetTimeKey, time.index);

@override
bool get doubleBackToClose => _prefs.getBool(_doubleBackToCloseKey);

@override
set doubleBackToClose(bool value) => _prefs.setBool(_doubleBackToCloseKey, value);

@override
AppSettings get appSettings => AppSettings(
appTheme: appTheme,
Expand All @@ -72,6 +79,7 @@ class SettingsServiceImpl extends SettingsService {
showWeaponDetails: showWeaponDetails,
isFirstInstall: isFirstInstall,
serverResetTime: serverResetTime,
doubleBackToClose: doubleBackToClose,
);

SettingsServiceImpl(this._logger);
Expand Down Expand Up @@ -121,6 +129,11 @@ class SettingsServiceImpl extends SettingsService {
serverResetTime = AppServerResetTimeType.northAmerica;
}

if (_prefs.get(_doubleBackToCloseKey) == null) {
_logger.info(runtimeType, 'Double back to close will be set to its default (false)');
doubleBackToClose = false;
}

_initialized = true;
_logger.info(runtimeType, 'Settings were initialized successfully');
}
Expand Down
1 change: 1 addition & 0 deletions lib/infrastructure/telemetry/telemetry_service.dart
Expand Up @@ -97,6 +97,7 @@ class TelemetryServiceImpl implements TelemetryService {
'ShowWeaponDetails': settings.showWeaponDetails.toString(),
'IsFirstInstall': settings.isFirstInstall.toString(),
'ServerResetTime': EnumToString.convertToString(settings.serverResetTime),
'DoubleBackToClose': settings.doubleBackToClose.toString(),
});
}

Expand Down
3 changes: 2 additions & 1 deletion lib/l10n/intl_en.arb
Expand Up @@ -287,5 +287,6 @@
"hilichurl": "Hilichurl",
"fatui": "Fatui",
"automaton": "Automaton",
"droppedBy": "Dropped by"
"droppedBy": "Dropped by",
"pressOnceAgainToExit": "Press once again to exit"
}
3 changes: 2 additions & 1 deletion lib/l10n/intl_es_ES.arb
Expand Up @@ -287,5 +287,6 @@
"hilichurl": "Hilichurl",
"fatui": "Fatui",
"automaton": "Automata",
"droppedBy": "Dejado por"
"droppedBy": "Dejado por",
"pressOnceAgainToExit": "Presiona una vez más para salir"
}
27 changes: 14 additions & 13 deletions lib/l10n/intl_ru.arb
Expand Up @@ -154,7 +154,7 @@
"na": "N/A",
"mainDps": "Основной ДД",
"supportDps": "Саппорт ДД",
"utility": "Помощник",
"utility": "Поддержка",
"normalAttack": "Обычная Атака",
"elementalSkill": "Элементальная способность",
"elementalBurst": "Взрыв стихии",
Expand Down Expand Up @@ -237,19 +237,19 @@
"approximate": "приблизително",
"active": "Активно",
"inactive": "Неактивно",
"gameCodes": "Коды игры",
"gameCodes": "Промокоды игры",
"codes": "Коды",
"rewards": "Награда",
"codeXWasCopied": "Код {value} был скопирован в буфер обмена",
"expiredCodes": "Просроченные коды",
"workingCodes": "Рабочие коды",
"seeAllInGameGameCodes": "Посмотрите все игровые коды, которые вы можете использовать",
"codeXWasCopied": "Промокод: {value} был скопирован в буфер обмена",
"expiredCodes": "Просроченные",
"workingCodes": "Рабочие",
"seeAllInGameGameCodes": "Посмотрите все промокоды, которые вы можете использовать в игре",
"ingredient": "Ингредиент",
"talent": "Талант",
"local": "Local",
"local": "Местность",
"elementalStone": "Элементный камень",
"jewel": "Драгоценность",
"checkAllMaterials": "Проверить все доступные материалы",
"checkAllMaterials": "Посмотреть все доступные материалы",
"related": "Связаны между собой",
"obtainedFrom": "Создается",
"sessions": "Сессия",
Expand Down Expand Up @@ -281,12 +281,13 @@
"markAsUnused": "Пометить как неиспользуемые",
"monsters": "Монстры",
"checkAllMonsters": "Посмотреть всех доступных монстров",
"abyssOrder": "Маги бездны",
"elementalLifeForm": "Элементарная существа",
"abyssOrder": "Маги Бездны",
"elementalLifeForm": "Элемнтальные существа",
"human": "Люди",
"magicalBeast": "Магические существа",
"magicalBeast": "Мистические существа",
"hilichurl": "Хиличурлы",
"fatui": "Фатуи",
"automaton": "Механические существа",
"droppedBy": "Где получить"
"automaton": "Автоматоны",
"droppedBy": "Где получить",
"pressOnceAgainToExit": "Press once again to exit"
}
3 changes: 2 additions & 1 deletion lib/l10n/intl_zh_CN.arb
Expand Up @@ -288,5 +288,6 @@
"hilichurl": "丘丘人",
"fatui": "愚人众",
"automaton": "自律机关",
"droppedBy": "掉落于"
"droppedBy": "掉落于",
"pressOnceAgainToExit": "Press once again to exit"
}
40 changes: 35 additions & 5 deletions lib/presentation/main_tab_page.dart
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:genshindb/application/bloc.dart';
import 'package:genshindb/generated/l10n.dart';
import 'package:genshindb/presentation/shared/extensions/focus_scope_node_extensions.dart';
import 'package:genshindb/presentation/shared/utils/toast_utils.dart';
import 'package:rate_my_app/rate_my_app.dart';

import 'artifacts/artifacts_page.dart';
Expand All @@ -20,7 +21,8 @@ class MainTabPage extends StatefulWidget {
class _MainTabPageState extends State<MainTabPage> with SingleTickerProviderStateMixin {
bool _didChangeDependencies = false;
TabController _tabController;
int _index = 2;
int _index;
final _defaultIndex = 2;
final _pages = [
const CharactersPage(),
const WeaponsPage(),
Expand All @@ -29,8 +31,11 @@ class _MainTabPageState extends State<MainTabPage> with SingleTickerProviderStat
MapPage(),
];

DateTime backButtonPressTime;

@override
void initState() {
_index = _defaultIndex;
_tabController = TabController(
initialIndex: _index,
length: _pages.length,
Expand Down Expand Up @@ -86,13 +91,14 @@ class _MainTabPageState extends State<MainTabPage> with SingleTickerProviderStat
orElse: () => {},
);
},
builder: (context, state) {
return TabBarView(
builder: (context, state) => WillPopScope(
onWillPop: () => handleWillPop(context),
child: TabBarView(
controller: _tabController,
physics: const NeverScrollableScrollPhysics(),
children: _pages,
);
},
),
),
),
),
bottomNavigationBar: BottomNavigationBar(
Expand Down Expand Up @@ -126,4 +132,28 @@ class _MainTabPageState extends State<MainTabPage> with SingleTickerProviderStat
_tabController.index = index;
});
}

Future<bool> handleWillPop(BuildContext context) async {
if (_tabController.index != _defaultIndex) {
_gotoTab(_defaultIndex);
return false;
}
final settings = context.read<SettingsBloc>();
if (!settings.doubleBackToClose()) {
return true;
}

final s = S.of(context);
final now = DateTime.now();
final mustWait = backButtonPressTime == null || now.difference(backButtonPressTime) > ToastUtils.toastDuration;

if (mustWait) {
backButtonPressTime = now;
final fToast = ToastUtils.of(context);
ToastUtils.showInfoToast(fToast, s.pressOnceAgainToExit);
return false;
}

return true;
}
}
6 changes: 6 additions & 0 deletions lib/presentation/settings/widgets/other_settings.dart
Expand Up @@ -53,6 +53,12 @@ class OtherSettings extends StatelessWidget {
value: settingsState.showWeaponDetails,
onChanged: (newVal) => context.read<SettingsBloc>().add(SettingsEvent.showWeaponDetailsChanged(newValue: newVal)),
),
SwitchListTile(
activeColor: theme.accentColor,
title: Text(s.pressOnceAgainToExit),
value: settingsState.doubleBackToClose,
onChanged: (newVal) => context.read<SettingsBloc>().add(SettingsEvent.doubleBackToCloseChanged(newValue: newVal)),
),
ListTile(
dense: true,
contentPadding: EdgeInsets.zero,
Expand Down
4 changes: 3 additions & 1 deletion lib/presentation/shared/utils/toast_utils.dart
Expand Up @@ -9,6 +9,8 @@ enum ToastType {
}

class ToastUtils {
static Duration toastDuration = const Duration(seconds: 2);

static FToast of(BuildContext context) {
final fToast = FToast();
fToast.init(context);
Expand Down Expand Up @@ -56,7 +58,7 @@ class ToastUtils {
toast.showToast(
child: widget,
gravity: ToastGravity.BOTTOM,
toastDuration: const Duration(seconds: 2),
toastDuration: toastDuration,
);
}

Expand Down

0 comments on commit f6a036b

Please sign in to comment.