Support system theme color (aka Material You)

This commit is contained in:
Ming Ming 2023-07-24 21:06:59 +08:00
parent 2c50e06991
commit cadf9c7410
13 changed files with 216 additions and 109 deletions

View file

@ -251,8 +251,14 @@ extension PrefExtension on Pref {
int? getSeedColor() => provider.getInt(PrefKey.seedColor);
int getSeedColorOr(int def) => getSeedColor() ?? def;
Future<bool> setSeedColor(int value) => _set<int>(
PrefKey.seedColor, value, (key, value) => provider.setInt(key, value));
Future<bool> setSeedColor(int? value) {
if (value == null) {
return _remove(PrefKey.seedColor);
} else {
return _set<int>(PrefKey.seedColor, value,
(key, value) => provider.setInt(key, value));
}
}
bool? isVideoPlayerMute() => provider.getBool(PrefKey.isVideoPlayerMute);
bool isVideoPlayerMuteOr([bool def = false]) => isVideoPlayerMute() ?? def;

View file

@ -383,10 +383,18 @@
"@settingsSeedColorDescription": {
"description": "Customize the colors used in app"
},
"settingsSeedColorSystemColorDescription": "Use system color",
"@settingsSeedColorSystemColorDescription": {
"description": "Use color provided by the OS, i.e., Material You"
},
"settingsSeedColorPickerTitle": "Pick a color",
"@settingsSeedColorPickerTitle": {
"description": "Dialog to customize the colors used in app"
},
"settingsSeedColorPickerSystemColorButtonLabel": "USE SYSTEM COLOR",
"@settingsSeedColorPickerSystemColorButtonLabel": {
"description": "Use color provided by the OS, i.e., Material You"
},
"settingsUseBlackInDarkThemeTitle": "Darker theme",
"@settingsUseBlackInDarkThemeTitle": {
"description": "Make the dark theme darker"

View file

@ -2,6 +2,8 @@
"cs": [
"nameInputInvalidEmpty",
"settingsPersonProviderTitle",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsServerVersionTitle",
"searchLandingPeopleListEmptyText2",
"createCollectionFailureNotification",
@ -49,7 +51,9 @@
"settingsImageEditSaveResultsToServerFalseDescription",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsMiscellaneousTitle",
"settingsDoubleTapExitTitle",
"settingsPhotosTabSortByNameTitle",
@ -242,7 +246,9 @@
"settingsImageEditSaveResultsToServerFalseDescription",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsDoubleTapExitTitle",
"settingsExpertTitle",
"settingsExpertWarningText",
@ -328,12 +334,16 @@
"es": [
"settingsPersonProviderTitle",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerSystemColorButtonLabel",
"searchLandingPeopleListEmptyText2",
"accountSettingsTooltip"
],
"fi": [
"settingsPersonProviderTitle",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerSystemColorButtonLabel",
"searchLandingPeopleListEmptyText2",
"accountSettingsTooltip"
],
@ -362,7 +372,9 @@
"settingsImageEditSaveResultsToServerFalseDescription",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsMiscellaneousTitle",
"settingsDoubleTapExitTitle",
"settingsPhotosTabSortByNameTitle",
@ -495,7 +507,9 @@
"settingsFollowSystemThemeTitle",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsUseBlackInDarkThemeTitle",
"settingsUseBlackInDarkThemeTrueDescription",
"settingsUseBlackInDarkThemeFalseDescription",
@ -843,7 +857,9 @@
"settingsFollowSystemThemeTitle",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsUseBlackInDarkThemeTitle",
"settingsUseBlackInDarkThemeTrueDescription",
"settingsUseBlackInDarkThemeFalseDescription",
@ -1145,7 +1161,9 @@
"settingsImageEditSaveResultsToServerFalseDescription",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsMiscellaneousTitle",
"settingsDoubleTapExitTitle",
"settingsPhotosTabSortByNameTitle",
@ -1265,6 +1283,8 @@
"pt": [
"nameInputInvalidEmpty",
"settingsPersonProviderTitle",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsServerVersionTitle",
"searchLandingPeopleListEmptyText2",
"createCollectionFailureNotification",
@ -1302,7 +1322,9 @@
"settingsImageEditSaveResultsToServerFalseDescription",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsMiscellaneousTitle",
"settingsDoubleTapExitTitle",
"settingsPhotosTabSortByNameTitle",
@ -1424,7 +1446,9 @@
"settingsImageEditSaveResultsToServerFalseDescription",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsMiscellaneousTitle",
"settingsDoubleTapExitTitle",
"settingsPhotosTabSortByNameTitle",
@ -1546,7 +1570,9 @@
"settingsImageEditSaveResultsToServerFalseDescription",
"settingsSeedColorTitle",
"settingsSeedColorDescription",
"settingsSeedColorSystemColorDescription",
"settingsSeedColorPickerTitle",
"settingsSeedColorPickerSystemColorButtonLabel",
"settingsMiscellaneousTitle",
"settingsDoubleTapExitTitle",
"settingsPhotosTabSortByNameTitle",

View file

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
class M3 extends ThemeExtension<M3> {
const M3({
required this.seed,
required this.checkbox,
required this.filterChip,
required this.listTile,
@ -12,13 +11,11 @@ class M3 extends ThemeExtension<M3> {
@override
M3 copyWith({
Color? seed,
M3Checkbox? checkbox,
M3FilterChip? filterChip,
M3ListTile? listTile,
}) =>
M3(
seed: seed ?? this.seed,
checkbox: checkbox ?? this.checkbox,
filterChip: filterChip ?? this.filterChip,
listTile: listTile ?? this.listTile,
@ -30,14 +27,12 @@ class M3 extends ThemeExtension<M3> {
return this;
}
return M3(
seed: Color.lerp(seed, other.seed, t)!,
checkbox: checkbox.lerp(other.checkbox, t),
filterChip: filterChip.lerp(other.filterChip, t),
listTile: listTile.lerp(other.listTile, t),
);
}
final Color seed;
final M3Checkbox checkbox;
final M3FilterChip filterChip;
final M3ListTile listTile;

View file

@ -12,5 +12,8 @@ class SessionStorage {
/// Whether the drag to rearrange notification has been shown
bool hasShowDragRearrangeNotification = false;
/// Whether the dynamic_color library is supported in this platform
bool isSupportDynamicColor = false;
static final _inst = SessionStorage._();
}

View file

@ -3,6 +3,9 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:nc_photos/entity/pref.dart';
import 'package:nc_photos/material3.dart';
import 'package:nc_photos/object_extension.dart';
const defaultSeedColor = 0xFF2196F3;
extension ThemeExtension on ThemeData {
double get widthLimitedContentMaxWidth => 550.0;
@ -90,38 +93,43 @@ ThemeData buildTheme(Brightness brightness) {
: buildDarkTheme();
}
ThemeData buildLightTheme() {
final seedColor = getSeedColor();
final colorScheme = ColorScheme.fromSeed(
seedColor: seedColor,
);
return _applyColorScheme(colorScheme, seedColor);
ThemeData buildLightTheme([ColorScheme? dynamicScheme]) {
final colorScheme = _getColorScheme(dynamicScheme, Brightness.light);
return _applyColorScheme(colorScheme);
}
ThemeData buildDarkTheme() {
final seedColor = getSeedColor();
final colorScheme = ColorScheme.fromSeed(
seedColor: seedColor,
brightness: Brightness.dark,
);
ThemeData buildDarkTheme([ColorScheme? dynamicScheme]) {
final colorScheme = _getColorScheme(dynamicScheme, Brightness.dark);
if (Pref().isUseBlackInDarkThemeOr(false)) {
return _applyColorScheme(
colorScheme.copyWith(
background: Colors.black,
surface: Colors.grey[900],
),
seedColor,
);
return _applyColorScheme(colorScheme.copyWith(
background: Colors.black,
surface: Colors.grey[900],
));
} else {
return _applyColorScheme(colorScheme, seedColor);
return _applyColorScheme(colorScheme);
}
}
Color getSeedColor() {
return Color(Pref().getSeedColor() ?? 0xFF2196F3).withAlpha(0xFF);
Color? getSeedColor() {
return Pref().getSeedColor()?.run((c) => Color(c).withAlpha(0xFF));
}
ThemeData _applyColorScheme(ColorScheme colorScheme, Color seedColor) {
ColorScheme _getColorScheme(ColorScheme? dynamicScheme, Brightness brightness) {
var seedColor = Pref().getSeedColor();
if (seedColor == null) {
if (dynamicScheme != null) {
return dynamicScheme;
} else {
seedColor = defaultSeedColor;
}
}
return ColorScheme.fromSeed(
seedColor: Color(seedColor),
brightness: brightness,
);
}
ThemeData _applyColorScheme(ColorScheme colorScheme) {
return ThemeData(
useMaterial3: true,
brightness: colorScheme.brightness,
@ -212,7 +220,6 @@ ThemeData _applyColorScheme(ColorScheme colorScheme, Color seedColor) {
),
extensions: [
M3(
seed: seedColor,
checkbox: M3Checkbox(
disabled: M3CheckboxDisabled(
container: colorScheme.onSurface.withOpacity(.38),

View file

@ -1,3 +1,4 @@
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -13,6 +14,7 @@ import 'package:nc_photos/language_util.dart' as language_util;
import 'package:nc_photos/legacy/connect.dart' as legacy;
import 'package:nc_photos/legacy/sign_in.dart' as legacy;
import 'package:nc_photos/navigation_manager.dart';
import 'package:nc_photos/session_storage.dart';
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/stream_util.dart';
import 'package:nc_photos/theme.dart';
@ -97,7 +99,7 @@ class _WrappedAppState extends State<_WrappedApp>
}
@override
build(BuildContext context) {
Widget build(BuildContext context) {
final ThemeMode themeMode;
if (Pref().isFollowSystemThemeOr(false)) {
themeMode = ThemeMode.system;
@ -108,42 +110,50 @@ class _WrappedAppState extends State<_WrappedApp>
final prefController = context.read<PrefController>();
return ValueStreamBuilder<language_util.AppLanguage>(
stream: prefController.language,
builder: (context, snapshot) => MaterialApp(
onGenerateTitle: (context) => AppLocalizations.of(context)!.appTitle,
theme: buildLightTheme(),
darkTheme: buildDarkTheme(),
themeMode: themeMode,
initialRoute: Splash.routeName,
onGenerateRoute: _onGenerateRoute,
navigatorObservers: <NavigatorObserver>[MyApp.routeObserver],
navigatorKey: _navigatorKey,
scaffoldMessengerKey: _scaffoldMessengerKey,
locale: snapshot.requireData.locale,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: const <Locale>[
// the order here doesn't matter, except for the first one, which must
// be en
Locale("en"),
Locale("el"),
Locale("es"),
Locale("fr"),
Locale("ru"),
Locale("de"),
Locale("cs"),
Locale("fi"),
Locale("pl"),
Locale("pt"),
Locale.fromSubtags(languageCode: "zh", scriptCode: "Hans"),
Locale.fromSubtags(languageCode: "zh", scriptCode: "Hant"),
Locale("it"),
Locale("nl"),
],
builder: (context, child) {
MyApp._globalContext = context;
return child!;
builder: (context, snapshot) => DynamicColorBuilder(
builder: (lightDynamic, darkDynamic) {
if (lightDynamic != null) {
SessionStorage().isSupportDynamicColor = true;
}
return MaterialApp(
onGenerateTitle: (context) =>
AppLocalizations.of(context)!.appTitle,
theme: buildLightTheme(lightDynamic),
darkTheme: buildDarkTheme(darkDynamic),
themeMode: themeMode,
initialRoute: Splash.routeName,
onGenerateRoute: _onGenerateRoute,
navigatorObservers: <NavigatorObserver>[MyApp.routeObserver],
navigatorKey: _navigatorKey,
scaffoldMessengerKey: _scaffoldMessengerKey,
locale: snapshot.requireData.locale,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: const <Locale>[
// the order here doesn't matter, except for the first one, which must
// be en
Locale("en"),
Locale("el"),
Locale("es"),
Locale("fr"),
Locale("ru"),
Locale("de"),
Locale("cs"),
Locale("fi"),
Locale("pl"),
Locale("pt"),
Locale.fromSubtags(languageCode: "zh", scriptCode: "Hans"),
Locale.fromSubtags(languageCode: "zh", scriptCode: "Hant"),
Locale("it"),
Locale("nl"),
],
builder: (context, child) {
MyApp._globalContext = context;
return child!;
},
debugShowCheckedModeBanner: false,
scrollBehavior: const _MyScrollBehavior(),
);
},
debugShowCheckedModeBanner: false,
scrollBehavior: const _MyScrollBehavior(),
),
);
}

View file

@ -14,7 +14,7 @@ class _Bloc extends Bloc<_Event, _State> {
super(_State(
isFollowSystemTheme: c.pref.isFollowSystemThemeOr(false),
isUseBlackInDarkTheme: c.pref.isUseBlackInDarkThemeOr(false),
seedColor: getSeedColor(),
seedColor: getSeedColor()?.value,
)) {
on<_SetFollowSystemTheme>(_onSetFollowSystemTheme);
on<_SetUseBlackInDarkTheme>(_onSetUseBlackInDarkTheme);
@ -27,6 +27,7 @@ class _Bloc extends Bloc<_Event, _State> {
Future<void> _onSetFollowSystemTheme(
_SetFollowSystemTheme ev, Emitter<_State> emit) async {
_log.info(ev);
final oldValue = state.isFollowSystemTheme;
emit(state.copyWith(isFollowSystemTheme: ev.value));
if (await _c.pref.setFollowSystemTheme(ev.value)) {
@ -40,6 +41,7 @@ class _Bloc extends Bloc<_Event, _State> {
Future<void> _onSetUseBlackInDarkTheme(
_SetUseBlackInDarkTheme ev, Emitter<_State> emit) async {
_log.info(ev);
final oldValue = state.isUseBlackInDarkTheme;
emit(state.copyWith(isUseBlackInDarkTheme: ev.value));
if (await _c.pref.setUseBlackInDarkTheme(ev.value)) {
@ -54,9 +56,10 @@ class _Bloc extends Bloc<_Event, _State> {
}
Future<void> _onSetSeedColor(_SetSeedColor ev, Emitter<_State> emit) async {
_log.info(ev);
final oldValue = state.seedColor;
emit(state.copyWith(seedColor: ev.value));
if (await _c.pref.setSeedColor(ev.value.withAlpha(0xFF).value)) {
emit(state.copyWith(seedColor: ev.value?.value));
if (await _c.pref.setSeedColor(ev.value?.withAlpha(0xFF).value)) {
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
} else {
_log.severe("[_onSetSeedColor] Failed writing pref");

View file

@ -14,7 +14,8 @@ class _State {
final bool isFollowSystemTheme;
final bool isUseBlackInDarkTheme;
final Color seedColor;
// workaround analyzer bug where Color type can't be recognized
final int? seedColor;
}
abstract class _Event {
@ -49,5 +50,5 @@ class _SetSeedColor extends _Event {
@override
String toString() => _$toString();
final Color value;
final Color? value;
}

View file

@ -14,6 +14,7 @@ import 'package:nc_photos/event/event.dart';
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/mobile/android/android_info.dart';
import 'package:nc_photos/platform/k.dart' as platform_k;
import 'package:nc_photos/session_storage.dart';
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/theme.dart';
import 'package:np_codegen/np_codegen.dart';
@ -23,6 +24,8 @@ part 'theme/bloc.dart';
part 'theme/state_event.dart';
part 'theme_settings.g.dart';
typedef _BlocBuilder = BlocBuilder<_Bloc, _State>;
class ThemeSettings extends StatelessWidget {
const ThemeSettings({super.key});
@ -47,7 +50,7 @@ class _WrappedThemeSettingsState extends State<_WrappedThemeSettings> {
@override
void initState() {
super.initState();
_errorSubscription = context.read<_Bloc>().errorStream().listen((_) {
_errorSubscription = _bloc.errorStream().listen((_) {
SnackBarManager().showSnackBar(SnackBar(
content: Text(L10n.global().writePreferenceFailureNotification),
duration: k.snackBarDurationNormal,
@ -80,25 +83,10 @@ class _WrappedThemeSettingsState extends State<_WrappedThemeSettings> {
SliverList(
delegate: SliverChildListDelegate(
[
BlocBuilder<_Bloc, _State>(
buildWhen: (previous, current) =>
previous.seedColor != current.seedColor,
builder: (context, state) {
return ListTile(
title: Text(L10n.global().settingsSeedColorTitle),
subtitle: Text(L10n.global().settingsSeedColorDescription),
trailing: Icon(
Icons.circle,
size: 32,
color: state.seedColor,
),
onTap: () => _onSeedColorPressed(context),
);
},
),
const _SeedColorOption(),
if (platform_k.isAndroid &&
AndroidInfo().sdkInt >= AndroidVersion.Q)
BlocBuilder<_Bloc, _State>(
_BlocBuilder(
buildWhen: (previous, current) =>
previous.isFollowSystemTheme !=
current.isFollowSystemTheme,
@ -107,12 +95,12 @@ class _WrappedThemeSettingsState extends State<_WrappedThemeSettings> {
title: Text(L10n.global().settingsFollowSystemThemeTitle),
value: state.isFollowSystemTheme,
onChanged: (value) {
context.read<_Bloc>().add(_SetFollowSystemTheme(value));
_bloc.add(_SetFollowSystemTheme(value));
},
);
},
),
BlocBuilder<_Bloc, _State>(
_BlocBuilder(
buildWhen: (previous, current) =>
previous.isUseBlackInDarkTheme !=
current.isUseBlackInDarkTheme,
@ -126,7 +114,7 @@ class _WrappedThemeSettingsState extends State<_WrappedThemeSettings> {
.settingsUseBlackInDarkThemeFalseDescription),
value: state.isUseBlackInDarkTheme,
onChanged: (value) {
context.read<_Bloc>().add(
_bloc.add(
_SetUseBlackInDarkTheme(value, Theme.of(context)));
},
);
@ -139,20 +127,63 @@ class _WrappedThemeSettingsState extends State<_WrappedThemeSettings> {
);
}
late final _bloc = context.read<_Bloc>();
late final StreamSubscription _errorSubscription;
}
class _SeedColorOption extends StatelessWidget {
const _SeedColorOption();
@override
Widget build(BuildContext context) {
return _BlocBuilder(
buildWhen: (previous, current) => previous.seedColor != current.seedColor,
builder: (context, state) {
if (SessionStorage().isSupportDynamicColor) {
return ListTile(
title: Text(L10n.global().settingsSeedColorTitle),
subtitle: Text(state.seedColor == null
? L10n.global().settingsSeedColorSystemColorDescription
: L10n.global().settingsSeedColorDescription),
trailing: state.seedColor == null
? null
: Icon(
Icons.circle,
size: 32,
color: Color(state.seedColor!),
),
onTap: () => _onSeedColorPressed(context),
);
} else {
return ListTile(
title: Text(L10n.global().settingsSeedColorTitle),
subtitle: Text(L10n.global().settingsSeedColorDescription),
trailing: Icon(
Icons.circle,
size: 32,
color: Color(state.seedColor ?? defaultSeedColor),
),
onTap: () => _onSeedColorPressed(context),
);
}
},
);
}
Future<void> _onSeedColorPressed(BuildContext context) async {
final result = await showDialog<Color>(
final result = await showDialog<int>(
context: context,
builder: (context) => const _SeedColorPicker(),
);
if (result == null) {
return;
}
if (mounted) {
context.read<_Bloc>().add(_SetSeedColor(result));
if (context.mounted) {
context
.read<_Bloc>()
.add(_SetSeedColor(result == -1 ? null : Color(result)));
}
}
late final StreamSubscription _errorSubscription;
}
class _SeedColorPicker extends StatefulWidget {
@ -180,15 +211,24 @@ class _SeedColorPickerState extends State<_SeedColorPicker> {
]
.map((c) => _SeedColorPickerItem(
seedColor: c,
onSelected: () => _onItemSelected(context, c),
onSelected: () => _onItemSelected(context, c?.value),
))
.toList(),
),
actions: SessionStorage().isSupportDynamicColor
? [
TextButton(
onPressed: () => _onItemSelected(context, -1),
child: Text(L10n.global()
.settingsSeedColorPickerSystemColorButtonLabel),
),
]
: null,
),
);
}
Future<void> _onItemSelected(BuildContext context, Color? seedColor) async {
Future<void> _onItemSelected(BuildContext context, int? seedColor) async {
if (seedColor != null) {
Navigator.of(context).pop(seedColor);
return;
@ -198,10 +238,10 @@ class _SeedColorPickerState extends State<_SeedColorPicker> {
});
final color = await showDialog<Color>(
context: context,
builder: (context) => const _SeedColorCustomPicker(),
builder: (_) => const _SeedColorCustomPicker(),
barrierColor: Colors.transparent,
);
Navigator.of(context).pop(color);
Navigator.of(context).pop(color?.value);
}
var _isVisible = true;
@ -240,7 +280,7 @@ class _SeedColorCustomPickerState extends State<_SeedColorCustomPicker> {
);
}
late Color _customColor = getSeedColor();
late Color _customColor = getSeedColor() ?? const Color(defaultSeedColor);
}
class _SeedColorPickerItem extends StatelessWidget {

View file

@ -14,9 +14,7 @@ part of 'theme_settings.dart';
abstract class $_StateCopyWithWorker {
_State call(
{bool? isFollowSystemTheme,
bool? isUseBlackInDarkTheme,
Color? seedColor});
{bool? isFollowSystemTheme, bool? isUseBlackInDarkTheme, int? seedColor});
}
class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
@ -26,13 +24,14 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
_State call(
{dynamic isFollowSystemTheme,
dynamic isUseBlackInDarkTheme,
dynamic seedColor}) {
dynamic seedColor = copyWithNull}) {
return _State(
isFollowSystemTheme:
isFollowSystemTheme as bool? ?? that.isFollowSystemTheme,
isUseBlackInDarkTheme:
isUseBlackInDarkTheme as bool? ?? that.isUseBlackInDarkTheme,
seedColor: seedColor as Color? ?? that.seedColor);
seedColor:
seedColor == copyWithNull ? that.seedColor : seedColor as int?);
}
final _State that;

View file

@ -413,6 +413,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.8.0"
dynamic_color:
dependency: "direct main"
description:
name: dynamic_color
sha256: de4798a7069121aee12d5895315680258415de9b00e717723a1bd73d58f0126d
url: "https://pub.dev"
source: hosted
version: "1.6.6"
equatable:
dependency: "direct main"
description:
@ -1779,4 +1787,4 @@ packages:
version: "3.1.2"
sdks:
dart: ">=2.19.0 <3.0.0"
flutter: ">=3.3.0"
flutter: ">=3.4.0-17.0.pre"

View file

@ -53,6 +53,7 @@ dependencies:
url: https://gitlab.com/nc-photos/flutter-draggable-scrollbar
ref: v0.1.0-nc-photos-6
drift: 2.8.0
dynamic_color: ^1.6.6
equatable: ^2.0.5
event_bus: ^2.0.0
exifdart: