barcode_scanner/lib/themes/app_theme.dart
mandreshope e963abb0ce feat: Implements app theme system
Replaces hardcoded colors and standard Theme.of(context) accesses with a custom AppTheme.

Introduces distinct light and dark themes and persists the selected theme mode using shared_preferences.

Integrates the theme into the main app structure and applies it to various components and pages.

Adds google_fonts dependency for theme typography.
2025-06-23 17:48:03 +03:00

382 lines
13 KiB
Dart

// ignore_for_file: overridden_fields, annotate_overrides
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
const kThemeModeKey = '__theme_mode__';
SharedPreferences? _prefs;
abstract class AppTheme {
static Future initialize() async =>
_prefs = await SharedPreferences.getInstance();
static ThemeMode get themeMode {
final darkMode = _prefs?.getBool(kThemeModeKey);
return darkMode == null
? ThemeMode.system
: darkMode
? ThemeMode.dark
: ThemeMode.light;
}
static void saveThemeMode(ThemeMode mode) => mode == ThemeMode.system
? _prefs?.remove(kThemeModeKey)
: _prefs?.setBool(kThemeModeKey, mode == ThemeMode.dark);
static AppTheme of(BuildContext context) {
return Theme.of(context).brightness == Brightness.dark
? DarkModeTheme()
: LightModeTheme();
}
late Color primary;
late Color secondary;
late Color tertiary;
late Color alternate;
late Color primaryText;
late Color secondaryText;
late Color primaryBackground;
late Color secondaryBackground;
late Color accent1;
late Color accent2;
late Color accent3;
late Color accent4;
late Color success;
late Color warning;
late Color error;
late Color info;
late Color trueBlue;
late Color orangePeel;
late Color white;
late Color columbiaBlue;
late Color battleshipGray;
late Color backgroundTransparent;
String get displayLargeFamily => typography.displayLargeFamily;
bool get displayLargeIsCustom => typography.displayLargeIsCustom;
TextStyle get displayLarge => typography.displayLarge;
String get displayMediumFamily => typography.displayMediumFamily;
bool get displayMediumIsCustom => typography.displayMediumIsCustom;
TextStyle get displayMedium => typography.displayMedium;
String get displaySmallFamily => typography.displaySmallFamily;
bool get displaySmallIsCustom => typography.displaySmallIsCustom;
TextStyle get displaySmall => typography.displaySmall;
String get headlineLargeFamily => typography.headlineLargeFamily;
bool get headlineLargeIsCustom => typography.headlineLargeIsCustom;
TextStyle get headlineLarge => typography.headlineLarge;
String get headlineMediumFamily => typography.headlineMediumFamily;
bool get headlineMediumIsCustom => typography.headlineMediumIsCustom;
TextStyle get headlineMedium => typography.headlineMedium;
String get headlineSmallFamily => typography.headlineSmallFamily;
bool get headlineSmallIsCustom => typography.headlineSmallIsCustom;
TextStyle get headlineSmall => typography.headlineSmall;
String get titleLargeFamily => typography.titleLargeFamily;
bool get titleLargeIsCustom => typography.titleLargeIsCustom;
TextStyle get titleLarge => typography.titleLarge;
String get titleMediumFamily => typography.titleMediumFamily;
bool get titleMediumIsCustom => typography.titleMediumIsCustom;
TextStyle get titleMedium => typography.titleMedium;
String get titleSmallFamily => typography.titleSmallFamily;
bool get titleSmallIsCustom => typography.titleSmallIsCustom;
TextStyle get titleSmall => typography.titleSmall;
String get labelLargeFamily => typography.labelLargeFamily;
bool get labelLargeIsCustom => typography.labelLargeIsCustom;
TextStyle get labelLarge => typography.labelLarge;
String get labelMediumFamily => typography.labelMediumFamily;
bool get labelMediumIsCustom => typography.labelMediumIsCustom;
TextStyle get labelMedium => typography.labelMedium;
String get labelSmallFamily => typography.labelSmallFamily;
bool get labelSmallIsCustom => typography.labelSmallIsCustom;
TextStyle get labelSmall => typography.labelSmall;
String get bodyLargeFamily => typography.bodyLargeFamily;
bool get bodyLargeIsCustom => typography.bodyLargeIsCustom;
TextStyle get bodyLarge => typography.bodyLarge;
String get bodyMediumFamily => typography.bodyMediumFamily;
bool get bodyMediumIsCustom => typography.bodyMediumIsCustom;
TextStyle get bodyMedium => typography.bodyMedium;
String get bodySmallFamily => typography.bodySmallFamily;
bool get bodySmallIsCustom => typography.bodySmallIsCustom;
TextStyle get bodySmall => typography.bodySmall;
Typography get typography => ThemeTypography(this);
}
class LightModeTheme extends AppTheme {
@Deprecated('Use primary instead')
Color get primaryColor => primary;
@Deprecated('Use secondary instead')
Color get secondaryColor => secondary;
@Deprecated('Use tertiary instead')
Color get tertiaryColor => tertiary;
late Color primary = const Color(0xFF3D6BB2);
late Color secondary = const Color(0xFFF9A434);
late Color tertiary = const Color(0xFFEE8B60);
late Color alternate = const Color(0xFFE0E3E7);
late Color primaryText = const Color(0xFF14181B);
late Color secondaryText = const Color(0xFF919191);
late Color primaryBackground = const Color(0xFFFFFFFF);
late Color secondaryBackground = const Color(0xFFF1F4F8);
late Color accent1 = const Color(0xFF003EA2);
late Color accent2 = const Color(0xFFB36600);
late Color accent3 = const Color(0x4DEE8B60);
late Color accent4 = const Color(0xCCFFFFFF);
late Color success = const Color(0xFF249689);
late Color warning = const Color(0xFFF9CF58);
late Color error = const Color(0xFFFF5963);
late Color info = const Color(0xFFFFFFFF);
late Color trueBlue = const Color(0xFF3D6BB2);
late Color orangePeel = const Color(0xFFF9A434);
late Color white = const Color(0xFFFFFFFF);
late Color columbiaBlue = const Color(0xFFC8D6E4);
late Color battleshipGray = const Color(0xFF919191);
late Color backgroundTransparent = const Color(0xB9FFFFFF);
}
abstract class Typography {
String get displayLargeFamily;
bool get displayLargeIsCustom;
TextStyle get displayLarge;
String get displayMediumFamily;
bool get displayMediumIsCustom;
TextStyle get displayMedium;
String get displaySmallFamily;
bool get displaySmallIsCustom;
TextStyle get displaySmall;
String get headlineLargeFamily;
bool get headlineLargeIsCustom;
TextStyle get headlineLarge;
String get headlineMediumFamily;
bool get headlineMediumIsCustom;
TextStyle get headlineMedium;
String get headlineSmallFamily;
bool get headlineSmallIsCustom;
TextStyle get headlineSmall;
String get titleLargeFamily;
bool get titleLargeIsCustom;
TextStyle get titleLarge;
String get titleMediumFamily;
bool get titleMediumIsCustom;
TextStyle get titleMedium;
String get titleSmallFamily;
bool get titleSmallIsCustom;
TextStyle get titleSmall;
String get labelLargeFamily;
bool get labelLargeIsCustom;
TextStyle get labelLarge;
String get labelMediumFamily;
bool get labelMediumIsCustom;
TextStyle get labelMedium;
String get labelSmallFamily;
bool get labelSmallIsCustom;
TextStyle get labelSmall;
String get bodyLargeFamily;
bool get bodyLargeIsCustom;
TextStyle get bodyLarge;
String get bodyMediumFamily;
bool get bodyMediumIsCustom;
TextStyle get bodyMedium;
String get bodySmallFamily;
bool get bodySmallIsCustom;
TextStyle get bodySmall;
}
class ThemeTypography extends Typography {
ThemeTypography(this.theme);
final AppTheme theme;
String get displayLargeFamily => 'Poppins';
bool get displayLargeIsCustom => false;
TextStyle get displayLarge => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 64.0,
);
String get displayMediumFamily => 'Poppins';
bool get displayMediumIsCustom => false;
TextStyle get displayMedium => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 44.0,
);
String get displaySmallFamily => 'Poppins';
bool get displaySmallIsCustom => false;
TextStyle get displaySmall => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 36.0,
);
String get headlineLargeFamily => 'Poppins';
bool get headlineLargeIsCustom => false;
TextStyle get headlineLarge => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 32.0,
);
String get headlineMediumFamily => 'Poppins';
bool get headlineMediumIsCustom => false;
TextStyle get headlineMedium => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 28.0,
);
String get headlineSmallFamily => 'Poppins';
bool get headlineSmallIsCustom => false;
TextStyle get headlineSmall => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 24.0,
);
String get titleLargeFamily => 'Poppins';
bool get titleLargeIsCustom => false;
TextStyle get titleLarge => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 20.0,
);
String get titleMediumFamily => 'Poppins';
bool get titleMediumIsCustom => false;
TextStyle get titleMedium => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 18.0,
);
String get titleSmallFamily => 'Poppins';
bool get titleSmallIsCustom => false;
TextStyle get titleSmall => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.w600,
fontSize: 16.0,
);
String get labelLargeFamily => 'Poppins';
bool get labelLargeIsCustom => false;
TextStyle get labelLarge => GoogleFonts.poppins(
color: theme.secondaryText,
fontWeight: FontWeight.normal,
fontSize: 16.0,
);
String get labelMediumFamily => 'Poppins';
bool get labelMediumIsCustom => false;
TextStyle get labelMedium => GoogleFonts.poppins(
color: theme.secondaryText,
fontWeight: FontWeight.normal,
fontSize: 14.0,
);
String get labelSmallFamily => 'Poppins';
bool get labelSmallIsCustom => false;
TextStyle get labelSmall => GoogleFonts.poppins(
color: theme.secondaryText,
fontWeight: FontWeight.normal,
fontSize: 12.0,
);
String get bodyLargeFamily => 'Poppins';
bool get bodyLargeIsCustom => false;
TextStyle get bodyLarge => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.normal,
fontSize: 16.0,
);
String get bodyMediumFamily => 'Poppins';
bool get bodyMediumIsCustom => false;
TextStyle get bodyMedium => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.normal,
fontSize: 14.0,
);
String get bodySmallFamily => 'Poppins';
bool get bodySmallIsCustom => false;
TextStyle get bodySmall => GoogleFonts.poppins(
color: theme.primaryText,
fontWeight: FontWeight.normal,
fontSize: 12.0,
);
}
class DarkModeTheme extends AppTheme {
@Deprecated('Use primary instead')
Color get primaryColor => primary;
@Deprecated('Use secondary instead')
Color get secondaryColor => secondary;
@Deprecated('Use tertiary instead')
Color get tertiaryColor => tertiary;
late Color primary = const Color(0xFF3D6BB2);
late Color secondary = const Color(0xFFB36600);
late Color tertiary = const Color(0xFFEE8B60);
late Color alternate = const Color(0xFF262D34);
late Color primaryText = const Color(0xFFFFFFFF);
late Color secondaryText = const Color(0xFF919191);
late Color primaryBackground = const Color(0xFF14181B);
late Color secondaryBackground = const Color(0xFF1D2428);
late Color accent1 = const Color(0xFF003EA2);
late Color accent2 = const Color(0xFFB36600);
late Color accent3 = const Color(0x4DEE8B60);
late Color accent4 = const Color(0xB2262D34);
late Color success = const Color(0xFF249689);
late Color warning = const Color(0xFFF9CF58);
late Color error = const Color(0xFFFF5963);
late Color info = const Color(0xFFFFFFFF);
late Color trueBlue = const Color(0xFF3D6BB2);
late Color orangePeel = const Color(0xFFF9A434);
late Color white = const Color(0xFFFFFFFF);
late Color columbiaBlue = const Color(0xFFC8D6E4);
late Color battleshipGray = const Color(0xFF919191);
late Color backgroundTransparent = const Color(0x91000000);
}
extension TextStyleHelper on TextStyle {
TextStyle override({
TextStyle? font,
String? fontFamily,
Color? color,
double? fontSize,
FontWeight? fontWeight,
double? letterSpacing,
FontStyle? fontStyle,
bool useGoogleFonts = false,
TextDecoration? decoration,
double? lineHeight,
List<Shadow>? shadows,
String? package,
}) {
if (useGoogleFonts && fontFamily != null) {
font = GoogleFonts.getFont(
fontFamily,
fontWeight: fontWeight ?? this.fontWeight,
fontStyle: fontStyle ?? this.fontStyle,
);
}
return font != null
? font.copyWith(
color: color ?? this.color,
fontSize: fontSize ?? this.fontSize,
letterSpacing: letterSpacing ?? this.letterSpacing,
fontWeight: fontWeight ?? this.fontWeight,
fontStyle: fontStyle ?? this.fontStyle,
decoration: decoration,
height: lineHeight,
shadows: shadows,
)
: copyWith(
fontFamily: fontFamily,
package: package,
color: color,
fontSize: fontSize,
letterSpacing: letterSpacing,
fontWeight: fontWeight,
fontStyle: fontStyle,
decoration: decoration,
height: lineHeight,
shadows: shadows,
);
}
}