Merge pull request #1280 from 21pages/setting

add setting page
This commit is contained in:
RustDesk 2022-08-15 09:55:09 +08:00 committed by GitHub
commit d710b8464c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1066 additions and 460 deletions

View File

@ -55,7 +55,6 @@ class MyTheme {
bool isDarkTheme() {
final isDark = "Y" == Get.find<SharedPreferences>().getString("darkTheme");
debugPrint("current is dark theme: $isDark");
return isDark;
}
@ -482,3 +481,35 @@ String translate(String name) {
}
return platformFFI.translate(name, localeName);
}
bool option2bool(String key, String value) {
bool res;
if (key.startsWith("enable-")) {
res = value != "N";
} else if (key.startsWith("allow-") ||
key == "stop-service" ||
key == "direct-server" ||
key == "stop-rendezvous-service") {
res = value == "Y";
} else {
assert(false);
res = value != "N";
}
return res;
}
String bool2option(String key, bool option) {
String res;
if (key.startsWith('enable-')) {
res = option ? '' : 'N';
} else if (key.startsWith('allow-') ||
key == "stop-service" ||
key == "direct-server" ||
key == "stop-rendezvous-service") {
res = option ? 'Y' : '';
} else {
assert(false);
res = option ? 'Y' : 'N';
}
return res;
}

View File

@ -6,6 +6,7 @@ import 'package:flutter/material.dart' hide MenuItem;
import 'package:flutter/services.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/desktop/pages/connection_page.dart';
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/server_model.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
@ -26,7 +27,10 @@ class DesktopHomePage extends StatefulWidget {
const borderColor = Color(0xFF2F65BA);
class _DesktopHomePageState extends State<DesktopHomePage>
with TrayListener, WindowListener {
with TrayListener, WindowListener, AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
void onWindowClose() async {
super.onWindowClose();
@ -678,440 +682,6 @@ class _DesktopHomePageState extends State<DesktopHomePage>
});
}
void changeServer() async {
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
print("${oldOptions}");
String idServer = oldOptions['custom-rendezvous-server'] ?? "";
var idServerMsg = "";
String relayServer = oldOptions['relay-server'] ?? "";
var relayServerMsg = "";
String apiServer = oldOptions['api-server'] ?? "";
var apiServerMsg = "";
var key = oldOptions['key'] ?? "";
var isInProgress = false;
gFFI.dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate("ID/Relay Server")),
content: ConstrainedBox(
constraints: BoxConstraints(minWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('ID Server')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
onChanged: (s) {
idServer = s;
},
decoration: InputDecoration(
border: OutlineInputBorder(),
errorText:
idServerMsg.isNotEmpty ? idServerMsg : null),
controller: TextEditingController(text: idServer),
),
),
],
),
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('Relay Server')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
onChanged: (s) {
relayServer = s;
},
decoration: InputDecoration(
border: OutlineInputBorder(),
errorText: relayServerMsg.isNotEmpty
? relayServerMsg
: null),
controller: TextEditingController(text: relayServer),
),
),
],
),
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('API Server')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
onChanged: (s) {
apiServer = s;
},
decoration: InputDecoration(
border: OutlineInputBorder(),
errorText:
apiServerMsg.isNotEmpty ? apiServerMsg : null),
controller: TextEditingController(text: apiServer),
),
),
],
),
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('Key')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
onChanged: (s) {
key = s;
},
decoration: InputDecoration(
border: OutlineInputBorder(),
),
controller: TextEditingController(text: key),
),
),
],
),
SizedBox(
height: 4.0,
),
Offstage(
offstage: !isInProgress, child: LinearProgressIndicator())
],
),
),
actions: [
TextButton(
onPressed: () {
close();
},
child: Text(translate("Cancel"))),
TextButton(
onPressed: () async {
setState(() {
[idServerMsg, relayServerMsg, apiServerMsg]
.forEach((element) {
element = "";
});
isInProgress = true;
});
final cancel = () {
setState(() {
isInProgress = false;
});
};
idServer = idServer.trim();
relayServer = relayServer.trim();
apiServer = apiServer.trim();
key = key.trim();
if (idServer.isNotEmpty) {
idServerMsg = translate(
await bind.mainTestIfValidServer(server: idServer));
if (idServerMsg.isEmpty) {
oldOptions['custom-rendezvous-server'] = idServer;
} else {
cancel();
return;
}
} else {
oldOptions['custom-rendezvous-server'] = "";
}
if (relayServer.isNotEmpty) {
relayServerMsg = translate(
await bind.mainTestIfValidServer(server: relayServer));
if (relayServerMsg.isEmpty) {
oldOptions['relay-server'] = relayServer;
} else {
cancel();
return;
}
} else {
oldOptions['relay-server'] = "";
}
if (apiServer.isNotEmpty) {
if (apiServer.startsWith('http://') ||
apiServer.startsWith("https://")) {
oldOptions['api-server'] = apiServer;
return;
} else {
apiServerMsg = translate("invalid_http");
cancel();
return;
}
} else {
oldOptions['api-server'] = "";
}
// ok
oldOptions['key'] = key;
await bind.mainSetOptions(json: jsonEncode(oldOptions));
close();
},
child: Text(translate("OK"))),
],
);
});
}
void changeWhiteList() async {
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
var newWhiteList = ((oldOptions['whitelist'] ?? "") as String).split(',');
var newWhiteListField = newWhiteList.join('\n');
var msg = "";
var isInProgress = false;
gFFI.dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate("IP Whitelisting")),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(translate("whitelist_sep")),
SizedBox(
height: 8.0,
),
Row(
children: [
Expanded(
child: TextField(
onChanged: (s) {
newWhiteListField = s;
},
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
errorText: msg.isEmpty ? null : translate(msg),
),
controller: TextEditingController(text: newWhiteListField),
),
),
],
),
SizedBox(
height: 4.0,
),
Offstage(offstage: !isInProgress, child: LinearProgressIndicator())
],
),
actions: [
TextButton(
onPressed: () {
close();
},
child: Text(translate("Cancel"))),
TextButton(
onPressed: () async {
setState(() {
msg = "";
isInProgress = true;
});
newWhiteListField = newWhiteListField.trim();
var newWhiteList = "";
if (newWhiteListField.isEmpty) {
// pass
} else {
final ips =
newWhiteListField.trim().split(RegExp(r"[\s,;\n]+"));
// test ip
final ipMatch = RegExp(r"^\d+\.\d+\.\d+\.\d+$");
for (final ip in ips) {
if (!ipMatch.hasMatch(ip)) {
msg = translate("Invalid IP") + " $ip";
setState(() {
isInProgress = false;
});
return;
}
}
newWhiteList = ips.join(',');
}
oldOptions['whitelist'] = newWhiteList;
await bind.mainSetOptions(json: jsonEncode(oldOptions));
close();
},
child: Text(translate("OK"))),
],
);
});
}
void changeSocks5Proxy() async {
var socks = await bind.mainGetSocks();
String proxy = "";
String proxyMsg = "";
String username = "";
String password = "";
if (socks.length == 3) {
proxy = socks[0];
username = socks[1];
password = socks[2];
}
var isInProgress = false;
gFFI.dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate("Socks5 Proxy")),
content: ConstrainedBox(
constraints: BoxConstraints(minWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('Hostname')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
onChanged: (s) {
proxy = s;
},
decoration: InputDecoration(
border: OutlineInputBorder(),
errorText: proxyMsg.isNotEmpty ? proxyMsg : null),
controller: TextEditingController(text: proxy),
),
),
],
),
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('Username')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
onChanged: (s) {
username = s;
},
decoration: InputDecoration(
border: OutlineInputBorder(),
),
controller: TextEditingController(text: username),
),
),
],
),
SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints(minWidth: 100),
child: Text("${translate('Password')}:")
.marginOnly(bottom: 16.0)),
SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
onChanged: (s) {
password = s;
},
decoration: InputDecoration(
border: OutlineInputBorder(),
),
controller: TextEditingController(text: password),
),
),
],
),
SizedBox(
height: 8.0,
),
Offstage(
offstage: !isInProgress, child: LinearProgressIndicator())
],
),
),
actions: [
TextButton(
onPressed: () {
close();
},
child: Text(translate("Cancel"))),
TextButton(
onPressed: () async {
setState(() {
proxyMsg = "";
isInProgress = true;
});
final cancel = () {
setState(() {
isInProgress = false;
});
};
proxy = proxy.trim();
username = username.trim();
password = password.trim();
if (proxy.isNotEmpty) {
proxyMsg = translate(
await bind.mainTestIfValidServer(server: proxy));
if (proxyMsg.isEmpty) {
// ignore
} else {
cancel();
return;
}
}
await bind.mainSetSocks(
proxy: proxy, username: username, password: password);
close();
},
child: Text(translate("OK"))),
],
);
});
}
void about() async {
final appName = await bind.mainGetAppName();
final license = await bind.mainGetLicense();

File diff suppressed because it is too large Load Diff

View File

@ -68,6 +68,6 @@ class _DesktopTabPageState extends State<DesktopTabPage>
void onAddSetting() {
DesktopTabBar.onAdd(this, tabController, tabs, _selected,
TabInfo(label: kTabLabelSettingPage, icon: Icons.settings));
TabInfo(label: kTabLabelSettingPage, icon: Icons.build));
}
}

View File

@ -51,26 +51,24 @@ class ServerModel with ChangeNotifier {
kUseBothPasswords
].indexOf(_verificationMethod);
if (index < 0) {
_verificationMethod = kUseBothPasswords;
return kUseBothPasswords;
}
return _verificationMethod;
}
set verificationMethod(String method) {
_verificationMethod = method;
bind.mainSetOption(key: "verification-method", value: method);
}
String get temporaryPasswordLength {
final lengthIndex = ["6", "8", "10"].indexOf(_temporaryPasswordLength);
if (lengthIndex < 0) {
_temporaryPasswordLength = "6";
return "6";
}
return _temporaryPasswordLength;
}
set temporaryPasswordLength(String length) {
_temporaryPasswordLength = length;
bind.mainSetOption(key: "temporary-password-length", value: length);
}

View File

@ -23,9 +23,9 @@ use crate::ui_interface;
use crate::ui_interface::{change_id, check_connect_status, is_ok_change_id};
use crate::ui_interface::{
discover, forget_password, get_api_server, get_app_name, get_async_job_status,
get_connect_status, get_fav, get_id, get_lan_peers, get_license, get_local_option, get_option,
get_options, get_peer, get_peer_option, get_socks, get_sound_inputs, get_uuid, get_version,
has_rendezvous_service, post_request, set_local_option, set_option, set_options,
get_connect_status, get_fav, get_id, get_lan_peers, get_langs, get_license, get_local_option,
get_option, get_options, get_peer, get_peer_option, get_socks, get_sound_inputs, get_uuid,
get_version, has_rendezvous_service, post_request, set_local_option, set_option, set_options,
set_peer_option, set_permanent_password, set_socks, store_fav, test_if_valid_server,
update_temporary_password, using_public_server,
};
@ -614,7 +614,7 @@ pub fn main_get_home_dir() -> String {
}
pub fn main_get_langs() -> String {
crate::lang::LANGS.to_string()
get_langs()
}
pub fn main_get_temporary_password() -> String {

View File

@ -24,17 +24,18 @@ use crate::ipc;
use crate::ui_interface::{
check_mouse_time, closing, create_shortcut, current_is_wayland, fix_login_wayland,
forget_password, get_api_server, get_async_job_status, get_connect_status, get_error, get_fav,
get_icon, get_lan_peers, get_license, get_local_option, get_mouse_time, get_new_version,
get_option, get_options, get_peer, get_peer_option, get_recent_sessions, get_remote_id,
get_size, get_socks, get_software_ext, get_software_store_path, get_software_update_url,
get_uuid, get_version, goto_install, has_rendezvous_service, install_me, install_path,
is_can_screen_recording, is_installed, is_installed_daemon, is_installed_lower_version,
is_login_wayland, is_ok_change_id, is_process_trusted, is_rdp_service_open, is_share_rdp,
is_xfce, modify_default_login, new_remote, open_url, peer_has_password, permanent_password,
post_request, recent_sessions_updated, remove_peer, run_without_install, set_local_option,
set_option, set_options, set_peer_option, set_permanent_password, set_remote_id, set_share_rdp,
set_socks, show_run_without_install, store_fav, t, temporary_password, test_if_valid_server,
update_me, update_temporary_password, using_public_server,
get_icon, get_lan_peers, get_langs, get_license, get_local_option, get_mouse_time,
get_new_version, get_option, get_options, get_peer, get_peer_option, get_recent_sessions,
get_remote_id, get_size, get_socks, get_software_ext, get_software_store_path,
get_software_update_url, get_uuid, get_version, goto_install, has_rendezvous_service,
install_me, install_path, is_can_screen_recording, is_installed, is_installed_daemon,
is_installed_lower_version, is_login_wayland, is_ok_change_id, is_process_trusted,
is_rdp_service_open, is_share_rdp, is_xfce, modify_default_login, new_remote, open_url,
peer_has_password, permanent_password, post_request, recent_sessions_updated, remove_peer,
run_without_install, set_local_option, set_option, set_options, set_peer_option,
set_permanent_password, set_remote_id, set_share_rdp, set_socks, show_run_without_install,
store_fav, t, temporary_password, test_if_valid_server, update_me, update_temporary_password,
using_public_server,
};
mod cm;
@ -547,7 +548,7 @@ impl UI {
}
fn get_langs(&self) -> String {
crate::lang::LANGS.to_string()
get_langs()
}
}

View File

@ -654,6 +654,10 @@ pub fn t(name: String) -> String {
crate::client::translate(name)
}
pub fn get_langs() -> String {
crate::lang::LANGS.to_string()
}
pub fn is_xfce() -> bool {
crate::platform::is_xfce()
}