mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-02-16 06:19:35 +00:00
156 lines
4.8 KiB
Dart
156 lines
4.8 KiB
Dart
import 'package:dynamic_color/dynamic_color.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:logging/logging.dart';
|
|
import 'package:material_color_utilities/material_color_utilities.dart';
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:vaani/features/settings/app_settings_provider.dart';
|
|
import 'package:vaani/theme/providers/theme_from_cover_provider.dart';
|
|
import 'package:vaani/theme/theme.dart';
|
|
|
|
part 'system_theme_provider.g.dart';
|
|
|
|
final _logger = Logger('SystemThemeProvider');
|
|
|
|
/// copied from [DynamicColorBuilder]
|
|
@Riverpod(keepAlive: true)
|
|
FutureOr<(ColorScheme light, ColorScheme dark)?> systemTheme(
|
|
Ref ref, {
|
|
bool highContrast = false,
|
|
}) async {
|
|
_logger.fine('Generating system theme');
|
|
ColorScheme? schemeLight;
|
|
ColorScheme? schemeDark;
|
|
// Platform messages may fail, so we use a try/catch PlatformException.
|
|
try {
|
|
CorePalette? corePalette = await DynamicColorPlugin.getCorePalette();
|
|
|
|
if (corePalette != null) {
|
|
_logger.fine('dynamic_color: Core palette detected.');
|
|
schemeLight = corePalette.toColorScheme(brightness: Brightness.light);
|
|
schemeDark = corePalette.toColorScheme(brightness: Brightness.dark);
|
|
}
|
|
} on PlatformException {
|
|
_logger.warning('dynamic_color: Failed to obtain core palette.');
|
|
}
|
|
|
|
if (schemeLight == null || schemeDark == null) {
|
|
try {
|
|
final Color? accentColor = await DynamicColorPlugin.getAccentColor();
|
|
|
|
if (accentColor != null) {
|
|
_logger.fine('dynamic_color: Accent color detected.');
|
|
schemeLight = ColorScheme.fromSeed(
|
|
seedColor: accentColor,
|
|
brightness: Brightness.light,
|
|
);
|
|
schemeDark = ColorScheme.fromSeed(
|
|
seedColor: accentColor,
|
|
brightness: Brightness.dark,
|
|
);
|
|
}
|
|
} on PlatformException {
|
|
_logger.warning('dynamic_color: Failed to obtain accent color.');
|
|
}
|
|
}
|
|
|
|
if (schemeLight == null || schemeDark == null) {
|
|
_logger
|
|
.warning('dynamic_color: Dynamic color not detected on this device.');
|
|
return null;
|
|
}
|
|
// set high contrast theme
|
|
if (highContrast) {
|
|
schemeLight = schemeLight
|
|
.copyWith(
|
|
surface: Colors.white,
|
|
)
|
|
.harmonized();
|
|
schemeDark = schemeDark
|
|
.copyWith(
|
|
surface: Colors.black,
|
|
)
|
|
.harmonized();
|
|
}
|
|
return (schemeLight, schemeDark);
|
|
}
|
|
|
|
@riverpod
|
|
(ThemeData light, ThemeData dark) currentTheme(
|
|
Ref ref, {
|
|
bool highContrast = false,
|
|
String? id,
|
|
}) {
|
|
final themeSettings =
|
|
ref.watch(appSettingsProvider.select((v) => v.themeSettings));
|
|
ColorScheme lightColorScheme = brandLightColorScheme;
|
|
ColorScheme darkColorScheme = brandDarkColorScheme;
|
|
|
|
final shouldUseHighContrast = themeSettings.highContrast || highContrast;
|
|
|
|
if (shouldUseHighContrast) {
|
|
lightColorScheme = lightColorScheme.copyWith(
|
|
surface: Colors.white,
|
|
);
|
|
darkColorScheme = darkColorScheme.copyWith(
|
|
surface: Colors.black,
|
|
);
|
|
}
|
|
|
|
if (themeSettings.useMaterialThemeFromSystem) {
|
|
var themes =
|
|
ref.watch(systemThemeProvider(highContrast: shouldUseHighContrast));
|
|
if (themes.valueOrNull != null) {
|
|
lightColorScheme = themes.valueOrNull!.$1;
|
|
darkColorScheme = themes.valueOrNull!.$2;
|
|
}
|
|
}
|
|
|
|
if (themeSettings.useCurrentPlayerThemeThroughoutApp) {
|
|
try {
|
|
if (id != null) {
|
|
final themeLight = ref.watch(
|
|
themeOfLibraryItemProvider(
|
|
id,
|
|
highContrast: shouldUseHighContrast,
|
|
brightness: Brightness.light,
|
|
),
|
|
);
|
|
final themeDark = ref.watch(
|
|
themeOfLibraryItemProvider(
|
|
id,
|
|
highContrast: shouldUseHighContrast,
|
|
brightness: Brightness.dark,
|
|
),
|
|
);
|
|
if (themeLight.valueOrNull != null && themeDark.valueOrNull != null) {
|
|
lightColorScheme = themeLight.valueOrNull!;
|
|
darkColorScheme = themeDark.valueOrNull!;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
debugPrintStack(stackTrace: StackTrace.current, label: e.toString());
|
|
_logger.severe('not building with player theme');
|
|
_logger.severe(e.toString());
|
|
}
|
|
}
|
|
final appThemeLight = ThemeData(
|
|
useMaterial3: true,
|
|
colorScheme: lightColorScheme.harmonized(),
|
|
fontFamily: fontFamilyPlatform,
|
|
textTheme: textTheme,
|
|
);
|
|
final appThemeDark = ThemeData(
|
|
useMaterial3: true,
|
|
colorScheme: darkColorScheme.harmonized(),
|
|
fontFamily: fontFamilyPlatform,
|
|
textTheme: textTheme,
|
|
brightness: Brightness.dark,
|
|
// TODO bottom sheet theme is not working
|
|
bottomSheetTheme: BottomSheetThemeData(
|
|
backgroundColor: darkColorScheme.surface,
|
|
),
|
|
);
|
|
return (appThemeLight, appThemeDark);
|
|
}
|