opt: dark theme, add follow system mode

This commit is contained in:
csf 2022-09-21 23:32:59 +08:00
parent 5a4806e9b2
commit 86d83e12b0
10 changed files with 89 additions and 52 deletions

View File

@ -197,30 +197,39 @@ class MyTheme {
], ],
); );
static changeTo(bool dark) { static ThemeMode getThemeModePreference() {
if (isDarkTheme() != dark) { return themeModeFromString(
Get.find<SharedPreferences>().setString("darkTheme", dark ? "Y" : ""); Get.find<SharedPreferences>().getString("themeMode") ?? "");
Get.changeThemeMode(dark ? ThemeMode.dark : ThemeMode.light); }
static void changeDarkMode(ThemeMode mode) {
final preference = getThemeModePreference();
if (preference != mode) {
if (mode == ThemeMode.system) {
Get.find<SharedPreferences>().setString("themeMode", "");
} else {
Get.find<SharedPreferences>()
.setString("themeMode", mode.toShortString());
}
Get.changeThemeMode(mode);
if (desktopType == DesktopType.main) { if (desktopType == DesktopType.main) {
bind.mainChangeTheme(dark: dark); bind.mainChangeTheme(dark: currentThemeMode().toShortString());
} }
} }
} }
static bool _themeInitialed = false; static ThemeMode currentThemeMode() {
final preference = getThemeModePreference();
static ThemeMode initialThemeMode({bool mainPage = false}) { if (preference == ThemeMode.system) {
bool dark; if (WidgetsBinding.instance.platformDispatcher.platformBrightness ==
// Brightnesss is always light on windows, Flutter 3.0.5 Brightness.light) {
if (_themeInitialed || !mainPage || Platform.isWindows) { return ThemeMode.light;
dark = isDarkTheme(); } else {
return ThemeMode.dark;
}
} else { } else {
dark = WidgetsBinding.instance.platformDispatcher.platformBrightness == return preference;
Brightness.dark;
Get.find<SharedPreferences>().setString("darkTheme", dark ? "Y" : "");
} }
_themeInitialed = true;
return dark ? ThemeMode.dark : ThemeMode.light;
} }
static ColorThemeExtension color(BuildContext context) { static ColorThemeExtension color(BuildContext context) {
@ -230,10 +239,23 @@ class MyTheme {
static TabbarTheme tabbar(BuildContext context) { static TabbarTheme tabbar(BuildContext context) {
return Theme.of(context).extension<TabbarTheme>()!; return Theme.of(context).extension<TabbarTheme>()!;
} }
static ThemeMode themeModeFromString(String v) {
switch (v) {
case "light":
return ThemeMode.light;
case "dark":
return ThemeMode.dark;
default:
return ThemeMode.system;
}
}
} }
bool isDarkTheme() { extension ParseToString on ThemeMode {
return "Y" == Get.find<SharedPreferences>().getString("darkTheme"); String toShortString() {
return toString().split('.').last;
}
} }
final ButtonStyle flatButtonStyle = TextButton.styleFrom( final ButtonStyle flatButtonStyle = TextButton.styleFrom(

View File

@ -205,22 +205,28 @@ class _GeneralState extends State<_General> {
} }
Widget theme() { Widget theme() {
change() { final current = MyTheme.getThemeModePreference().toShortString();
MyTheme.changeTo(!isDarkTheme()); onChanged(String value) {
MyTheme.changeDarkMode(MyTheme.themeModeFromString(value));
setState(() {}); setState(() {});
} }
return _Card(title: 'Theme', children: [ return _Card(title: 'Theme', children: [
GestureDetector( _Radio<String>(context,
onTap: change, value: "light",
child: Row( groupValue: current,
children: [ label: "Light",
Checkbox(value: isDarkTheme(), onChanged: (_) => change()) onChanged: onChanged),
.marginOnly(right: 5), _Radio<String>(context,
Expanded(child: Text(translate('Dark Theme'))), value: "dark",
], groupValue: current,
).marginOnly(left: _kCheckBoxLeftMargin), label: "Dark",
) onChanged: onChanged),
_Radio<String>(context,
value: "system",
groupValue: current,
label: "Follow System",
onChanged: onChanged),
]); ]);
} }

View File

@ -247,7 +247,7 @@ class _PortForwardPageState extends State<PortForwardPage>
height: _kRowHeight, height: _kRowHeight,
decoration: BoxDecoration( decoration: BoxDecoration(
color: index % 2 == 0 color: index % 2 == 0
? isDarkTheme() ? MyTheme.currentThemeMode() == ThemeMode.dark
? const Color(0xFF202020) ? const Color(0xFF202020)
: const Color(0xFFF4F5F6) : const Color(0xFFF4F5F6)
: MyTheme.color(context).bg), : MyTheme.color(context).bg),

View File

@ -120,7 +120,7 @@ void runRemoteScreen(Map<String, dynamic> argument) async {
title: 'RustDesk - Remote Desktop', title: 'RustDesk - Remote Desktop',
theme: MyTheme.lightTheme, theme: MyTheme.lightTheme,
darkTheme: MyTheme.darkTheme, darkTheme: MyTheme.darkTheme,
themeMode: MyTheme.initialThemeMode(), themeMode: MyTheme.currentThemeMode(),
home: DesktopRemoteScreen( home: DesktopRemoteScreen(
params: argument, params: argument,
), ),
@ -146,7 +146,7 @@ void runFileTransferScreen(Map<String, dynamic> argument) async {
title: 'RustDesk - File Transfer', title: 'RustDesk - File Transfer',
theme: MyTheme.lightTheme, theme: MyTheme.lightTheme,
darkTheme: MyTheme.darkTheme, darkTheme: MyTheme.darkTheme,
themeMode: MyTheme.initialThemeMode(), themeMode: MyTheme.currentThemeMode(),
home: DesktopFileTransferScreen(params: argument), home: DesktopFileTransferScreen(params: argument),
localizationsDelegates: const [ localizationsDelegates: const [
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
@ -171,7 +171,7 @@ void runPortForwardScreen(Map<String, dynamic> argument) async {
title: 'RustDesk - Port Forward', title: 'RustDesk - Port Forward',
theme: MyTheme.lightTheme, theme: MyTheme.lightTheme,
darkTheme: MyTheme.darkTheme, darkTheme: MyTheme.darkTheme,
themeMode: MyTheme.initialThemeMode(), themeMode: MyTheme.currentThemeMode(),
home: DesktopPortForwardScreen(params: argument), home: DesktopPortForwardScreen(params: argument),
localizationsDelegates: const [ localizationsDelegates: const [
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
@ -196,7 +196,7 @@ void runConnectionManagerScreen() async {
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: MyTheme.lightTheme, theme: MyTheme.lightTheme,
darkTheme: MyTheme.darkTheme, darkTheme: MyTheme.darkTheme,
themeMode: MyTheme.initialThemeMode(), themeMode: MyTheme.currentThemeMode(),
localizationsDelegates: const [ localizationsDelegates: const [
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate, GlobalWidgetsLocalizations.delegate,
@ -233,12 +233,21 @@ class _AppState extends State<App> {
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.window.onPlatformBrightnessChanged = () { WidgetsBinding.instance.window.onPlatformBrightnessChanged = () {
final userPreference = MyTheme.getThemeModePreference();
if (userPreference != ThemeMode.system) return;
WidgetsBinding.instance.handlePlatformBrightnessChanged(); WidgetsBinding.instance.handlePlatformBrightnessChanged();
var system = final systemIsDark =
WidgetsBinding.instance.platformDispatcher.platformBrightness; WidgetsBinding.instance.platformDispatcher.platformBrightness ==
var current = isDarkTheme() ? Brightness.dark : Brightness.light; Brightness.dark;
if (current != system) { final ThemeMode to;
MyTheme.changeTo(system == Brightness.dark); if (systemIsDark) {
to = ThemeMode.dark;
} else {
to = ThemeMode.light;
}
Get.changeThemeMode(to);
if (desktopType == DesktopType.main) {
bind.mainChangeTheme(dark: to.toShortString());
} }
}; };
} }
@ -263,7 +272,7 @@ class _AppState extends State<App> {
title: 'RustDesk', title: 'RustDesk',
theme: MyTheme.lightTheme, theme: MyTheme.lightTheme,
darkTheme: MyTheme.darkTheme, darkTheme: MyTheme.darkTheme,
themeMode: MyTheme.initialThemeMode(mainPage: true), themeMode: MyTheme.currentThemeMode(),
home: isDesktop home: isDesktop
? const DesktopTabPage() ? const DesktopTabPage()
: !isAndroid : !isAndroid
@ -309,7 +318,7 @@ _registerEventHandler() {
platformFFI.registerEventHandler('theme', 'theme', (evt) async { platformFFI.registerEventHandler('theme', 'theme', (evt) async {
String? dark = evt['dark']; String? dark = evt['dark'];
if (dark != null) { if (dark != null) {
MyTheme.changeTo(dark == 'true'); MyTheme.changeDarkMode(MyTheme.themeModeFromString(dark));
} }
}); });
platformFFI.registerEventHandler('language', 'language', (_) async { platformFFI.registerEventHandler('language', 'language', (_) async {

View File

@ -60,7 +60,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
_enableAbr = enableAbrRes; _enableAbr = enableAbrRes;
} }
_enableAbr = isDarkTheme(); // _isDarkMode = MyTheme.currentDarkMode(); // TODO
if (update) { if (update) {
setState(() {}); setState(() {});
@ -184,7 +184,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
onToggle: (v) { onToggle: (v) {
setState(() { setState(() {
_isDarkMode = !_isDarkMode; _isDarkMode = !_isDarkMode;
MyTheme.changeTo(_isDarkMode); // MyTheme.changeDarkMode(_isDarkMode); // TODO
}); });
}, },
) )

View File

@ -379,8 +379,8 @@ pub mod connection_manager {
); );
} }
fn change_theme(&self, dark: bool) { fn change_theme(&self, dark: String) {
self.push_event("theme", vec![("dark", &dark.to_string())]); self.push_event("theme", vec![("dark", &dark)]);
} }
fn change_language(&self) { fn change_language(&self) {

View File

@ -692,10 +692,10 @@ fn main_broadcast_message(data: &HashMap<&str, &str>) {
} }
} }
pub fn main_change_theme(dark: bool) { pub fn main_change_theme(dark: String) {
main_broadcast_message(&HashMap::from([ main_broadcast_message(&HashMap::from([
("name", "theme"), ("name", "theme"),
("dark", &dark.to_string()), ("dark", &dark),
])); ]));
send_to_cm(&crate::ipc::Data::Theme(dark)); send_to_cm(&crate::ipc::Data::Theme(dark));
} }

View File

@ -182,7 +182,7 @@ pub enum Data {
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
Mouse(DataMouse), Mouse(DataMouse),
Control(DataControl), Control(DataControl),
Theme(bool), Theme(String),
Language(String), Language(String),
Empty, Empty,
} }

View File

@ -48,7 +48,7 @@ impl InvokeUiCM for SciterHandler {
self.call("newMessage", &make_args!(id, text)); self.call("newMessage", &make_args!(id, text));
} }
fn change_theme(&self, _dark: bool) { fn change_theme(&self, _dark: String) {
// TODO // TODO
} }

View File

@ -61,7 +61,7 @@ pub trait InvokeUiCM: Send + Clone + 'static + Sized {
fn new_message(&self, id: i32, text: String); fn new_message(&self, id: i32, text: String);
fn change_theme(&self, dark: bool); fn change_theme(&self, dark: String);
fn change_language(&self); fn change_language(&self);
} }