mirror of
https://github.com/hamaluik/timecop.git
synced 2025-08-06 06:56:11 +08:00
Material You theming support
This commit is contained in:
@ -14,10 +14,8 @@
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:timecop/data_providers/settings/settings_provider.dart';
|
||||
import 'package:timecop/models/theme_type.dart';
|
||||
import 'package:timecop/themes.dart';
|
||||
|
||||
part 'theme_event.dart';
|
||||
part 'theme_state.dart';
|
||||
|
@ -19,19 +19,4 @@ class ThemeState extends Equatable {
|
||||
const ThemeState(this.theme);
|
||||
@override
|
||||
List<Object?> get props => [theme];
|
||||
|
||||
ThemeData? get themeData {
|
||||
switch (theme) {
|
||||
case ThemeType.auto:
|
||||
return null;
|
||||
case ThemeType.light:
|
||||
return ThemeUtil.lightTheme;
|
||||
case ThemeType.dark:
|
||||
return ThemeUtil.darkTheme;
|
||||
case ThemeType.black:
|
||||
return ThemeUtil.blackTheme;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'dart:io';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
@ -33,6 +34,7 @@ import 'package:timecop/data_providers/notifications/notifications_provider.dart
|
||||
import 'package:timecop/data_providers/settings/settings_provider.dart';
|
||||
import 'package:timecop/fontlicenses.dart';
|
||||
import 'package:timecop/l10n.dart';
|
||||
import 'package:timecop/models/theme_type.dart';
|
||||
import 'package:timecop/screens/dashboard/DashboardScreen.dart';
|
||||
import 'package:timecop/themes.dart';
|
||||
import 'package:flutter_app_badger/flutter_app_badger.dart';
|
||||
@ -195,6 +197,46 @@ class _TimeCopAppState extends State<TimeCopApp> with WidgetsBindingObserver {
|
||||
() => brightness = WidgetsBinding.instance.window.platformBrightness);
|
||||
}
|
||||
|
||||
ThemeData getTheme(
|
||||
ThemeType? type, ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
|
||||
if (type == ThemeType.autoMaterialYou) {
|
||||
if (brightness == Brightness.dark) {
|
||||
type = ThemeType.darkMaterialYou;
|
||||
} else {
|
||||
type = ThemeType.lightMaterialYou;
|
||||
}
|
||||
}
|
||||
switch (type) {
|
||||
case ThemeType.light:
|
||||
return ThemeUtil.lightTheme;
|
||||
case ThemeType.dark:
|
||||
return ThemeUtil.darkTheme;
|
||||
case ThemeType.black:
|
||||
return ThemeUtil.blackTheme;
|
||||
case ThemeType.lightMaterialYou:
|
||||
return ThemeUtil.getThemeFromColors(
|
||||
brightness: Brightness.light,
|
||||
colors: lightDynamic ?? ThemeUtil.lightColors,
|
||||
appBarBackground:
|
||||
lightDynamic?.background ?? ThemeUtil.lightColors.background,
|
||||
appBarForeground: lightDynamic?.onBackground ??
|
||||
ThemeUtil.lightColors.onBackground);
|
||||
case ThemeType.darkMaterialYou:
|
||||
return ThemeUtil.getThemeFromColors(
|
||||
brightness: Brightness.dark,
|
||||
colors: darkDynamic ?? ThemeUtil.darkColors,
|
||||
appBarBackground:
|
||||
darkDynamic?.background ?? ThemeUtil.darkColors.background,
|
||||
appBarForeground:
|
||||
darkDynamic?.onBackground ?? ThemeUtil.darkColors.onBackground);
|
||||
case ThemeType.auto:
|
||||
default:
|
||||
return brightness == Brightness.dark
|
||||
? ThemeUtil.darkTheme
|
||||
: ThemeUtil.lightTheme;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiRepositoryProvider(
|
||||
@ -205,13 +247,14 @@ class _TimeCopAppState extends State<TimeCopApp> with WidgetsBindingObserver {
|
||||
builder: (BuildContext context, ThemeState themeState) =>
|
||||
BlocBuilder<LocaleBloc, LocaleState>(
|
||||
builder: (BuildContext context, LocaleState localeState) =>
|
||||
DynamicColorBuilder(
|
||||
builder: (ColorScheme? lightDynamic,
|
||||
ColorScheme? darkDynamic) =>
|
||||
MaterialApp(
|
||||
title: 'Time Cop',
|
||||
home: const DashboardScreen(),
|
||||
theme: themeState.themeData ??
|
||||
(brightness == Brightness.dark
|
||||
? ThemeUtil.darkTheme
|
||||
: ThemeUtil.lightTheme),
|
||||
theme: getTheme(
|
||||
themeState.theme, lightDynamic, darkDynamic),
|
||||
localizationsDelegates: const [
|
||||
L10N.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
@ -240,6 +283,6 @@ class _TimeCopAppState extends State<TimeCopApp> with WidgetsBindingObserver {
|
||||
Locale('zh', 'TW'),
|
||||
],
|
||||
),
|
||||
)));
|
||||
))));
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,15 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:timecop/l10n.dart';
|
||||
|
||||
enum ThemeType { auto, light, dark, black }
|
||||
enum ThemeType {
|
||||
auto,
|
||||
light,
|
||||
dark,
|
||||
black,
|
||||
autoMaterialYou,
|
||||
lightMaterialYou,
|
||||
darkMaterialYou
|
||||
}
|
||||
|
||||
ThemeType themeFromString(String? type) {
|
||||
if (type == null) return ThemeType.auto;
|
||||
@ -28,12 +36,18 @@ ThemeType themeFromString(String? type) {
|
||||
return ThemeType.dark;
|
||||
case "black":
|
||||
return ThemeType.black;
|
||||
case "autoMaterialYou":
|
||||
return ThemeType.autoMaterialYou;
|
||||
case "lightMaterialYou":
|
||||
return ThemeType.lightMaterialYou;
|
||||
case "darkMaterialYou":
|
||||
return ThemeType.darkMaterialYou;
|
||||
default:
|
||||
return ThemeType.auto;
|
||||
}
|
||||
}
|
||||
|
||||
extension ThemeTypeStr on ThemeType? {
|
||||
extension ThemeTypeStr on ThemeType {
|
||||
String? get stringify {
|
||||
switch (this) {
|
||||
case ThemeType.auto:
|
||||
@ -44,8 +58,12 @@ extension ThemeTypeStr on ThemeType? {
|
||||
return "dark";
|
||||
case ThemeType.black:
|
||||
return "black";
|
||||
default:
|
||||
return null;
|
||||
case ThemeType.autoMaterialYou:
|
||||
return "autoMaterialYou";
|
||||
case ThemeType.lightMaterialYou:
|
||||
return "lightMaterialYou";
|
||||
case ThemeType.darkMaterialYou:
|
||||
return "darkMaterialYou";
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +77,12 @@ extension ThemeTypeStr on ThemeType? {
|
||||
return L10N.of(context).tr.dark;
|
||||
case ThemeType.black:
|
||||
return L10N.of(context).tr.black;
|
||||
case ThemeType.autoMaterialYou:
|
||||
return L10N.of(context).tr.autoMaterialYou;
|
||||
case ThemeType.lightMaterialYou:
|
||||
return L10N.of(context).tr.lightMaterialYou;
|
||||
case ThemeType.darkMaterialYou:
|
||||
return L10N.of(context).tr.darkMaterialYou;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ class ThemeOptions extends StatelessWidget {
|
||||
return ListTile(
|
||||
key: const Key("themeOption"),
|
||||
title: Text(L10N.of(context).tr.theme),
|
||||
subtitle: Text(state.theme.display(context)!),
|
||||
subtitle: Text(state.theme?.display(context) ?? ""),
|
||||
trailing: Icon(L10N.of(context).rtl
|
||||
? FontAwesomeIcons.chevronLeft
|
||||
: FontAwesomeIcons.chevronRight),
|
||||
@ -75,6 +75,30 @@ class ThemeOptions extends StatelessWidget {
|
||||
onChanged: (ThemeType? type) =>
|
||||
Navigator.pop(context, type),
|
||||
),
|
||||
RadioListTile<ThemeType>(
|
||||
key: const Key("themeAutoMaterialYou"),
|
||||
title: Text(L10N.of(context).tr.autoMaterialYou),
|
||||
value: ThemeType.autoMaterialYou,
|
||||
groupValue: state.theme,
|
||||
onChanged: (ThemeType? type) =>
|
||||
Navigator.pop(context, type),
|
||||
),
|
||||
RadioListTile<ThemeType>(
|
||||
key: const Key("themeLightMaterialYou"),
|
||||
title: Text(L10N.of(context).tr.lightMaterialYou),
|
||||
value: ThemeType.lightMaterialYou,
|
||||
groupValue: state.theme,
|
||||
onChanged: (ThemeType? type) =>
|
||||
Navigator.pop(context, type),
|
||||
),
|
||||
RadioListTile<ThemeType>(
|
||||
key: const Key("themeDarkMaterialYou"),
|
||||
title: Text(L10N.of(context).tr.darkMaterialYou),
|
||||
value: ThemeType.darkMaterialYou,
|
||||
groupValue: state.theme,
|
||||
onChanged: (ThemeType? type) =>
|
||||
Navigator.pop(context, type),
|
||||
),
|
||||
],
|
||||
));
|
||||
|
||||
|
@ -6,9 +6,13 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <dynamic_color/dynamic_color_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
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) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
dynamic_color
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import dynamic_color
|
||||
import flutter_app_badger
|
||||
import flutter_local_notifications
|
||||
import package_info_plus
|
||||
@ -15,6 +16,7 @@ import sqflite
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||
FlutterAppBadgerPlugin.register(with: registry.registrar(forPlugin: "FlutterAppBadgerPlugin"))
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
|
@ -1,4 +1,6 @@
|
||||
PODS:
|
||||
- dynamic_color (0.0.2):
|
||||
- FlutterMacOS
|
||||
- flutter_app_badger (1.3.0):
|
||||
- FlutterMacOS
|
||||
- flutter_local_notifications (0.0.1):
|
||||
@ -24,6 +26,7 @@ PODS:
|
||||
- FlutterMacOS
|
||||
|
||||
DEPENDENCIES:
|
||||
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`)
|
||||
- flutter_app_badger (from `Flutter/ephemeral/.symlinks/plugins/flutter_app_badger/macos`)
|
||||
- flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`)
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
@ -39,6 +42,8 @@ SPEC REPOS:
|
||||
- FMDB
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
dynamic_color:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos
|
||||
flutter_app_badger:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/flutter_app_badger/macos
|
||||
flutter_local_notifications:
|
||||
@ -59,6 +64,7 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
|
||||
flutter_app_badger: 55a64b179f8438e89d574320c77b306e327a1730
|
||||
flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
|
@ -161,6 +161,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.8"
|
||||
dynamic_color:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dynamic_color
|
||||
sha256: de4798a7069121aee12d5895315680258415de9b00e717723a1bd73d58f0126d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.6"
|
||||
effective_dart:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -44,6 +44,7 @@ dependencies:
|
||||
xdg_directories: ^1.0.0
|
||||
fluent: ^2.0.1
|
||||
permission_handler: ^10.2.0
|
||||
dynamic_color: ^1.6.6
|
||||
|
||||
dependency_overrides:
|
||||
intl: 0.18.1
|
||||
|
Reference in New Issue
Block a user