Refactor theme management: Replace AppColors with AppPalette

- Removed AppColors class and migrated all references to AppPalette.
- Updated VaultAccessScreen, MenuDrawer, NoteCard, SearchAppBar, and other widgets to use AppPalette for color management.
- Introduced AppPalette to handle light and dark themes with appropriate color schemes.
- Adjusted theme application in AppTheme to utilize AppPalette extensions.
- Updated tests to reflect changes in theme structure and color references.
This commit is contained in:
2026-05-23 13:55:40 +02:00
parent 29881183ed
commit 1dede9eb78
16 changed files with 1031 additions and 618 deletions
+111 -31
View File
@@ -14,7 +14,7 @@ import 'package:notas/screens/biometric_gate_screen.dart';
import 'package:notas/screens/home_screen.dart';
import 'package:notas/screens/settings_screen.dart';
import 'package:notas/screens/vault_access_screen.dart';
import 'package:notas/theme/app_colors.dart';
import 'package:notas/theme/app_palette.dart';
import 'package:notas/theme/app_theme.dart';
import 'package:notas/widgets/sync_status.dart';
import 'package:path/path.dart' as p;
@@ -44,6 +44,7 @@ class _NotesAppState extends State<NotesApp>
static const Duration _syncInterval = Duration(minutes: 5);
static const Duration _windowSizeSaveDelay = Duration(milliseconds: 350);
static const String _themeSeedColorKey = 'theme_seed_color_v1';
static const String _themeModeKey = 'theme_mode_v1';
final LocalVaultService _vaultService = LocalVaultService.instance;
final GlobalKey<ScaffoldMessengerState> _scaffoldMessengerKey =
@@ -69,7 +70,30 @@ class _NotesAppState extends State<NotesApp>
String? _syncErrorMessage;
int _syncOperationId = 0;
int _homeRefreshToken = 0;
Color _themeSeedColor = AppColors.defaultThemeSeedColor;
Color _themeSeedColor = Colors.amber;
ThemeMode _themeMode = ThemeMode.system;
// Cached ThemeData for light and dark variants.
ThemeData? _lightTheme;
ThemeData? _darkTheme;
Brightness _effectiveBrightness() {
switch (_themeMode) {
case ThemeMode.dark:
return Brightness.dark;
case ThemeMode.light:
return Brightness.light;
case ThemeMode.system:
return WidgetsBinding.instance.platformDispatcher.platformBrightness;
}
}
AppPalette _activePalette() {
return AppPalette.fromBrightness(
_effectiveBrightness(),
seedColor: _themeSeedColor,
);
}
@override
void initState() {
@@ -80,6 +104,7 @@ class _NotesAppState extends State<NotesApp>
windowManager.setPreventClose(true);
}
_loadThemeSeedColor();
_loadThemeMode();
_bootstrapVault();
}
@@ -106,7 +131,7 @@ class _NotesAppState extends State<NotesApp>
setState(() {
_themeSeedColor = Color(storedColorValue);
_themeData = AppTheme.theme(seedColor: _themeSeedColor);
_updateThemeData();
});
}
@@ -120,15 +145,54 @@ class _NotesAppState extends State<NotesApp>
setState(() {
_themeSeedColor = color;
_themeData = AppTheme.theme(seedColor: _themeSeedColor);
_updateThemeData();
});
}
// Cached ThemeData to avoid recomputing on every build.
ThemeData? _themeData;
Future<void> _loadThemeMode() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final int? stored = prefs.getInt(_themeModeKey);
if (!mounted) return;
ThemeData get _theme =>
_themeData ??= AppTheme.theme(seedColor: _themeSeedColor);
setState(() {
if (stored == null) {
_themeMode = ThemeMode.system;
} else if (stored == 1) {
_themeMode = ThemeMode.light;
} else if (stored == 2) {
_themeMode = ThemeMode.dark;
} else {
_themeMode = ThemeMode.system;
}
_updateThemeData();
});
}
Future<void> _setThemeMode(ThemeMode mode) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final int stored = mode == ThemeMode.system
? 0
: (mode == ThemeMode.light ? 1 : 2);
await prefs.setInt(_themeModeKey, stored);
if (!mounted) return;
setState(() {
_themeMode = mode;
});
}
void _updateThemeData() {
_lightTheme = AppTheme.theme(
seedColor: _themeSeedColor,
brightness: Brightness.light,
);
_darkTheme = AppTheme.theme(
seedColor: _themeSeedColor,
brightness: Brightness.dark,
);
// Updated light/dark themes regenerated
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
@@ -429,27 +493,30 @@ class _NotesAppState extends State<NotesApp>
final bool? retry = await showDialog<bool>(
context: dialogCtx,
builder: (BuildContext context) => AlertDialog(
backgroundColor: AppColors.cardBackground,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: AppColors.border),
),
title: const Text('No se pudo activar la biometría'),
content: const Text(
'No se pudo activar la biometría. ¿Quieres intentarlo de nuevo o entrar sin huella?',
),
actions: [
TextButton(
onPressed: () => navigator.pop(false),
child: const Text('Entrar sin huella'),
builder: (BuildContext context) {
final AppPalette palette = _activePalette();
return AlertDialog(
backgroundColor: palette.cardBackground,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: palette.border),
),
FilledButton(
onPressed: () => navigator.pop(true),
child: const Text('Reintentar'),
title: const Text('No se pudo activar la biometría'),
content: const Text(
'No se pudo activar la biometría. ¿Quieres intentarlo de nuevo o entrar sin huella?',
),
],
),
actions: [
TextButton(
onPressed: () => navigator.pop(false),
child: const Text('Entrar sin huella'),
),
FilledButton(
onPressed: () => navigator.pop(true),
child: const Text('Reintentar'),
),
],
);
},
);
if (retry != true) {
@@ -825,6 +892,7 @@ class _NotesAppState extends State<NotesApp>
}
Widget _buildMainShell(NoteRepository repository) {
final AppPalette palette = _activePalette();
final Widget activeScreen = _currentSection == _AppSection.home
? HomeScreen(
key: const ValueKey<String>('home-screen'),
@@ -845,6 +913,8 @@ class _NotesAppState extends State<NotesApp>
onForceSync: () => _performSync(forceFull: true),
currentSeedColor: _themeSeedColor,
onThemeColorSelected: _setThemeSeedColor,
currentThemeMode: _themeMode,
onThemeModeSelected: _setThemeMode,
);
return Shortcuts(
@@ -864,9 +934,7 @@ class _NotesAppState extends State<NotesApp>
autofocus: true,
child: Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: AppColors.backdropGradient,
),
decoration: BoxDecoration(gradient: palette.backdropGradient),
child: SafeArea(
child: Column(
children: [
@@ -1026,7 +1094,19 @@ class _NotesAppState extends State<NotesApp>
title: 'Mis Notas',
debugShowCheckedModeBanner: false,
scaffoldMessengerKey: _scaffoldMessengerKey,
theme: _theme,
theme:
_lightTheme ??
AppTheme.theme(
seedColor: _themeSeedColor,
brightness: Brightness.light,
),
darkTheme:
_darkTheme ??
AppTheme.theme(
seedColor: _themeSeedColor,
brightness: Brightness.dark,
),
themeMode: _themeMode,
home: homeWidget,
);
}