🐛 Fix theme switching

This commit is contained in:
2024-07-31 13:29:26 +08:00
parent 771b2029b0
commit dfdf7b23c8
11 changed files with 156 additions and 116 deletions

View File

@ -1,14 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:solian/exts.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/providers/content/channel.dart';
import 'package:solian/providers/relation.dart';
import 'package:solian/providers/websocket.dart';
import 'package:solian/services.dart';
import 'package:solian/theme.dart';
import 'package:solian/widgets/sized_container.dart';
class BootstrapperShell extends StatefulWidget {
@ -31,18 +29,6 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
int _periodCursor = 0;
late final List<({String label, Future<void> Function() action})> _periods = [
(
label: 'bsLoadingTheme',
action: () async {
final prefs = await SharedPreferences.getInstance();
if (prefs.containsKey('global_theme_color')) {
final value = prefs.getInt('global_theme_color')!;
final color = Color(value);
currentLightTheme = SolianTheme.build(Brightness.light, seedColor: color);
currentDarkTheme = SolianTheme.build(Brightness.dark, seedColor: color);
}
}
),
(
label: 'bsCheckingServer',
action: () async {

View File

@ -6,6 +6,7 @@ import 'package:go_router/go_router.dart';
import 'package:media_kit/media_kit.dart';
import 'package:protocol_handler/protocol_handler.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:solian/bootstrapper.dart';
import 'package:solian/firebase_options.dart';
import 'package:solian/platform.dart';
@ -37,6 +38,7 @@ void main() async {
MediaKit.ensureInitialized();
await Future.wait([
_initializeTheme(),
_initializeFirebase(),
_initializePlatformComponents(),
]);
@ -49,6 +51,16 @@ void main() async {
);
}
Future<void> _initializeTheme() async {
final prefs = await SharedPreferences.getInstance();
if (prefs.containsKey('global_theme_color')) {
final value = prefs.getInt('global_theme_color')!;
final color = Color(value);
currentLightTheme = SolianTheme.build(Brightness.light, seedColor: color);
currentDarkTheme = SolianTheme.build(Brightness.dark, seedColor: color);
}
}
Future<void> _initializeFirebase() async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
}

View File

@ -30,15 +30,37 @@ class _SettingScreenState extends State<SettingScreen> {
icon: Icon(Icons.circle, color: color),
tooltip: label,
onPressed: () {
currentLightTheme =
SolianTheme.build(Brightness.light, seedColor: color);
currentDarkTheme = SolianTheme.build(Brightness.dark, seedColor: color);
currentLightTheme = SolianTheme.build(
Brightness.light,
seedColor: color,
);
currentDarkTheme = SolianTheme.build(
Brightness.dark,
seedColor: color,
);
if (!Get.isDarkMode) {
Get.changeTheme(
SolianTheme.build(Brightness.light, seedColor: color),
);
} else {
// Dark mode cannot be hot reload
// https://github.com/jonataslaw/getx/issues/1411
}
_prefs.setInt('global_theme_color', color.value);
context.clearSnackbar();
context.showSnackbar('themeColorApplied'.tr);
},
);
}
static final List<(String, Color)> _presentTheme = [
('themeColorRed', const Color.fromRGBO(154, 98, 91, 1)),
('themeColorBlue', const Color.fromRGBO(103, 96, 193, 1)),
('themeColorMiku', const Color.fromRGBO(56, 120, 126, 1)),
('themeColorKagamine', const Color.fromRGBO(244, 183, 63, 1)),
('themeColorLuka', const Color.fromRGBO(243, 174, 218, 1)),
];
@override
void initState() {
super.initState();
@ -58,20 +80,9 @@ class _SettingScreenState extends State<SettingScreen> {
height: 56,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
_buildThemeColorButton(
'themeColorRed'.tr,
const Color.fromRGBO(154, 98, 91, 1),
),
_buildThemeColorButton(
'themeColorBlue'.tr,
const Color.fromRGBO(103, 96, 193, 1),
),
_buildThemeColorButton(
'themeColorMiku'.tr,
const Color.fromRGBO(56, 120, 126, 1),
),
],
children: _presentTheme
.map((x) => _buildThemeColorButton(x.$1, x.$2))
.toList(),
).paddingSymmetric(horizontal: 12, vertical: 8),
),
],

View File

@ -38,6 +38,9 @@ abstract class SolianTheme {
brightness: brightness,
seedColor: seedColor ?? const Color.fromRGBO(154, 98, 91, 1),
),
fontFamily: 'Quicksand',
fontFamilyFallback: const ['NotoSansSC', 'NotoSansHK'],
typography: Typography.material2021(),
);
}
}

View File

@ -310,5 +310,8 @@ const i18nEnglish = {
'themeColorRed': 'Modern Red',
'themeColorBlue': 'Classic Blue',
'themeColorMiku': 'Miku Blue',
'themeColorApplied': 'Global theme color has been saved, restart to get applied.',
'themeColorKagamine': 'Kagamine Yellow',
'themeColorLuka': 'Luka Pink',
'themeColorApplied':
'Global theme color has been applied, dark mode theme need restart to get applied.',
};

View File

@ -287,5 +287,7 @@ const i18nSimplifiedChinese = {
'themeColorRed': '现代红',
'themeColorBlue': '经典蓝',
'themeColorMiku': '未来色',
'themeColorApplied': '全局主题颜色已保存,重启后生效。',
'themeColorKagamine': '镜音黄',
'themeColorLuka': '流音粉',
'themeColorApplied': '全局主题颜色已应用,深色模式中主题需要重启生效',
};

View File

@ -29,7 +29,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
late final ChannelProvider _channels;
void getStatus() async {
Future<void> _getStatus() async {
final StatusProvider provider = Get.find();
final resp = await provider.getCurrentStatus();
@ -40,7 +40,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
});
}
void detectSelectedIndex() {
void _detectSelectedIndex() {
if (widget.routeName == null) return;
final nameList = AppNavigation.destinations.map((x) => x.page).toList();
@ -49,22 +49,33 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
_selectedIndex = idx != -1 ? idx : null;
}
void closeDrawer() {
void _closeDrawer() {
rootScaffoldKey.currentState!.closeDrawer();
}
Widget _buildSettingButton() {
return IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
AppRouter.instance.pushNamed('settings');
setState(() => _selectedIndex = null);
_closeDrawer();
}
);
}
@override
void initState() {
super.initState();
_channels = Get.find();
detectSelectedIndex();
getStatus();
_detectSelectedIndex();
_getStatus();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
detectSelectedIndex();
_detectSelectedIndex();
}
@override
@ -78,7 +89,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
onDestinationSelected: (idx) {
setState(() => _selectedIndex = idx);
AppRouter.instance.goNamed(AppNavigation.destinations[idx].page);
closeDrawer();
_closeDrawer();
},
children: [
Obx(() {
@ -88,10 +99,11 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
leading: const Icon(Icons.account_circle),
title: Text('guest'.tr),
subtitle: Text('unsignedIn'.tr),
trailing: _buildSettingButton(),
onTap: () {
AppRouter.instance.goNamed('account');
setState(() => _selectedIndex = null);
closeDrawer();
_closeDrawer();
},
);
}
@ -137,18 +149,11 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
),
);
}),
trailing: IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
AppRouter.instance.pushNamed('settings');
setState(() => _selectedIndex = null);
closeDrawer();
},
),
trailing: _buildSettingButton(),
onTap: () {
AppRouter.instance.goNamed('account');
setState(() => _selectedIndex = null);
closeDrawer();
_closeDrawer();
},
onLongPress: () {
showModalBottomSheet(
@ -158,7 +163,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
currentStatus: _accountStatus!.status,
),
).then((val) {
if (val == true) getStatus();
if (val == true) _getStatus();
});
},
);
@ -204,7 +209,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
useReplace: true,
onSelected: (_) {
setState(() => _selectedIndex = null);
closeDrawer();
_closeDrawer();
},
),
),