feat: Optimize theme data handling and simplify widget structure in NotesApp

This commit is contained in:
2026-05-21 17:02:05 +02:00
parent 063b300428
commit 62d47904d9
+141 -144
View File
@@ -102,6 +102,7 @@ class _NotesAppState extends State<NotesApp>
setState(() { setState(() {
_themeSeedColor = Color(storedColorValue); _themeSeedColor = Color(storedColorValue);
_themeData = AppTheme.theme(seedColor: _themeSeedColor);
}); });
} }
@@ -115,10 +116,14 @@ class _NotesAppState extends State<NotesApp>
setState(() { setState(() {
_themeSeedColor = color; _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 @override
void didChangeAppLifecycleState(AppLifecycleState state) { void didChangeAppLifecycleState(AppLifecycleState state) {
@@ -767,43 +772,30 @@ class _NotesAppState extends State<NotesApp>
} }
Widget _buildLoadingScreen() { Widget _buildLoadingScreen() {
return MaterialApp( return const Scaffold(
navigatorKey: _navigatorKey, body: SafeArea(
title: 'Mis Notas', child: Column(
debugShowCheckedModeBanner: false, children: [
theme: _theme, Expanded(
home: const Scaffold( child: Center(
body: SafeArea( child: Column(
child: Column( mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Expanded( CircularProgressIndicator(),
child: Center( SizedBox(height: 16),
child: Column( Text('Preparando el vault local...'),
mainAxisAlignment: MainAxisAlignment.center, ],
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('Preparando el vault local...'),
],
),
), ),
), ),
], ),
), ],
), ),
), ),
); );
} }
Widget _buildAppShell({required Widget home}) { Widget _buildAppShell({required Widget home}) {
return MaterialApp( return home;
navigatorKey: _navigatorKey,
title: 'Mis Notas',
debugShowCheckedModeBanner: false,
scaffoldMessengerKey: _scaffoldMessengerKey,
theme: _theme,
home: home,
);
} }
Widget _buildMainShell(NoteRepository repository) { Widget _buildMainShell(NoteRepository repository) {
@@ -829,69 +821,62 @@ class _NotesAppState extends State<NotesApp>
onThemeColorSelected: _setThemeSeedColor, onThemeColorSelected: _setThemeSeedColor,
); );
return MaterialApp( return Shortcuts(
navigatorKey: _navigatorKey, shortcuts: <LogicalKeySet, Intent>{
title: 'Mis Notas', LogicalKeySet(LogicalKeyboardKey.f5): const PerformSyncIntent(),
debugShowCheckedModeBanner: false, },
scaffoldMessengerKey: _scaffoldMessengerKey, child: Actions(
theme: _theme, actions: <Type, Action<Intent>>{
home: Shortcuts( PerformSyncIntent: CallbackAction<PerformSyncIntent>(
shortcuts: <LogicalKeySet, Intent>{ onInvoke: (PerformSyncIntent intent) {
LogicalKeySet(LogicalKeyboardKey.f5): const PerformSyncIntent(), _performSync();
return null;
},
),
}, },
child: Actions( child: Focus(
actions: <Type, Action<Intent>>{ autofocus: true,
PerformSyncIntent: CallbackAction<PerformSyncIntent>( child: Scaffold(
onInvoke: (PerformSyncIntent intent) { body: Container(
_performSync(); decoration: const BoxDecoration(
return null; gradient: LinearGradient(
}, colors: [
), Color(0xFF191A1D),
}, Color(0xFF222326),
child: Focus( Color(0xFF101114),
autofocus: true, ],
child: Scaffold( begin: Alignment.topLeft,
body: Container( end: Alignment.bottomRight,
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF191A1D),
Color(0xFF222326),
Color(0xFF101114),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
), ),
child: SafeArea( ),
child: Column( child: SafeArea(
children: [ child: Column(
Expanded( children: [
child: AnimatedSwitcher( Expanded(
duration: _screenTransitionDuration, child: AnimatedSwitcher(
switchInCurve: Curves.easeOutCubic, duration: _screenTransitionDuration,
switchOutCurve: Curves.easeInCubic, switchInCurve: Curves.easeOutCubic,
transitionBuilder: switchOutCurve: Curves.easeInCubic,
(Widget child, Animation<double> animation) { transitionBuilder:
final Animation<Offset> offsetAnimation = (Widget child, Animation<double> animation) {
Tween<Offset>( final Animation<Offset> offsetAnimation =
begin: const Offset(0.08, 0.0), Tween<Offset>(
end: Offset.zero, begin: const Offset(0.08, 0.0),
).animate(animation); end: Offset.zero,
).animate(animation);
return FadeTransition( return FadeTransition(
opacity: animation, opacity: animation,
child: SlideTransition( child: SlideTransition(
position: offsetAnimation, position: offsetAnimation,
child: child, child: child,
), ),
); );
}, },
child: activeScreen, child: activeScreen,
),
), ),
], ),
), ],
), ),
), ),
), ),
@@ -951,64 +936,76 @@ class _NotesAppState extends State<NotesApp>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget homeWidget;
if (_isBootstrapping) { if (_isBootstrapping) {
return _buildLoadingScreen(); homeWidget = _buildLoadingScreen();
} } else {
final NoteRepository? repository = _repository;
final NoteRepository? repository = _repository; if (repository != null) {
homeWidget = _buildMainShell(repository);
if (repository != null) { } else {
return _buildMainShell(repository); switch (_phase) {
} case _AppPhase.loading:
homeWidget = _buildLoadingScreen();
switch (_phase) { break;
case _AppPhase.loading: case _AppPhase.access:
return _buildLoadingScreen(); homeWidget = _buildAppShell(
case _AppPhase.access: home: VaultAccessScreen(
return _buildAppShell( isBusy: _isUnlocking,
home: VaultAccessScreen( onCreateAccountPressed: (String email, String password) async {
isBusy: _isUnlocking, await _beginRemoteVaultFlow(
onCreateAccountPressed: (String email, String password) async { username: email,
await _beginRemoteVaultFlow( password: password,
username: email, isRegister: true,
password: password, );
isRegister: true, },
); onSignInPressed: (String email, String password) async {
}, await _beginRemoteVaultFlow(
onSignInPressed: (String email, String password) async { username: email,
await _beginRemoteVaultFlow( password: password,
username: email, isRegister: false,
password: password, );
isRegister: false, },
); onContinueWithoutAccount: _enterWithoutAccount,
}, ),
onContinueWithoutAccount: _enterWithoutAccount, );
), break;
); case _AppPhase.biometricChoice:
case _AppPhase.biometricChoice: homeWidget = _buildAppShell(
return _buildAppShell( home: BiometricChoiceScreen(
home: BiometricChoiceScreen( isBusy: _isUnlocking,
isBusy: _isUnlocking, onEnableBiometrics: () =>
onEnableBiometrics: () => _completeBiometricChoice(enableBiometrics: true),
_completeBiometricChoice(enableBiometrics: true), onSkipBiometrics: () =>
onSkipBiometrics: () => _completeBiometricChoice(enableBiometrics: false),
_completeBiometricChoice(enableBiometrics: false), ),
), );
); break;
case _AppPhase.biometricGate: case _AppPhase.biometricGate:
return _buildAppShell( homeWidget = _buildAppShell(
home: BiometricGateScreen( home: BiometricGateScreen(
key: ValueKey<int>(_biometricGateSession), key: ValueKey<int>(_biometricGateSession),
isBusy: _isUnlocking, isBusy: _isUnlocking,
onUnlockRequested: _unlockBiometricGate, onUnlockRequested: _unlockBiometricGate,
), ),
); );
case _AppPhase.notes: break;
if (repository == null) { case _AppPhase.notes:
return _buildLoadingScreen(); homeWidget = _buildLoadingScreen();
break;
} }
}
return _buildMainShell(repository);
} }
return MaterialApp(
navigatorKey: _navigatorKey,
title: 'Mis Notas',
debugShowCheckedModeBanner: false,
scaffoldMessengerKey: _scaffoldMessengerKey,
theme: _theme,
home: homeWidget,
);
} }
} }