feat: Use Android system accent color
This commit is contained in:
parent
5f3e8791dd
commit
a35229bf7d
11 changed files with 183 additions and 113 deletions
|
|
@ -1,14 +1,13 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:vrouter/vrouter.dart';
|
||||
|
||||
import 'package:fluffychat/config/routes.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/widgets/theme_builder.dart';
|
||||
import '../config/app_config.dart';
|
||||
import '../utils/custom_scroll_behaviour.dart';
|
||||
import 'matrix.dart';
|
||||
|
|
@ -47,51 +46,41 @@ class FluffyChatAppState extends State<FluffyChatApp> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DynamicColorBuilder(
|
||||
builder: (lightColorScheme, darkColorScheme) => AdaptiveTheme(
|
||||
light: FluffyThemes.buildTheme(
|
||||
Brightness.light,
|
||||
lightColorScheme,
|
||||
),
|
||||
dark: FluffyThemes.buildTheme(
|
||||
Brightness.dark,
|
||||
lightColorScheme,
|
||||
),
|
||||
initial: AdaptiveThemeMode.system,
|
||||
builder: (theme, darkTheme) => LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final isColumnMode =
|
||||
FluffyThemes.isColumnModeByWidth(constraints.maxWidth);
|
||||
if (isColumnMode != columnMode) {
|
||||
Logs().v('Set Column Mode = $isColumnMode');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
_initialUrl = FluffyChatApp.routerKey.currentState?.url;
|
||||
columnMode = isColumnMode;
|
||||
FluffyChatApp.routerKey = GlobalKey<VRouterState>();
|
||||
});
|
||||
return ThemeBuilder(
|
||||
builder: (context, themeMode, primaryColor) => LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final isColumnMode =
|
||||
FluffyThemes.isColumnModeByWidth(constraints.maxWidth);
|
||||
if (isColumnMode != columnMode) {
|
||||
Logs().v('Set Column Mode = $isColumnMode');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
_initialUrl = FluffyChatApp.routerKey.currentState?.url;
|
||||
columnMode = isColumnMode;
|
||||
FluffyChatApp.routerKey = GlobalKey<VRouterState>();
|
||||
});
|
||||
}
|
||||
return VRouter(
|
||||
key: FluffyChatApp.routerKey,
|
||||
title: AppConfig.applicationName,
|
||||
theme: theme,
|
||||
scrollBehavior: CustomScrollBehavior(),
|
||||
logs: kReleaseMode ? VLogs.none : VLogs.info,
|
||||
darkTheme: darkTheme,
|
||||
localizationsDelegates: L10n.localizationsDelegates,
|
||||
supportedLocales: L10n.supportedLocales,
|
||||
initialUrl: _initialUrl ?? '/',
|
||||
routes: AppRoutes(columnMode ?? false).routes,
|
||||
builder: (context, child) => Matrix(
|
||||
context: context,
|
||||
router: FluffyChatApp.routerKey,
|
||||
clients: widget.clients,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
});
|
||||
}
|
||||
return VRouter(
|
||||
key: FluffyChatApp.routerKey,
|
||||
title: AppConfig.applicationName,
|
||||
themeMode: themeMode,
|
||||
theme: FluffyThemes.buildTheme(Brightness.light, primaryColor),
|
||||
darkTheme: FluffyThemes.buildTheme(Brightness.dark, primaryColor),
|
||||
scrollBehavior: CustomScrollBehavior(),
|
||||
logs: kReleaseMode ? VLogs.none : VLogs.info,
|
||||
localizationsDelegates: L10n.localizationsDelegates,
|
||||
supportedLocales: L10n.supportedLocales,
|
||||
initialUrl: _initialUrl ?? '/',
|
||||
routes: AppRoutes(columnMode ?? false).routes,
|
||||
builder: (context, child) => Matrix(
|
||||
context: context,
|
||||
router: FluffyChatApp.routerKey,
|
||||
clients: widget.clients,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:desktop_notifications/desktop_notifications.dart';
|
||||
import 'package:flutter_app_lock/flutter_app_lock.dart';
|
||||
|
|
@ -23,7 +22,6 @@ import 'package:universal_html/html.dart' as html;
|
|||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:vrouter/vrouter.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/utils/client_manager.dart';
|
||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
|
|
@ -488,19 +486,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||
store
|
||||
.getItemBool(SettingKeys.experimentalVoip, AppConfig.experimentalVoip)
|
||||
.then((value) => AppConfig.experimentalVoip = value);
|
||||
store.getItem(SettingKeys.chatColor).then((value) {
|
||||
if (value != null && int.tryParse(value) != null) {
|
||||
AppConfig.colorSchemeSeed = Color(int.parse(value));
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
AdaptiveTheme.of(context).setTheme(
|
||||
light: FluffyThemes.buildTheme(Brightness.light),
|
||||
dark: FluffyThemes.buildTheme(Brightness.dark),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
107
lib/widgets/theme_builder.dart
Normal file
107
lib/widgets/theme_builder.dart
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:system_theme/system_theme.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
|
||||
class ThemeBuilder extends StatefulWidget {
|
||||
final Widget Function(
|
||||
BuildContext context,
|
||||
ThemeMode themeMode,
|
||||
Color? primaryColor,
|
||||
) builder;
|
||||
|
||||
final String themeModeSettingsKey;
|
||||
final String primaryColorSettingsKey;
|
||||
|
||||
const ThemeBuilder({
|
||||
required this.builder,
|
||||
this.themeModeSettingsKey = 'theme_mode',
|
||||
this.primaryColorSettingsKey = 'primary_color',
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ThemeBuilder> createState() => ThemeController();
|
||||
}
|
||||
|
||||
class ThemeController extends State<ThemeBuilder> {
|
||||
SharedPreferences? _sharedPreferences;
|
||||
ThemeMode? _themeMode;
|
||||
Color? _primaryColor;
|
||||
|
||||
ThemeMode get themeMode => _themeMode ?? ThemeMode.system;
|
||||
Color? get primaryColor => _primaryColor;
|
||||
|
||||
static ThemeController of(BuildContext context) =>
|
||||
Provider.of<ThemeController>(
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
|
||||
void _loadData(_) async {
|
||||
final preferences =
|
||||
_sharedPreferences ??= await SharedPreferences.getInstance();
|
||||
|
||||
final rawThemeMode = preferences.getString(widget.themeModeSettingsKey);
|
||||
final rawColor = preferences.getInt(widget.primaryColorSettingsKey);
|
||||
|
||||
setState(() {
|
||||
_themeMode = ThemeMode.values
|
||||
.singleWhereOrNull((value) => value.name == rawThemeMode);
|
||||
_primaryColor = rawColor == null ? null : Color(rawColor);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> setThemeMode(ThemeMode newThemeMode) async {
|
||||
final preferences =
|
||||
_sharedPreferences ??= await SharedPreferences.getInstance();
|
||||
await preferences.setString(widget.themeModeSettingsKey, newThemeMode.name);
|
||||
setState(() {
|
||||
_themeMode = newThemeMode;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> setPrimaryColor(Color? newPrimaryColor) async {
|
||||
final preferences =
|
||||
_sharedPreferences ??= await SharedPreferences.getInstance();
|
||||
if (newPrimaryColor == null) {
|
||||
await preferences.remove(widget.primaryColorSettingsKey);
|
||||
} else {
|
||||
await preferences.setInt(
|
||||
widget.primaryColorSettingsKey,
|
||||
newPrimaryColor.value,
|
||||
);
|
||||
}
|
||||
setState(() {
|
||||
_primaryColor = newPrimaryColor;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance.addPostFrameCallback(_loadData);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Color? get systemAccentColor {
|
||||
final color = SystemTheme.accentColor.accent;
|
||||
if (color == kDefaultSystemAccentColor) return AppConfig.chatColor;
|
||||
return color;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Provider(
|
||||
create: (_) => this,
|
||||
child: widget.builder(
|
||||
context,
|
||||
themeMode,
|
||||
primaryColor ?? systemAccentColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue