Merge remote-tracking branch 'origin/feature/remote-management' into feature/remote-management
This commit is contained in:
@@ -26,7 +26,7 @@ late final GoRouter appRouter;
|
||||
void configureAppRouter() {
|
||||
appRouter = GoRouter(
|
||||
navigatorKey: rootNavigatorKey,
|
||||
initialLocation: AppRoutes.onboarding,
|
||||
initialLocation: AppRoutes.splash,
|
||||
debugLogDiagnostics: true,
|
||||
routes: [
|
||||
GoRoute(
|
||||
|
||||
42
apps/mobile_app/lib/providers/legacy_heartbeat_service.dart
Normal file
42
apps/mobile_app/lib/providers/legacy_heartbeat_service.dart
Normal file
@@ -0,0 +1,42 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
class LegacyHeartbeatService {
|
||||
LegacyHeartbeatService({
|
||||
required QuestiaRepository repository,
|
||||
required void Function() onUnauthorized,
|
||||
}) : _repository = repository,
|
||||
_onUnauthorized = onUnauthorized;
|
||||
|
||||
final QuestiaRepository _repository;
|
||||
final void Function() _onUnauthorized;
|
||||
Timer? _timer;
|
||||
|
||||
static const _interval = Duration(minutes: 3);
|
||||
|
||||
void start() {
|
||||
if (_timer != null) return;
|
||||
_beat();
|
||||
_timer = Timer.periodic(_interval, (_) => _beat());
|
||||
debugPrint('[LegacyHeartbeat] started');
|
||||
}
|
||||
|
||||
void stop() {
|
||||
_timer?.cancel();
|
||||
_timer = null;
|
||||
debugPrint('[LegacyHeartbeat] stopped');
|
||||
}
|
||||
|
||||
Future<void> _beat() async {
|
||||
try {
|
||||
await _repository.get<dynamic>('/auth/me');
|
||||
debugPrint('[LegacyHeartbeat] /auth/me => OK');
|
||||
} catch (e) {
|
||||
debugPrint('[LegacyHeartbeat] error: $e');
|
||||
stop();
|
||||
_onUnauthorized();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,9 @@ import 'package:sf_app_platform/navigation/app_router.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_app_platform/providers/app_state_provider.dart';
|
||||
import 'package:sf_app_platform/providers/permissions/permissions_provider.dart';
|
||||
import 'package:sf_app_platform/providers/legacy_heartbeat_service.dart';
|
||||
import 'package:sf_app_platform/providers/wallet_heartbeat_service.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
@@ -23,6 +25,7 @@ class SaveFamilyApp extends ConsumerStatefulWidget {
|
||||
class SaveFamilyAppState extends ConsumerState<SaveFamilyApp>
|
||||
with WidgetsBindingObserver {
|
||||
late final WalletHeartbeatService walletHeartbeat;
|
||||
late final LegacyHeartbeatService legacyHeartbeat;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -33,13 +36,25 @@ class SaveFamilyAppState extends ConsumerState<SaveFamilyApp>
|
||||
sessionLocal: SessionLocalDatasourceImpl(),
|
||||
onError: () => appRouter.go(AppRoutes.scaTreezor),
|
||||
);
|
||||
onBeforeSessionCleared = walletHeartbeat.stop;
|
||||
legacyHeartbeat = LegacyHeartbeatService(
|
||||
repository: GetIt.I<QuestiaRepository>(),
|
||||
onUnauthorized: () {
|
||||
clearSessionData();
|
||||
appRouter.go(AppRoutes.legacyLogin);
|
||||
},
|
||||
);
|
||||
onBeforeSessionCleared = () {
|
||||
walletHeartbeat.stop();
|
||||
legacyHeartbeat.stop();
|
||||
};
|
||||
// walletHeartbeat.start();
|
||||
legacyHeartbeat.start();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
walletHeartbeat.stop();
|
||||
legacyHeartbeat.stop();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
super.dispose();
|
||||
}
|
||||
@@ -50,9 +65,11 @@ class SaveFamilyAppState extends ConsumerState<SaveFamilyApp>
|
||||
ref.read(appLifecycleStateProvider.notifier).setState(state);
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
// walletHeartbeat.start();
|
||||
legacyHeartbeat.start();
|
||||
ref.read(permissionsProvider.notifier).checkPermissions();
|
||||
} else if (state == AppLifecycleState.paused) {
|
||||
// walletHeartbeat.stop();
|
||||
legacyHeartbeat.stop();
|
||||
}
|
||||
super.didChangeAppLifecycleState(state);
|
||||
}
|
||||
|
||||
@@ -26,14 +26,14 @@ class AccountSettingsScreen extends ConsumerWidget {
|
||||
accountSettingsViewModelProvider.select((s) => s.isLoggingOut),
|
||||
);
|
||||
|
||||
ref.listen(
|
||||
accountSettingsViewModelProvider.select((s) => s.isLoggingOut),
|
||||
(prev, isLoggingOut) {
|
||||
if (prev == true && !isLoggingOut) {
|
||||
navigationContract.goTo(AppRoutes.legacyLogin);
|
||||
}
|
||||
},
|
||||
);
|
||||
ref.listen(accountSettingsViewModelProvider.select((s) => s.isLoggingOut), (
|
||||
prev,
|
||||
isLoggingOut,
|
||||
) {
|
||||
if (prev == true && !isLoggingOut) {
|
||||
navigationContract.goTo(AppRoutes.legacyLogin);
|
||||
}
|
||||
});
|
||||
|
||||
return LegacyPageLayout(
|
||||
theme: theme,
|
||||
@@ -46,11 +46,39 @@ class AccountSettingsScreen extends ConsumerWidget {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.personalData), icon: SFIcons.account, text: I18n.personalData, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.changePassword), icon: Icons.lock, text: I18n.changePassword, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.legacyDeviceSetup), icon: Icons.add_circle_outline, text: I18n.addNewSF, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.linkedDevices), icon: Icons.account_circle_outlined, text: I18n.linkedDevices, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.appUsers), icon: Icons.groups_outlined, text: I18n.appUsers, color: color),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.personalData),
|
||||
icon: SFIcons.account,
|
||||
text: I18n.personalData,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.changePassword),
|
||||
icon: Icons.lock,
|
||||
text: I18n.changePassword,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.legacyDeviceSetup),
|
||||
icon: Icons.add_circle_outline,
|
||||
text: I18n.addNewSF,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.linkedDevices),
|
||||
icon: Icons.account_circle_outlined,
|
||||
text: I18n.linkedDevices,
|
||||
color: color,
|
||||
),
|
||||
// _item(context, onPressed: () => navigationContract.pushTo(AppRoutes.appUsers), icon: Icons.groups_outlined, text: I18n.appUsers, color: color),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () async {
|
||||
@@ -82,7 +110,14 @@ class AccountSettingsScreen extends ConsumerWidget {
|
||||
text: I18n.regCode,
|
||||
color: color,
|
||||
),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.deleteAccount), icon: Icons.no_accounts, text: I18n.deleteAccount, color: color),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.deleteAccount),
|
||||
icon: Icons.no_accounts,
|
||||
text: I18n.deleteAccount,
|
||||
color: color,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -121,7 +156,9 @@ class AccountSettingsScreen extends ConsumerWidget {
|
||||
required Color color,
|
||||
}) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
padding: EdgeInsets.only(
|
||||
bottom: SizeUtils.getByScreen(small: 16, big: 15),
|
||||
),
|
||||
child: SectionButton(
|
||||
onPressed: onPressed,
|
||||
icon: Icon(
|
||||
|
||||
@@ -27,14 +27,14 @@ class DeviceManagementScreen extends ConsumerWidget {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.remoteConnection),
|
||||
icon: SFIcons.connection,
|
||||
text: context.translate(I18n.remoteConnection),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
// AppMenuButton(
|
||||
// color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
// onPressed: () =>
|
||||
// navigationContract.pushTo(AppRoutes.remoteConnection),
|
||||
// icon: SFIcons.connection,
|
||||
// text: context.translate(I18n.remoteConnection),
|
||||
// ),
|
||||
// SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () =>
|
||||
@@ -106,8 +106,7 @@ class DeviceManagementScreen extends ConsumerWidget {
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.appsUse),
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.appsUse),
|
||||
icon: SFIcons.screenTime,
|
||||
text: context.translate(I18n.appsUse),
|
||||
),
|
||||
|
||||
@@ -27,21 +27,111 @@ class SettingsScreen extends ConsumerWidget {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.alarm), icon: Icons.notifications_outlined, text: I18n.alarm, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.appStore), icon: Icons.apps_rounded, text: I18n.appStore, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.blockPhone), icon: Icons.phone_outlined, text: I18n.blockPhone, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.timezone), icon: Icons.check, text: I18n.timezone, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.language), icon: Icons.translate_outlined, text: I18n.language, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.battery), icon: Icons.nightlight_outlined, text: I18n.battery, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.remoteManagement), icon: Icons.settings_remote_outlined, text: I18n.remoteManagement, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.legacyNotifications), icon: Icons.message_outlined, text: I18n.legacyNotifications, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.smsAlert), icon: Icons.sms_outlined, text: I18n.smsAlert, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.sosContacts), icon: Icons.perm_contact_calendar_outlined, text: I18n.sosContacts, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.sound), icon: Icons.volume_up_outlined, text: I18n.sound, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.wifiSettings), icon: Icons.wifi_find_outlined, text: I18n.wifiSettings, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.remoteOnOff), icon: Icons.settings_power_outlined, text: I18n.remoteOnOff, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.disableFunctions), icon: Icons.dashboard_customize_outlined, text: I18n.disableFunctions, color: color),
|
||||
_item(context, onPressed: () => navigationContract.pushTo(AppRoutes.syncClock), icon: Icons.share_arrival_time_outlined, text: I18n.syncClock, color: color),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.alarm),
|
||||
icon: Icons.notifications_outlined,
|
||||
text: I18n.alarm,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.appStore),
|
||||
icon: Icons.apps_rounded,
|
||||
text: I18n.appStore,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.blockPhone),
|
||||
icon: Icons.phone_outlined,
|
||||
text: I18n.blockPhone,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.timezone),
|
||||
icon: Icons.check,
|
||||
text: I18n.timezone,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.language),
|
||||
icon: Icons.translate_outlined,
|
||||
text: I18n.language,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.battery),
|
||||
icon: Icons.nightlight_outlined,
|
||||
text: I18n.battery,
|
||||
color: color,
|
||||
),
|
||||
// _item(context, onPressed: () => navigationContract.pushTo(AppRoutes.remoteManagement), icon: Icons.settings_remote_outlined, text: I18n.remoteManagement, color: color),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.legacyNotifications),
|
||||
icon: Icons.message_outlined,
|
||||
text: I18n.legacyNotifications,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.smsAlert),
|
||||
icon: Icons.sms_outlined,
|
||||
text: I18n.smsAlert,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.sosContacts),
|
||||
icon: Icons.perm_contact_calendar_outlined,
|
||||
text: I18n.sosContacts,
|
||||
color: color,
|
||||
),
|
||||
// _item(
|
||||
// context,
|
||||
// onPressed: () => navigationContract.pushTo(AppRoutes.sound),
|
||||
// icon: Icons.volume_up_outlined,
|
||||
// text: I18n.sound,
|
||||
// color: color,
|
||||
// ),
|
||||
// _item(
|
||||
// context,
|
||||
// onPressed: () =>
|
||||
// navigationContract.pushTo(AppRoutes.wifiSettings),
|
||||
// icon: Icons.wifi_find_outlined,
|
||||
// text: I18n.wifiSettings,
|
||||
// color: color,
|
||||
// ),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.remoteOnOff),
|
||||
icon: Icons.settings_power_outlined,
|
||||
text: I18n.remoteOnOff,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.disableFunctions),
|
||||
icon: Icons.dashboard_customize_outlined,
|
||||
text: I18n.disableFunctions,
|
||||
color: color,
|
||||
),
|
||||
_item(
|
||||
context,
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.syncClock),
|
||||
icon: Icons.share_arrival_time_outlined,
|
||||
text: I18n.syncClock,
|
||||
color: color,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -12,7 +12,7 @@ class CheckSessionUseCaseImpl implements CheckSessionUseCase {
|
||||
@override
|
||||
Future<InitialRoute> execute() async {
|
||||
try {
|
||||
await _userRepository.getChildProfiles();
|
||||
await _userRepository.getUserInfo();
|
||||
return InitialRoute.home;
|
||||
} catch (e) {
|
||||
debugPrint('[CheckSessionUseCase] error: $e');
|
||||
|
||||
@@ -53,8 +53,8 @@ class _SplashScreenState extends State<SplashScreen>
|
||||
if (!_animationDone || _route == null || !mounted) return;
|
||||
|
||||
final destination = switch (_route!) {
|
||||
InitialRoute.login => AppRoutes.login,
|
||||
InitialRoute.home => AppRoutes.dashboardHome,
|
||||
InitialRoute.login => AppRoutes.legacyLogin,
|
||||
InitialRoute.home => AppRoutes.controlPanel,
|
||||
};
|
||||
widget.navigationContract.goTo(destination);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user