Merge pull request #1596 from Heap-Hop/master

Optimize flutter
This commit is contained in:
RustDesk 2022-09-22 07:39:00 +08:00 committed by GitHub
commit f5b7c34c81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 195 additions and 141 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

@ -303,7 +303,7 @@ class AddressBookPeerWidget extends BasePeerWidget {
static List<Peer> _loadPeers() { static List<Peer> _loadPeers() {
debugPrint("_loadPeers : ${gFFI.abModel.peers.toString()}"); debugPrint("_loadPeers : ${gFFI.abModel.peers.toString()}");
return gFFI.abModel.peers.map((e) { return gFFI.abModel.peers.map((e) {
return Peer.fromJson(e['id'], e); return Peer.fromJson(e);
}).toList(); }).toList();
} }

View File

@ -27,13 +27,11 @@ final peerCardUiType = PeerUiType.grid.obs;
class _PeerCard extends StatefulWidget { class _PeerCard extends StatefulWidget {
final Peer peer; final Peer peer;
final RxString alias;
final Function(BuildContext, String) connect; final Function(BuildContext, String) connect;
final PopupMenuEntryBuilder popupMenuEntryBuilder; final PopupMenuEntryBuilder popupMenuEntryBuilder;
const _PeerCard( const _PeerCard(
{required this.peer, {required this.peer,
required this.alias,
required this.connect, required this.connect,
required this.popupMenuEntryBuilder, required this.popupMenuEntryBuilder,
Key? key}) Key? key})
@ -77,7 +75,7 @@ class _PeerCardState extends State<_PeerCard>
child: ListTile( child: ListTile(
contentPadding: const EdgeInsets.only(left: 12), contentPadding: const EdgeInsets.only(left: 12),
subtitle: Text('${peer.username}@${peer.hostname}'), subtitle: Text('${peer.username}@${peer.hostname}'),
title: Text(formatID(peer.id)), title: Text(peer.alias.isEmpty ? formatID(peer.id) : peer.alias),
leading: Container( leading: Container(
padding: const EdgeInsets.all(6), padding: const EdgeInsets.all(6),
color: str2color('${peer.id}${peer.platform}', 0x7f), color: str2color('${peer.id}${peer.platform}', 0x7f),
@ -216,6 +214,7 @@ class _PeerCardState extends State<_PeerCard>
Widget _buildPeerCard( Widget _buildPeerCard(
BuildContext context, Peer peer, Rx<BoxDecoration?> deco) { BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
final name = '${peer.username}@${peer.hostname}';
return Card( return Card(
color: Colors.transparent, color: Colors.transparent,
elevation: 0, elevation: 0,
@ -246,24 +245,18 @@ class _PeerCardState extends State<_PeerCard>
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Obx(() { child: Tooltip(
final name = widget.alias.value.isEmpty message: name,
? '${peer.username}@${peer.hostname}' waitDuration: const Duration(seconds: 1),
: widget.alias.value; child: Text(
return Tooltip( name,
message: name, style: const TextStyle(
waitDuration: color: Colors.white70,
const Duration(seconds: 1), fontSize: 12),
child: Text( textAlign: TextAlign.center,
name, overflow: TextOverflow.ellipsis,
style: const TextStyle( ),
color: Colors.white70, ),
fontSize: 12),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
),
);
}),
), ),
], ],
), ),
@ -287,7 +280,8 @@ class _PeerCardState extends State<_PeerCard>
backgroundColor: peer.online backgroundColor: peer.online
? Colors.green ? Colors.green
: Colors.yellow)), : Colors.yellow)),
Text(formatID(peer.id)) Text(
peer.alias.isEmpty ? formatID(peer.id) : peer.alias)
]).paddingSymmetric(vertical: 8), ]).paddingSymmetric(vertical: 8),
_actionMore(peer), _actionMore(peer),
], ],
@ -338,20 +332,14 @@ class _PeerCardState extends State<_PeerCard>
} }
abstract class BasePeerCard extends StatelessWidget { abstract class BasePeerCard extends StatelessWidget {
final RxString alias = ''.obs;
final Peer peer; final Peer peer;
BasePeerCard({required this.peer, Key? key}) : super(key: key) { BasePeerCard({required this.peer, Key? key}) : super(key: key);
bind
.mainGetPeerOption(id: peer.id, key: 'alias')
.then((value) => alias.value = value);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _PeerCard( return _PeerCard(
peer: peer, peer: peer,
alias: alias,
connect: (BuildContext context, String id) => connect(context, id), connect: (BuildContext context, String id) => connect(context, id),
popupMenuEntryBuilder: _buildPopupMenuEntry, popupMenuEntryBuilder: _buildPopupMenuEntry,
); );
@ -379,7 +367,7 @@ abstract class BasePeerCard extends StatelessWidget {
bool isRDP = false}) { bool isRDP = false}) {
return MenuEntryButton<String>( return MenuEntryButton<String>(
childBuilder: (TextStyle? style) => Text( childBuilder: (TextStyle? style) => Text(
translate(title), title,
style: style, style: style,
), ),
proc: () { proc: () {
@ -396,8 +384,13 @@ abstract class BasePeerCard extends StatelessWidget {
} }
@protected @protected
MenuEntryBase<String> _connectAction(BuildContext context, String id) { MenuEntryBase<String> _connectAction(BuildContext context, Peer peer) {
return _connectCommonAction(context, id, 'Connect'); return _connectCommonAction(
context,
peer.id,
peer.alias.isEmpty
? translate('Connect')
: "${translate('Connect')} ${peer.id}");
} }
@protected @protected
@ -405,7 +398,7 @@ abstract class BasePeerCard extends StatelessWidget {
return _connectCommonAction( return _connectCommonAction(
context, context,
id, id,
'Transfer File', translate('Transfer File'),
isFileTransfer: true, isFileTransfer: true,
); );
} }
@ -415,7 +408,7 @@ abstract class BasePeerCard extends StatelessWidget {
return _connectCommonAction( return _connectCommonAction(
context, context,
id, id,
'TCP Tunneling', translate('TCP Tunneling'),
isTcpTunneling: true, isTcpTunneling: true,
); );
} }
@ -578,7 +571,7 @@ abstract class BasePeerCard extends StatelessWidget {
void _rename(String id, bool isAddressBook) async { void _rename(String id, bool isAddressBook) async {
RxBool isInProgress = false.obs; RxBool isInProgress = false.obs;
var name = await bind.mainGetPeerOption(id: id, key: 'alias'); var name = peer.alias;
var controller = TextEditingController(text: name); var controller = TextEditingController(text: name);
if (isAddressBook) { if (isAddressBook) {
final peer = gFFI.abModel.peers.firstWhere((p) => id == p['id']); final peer = gFFI.abModel.peers.firstWhere((p) => id == p['id']);
@ -597,7 +590,12 @@ abstract class BasePeerCard extends StatelessWidget {
gFFI.abModel.setPeerOption(id, 'alias', name); gFFI.abModel.setPeerOption(id, 'alias', name);
await gFFI.abModel.updateAb(); await gFFI.abModel.updateAb();
} }
alias.value = await bind.mainGetPeerOption(id: peer.id, key: 'alias'); if (isAddressBook) {
gFFI.abModel.getAb();
} else {
bind.mainLoadRecentPeers();
bind.mainLoadFavPeers();
}
close(); close();
isInProgress.value = false; isInProgress.value = false;
} }
@ -642,7 +640,7 @@ class RecentPeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems( Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async { BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [ final List<MenuEntryBase<String>> menuItems = [
_connectAction(context, peer.id), _connectAction(context, peer),
_transferFileAction(context, peer.id), _transferFileAction(context, peer.id),
_tcpTunnelingAction(context, peer.id), _tcpTunnelingAction(context, peer.id),
]; ];
@ -674,7 +672,7 @@ class FavoritePeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems( Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async { BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [ final List<MenuEntryBase<String>> menuItems = [
_connectAction(context, peer.id), _connectAction(context, peer),
_transferFileAction(context, peer.id), _transferFileAction(context, peer.id),
_tcpTunnelingAction(context, peer.id), _tcpTunnelingAction(context, peer.id),
]; ];
@ -708,7 +706,7 @@ class DiscoveredPeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems( Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async { BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [ final List<MenuEntryBase<String>> menuItems = [
_connectAction(context, peer.id), _connectAction(context, peer),
_transferFileAction(context, peer.id), _transferFileAction(context, peer.id),
_tcpTunnelingAction(context, peer.id), _tcpTunnelingAction(context, peer.id),
]; ];
@ -739,7 +737,7 @@ class AddressBookPeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems( Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async { BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [ final List<MenuEntryBase<String>> menuItems = [
_connectAction(context, peer.id), _connectAction(context, peer),
_transferFileAction(context, peer.id), _transferFileAction(context, peer.id),
_tcpTunnelingAction(context, peer.id), _tcpTunnelingAction(context, peer.id),
]; ];

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

@ -22,7 +22,6 @@ import '../common.dart';
import '../common/shared_state.dart'; import '../common/shared_state.dart';
import '../utils/image.dart' as img; import '../utils/image.dart' as img;
import '../mobile/widgets/dialog.dart'; import '../mobile/widgets/dialog.dart';
import 'peer_model.dart';
import 'platform_model.dart'; import 'platform_model.dart';
typedef HandleMsgBox = Function(Map<String, dynamic> evt, String id); typedef HandleMsgBox = Function(Map<String, dynamic> evt, String id);
@ -1107,23 +1106,6 @@ class FFI {
id: id, msg: json.encode(modify({'x': '$x2', 'y': '$y2'}))); id: id, msg: json.encode(modify({'x': '$x2', 'y': '$y2'})));
} }
/// List the saved peers.
Future<List<Peer>> peers() async {
try {
var str = await bind.mainGetRecentPeers();
if (str == '') return [];
List<dynamic> peers = json.decode(str);
return peers
.map((s) => s as List<dynamic>)
.map((s) =>
Peer.fromJson(s[0] as String, s[1] as Map<String, dynamic>))
.toList();
} catch (e) {
debugPrint('peers(): $e');
}
return [];
}
/// Connect with the given [id]. Only transfer file if [isFileTransfer], only port forward if [isPortForward]. /// Connect with the given [id]. Only transfer file if [isFileTransfer], only port forward if [isPortForward].
connect(String id, connect(String id,
{bool isFileTransfer = false, {bool isFileTransfer = false,

View File

@ -7,13 +7,16 @@ class Peer {
final String username; final String username;
final String hostname; final String hostname;
final String platform; final String platform;
final String alias;
final List<dynamic> tags; final List<dynamic> tags;
bool online = false; bool online = false;
Peer.fromJson(this.id, Map<String, dynamic> json) Peer.fromJson(Map<String, dynamic> json)
: username = json['username'] ?? '', : id = json['id'] ?? '',
username = json['username'] ?? '',
hostname = json['hostname'] ?? '', hostname = json['hostname'] ?? '',
platform = json['platform'] ?? '', platform = json['platform'] ?? '',
alias = json['alias'] ?? '',
tags = json['tags'] ?? []; tags = json['tags'] ?? [];
Peer({ Peer({
@ -21,6 +24,7 @@ class Peer {
required this.username, required this.username,
required this.hostname, required this.hostname,
required this.platform, required this.platform,
required this.alias,
required this.tags, required this.tags,
}); });
@ -30,6 +34,7 @@ class Peer {
username: '...', username: '...',
hostname: '...', hostname: '...',
platform: '...', platform: '...',
alias: '',
tags: []); tags: []);
} }
@ -109,11 +114,9 @@ class Peers extends ChangeNotifier {
try { try {
if (peersStr == "") return []; if (peersStr == "") return [];
List<dynamic> peers = json.decode(peersStr); List<dynamic> peers = json.decode(peersStr);
return peers return peers.map((peer) {
.map((s) => s as List<dynamic>) return Peer.fromJson(peer as Map<String, dynamic>);
.map((s) => }).toList();
Peer.fromJson(s[0] as String, s[1] as Map<String, dynamic>))
.toList();
} catch (e) { } catch (e) {
debugPrint('peers(): $e'); debugPrint('peers(): $e');
} }

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

@ -7,11 +7,11 @@ use std::{
use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer}; use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer};
use serde_json::json; use serde_json::json;
use hbb_common::ResultType;
use hbb_common::{ use hbb_common::{
config::{self, LocalConfig, PeerConfig, ONLINE}, config::{self, LocalConfig, PeerConfig, ONLINE},
fs, log, fs, log,
}; };
use hbb_common::{message_proto::Hash, ResultType};
use crate::flutter::{self, SESSIONS}; use crate::flutter::{self, SESSIONS};
use crate::start_server; use crate::start_server;
@ -567,9 +567,20 @@ pub fn main_forget_password(id: String) {
pub fn main_get_recent_peers() -> String { pub fn main_get_recent_peers() -> String {
if !config::APP_DIR.read().unwrap().is_empty() { if !config::APP_DIR.read().unwrap().is_empty() {
let peers: Vec<(String, config::PeerInfoSerde)> = PeerConfig::peers() let peers: Vec<HashMap<&str, String>> = PeerConfig::peers()
.drain(..) .drain(..)
.map(|(id, _, p)| (id, p.info)) .map(|(id, _, p)| {
HashMap::<&str, String>::from_iter([
("id", id),
("username", p.info.username.clone()),
("hostname", p.info.hostname.clone()),
("platform", p.info.platform.clone()),
(
"alias",
p.options.get("alias").unwrap_or(&"".to_owned()).to_owned(),
),
])
})
.collect(); .collect();
serde_json::ser::to_string(&peers).unwrap_or("".to_owned()) serde_json::ser::to_string(&peers).unwrap_or("".to_owned())
} else { } else {
@ -579,9 +590,20 @@ pub fn main_get_recent_peers() -> String {
pub fn main_load_recent_peers() { pub fn main_load_recent_peers() {
if !config::APP_DIR.read().unwrap().is_empty() { if !config::APP_DIR.read().unwrap().is_empty() {
let peers: Vec<(String, config::PeerInfoSerde)> = PeerConfig::peers() let peers: Vec<HashMap<&str, String>> = PeerConfig::peers()
.drain(..) .drain(..)
.map(|(id, _, p)| (id, p.info)) .map(|(id, _, p)| {
HashMap::<&str, String>::from_iter([
("id", id),
("username", p.info.username.clone()),
("hostname", p.info.hostname.clone()),
("platform", p.info.platform.clone()),
(
"alias",
p.options.get("alias").unwrap_or(&"".to_owned()).to_owned(),
),
])
})
.collect(); .collect();
if let Some(s) = flutter::GLOBAL_EVENT_STREAM if let Some(s) = flutter::GLOBAL_EVENT_STREAM
.read() .read()
@ -603,11 +625,20 @@ pub fn main_load_recent_peers() {
pub fn main_load_fav_peers() { pub fn main_load_fav_peers() {
if !config::APP_DIR.read().unwrap().is_empty() { if !config::APP_DIR.read().unwrap().is_empty() {
let favs = get_fav(); let favs = get_fav();
let peers: Vec<(String, config::PeerInfoSerde)> = PeerConfig::peers() let peers: Vec<HashMap<&str, String>> = PeerConfig::peers()
.into_iter() .into_iter()
.filter_map(|(id, _, peer)| { .filter_map(|(id, _, p)| {
if favs.contains(&id) { if favs.contains(&id) {
Some((id, peer.info)) Some(HashMap::<&str, String>::from_iter([
("id", id),
("username", p.info.username.clone()),
("hostname", p.info.hostname.clone()),
("platform", p.info.platform.clone()),
(
"alias",
p.options.get("alias").unwrap_or(&"".to_owned()).to_owned(),
),
]))
} else { } else {
None None
} }
@ -661,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

@ -18,7 +18,7 @@ use hbb_common::{
tokio::{self, sync::mpsc, time}, tokio::{self, sync::mpsc, time},
}; };
use crate::common::{get_app_name}; use crate::common::get_app_name;
use crate::ipc; use crate::ipc;
use crate::ui_interface::{ use crate::ui_interface::{
check_mouse_time, closing, create_shortcut, current_is_wayland, fix_login_wayland, check_mouse_time, closing, create_shortcut, current_is_wayland, fix_login_wayland,
@ -73,9 +73,7 @@ fn check_connect_status(
let (tx, rx) = mpsc::unbounded_channel::<ipc::Data>(); let (tx, rx) = mpsc::unbounded_channel::<ipc::Data>();
let password = Arc::new(Mutex::new(String::default())); let password = Arc::new(Mutex::new(String::default()));
let cloned_password = password.clone(); let cloned_password = password.clone();
std::thread::spawn(move || { std::thread::spawn(move || crate::ui_interface::check_connect_status_(reconnect, rx));
crate::ui_interface::check_connect_status_(reconnect, rx)
});
(status, options, tx, password) (status, options, tx, password)
} }
@ -525,9 +523,16 @@ impl UI {
fn get_lan_peers(&self) -> String { fn get_lan_peers(&self) -> String {
let peers = get_lan_peers() let peers = get_lan_peers()
.into_iter() .into_iter()
.map(|(id, peer)| (id, peer.username, peer.hostname, peer.platform)) .map(|mut peer| {
(
peer.remove("id").unwrap_or_default(),
peer.remove("username").unwrap_or_default(),
peer.remove("hostname").unwrap_or_default(),
peer.remove("platform").unwrap_or_default(),
)
})
.collect::<Vec<(String, String, String, String)>>(); .collect::<Vec<(String, String, String, String)>>();
serde_json::to_string(&peers).unwrap_or_default() serde_json::to_string(&get_lan_peers()).unwrap_or_default()
} }
fn get_uuid(&self) -> String { fn get_uuid(&self) -> String {

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

View File

@ -648,19 +648,17 @@ pub fn discover() {
} }
#[inline] #[inline]
pub fn get_lan_peers() -> Vec<(String, config::PeerInfoSerde)> { pub fn get_lan_peers() -> Vec<HashMap<&'static str, String>> {
config::LanPeers::load() config::LanPeers::load()
.peers .peers
.iter() .iter()
.map(|peer| { .map(|peer| {
( HashMap::<&str, String>::from_iter([
peer.id.clone(), ("id", peer.id.clone()),
config::PeerInfoSerde { ("username", peer.username.clone()),
username: peer.username.clone(), ("hostname", peer.hostname.clone()),
hostname: peer.hostname.clone(), ("platform", peer.platform.clone()),
platform: peer.platform.clone(), ])
},
)
}) })
.collect() .collect()
} }