feat: Use Android system accent color

This commit is contained in:
Krille Fear 2022-12-24 11:48:48 +01:00
commit a35229bf7d
11 changed files with 183 additions and 113 deletions

View file

@ -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,
),
);
},
),
);
}

View file

@ -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

View 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,
),
);
}
}