import 'dart:io'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:system_theme/system_theme.dart'; import 'package:gtk_theme_fl/gtk_theme_fl.dart'; abstract class AppThemeFactory { AppThemeFactory._(); static Future create({ required final bool isDark, required final Color fallbackColor, }) => _createAppTheme( isDark: isDark, fallbackColor: fallbackColor, ); static Future _createAppTheme({ required final Color fallbackColor, final bool isDark = false, }) async { ColorScheme? gtkColorsScheme; final Brightness brightness = isDark ? Brightness.dark : Brightness.light; final ColorScheme? dynamicColorsScheme = await _getDynamicColors(brightness); if (Platform.isLinux) { final GtkThemeData themeData = await GtkThemeData.initialize(); final bool isGtkDark = Color(themeData.theme_bg_color).computeLuminance() < 0.5; final bool isInverseNeeded = isGtkDark != isDark; gtkColorsScheme = ColorScheme.fromSeed( seedColor: Color(themeData.theme_selected_bg_color), brightness: brightness, background: isInverseNeeded ? null : Color(themeData.theme_bg_color), surface: isInverseNeeded ? null : Color(themeData.theme_base_color), ); } final SystemAccentColor accentColor = SystemAccentColor(fallbackColor); try { await accentColor.load(); } on MissingPluginException catch (e) { print('_createAppTheme: ${e.message}'); } final ColorScheme fallbackColorScheme = ColorScheme.fromSeed( seedColor: accentColor.accent, brightness: brightness, ); final ColorScheme colorScheme = dynamicColorsScheme ?? gtkColorsScheme ?? fallbackColorScheme; final Typography appTypography = Typography.material2021(); final ThemeData materialThemeData = ThemeData( visualDensity: VisualDensity.adaptivePlatformDensity, colorScheme: colorScheme, brightness: colorScheme.brightness, typography: appTypography, useMaterial3: true, scaffoldBackgroundColor: colorScheme.background, appBarTheme: AppBarTheme( elevation: 0, backgroundColor: colorScheme.primary, foregroundColor: colorScheme.onPrimary, ), ); return materialThemeData; } static Future _getDynamicColors(final Brightness brightness) { try { return DynamicColorPlugin.getCorePalette().then( (final corePallet) => corePallet?.toColorScheme(brightness: brightness), ); } on PlatformException { return Future.value(null); } } }