feat: split legacy/payment apps via APP_MODE flag
This commit is contained in:
20
apps/mobile_app/lib/core/config/app_mode.dart
Normal file
20
apps/mobile_app/lib/core/config/app_mode.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
/// Compile-time constant that controls which app the splash screen
|
||||
/// navigates to when the app starts.
|
||||
///
|
||||
/// Set via `--dart-define=APP_MODE=payment` (or `legacy`) at launch time.
|
||||
/// Defaults to `legacy` to preserve historical behavior when no flag is
|
||||
/// passed (e.g. `flutter run` from CLI without arguments).
|
||||
///
|
||||
/// Used only for local development to switch between the legacy app
|
||||
/// (watch/device control) and the payment app (Treezor wallet) without
|
||||
/// needing separate flavors or entry points.
|
||||
const String appMode = String.fromEnvironment(
|
||||
'APP_MODE',
|
||||
defaultValue: 'legacy',
|
||||
);
|
||||
|
||||
/// Whether the app should boot into the payment (Treezor wallet) flow.
|
||||
bool get isPaymentMode => appMode == 'payment';
|
||||
|
||||
/// Whether the app should boot into the legacy (watch/device) flow.
|
||||
bool get isLegacyMode => appMode == 'legacy';
|
||||
@@ -7,6 +7,7 @@ import 'package:design_system/design_system.dart';
|
||||
import 'package:sca_treezor/sca_treezor.dart';
|
||||
import 'package:sf_app_platform/config/env/environment_enum.dart';
|
||||
import 'package:sf_app_platform/config/env/questia_env_config.dart';
|
||||
import 'package:sf_app_platform/core/config/app_mode.dart';
|
||||
import 'package:sf_app_platform/navigation/app_router.dart';
|
||||
import 'package:sf_app_platform/save_family_app.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
@@ -30,9 +31,11 @@ Future<void> initApp(EnvironmentEnum env) async {
|
||||
await configureDependencies(
|
||||
QuestiaEnvConfig(),
|
||||
log: env.isDevelopment || kDebugMode,
|
||||
onTokenExpired: () => appRouter.go(
|
||||
AppRoutes.legacyLogin,
|
||||
), //change to payments app to AppRoutes.scaTreezor
|
||||
// Treezor-specific detection (message + 500) runs in both modes;
|
||||
// only the destination route differs based on the active app mode.
|
||||
onTokenExpired: isPaymentMode
|
||||
? () => appRouter.go(AppRoutes.scaTreezor)
|
||||
: () => appRouter.go(AppRoutes.legacyLogin),
|
||||
onUnauthorized: () async {
|
||||
final currentLocation =
|
||||
appRouter.routerDelegate.currentConfiguration.uri.path;
|
||||
@@ -41,7 +44,7 @@ Future<void> initApp(EnvironmentEnum env) async {
|
||||
await GetIt.I<TreezorWalletConnectionService>().logout();
|
||||
} catch (_) {}
|
||||
await clearSessionData();
|
||||
appRouter.go(AppRoutes.legacyLogin);
|
||||
appRouter.go(isPaymentMode ? AppRoutes.login : AppRoutes.legacyLogin);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -17,13 +17,33 @@ import 'package:notifications/notifications.dart';
|
||||
import 'package:payments/payments.dart';
|
||||
import 'package:profile/profile.dart';
|
||||
import 'package:settings/settings.dart';
|
||||
import 'package:sf_app_platform/core/config/app_mode.dart';
|
||||
import 'package:splash/splash.dart';
|
||||
|
||||
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
late final GoRouter appRouter;
|
||||
|
||||
/// Maps the splash's session check result to the destination route based
|
||||
/// on the active [appMode]. Set `--dart-define=APP_MODE=payment` (or use
|
||||
/// the `(Payment)` launch configurations) to boot into the payment app.
|
||||
const _legacySplashRouteMap = <InitialRoute, String>{
|
||||
InitialRoute.onboarding: AppRoutes.legacyOnboarding,
|
||||
InitialRoute.login: AppRoutes.legacyLogin,
|
||||
InitialRoute.home: AppRoutes.controlPanel,
|
||||
};
|
||||
|
||||
const _paymentSplashRouteMap = <InitialRoute, String>{
|
||||
InitialRoute.onboarding: AppRoutes.onboarding,
|
||||
InitialRoute.login: AppRoutes.login,
|
||||
InitialRoute.home: AppRoutes.dashboardHome,
|
||||
};
|
||||
|
||||
void configureAppRouter() {
|
||||
final splashRouteMap = isPaymentMode
|
||||
? _paymentSplashRouteMap
|
||||
: _legacySplashRouteMap;
|
||||
|
||||
appRouter = GoRouter(
|
||||
navigatorKey: rootNavigatorKey,
|
||||
initialLocation: AppRoutes.splash,
|
||||
@@ -32,7 +52,7 @@ void configureAppRouter() {
|
||||
GoRoute(
|
||||
path: AppRoutes.splash,
|
||||
name: 'splash',
|
||||
pageBuilder: SplashBuilder().buildPage,
|
||||
pageBuilder: SplashBuilder(routeMap: splashRouteMap).buildPage,
|
||||
),
|
||||
StatefulShellRoute.indexedStack(
|
||||
builder: (context, state, navShell) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:auth/auth.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_app_platform/core/config/app_mode.dart';
|
||||
import 'package:sf_app_platform/navigation/app_router.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_app_platform/providers/app_state_provider.dart';
|
||||
@@ -24,48 +25,58 @@ class SaveFamilyApp extends ConsumerStatefulWidget {
|
||||
|
||||
class SaveFamilyAppState extends ConsumerState<SaveFamilyApp>
|
||||
with WidgetsBindingObserver {
|
||||
late final WalletHeartbeatService walletHeartbeat;
|
||||
late final LegacyHeartbeatService legacyHeartbeat;
|
||||
WalletHeartbeatService? _walletHeartbeat;
|
||||
LegacyHeartbeatService? _legacyHeartbeat;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
walletHeartbeat = WalletHeartbeatService(
|
||||
repository: ref.read(treezorRepositoryProvider),
|
||||
sessionLocal: SessionLocalDatasourceImpl(),
|
||||
onError: () => appRouter.go(
|
||||
AppRoutes.legacyLogin,
|
||||
), //change to payments app to AppRoutes.scaTreezor
|
||||
);
|
||||
legacyHeartbeat = LegacyHeartbeatService(
|
||||
repository: GetIt.I<QuestiaRepository>(),
|
||||
onUnauthorized: () {
|
||||
clearSessionData();
|
||||
appRouter.go(AppRoutes.legacyLogin);
|
||||
},
|
||||
);
|
||||
|
||||
if (isPaymentMode) {
|
||||
_walletHeartbeat = WalletHeartbeatService(
|
||||
repository: ref.read(treezorRepositoryProvider),
|
||||
sessionLocal: SessionLocalDatasourceImpl(),
|
||||
onError: () => appRouter.go(AppRoutes.scaTreezor),
|
||||
);
|
||||
}
|
||||
|
||||
if (isLegacyMode) {
|
||||
_legacyHeartbeat = LegacyHeartbeatService(
|
||||
repository: GetIt.I<QuestiaRepository>(),
|
||||
onUnauthorized: () {
|
||||
clearSessionData();
|
||||
appRouter.go(AppRoutes.legacyLogin);
|
||||
},
|
||||
);
|
||||
appRouter.routerDelegate.addListener(_onRouteChanged);
|
||||
}
|
||||
|
||||
onBeforeSessionCleared = () {
|
||||
walletHeartbeat.stop();
|
||||
legacyHeartbeat.stop();
|
||||
_walletHeartbeat?.stop();
|
||||
_legacyHeartbeat?.stop();
|
||||
};
|
||||
appRouter.routerDelegate.addListener(_onRouteChanged);
|
||||
}
|
||||
|
||||
void _onRouteChanged() {
|
||||
final heartbeat = _legacyHeartbeat;
|
||||
if (heartbeat == null) return;
|
||||
|
||||
final location = appRouter.routerDelegate.currentConfiguration.uri.path;
|
||||
if (location.startsWith(AppRoutes.legacyDashboard)) {
|
||||
legacyHeartbeat.start();
|
||||
heartbeat.start();
|
||||
} else {
|
||||
legacyHeartbeat.stop();
|
||||
heartbeat.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
appRouter.routerDelegate.removeListener(_onRouteChanged);
|
||||
walletHeartbeat.stop();
|
||||
legacyHeartbeat.stop();
|
||||
if (isLegacyMode) {
|
||||
appRouter.routerDelegate.removeListener(_onRouteChanged);
|
||||
}
|
||||
_walletHeartbeat?.stop();
|
||||
_legacyHeartbeat?.stop();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
super.dispose();
|
||||
}
|
||||
@@ -75,12 +86,14 @@ class SaveFamilyAppState extends ConsumerState<SaveFamilyApp>
|
||||
debugPrint('State: $state');
|
||||
ref.read(appLifecycleStateProvider.notifier).setState(state);
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
// walletHeartbeat.start();
|
||||
_onRouteChanged();
|
||||
_walletHeartbeat?.start();
|
||||
if (isLegacyMode) {
|
||||
_onRouteChanged();
|
||||
}
|
||||
ref.read(permissionsProvider.notifier).checkPermissions();
|
||||
} else if (state == AppLifecycleState.paused) {
|
||||
// walletHeartbeat.stop();
|
||||
legacyHeartbeat.stop();
|
||||
_walletHeartbeat?.stop();
|
||||
_legacyHeartbeat?.stop();
|
||||
}
|
||||
super.didChangeAppLifecycleState(state);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user