Implement Material 3 dynamic theming
This commit is contained in:
committed by
imshahab
parent
f8976da06d
commit
d67c9be306
@@ -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:flutter/material.dart';
|
||||||
import 'package:hiddify/core/theme/app_theme_mode.dart';
|
import 'package:hiddify/core/theme/app_theme_mode.dart';
|
||||||
import 'package:hiddify/core/theme/theme_extensions.dart';
|
import 'package:hiddify/core/theme/theme_extensions.dart';
|
||||||
|
|
||||||
class AppTheme {
|
class AppTheme {
|
||||||
AppTheme(
|
AppTheme(this.mode, this.fontFamily);
|
||||||
this.mode,
|
|
||||||
this.fontFamily,
|
|
||||||
);
|
|
||||||
|
|
||||||
final AppThemeMode mode;
|
final AppThemeMode mode;
|
||||||
final String fontFamily;
|
final String fontFamily;
|
||||||
|
|
||||||
ThemeData light() {
|
ThemeData lightTheme(ColorScheme? lightColorScheme) {
|
||||||
return FlexThemeData.light(
|
final ColorScheme scheme = lightColorScheme ??
|
||||||
scheme: FlexScheme.indigoM3,
|
ColorScheme.fromSeed(seedColor: const Color(0xFF293CA0));
|
||||||
surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
|
return ThemeData(
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
swapLegacyOnMaterial3: true,
|
colorScheme: scheme,
|
||||||
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,
|
|
||||||
fontFamily: fontFamily,
|
fontFamily: fontFamily,
|
||||||
extensions: <ThemeExtension<dynamic>>{
|
extensions: const <ThemeExtension<dynamic>>{
|
||||||
ConnectionButtonTheme.light,
|
ConnectionButtonTheme.light,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeData dark() {
|
ThemeData darkTheme(ColorScheme? darkColorScheme) {
|
||||||
return FlexThemeData.dark(
|
final ColorScheme scheme = darkColorScheme ??
|
||||||
scheme: FlexScheme.indigoM3,
|
ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFF293CA0),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
);
|
||||||
|
return ThemeData(
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
swapLegacyOnMaterial3: true,
|
colorScheme: scheme,
|
||||||
useMaterial3ErrorColors: true,
|
scaffoldBackgroundColor:
|
||||||
darkIsTrueBlack: mode.trueBlack,
|
mode.trueBlack ? Colors.black : scheme.background,
|
||||||
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,
|
|
||||||
fontFamily: fontFamily,
|
fontFamily: fontFamily,
|
||||||
extensions: <ThemeExtension<dynamic>>{
|
extensions: const <ThemeExtension<dynamic>>{
|
||||||
ConnectionButtonTheme.light,
|
ConnectionButtonTheme.light,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:accessibility_tools/accessibility_tools.dart';
|
import 'package:accessibility_tools/accessibility_tools.dart';
|
||||||
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
@@ -38,33 +39,36 @@ class App extends HookConsumerWidget with PresLogger {
|
|||||||
return WindowWrapper(
|
return WindowWrapper(
|
||||||
TrayWrapper(
|
TrayWrapper(
|
||||||
ShortcutWrapper(
|
ShortcutWrapper(
|
||||||
ConnectionWrapper(
|
ConnectionWrapper(DynamicColorBuilder(
|
||||||
MaterialApp.router(
|
builder:
|
||||||
routerConfig: router,
|
(ColorScheme? lightColorScheme, ColorScheme? darkColorScheme) {
|
||||||
locale: locale.flutterLocale,
|
return MaterialApp.router(
|
||||||
supportedLocales: AppLocaleUtils.supportedLocales,
|
routerConfig: router,
|
||||||
localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
locale: locale.flutterLocale,
|
||||||
debugShowCheckedModeBanner: false,
|
supportedLocales: AppLocaleUtils.supportedLocales,
|
||||||
themeMode: themeMode.flutterThemeMode,
|
localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
||||||
theme: theme.light(),
|
debugShowCheckedModeBanner: false,
|
||||||
darkTheme: theme.dark(),
|
themeMode: themeMode.flutterThemeMode,
|
||||||
title: Constants.appName,
|
theme: theme.lightTheme(lightColorScheme),
|
||||||
builder: (context, child) {
|
darkTheme: theme.darkTheme(darkColorScheme),
|
||||||
child = UpgradeAlert(
|
title: Constants.appName,
|
||||||
upgrader: upgrader,
|
builder: (context, child) {
|
||||||
navigatorKey: router.routerDelegate.navigatorKey,
|
child = UpgradeAlert(
|
||||||
child: child ?? const SizedBox(),
|
upgrader: upgrader,
|
||||||
);
|
navigatorKey: router.routerDelegate.navigatorKey,
|
||||||
if (kDebugMode && _debugAccessibility) {
|
child: child ?? const SizedBox(),
|
||||||
return AccessibilityTools(
|
|
||||||
checkFontOverflows: true,
|
|
||||||
child: child,
|
|
||||||
);
|
);
|
||||||
}
|
if (kDebugMode && _debugAccessibility) {
|
||||||
return child;
|
return AccessibilityTools(
|
||||||
},
|
checkFontOverflows: true,
|
||||||
),
|
child: child,
|
||||||
),
|
);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <dynamic_color/dynamic_color_plugin.h>
|
||||||
#include <screen_retriever/screen_retriever_plugin.h>
|
#include <screen_retriever/screen_retriever_plugin.h>
|
||||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||||
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
@@ -14,6 +15,9 @@
|
|||||||
#include <window_manager/window_manager_plugin.h>
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
|
||||||
|
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
|
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
|
||||||
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
|
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
dynamic_color
|
||||||
screen_retriever
|
screen_retriever
|
||||||
sentry_flutter
|
sentry_flutter
|
||||||
sqlite3_flutter_libs
|
sqlite3_flutter_libs
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import FlutterMacOS
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
|
import dynamic_color
|
||||||
import flutter_timezone
|
import flutter_timezone
|
||||||
import in_app_review
|
import in_app_review
|
||||||
import mobile_scanner
|
import mobile_scanner
|
||||||
@@ -23,6 +24,7 @@ import window_manager
|
|||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
|
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||||
FlutterTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterTimezonePlugin"))
|
FlutterTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterTimezonePlugin"))
|
||||||
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
||||||
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
|
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
|
||||||
|
|||||||
24
pubspec.lock
24
pubspec.lock
@@ -402,6 +402,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.16.0"
|
version: "2.16.0"
|
||||||
|
dynamic_color:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dynamic_color
|
||||||
|
sha256: eae98052fa6e2826bdac3dd2e921c6ce2903be15c6b7f8b6d8a5d49b5086298d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.7.0"
|
||||||
equatable:
|
equatable:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -450,22 +458,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
flex_color_scheme:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: flex_color_scheme
|
|
||||||
sha256: "32914024a4f404d90ff449f58d279191675b28e7c08824046baf06826e99d984"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.3.1"
|
|
||||||
flex_seed_scheme:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: flex_seed_scheme
|
|
||||||
sha256: "29c12aba221eb8a368a119685371381f8035011d18de5ba277ad11d7dfb8657f"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.4.0"
|
|
||||||
fluentui_system_icons:
|
fluentui_system_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ dependencies:
|
|||||||
neat_periodic_task: ^2.0.1
|
neat_periodic_task: ^2.0.1
|
||||||
watcher: ^1.1.0
|
watcher: ^1.1.0
|
||||||
go_router: ^13.2.0
|
go_router: ^13.2.0
|
||||||
flex_color_scheme: ^7.3.1
|
|
||||||
flutter_animate: ^4.5.0
|
flutter_animate: ^4.5.0
|
||||||
flutter_svg: ^2.0.10+1
|
flutter_svg: ^2.0.10+1
|
||||||
gap: ^3.0.1
|
gap: ^3.0.1
|
||||||
@@ -84,6 +83,7 @@ dependencies:
|
|||||||
git: https://github.com/hiddify-com/flutter_circle_flags.git
|
git: https://github.com/hiddify-com/flutter_circle_flags.git
|
||||||
protobuf: ^3.1.0
|
protobuf: ^3.1.0
|
||||||
grpc: ^3.2.4
|
grpc: ^3.2.4
|
||||||
|
dynamic_color: ^1.7.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <dynamic_color/dynamic_color_plugin_c_api.h>
|
||||||
#include <protocol_handler_windows/protocol_handler_windows_plugin_c_api.h>
|
#include <protocol_handler_windows/protocol_handler_windows_plugin_c_api.h>
|
||||||
#include <screen_retriever/screen_retriever_plugin.h>
|
#include <screen_retriever/screen_retriever_plugin.h>
|
||||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||||
@@ -17,6 +18,8 @@
|
|||||||
#include <window_manager/window_manager_plugin.h>
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
DynamicColorPluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
|
||||||
ProtocolHandlerWindowsPluginCApiRegisterWithRegistrar(
|
ProtocolHandlerWindowsPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("ProtocolHandlerWindowsPluginCApi"));
|
registry->GetRegistrarForPlugin("ProtocolHandlerWindowsPluginCApi"));
|
||||||
ScreenRetrieverPluginRegisterWithRegistrar(
|
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
dynamic_color
|
||||||
protocol_handler_windows
|
protocol_handler_windows
|
||||||
screen_retriever
|
screen_retriever
|
||||||
sentry_flutter
|
sentry_flutter
|
||||||
|
|||||||
Reference in New Issue
Block a user