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
-78
View File
@@ -1,78 +0,0 @@
import 'package:flutter/material.dart';
class AppColors {
AppColors._();
static const Color defaultThemeSeedColor = Colors.amber;
static const Color scaffoldBackground = Color.fromRGBO(31, 32, 33, 1);
static const Color backdropStart = Color(0xFF191A1D);
static const Color backdropMid = Color(0xFF222326);
static const Color backdropEnd = Color(0xFF101114);
static const LinearGradient backdropGradient = LinearGradient(
colors: <Color>[backdropStart, backdropMid, backdropEnd],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
static const Color surface = Color(0xFF1D1E20);
static const Color surfaceElevated = Color(0xFF303134);
static const Color drawerBackground = Color.fromARGB(255, 30, 31, 35);
static const Color cardBackground = Color.fromRGBO(24, 25, 26, 1);
static const Color overlay = Color.fromARGB(140, 0, 0, 0);
static const Color shadow = Color.fromRGBO(0, 0, 0, 0.35);
static const Color transparent = Colors.transparent;
static const Color accent = Colors.amber;
static const Color destructive = Colors.red;
static const Color destructiveAccent = Colors.redAccent;
static const Color success = Colors.green;
static const Color textOnAccent = Colors.black;
static const Color textOnSurfaceDark = Colors.black87;
static const Color textPrimary = Colors.white;
static const Color textSecondary = Colors.white70;
static const Color textMuted = Colors.white54;
static const Color textSubtle = Colors.white38;
static const Color textDisabled = Colors.white24;
static const Color textHint = Color.fromRGBO(255, 255, 255, 0.30);
static const Color borderStrong = Color.fromRGBO(255, 255, 255, 0.20);
static const Color border = Color.fromRGBO(255, 255, 255, 0.12);
static const Color borderMuted = Color.fromRGBO(255, 255, 255, 0.08);
static const Color fill = Color.fromRGBO(255, 255, 255, 0.05);
static const Color hover = Color.fromRGBO(255, 255, 255, 0.10);
static const Color searchFocusBorder = Color.fromRGBO(255, 255, 255, 0.40);
static const Color shadowSoft = Color.fromRGBO(0, 0, 0, 0.25);
static const Color shadowDim = Color.fromARGB(54, 0, 0, 0);
static const Color categoryFallback = Color(0xFFFFC107);
static const List<Color> categoryColors = <Color>[
Colors.amber,
Colors.blue,
Colors.green,
Colors.purple,
Colors.red,
Colors.teal,
Colors.orange,
Colors.grey,
];
static const List<Color> themeSeedColors = <Color>[
Colors.amber,
Colors.blue,
Colors.teal,
Colors.green,
Colors.pink,
Colors.purple,
];
static const Color dragTargetBorder = Color(0xFF42A5F5);
static const Color syncPreparing = Color.fromARGB(255, 165, 165, 165);
static const Color syncEncrypting = Color.fromARGB(255, 109, 191, 255);
static const Color syncUploading = Color.fromARGB(255, 98, 190, 255);
static const Color syncWaiting = Color.fromARGB(255, 150, 150, 150);
static const Color syncDecrypting = Color.fromARGB(255, 154, 194, 112);
}
+321
View File
@@ -0,0 +1,321 @@
import 'package:flutter/material.dart';
@immutable
class AppPalette extends ThemeExtension<AppPalette> {
static const Color darkDefaultThemeSeedColor = Colors.amber;
static const Color lightDefaultThemeSeedColor = Colors.blue;
static const List<Color> defaultCategoryColors = <Color>[
Colors.amber,
Colors.blue,
Colors.green,
Colors.purple,
Colors.red,
Colors.teal,
Colors.orange,
Colors.grey,
];
static const List<Color> themeSeedColors = <Color>[
Colors.blue,
Colors.teal,
Colors.green,
Colors.pink,
Colors.purple,
Colors.orange,
];
static const Gradient _darkBackdropGradient = LinearGradient(
colors: <Color>[Color(0xFF191A1D), Color(0xFF222326), Color(0xFF101114)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
static const Gradient _lightBackdropGradient = LinearGradient(
colors: <Color>[Color(0xFFFFFFFF), Color(0xFFF2F4F6), Color(0xFFECEFF1)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
static const Color _darkDrawerBackground = Color.fromARGB(255, 30, 31, 35);
static const Color _lightDrawerBackground = Color(0xFFF7F9FA);
static const Color _darkCardBackground = Color.fromRGBO(24, 25, 26, 1);
static const Color _lightCardBackground = Color(0xFFFFFFFF);
static const Color _darkSurfaceElevated = Color(0xFF303134);
static const Color _lightSurfaceElevated = Color(0xFFF0F2F4);
static const Color _darkBorder = Color.fromRGBO(255, 255, 255, 0.12);
static const Color _lightBorder = Color.fromRGBO(15, 23, 32, 0.06);
static const Color _darkBorderMuted = Color.fromRGBO(255, 255, 255, 0.08);
static const Color _lightBorderMuted = Color.fromRGBO(15, 23, 32, 0.03);
static const Color _darkTextPrimary = Colors.white;
static const Color _lightTextPrimary = Color(0xFF0F1720);
static const Color _darkTextSecondary = Colors.white70;
static const Color _lightTextSecondary = Color(0xFF374151);
static const Color _darkTextOnSurfaceDark = Colors.black87;
static const Color _lightTextOnSurfaceDark = Colors.black87;
static const Color _darkTextMuted = Colors.white54;
static const Color _lightTextMuted = Color(0xFF6B7280);
static const Color _darkTextDisabled = Colors.white24;
static const Color _lightTextDisabled = Color(0xFFBDBDBD);
static const Color _darkTextHint = Color.fromRGBO(255, 255, 255, 0.30);
static const Color _lightTextHint = Color.fromRGBO(15, 23, 32, 0.30);
static const Color _darkFill = Color.fromRGBO(255, 255, 255, 0.05);
static const Color _lightFill = Color.fromRGBO(15, 23, 32, 0.02);
static const Color _darkHover = Color.fromRGBO(255, 255, 255, 0.10);
static const Color _lightHover = Color.fromRGBO(15, 23, 32, 0.04);
static const Color _darkShadowSoft = Color.fromRGBO(0, 0, 0, 0.25);
static const Color _lightShadowSoft = Color.fromRGBO(0, 0, 0, 0.08);
static const Color _darkShadowDim = Color.fromARGB(54, 0, 0, 0);
static const Color _lightShadowDim = Color.fromARGB(40, 0, 0, 0);
static const Color _darkAccent = Colors.amber;
static const Color _lightAccent = Colors.blue;
static const Color _darkTextOnAccent = Colors.black;
static const Color _lightTextOnAccent = Colors.white;
static const Color _darkOverlay = Color.fromARGB(140, 0, 0, 0);
static const Color _lightOverlay = Color.fromARGB(120, 0, 0, 0);
static const Color _transparent = Colors.transparent;
static const Color _darkDragTargetBorder = Color(0xFF42A5F5);
static const Color _lightDragTargetBorder = Color(0xFF1565C0);
static const Color _darkSyncPreparing = Color.fromARGB(255, 165, 165, 165);
static const Color _lightSyncPreparing = Color.fromARGB(255, 120, 120, 120);
static const Color _darkSyncEncrypting = Color.fromARGB(255, 109, 191, 255);
static const Color _lightSyncEncrypting = Color.fromARGB(255, 2, 136, 209);
static const Color _darkSyncUploading = Color.fromARGB(255, 98, 190, 255);
static const Color _lightSyncUploading = Color.fromARGB(255, 2, 119, 189);
static const Color _darkSyncWaiting = Color.fromARGB(255, 150, 150, 150);
static const Color _lightSyncWaiting = Color.fromARGB(255, 150, 150, 150);
static const Color _darkSyncDecrypting = Color.fromARGB(255, 154, 194, 112);
static const Color _lightSyncDecrypting = Color.fromARGB(255, 76, 175, 80);
static const Color _darkSuccess = Colors.green;
static const Color _lightSuccess = Colors.green;
const AppPalette({
required this.backdropGradient,
required this.drawerBackground,
required this.cardBackground,
required this.categoryColors,
required this.surfaceElevated,
required this.border,
required this.borderMuted,
required this.accent,
required this.textPrimary,
required this.textSecondary,
required this.textOnSurfaceDark,
required this.textMuted,
required this.textDisabled,
required this.textHint,
required this.fill,
required this.hover,
required this.shadowSoft,
required this.shadowDim,
required this.destructiveAccent,
required this.textOnAccent,
required this.overlay,
required this.transparent,
required this.dragTargetBorder,
required this.syncPreparing,
required this.syncEncrypting,
required this.syncUploading,
required this.syncWaiting,
required this.syncDecrypting,
required this.success,
});
final Gradient backdropGradient;
final Color drawerBackground;
final Color cardBackground;
final List<Color> categoryColors;
final Color surfaceElevated;
final Color border;
final Color borderMuted;
final Color accent;
final Color textPrimary;
final Color textSecondary;
final Color textOnSurfaceDark;
final Color textMuted;
final Color textDisabled;
final Color textHint;
final Color fill;
final Color hover;
final Color shadowSoft;
final Color shadowDim;
final Color destructiveAccent;
final Color textOnAccent;
final Color overlay;
final Color transparent;
final Color dragTargetBorder;
final Color syncPreparing;
final Color syncEncrypting;
final Color syncUploading;
final Color syncWaiting;
final Color syncDecrypting;
final Color success;
@override
AppPalette copyWith({
Gradient? backdropGradient,
Color? drawerBackground,
Color? cardBackground,
List<Color>? categoryColors,
Color? surfaceElevated,
Color? border,
Color? borderMuted,
Color? accent,
Color? textPrimary,
Color? textSecondary,
Color? textOnSurfaceDark,
Color? textMuted,
Color? textDisabled,
Color? textHint,
Color? fill,
Color? hover,
Color? shadowSoft,
Color? shadowDim,
Color? destructiveAccent,
Color? textOnAccent,
Color? overlay,
Color? transparent,
Color? dragTargetBorder,
Color? syncPreparing,
Color? syncEncrypting,
Color? syncUploading,
Color? syncWaiting,
Color? syncDecrypting,
Color? success,
}) {
return AppPalette(
backdropGradient: backdropGradient ?? this.backdropGradient,
drawerBackground: drawerBackground ?? this.drawerBackground,
cardBackground: cardBackground ?? this.cardBackground,
categoryColors: categoryColors ?? this.categoryColors,
surfaceElevated: surfaceElevated ?? this.surfaceElevated,
border: border ?? this.border,
borderMuted: borderMuted ?? this.borderMuted,
accent: accent ?? this.accent,
textPrimary: textPrimary ?? this.textPrimary,
textSecondary: textSecondary ?? this.textSecondary,
textOnSurfaceDark: textOnSurfaceDark ?? this.textOnSurfaceDark,
textMuted: textMuted ?? this.textMuted,
textDisabled: textDisabled ?? this.textDisabled,
textHint: textHint ?? this.textHint,
fill: fill ?? this.fill,
hover: hover ?? this.hover,
shadowSoft: shadowSoft ?? this.shadowSoft,
shadowDim: shadowDim ?? this.shadowDim,
destructiveAccent: destructiveAccent ?? this.destructiveAccent,
textOnAccent: textOnAccent ?? this.textOnAccent,
overlay: overlay ?? this.overlay,
transparent: transparent ?? this.transparent,
dragTargetBorder: dragTargetBorder ?? this.dragTargetBorder,
syncPreparing: syncPreparing ?? this.syncPreparing,
syncEncrypting: syncEncrypting ?? this.syncEncrypting,
syncUploading: syncUploading ?? this.syncUploading,
syncWaiting: syncWaiting ?? this.syncWaiting,
syncDecrypting: syncDecrypting ?? this.syncDecrypting,
success: success ?? this.success,
);
}
@override
AppPalette lerp(ThemeExtension<AppPalette>? other, double t) {
if (other is! AppPalette) return this;
return AppPalette(
backdropGradient:
LinearGradient.lerp(
backdropGradient as LinearGradient,
other.backdropGradient as LinearGradient,
t,
) ??
backdropGradient,
drawerBackground:
Color.lerp(drawerBackground, other.drawerBackground, t) ??
drawerBackground,
cardBackground:
Color.lerp(cardBackground, other.cardBackground, t) ?? cardBackground,
categoryColors: t < 0.5 ? categoryColors : other.categoryColors,
surfaceElevated:
Color.lerp(surfaceElevated, other.surfaceElevated, t) ??
surfaceElevated,
border: Color.lerp(border, other.border, t) ?? border,
borderMuted: Color.lerp(borderMuted, other.borderMuted, t) ?? borderMuted,
accent: Color.lerp(accent, other.accent, t) ?? accent,
textPrimary: Color.lerp(textPrimary, other.textPrimary, t) ?? textPrimary,
textSecondary:
Color.lerp(textSecondary, other.textSecondary, t) ?? textSecondary,
textOnSurfaceDark:
Color.lerp(textOnSurfaceDark, other.textOnSurfaceDark, t) ??
textOnSurfaceDark,
textMuted: Color.lerp(textMuted, other.textMuted, t) ?? textMuted,
textDisabled:
Color.lerp(textDisabled, other.textDisabled, t) ?? textDisabled,
textHint: Color.lerp(textHint, other.textHint, t) ?? textHint,
fill: Color.lerp(fill, other.fill, t) ?? fill,
hover: Color.lerp(hover, other.hover, t) ?? hover,
shadowSoft: Color.lerp(shadowSoft, other.shadowSoft, t) ?? shadowSoft,
shadowDim: Color.lerp(shadowDim, other.shadowDim, t) ?? shadowDim,
destructiveAccent:
Color.lerp(destructiveAccent, other.destructiveAccent, t) ??
destructiveAccent,
textOnAccent:
Color.lerp(textOnAccent, other.textOnAccent, t) ?? textOnAccent,
overlay: Color.lerp(overlay, other.overlay, t) ?? overlay,
transparent: Color.lerp(transparent, other.transparent, t) ?? transparent,
dragTargetBorder:
Color.lerp(dragTargetBorder, other.dragTargetBorder, t) ??
dragTargetBorder,
syncPreparing:
Color.lerp(syncPreparing, other.syncPreparing, t) ?? syncPreparing,
syncEncrypting:
Color.lerp(syncEncrypting, other.syncEncrypting, t) ?? syncEncrypting,
syncUploading:
Color.lerp(syncUploading, other.syncUploading, t) ?? syncUploading,
syncWaiting: Color.lerp(syncWaiting, other.syncWaiting, t) ?? syncWaiting,
syncDecrypting:
Color.lerp(syncDecrypting, other.syncDecrypting, t) ?? syncDecrypting,
success: Color.lerp(success, other.success, t) ?? success,
);
}
static AppPalette fromBrightness(Brightness brightness, {Color? seedColor}) {
final bool isLight = brightness == Brightness.light;
return AppPalette(
backdropGradient: isLight
? _lightBackdropGradient
: _darkBackdropGradient,
drawerBackground: isLight
? _lightDrawerBackground
: _darkDrawerBackground,
cardBackground: isLight ? _lightCardBackground : _darkCardBackground,
categoryColors: defaultCategoryColors,
surfaceElevated: isLight ? _lightSurfaceElevated : _darkSurfaceElevated,
border: isLight ? _lightBorder : _darkBorder,
borderMuted: isLight ? _lightBorderMuted : _darkBorderMuted,
accent: seedColor ?? (isLight ? _lightAccent : _darkAccent),
textPrimary: isLight ? _lightTextPrimary : _darkTextPrimary,
textSecondary: isLight ? _lightTextSecondary : _darkTextSecondary,
textOnSurfaceDark: isLight
? _lightTextOnSurfaceDark
: _darkTextOnSurfaceDark,
textMuted: isLight ? _lightTextMuted : _darkTextMuted,
textDisabled: isLight ? _lightTextDisabled : _darkTextDisabled,
textHint: isLight ? _lightTextHint : _darkTextHint,
fill: isLight ? _lightFill : _darkFill,
hover: isLight ? _lightHover : _darkHover,
shadowSoft: isLight ? _lightShadowSoft : _darkShadowSoft,
shadowDim: isLight ? _lightShadowDim : _darkShadowDim,
destructiveAccent: Colors.redAccent,
textOnAccent: isLight ? _lightTextOnAccent : _darkTextOnAccent,
overlay: isLight ? _lightOverlay : _darkOverlay,
transparent: _transparent,
dragTargetBorder: isLight
? _lightDragTargetBorder
: _darkDragTargetBorder,
syncPreparing: isLight ? _lightSyncPreparing : _darkSyncPreparing,
syncEncrypting: isLight ? _lightSyncEncrypting : _darkSyncEncrypting,
syncUploading: isLight ? _lightSyncUploading : _darkSyncUploading,
syncWaiting: isLight ? _lightSyncWaiting : _darkSyncWaiting,
syncDecrypting: isLight ? _lightSyncDecrypting : _darkSyncDecrypting,
success: isLight ? _lightSuccess : _darkSuccess,
);
}
}
+21 -9
View File
@@ -1,21 +1,33 @@
import 'package:flutter/material.dart';
import 'package:notas/theme/app_colors.dart';
import 'package:notas/theme/app_palette.dart';
class AppTheme {
static ThemeData theme({Color seedColor = AppColors.defaultThemeSeedColor}) {
static ThemeData theme({
Color seedColor = Colors.amber,
Brightness brightness = Brightness.dark,
}) {
final Brightness foregroundBrightness =
ThemeData.estimateBrightnessForColor(seedColor);
final Color foregroundColor = foregroundBrightness == Brightness.dark
? AppColors.textPrimary
: AppColors.textOnAccent;
? Colors.white
: Colors.black87;
final ColorScheme scheme = ColorScheme.fromSeed(
seedColor: seedColor,
brightness: brightness,
);
final AppPalette palette = AppPalette.fromBrightness(
brightness,
seedColor: seedColor,
);
return ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: AppColors.scaffoldBackground,
colorScheme: ColorScheme.fromSeed(
seedColor: seedColor,
brightness: Brightness.dark,
),
scaffoldBackgroundColor: scheme.background,
colorScheme: scheme,
extensions: <ThemeExtension<dynamic>>[palette],
brightness: brightness,
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: seedColor,
foregroundColor: foregroundColor,