commit
d710b8464c
@ -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;
|
||||
}
|
||||
|
@ -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
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
25
src/ui.rs
25
src/ui.rs
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user