Merge pull request #690 from imshahab/m3-dynamic-theme

Implement Material 3 dynamic theming
This commit is contained in:
Hiddify
2024-03-19 12:04:53 +01:00
committed by GitHub
9 changed files with 68 additions and 161 deletions

View File

@@ -1,138 +1,38 @@
// mostly exact copy of flex color scheme 7.1's fabulous 12 theme
import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter/material.dart';
import 'package:hiddify/core/theme/app_theme_mode.dart';
import 'package:hiddify/core/theme/theme_extensions.dart';
class AppTheme {
AppTheme(
this.mode,
this.fontFamily,
);
AppTheme(this.mode, this.fontFamily);
final AppThemeMode mode;
final String fontFamily;
ThemeData light() {
return FlexThemeData.light(
scheme: FlexScheme.indigoM3,
surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
ThemeData lightTheme(ColorScheme? lightColorScheme) {
final ColorScheme scheme = lightColorScheme ??
ColorScheme.fromSeed(seedColor: const Color(0xFF293CA0));
return ThemeData(
useMaterial3: true,
swapLegacyOnMaterial3: true,
useMaterial3ErrorColors: true,
blendLevel: 1,
subThemesData: const FlexSubThemesData(
useTextTheme: true,
useM2StyleDividerInM3: true,
elevatedButtonSchemeColor: SchemeColor.onPrimaryContainer,
elevatedButtonSecondarySchemeColor: SchemeColor.primaryContainer,
outlinedButtonOutlineSchemeColor: SchemeColor.primary,
toggleButtonsBorderSchemeColor: SchemeColor.primary,
segmentedButtonSchemeColor: SchemeColor.primary,
segmentedButtonBorderSchemeColor: SchemeColor.primary,
unselectedToggleIsColored: true,
sliderValueTinted: true,
inputDecoratorSchemeColor: SchemeColor.primary,
inputDecoratorBackgroundAlpha: 43,
inputDecoratorUnfocusedHasBorder: false,
inputDecoratorFocusedBorderWidth: 1.0,
inputDecoratorPrefixIconSchemeColor: SchemeColor.primary,
popupMenuRadius: 8.0,
popupMenuElevation: 3.0,
drawerIndicatorSchemeColor: SchemeColor.primary,
bottomNavigationBarMutedUnselectedLabel: false,
bottomNavigationBarMutedUnselectedIcon: false,
menuRadius: 8.0,
menuElevation: 3.0,
menuBarRadius: 0.0,
menuBarElevation: 2.0,
menuBarShadowColor: Color(0x00000000),
navigationBarSelectedLabelSchemeColor: SchemeColor.primary,
navigationBarMutedUnselectedLabel: false,
navigationBarSelectedIconSchemeColor: SchemeColor.onPrimary,
navigationBarMutedUnselectedIcon: false,
navigationBarIndicatorSchemeColor: SchemeColor.primary,
navigationBarIndicatorOpacity: 1.00,
navigationRailSelectedLabelSchemeColor: SchemeColor.primary,
navigationRailMutedUnselectedLabel: false,
navigationRailSelectedIconSchemeColor: SchemeColor.onPrimary,
navigationRailMutedUnselectedIcon: false,
navigationRailIndicatorSchemeColor: SchemeColor.primary,
navigationRailIndicatorOpacity: 1.00,
navigationRailBackgroundSchemeColor: SchemeColor.surface,
),
keyColors: const FlexKeyColors(
useSecondary: true,
useTertiary: true,
keepPrimary: true,
),
tones: FlexTones.jolly(Brightness.light),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
colorScheme: scheme,
fontFamily: fontFamily,
extensions: <ThemeExtension<dynamic>>{
extensions: const <ThemeExtension<dynamic>>{
ConnectionButtonTheme.light,
},
);
}
ThemeData dark() {
return FlexThemeData.dark(
scheme: FlexScheme.indigoM3,
ThemeData darkTheme(ColorScheme? darkColorScheme) {
final ColorScheme scheme = darkColorScheme ??
ColorScheme.fromSeed(
seedColor: const Color(0xFF293CA0),
brightness: Brightness.dark,
);
return ThemeData(
useMaterial3: true,
swapLegacyOnMaterial3: true,
useMaterial3ErrorColors: true,
darkIsTrueBlack: mode.trueBlack,
surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
// blendLevel: 1,
subThemesData: const FlexSubThemesData(
blendTextTheme: true,
useTextTheme: true,
useM2StyleDividerInM3: true,
elevatedButtonSchemeColor: SchemeColor.onPrimaryContainer,
elevatedButtonSecondarySchemeColor: SchemeColor.primaryContainer,
outlinedButtonOutlineSchemeColor: SchemeColor.primary,
toggleButtonsBorderSchemeColor: SchemeColor.primary,
segmentedButtonSchemeColor: SchemeColor.primary,
segmentedButtonBorderSchemeColor: SchemeColor.primary,
unselectedToggleIsColored: true,
sliderValueTinted: true,
inputDecoratorSchemeColor: SchemeColor.primary,
inputDecoratorBackgroundAlpha: 43,
inputDecoratorUnfocusedHasBorder: false,
inputDecoratorFocusedBorderWidth: 1.0,
inputDecoratorPrefixIconSchemeColor: SchemeColor.primary,
popupMenuRadius: 8.0,
popupMenuElevation: 3.0,
drawerIndicatorSchemeColor: SchemeColor.primary,
bottomNavigationBarMutedUnselectedLabel: false,
bottomNavigationBarMutedUnselectedIcon: false,
menuRadius: 8.0,
menuElevation: 3.0,
menuBarRadius: 0.0,
menuBarElevation: 2.0,
menuBarShadowColor: Color(0x00000000),
navigationBarSelectedLabelSchemeColor: SchemeColor.primary,
navigationBarMutedUnselectedLabel: false,
navigationBarSelectedIconSchemeColor: SchemeColor.onPrimary,
navigationBarMutedUnselectedIcon: false,
navigationBarIndicatorSchemeColor: SchemeColor.primary,
navigationBarIndicatorOpacity: 1.00,
navigationRailSelectedLabelSchemeColor: SchemeColor.primary,
navigationRailMutedUnselectedLabel: false,
navigationRailSelectedIconSchemeColor: SchemeColor.onPrimary,
navigationRailMutedUnselectedIcon: false,
navigationRailIndicatorSchemeColor: SchemeColor.primary,
navigationRailIndicatorOpacity: 1.00,
navigationRailBackgroundSchemeColor: SchemeColor.surface,
),
keyColors: const FlexKeyColors(
useSecondary: true,
useTertiary: true,
),
// tones: FlexTones.jolly(Brightness.dark),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
colorScheme: scheme,
scaffoldBackgroundColor:
mode.trueBlack ? Colors.black : scheme.background,
fontFamily: fontFamily,
extensions: <ThemeExtension<dynamic>>{
extensions: const <ThemeExtension<dynamic>>{
ConnectionButtonTheme.light,
},
);

View File

@@ -1,4 +1,5 @@
import 'package:accessibility_tools/accessibility_tools.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
@@ -38,33 +39,36 @@ class App extends HookConsumerWidget with PresLogger {
return WindowWrapper(
TrayWrapper(
ShortcutWrapper(
ConnectionWrapper(
MaterialApp.router(
routerConfig: router,
locale: locale.flutterLocale,
supportedLocales: AppLocaleUtils.supportedLocales,
localizationsDelegates: GlobalMaterialLocalizations.delegates,
debugShowCheckedModeBanner: false,
themeMode: themeMode.flutterThemeMode,
theme: theme.light(),
darkTheme: theme.dark(),
title: Constants.appName,
builder: (context, child) {
child = UpgradeAlert(
upgrader: upgrader,
navigatorKey: router.routerDelegate.navigatorKey,
child: child ?? const SizedBox(),
);
if (kDebugMode && _debugAccessibility) {
return AccessibilityTools(
checkFontOverflows: true,
child: child,
ConnectionWrapper(DynamicColorBuilder(
builder:
(ColorScheme? lightColorScheme, ColorScheme? darkColorScheme) {
return MaterialApp.router(
routerConfig: router,
locale: locale.flutterLocale,
supportedLocales: AppLocaleUtils.supportedLocales,
localizationsDelegates: GlobalMaterialLocalizations.delegates,
debugShowCheckedModeBanner: false,
themeMode: themeMode.flutterThemeMode,
theme: theme.lightTheme(lightColorScheme),
darkTheme: theme.darkTheme(darkColorScheme),
title: Constants.appName,
builder: (context, child) {
child = UpgradeAlert(
upgrader: upgrader,
navigatorKey: router.routerDelegate.navigatorKey,
child: child ?? const SizedBox(),
);
}
return child;
},
),
),
if (kDebugMode && _debugAccessibility) {
return AccessibilityTools(
checkFontOverflows: true,
child: child,
);
}
return child;
},
);
},
)),
),
),
);