diff --git a/lib/app.dart b/lib/app.dart index 2af1624..3cfa326 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -102,6 +102,7 @@ class _NotesAppState extends State setState(() { _themeSeedColor = Color(storedColorValue); + _themeData = AppTheme.theme(seedColor: _themeSeedColor); }); } @@ -115,10 +116,14 @@ class _NotesAppState extends State setState(() { _themeSeedColor = color; + _themeData = AppTheme.theme(seedColor: _themeSeedColor); }); } - ThemeData get _theme => AppTheme.theme(seedColor: _themeSeedColor); + // Cached ThemeData to avoid recomputing on every build. + ThemeData? _themeData; + + ThemeData get _theme => _themeData ??= AppTheme.theme(seedColor: _themeSeedColor); @override void didChangeAppLifecycleState(AppLifecycleState state) { @@ -767,43 +772,30 @@ class _NotesAppState extends State } Widget _buildLoadingScreen() { - return MaterialApp( - navigatorKey: _navigatorKey, - title: 'Mis Notas', - debugShowCheckedModeBanner: false, - theme: _theme, - home: const Scaffold( - body: SafeArea( - child: Column( - children: [ - Expanded( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CircularProgressIndicator(), - SizedBox(height: 16), - Text('Preparando el vault local...'), - ], - ), + return const Scaffold( + body: SafeArea( + child: Column( + children: [ + Expanded( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircularProgressIndicator(), + SizedBox(height: 16), + Text('Preparando el vault local...'), + ], ), ), - ], - ), + ), + ], ), ), ); } Widget _buildAppShell({required Widget home}) { - return MaterialApp( - navigatorKey: _navigatorKey, - title: 'Mis Notas', - debugShowCheckedModeBanner: false, - scaffoldMessengerKey: _scaffoldMessengerKey, - theme: _theme, - home: home, - ); + return home; } Widget _buildMainShell(NoteRepository repository) { @@ -829,69 +821,62 @@ class _NotesAppState extends State onThemeColorSelected: _setThemeSeedColor, ); - return MaterialApp( - navigatorKey: _navigatorKey, - title: 'Mis Notas', - debugShowCheckedModeBanner: false, - scaffoldMessengerKey: _scaffoldMessengerKey, - theme: _theme, - home: Shortcuts( - shortcuts: { - LogicalKeySet(LogicalKeyboardKey.f5): const PerformSyncIntent(), + return Shortcuts( + shortcuts: { + LogicalKeySet(LogicalKeyboardKey.f5): const PerformSyncIntent(), + }, + child: Actions( + actions: >{ + PerformSyncIntent: CallbackAction( + onInvoke: (PerformSyncIntent intent) { + _performSync(); + return null; + }, + ), }, - child: Actions( - actions: >{ - PerformSyncIntent: CallbackAction( - onInvoke: (PerformSyncIntent intent) { - _performSync(); - return null; - }, - ), - }, - child: Focus( - autofocus: true, - child: Scaffold( - body: Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [ - Color(0xFF191A1D), - Color(0xFF222326), - Color(0xFF101114), - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), + child: Focus( + autofocus: true, + child: Scaffold( + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [ + Color(0xFF191A1D), + Color(0xFF222326), + Color(0xFF101114), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, ), - child: SafeArea( - child: Column( - children: [ - Expanded( - child: AnimatedSwitcher( - duration: _screenTransitionDuration, - switchInCurve: Curves.easeOutCubic, - switchOutCurve: Curves.easeInCubic, - transitionBuilder: - (Widget child, Animation animation) { - final Animation offsetAnimation = - Tween( - begin: const Offset(0.08, 0.0), - end: Offset.zero, - ).animate(animation); + ), + child: SafeArea( + child: Column( + children: [ + Expanded( + child: AnimatedSwitcher( + duration: _screenTransitionDuration, + switchInCurve: Curves.easeOutCubic, + switchOutCurve: Curves.easeInCubic, + transitionBuilder: + (Widget child, Animation animation) { + final Animation offsetAnimation = + Tween( + begin: const Offset(0.08, 0.0), + end: Offset.zero, + ).animate(animation); - return FadeTransition( - opacity: animation, - child: SlideTransition( - position: offsetAnimation, - child: child, - ), - ); - }, - child: activeScreen, - ), + return FadeTransition( + opacity: animation, + child: SlideTransition( + position: offsetAnimation, + child: child, + ), + ); + }, + child: activeScreen, ), - ], - ), + ), + ], ), ), ), @@ -951,64 +936,76 @@ class _NotesAppState extends State @override Widget build(BuildContext context) { + Widget homeWidget; + if (_isBootstrapping) { - return _buildLoadingScreen(); - } + homeWidget = _buildLoadingScreen(); + } else { + final NoteRepository? repository = _repository; - final NoteRepository? repository = _repository; - - if (repository != null) { - return _buildMainShell(repository); - } - - switch (_phase) { - case _AppPhase.loading: - return _buildLoadingScreen(); - case _AppPhase.access: - return _buildAppShell( - home: VaultAccessScreen( - isBusy: _isUnlocking, - onCreateAccountPressed: (String email, String password) async { - await _beginRemoteVaultFlow( - username: email, - password: password, - isRegister: true, - ); - }, - onSignInPressed: (String email, String password) async { - await _beginRemoteVaultFlow( - username: email, - password: password, - isRegister: false, - ); - }, - onContinueWithoutAccount: _enterWithoutAccount, - ), - ); - case _AppPhase.biometricChoice: - return _buildAppShell( - home: BiometricChoiceScreen( - isBusy: _isUnlocking, - onEnableBiometrics: () => - _completeBiometricChoice(enableBiometrics: true), - onSkipBiometrics: () => - _completeBiometricChoice(enableBiometrics: false), - ), - ); - case _AppPhase.biometricGate: - return _buildAppShell( - home: BiometricGateScreen( - key: ValueKey(_biometricGateSession), - isBusy: _isUnlocking, - onUnlockRequested: _unlockBiometricGate, - ), - ); - case _AppPhase.notes: - if (repository == null) { - return _buildLoadingScreen(); + if (repository != null) { + homeWidget = _buildMainShell(repository); + } else { + switch (_phase) { + case _AppPhase.loading: + homeWidget = _buildLoadingScreen(); + break; + case _AppPhase.access: + homeWidget = _buildAppShell( + home: VaultAccessScreen( + isBusy: _isUnlocking, + onCreateAccountPressed: (String email, String password) async { + await _beginRemoteVaultFlow( + username: email, + password: password, + isRegister: true, + ); + }, + onSignInPressed: (String email, String password) async { + await _beginRemoteVaultFlow( + username: email, + password: password, + isRegister: false, + ); + }, + onContinueWithoutAccount: _enterWithoutAccount, + ), + ); + break; + case _AppPhase.biometricChoice: + homeWidget = _buildAppShell( + home: BiometricChoiceScreen( + isBusy: _isUnlocking, + onEnableBiometrics: () => + _completeBiometricChoice(enableBiometrics: true), + onSkipBiometrics: () => + _completeBiometricChoice(enableBiometrics: false), + ), + ); + break; + case _AppPhase.biometricGate: + homeWidget = _buildAppShell( + home: BiometricGateScreen( + key: ValueKey(_biometricGateSession), + isBusy: _isUnlocking, + onUnlockRequested: _unlockBiometricGate, + ), + ); + break; + case _AppPhase.notes: + homeWidget = _buildLoadingScreen(); + break; } - - return _buildMainShell(repository); + } } + + return MaterialApp( + navigatorKey: _navigatorKey, + title: 'Mis Notas', + debugShowCheckedModeBanner: false, + scaffoldMessengerKey: _scaffoldMessengerKey, + theme: _theme, + home: homeWidget, + ); } }