Merge pull request from 21pages/opt_button

desktop style button && sync depend on web
This commit is contained in:
RustDesk 2023-01-16 10:38:58 +08:00 committed by GitHub
commit 2a7f8d5367
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 174 additions and 247 deletions

@ -668,24 +668,25 @@ void msgBox(String id, String type, String title, String text, String link,
if (type != "connecting" && type != "success" && !type.contains("nook")) { if (type != "connecting" && type != "success" && !type.contains("nook")) {
hasOk = true; hasOk = true;
buttons.insert(0, msgBoxButton(translate('OK'), submit)); buttons.insert(0, dialogButton('OK', onPressed: submit));
} }
hasCancel ??= !type.contains("error") && hasCancel ??= !type.contains("error") &&
!type.contains("nocancel") && !type.contains("nocancel") &&
type != "restarting"; type != "restarting";
if (hasCancel) { if (hasCancel) {
buttons.insert(0, msgBoxButton(translate('Cancel'), cancel)); buttons.insert(
0, dialogButton('Cancel', onPressed: cancel, isOutline: true));
} }
// TODO: test this button // TODO: test this button
if (type.contains("hasclose")) { if (type.contains("hasclose")) {
buttons.insert( buttons.insert(
0, 0,
msgBoxButton(translate('Close'), () { dialogButton('Close', onPressed: () {
dialogManager.dismissAll(); dialogManager.dismissAll();
})); }));
} }
if (link.isNotEmpty) { if (link.isNotEmpty) {
buttons.insert(0, msgBoxButton(translate('JumpLink'), jumplink)); buttons.insert(0, dialogButton('JumpLink', onPressed: jumplink));
} }
dialogManager.show( dialogManager.show(
(setState, close) => CustomAlertDialog( (setState, close) => CustomAlertDialog(
@ -1566,3 +1567,30 @@ class ServerConfig {
apiServer = options['api-server'] ?? "", apiServer = options['api-server'] ?? "",
key = options['key'] ?? ""; key = options['key'] ?? "";
} }
Widget dialogButton(String text,
{required VoidCallback? onPressed,
bool isOutline = false,
TextStyle? style}) {
if (isDesktop) {
if (isOutline) {
return OutlinedButton(
onPressed: onPressed,
child: Text(translate(text), style: style),
);
} else {
return ElevatedButton(
style: ElevatedButton.styleFrom(elevation: 0),
onPressed: onPressed,
child: Text(translate(text), style: style),
);
}
} else {
return TextButton(
onPressed: onPressed,
child: Text(
translate(text),
style: style,
));
}
}

@ -335,8 +335,8 @@ class _AddressBookState extends State<AddressBook> {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,
@ -402,8 +402,8 @@ class _AddressBookState extends State<AddressBook> {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -64,8 +64,8 @@ void changeIdDialog() {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,
@ -111,48 +111,46 @@ void changeWhiteList({Function()? callback}) async {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton( dialogButton("Clear", onPressed: () async {
onPressed: () async { await bind.mainSetOption(key: 'whitelist', value: '');
await bind.mainSetOption(key: 'whitelist', value: ''); callback?.call();
callback?.call(); close();
close(); }, isOutline: true),
}, dialogButton(
child: Text(translate("Clear"))), "OK",
TextButton( onPressed: () async {
onPressed: () async { setState(() {
setState(() { msg = "";
msg = ""; isInProgress = true;
isInProgress = true; });
}); newWhiteListField = controller.text.trim();
newWhiteListField = controller.text.trim(); var newWhiteList = "";
var newWhiteList = ""; if (newWhiteListField.isEmpty) {
if (newWhiteListField.isEmpty) { // pass
// pass } else {
} else { final ips = newWhiteListField.trim().split(RegExp(r"[\s,;\n]+"));
final ips = // test ip
newWhiteListField.trim().split(RegExp(r"[\s,;\n]+")); final ipMatch = RegExp(
// test ip r"^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)(\/([1-9]|[1-2][0-9]|3[0-2])){0,1}$");
final ipMatch = RegExp( final ipv6Match = RegExp(
r"^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)(\/([1-9]|[1-2][0-9]|3[0-2])){0,1}$"); r"^(((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*::((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*|((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4})){7})(\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}$");
final ipv6Match = RegExp( for (final ip in ips) {
r"^(((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*::((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*|((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4})){7})(\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}$"); if (!ipMatch.hasMatch(ip) && !ipv6Match.hasMatch(ip)) {
for (final ip in ips) { msg = "${translate("Invalid IP")} $ip";
if (!ipMatch.hasMatch(ip) && !ipv6Match.hasMatch(ip)) { setState(() {
msg = "${translate("Invalid IP")} $ip"; isInProgress = false;
setState(() { });
isInProgress = false; return;
});
return;
}
} }
newWhiteList = ips.join(',');
} }
await bind.mainSetOption(key: 'whitelist', value: newWhiteList); newWhiteList = ips.join(',');
callback?.call(); }
close(); await bind.mainSetOption(key: 'whitelist', value: newWhiteList);
}, callback?.call();
child: Text(translate("OK"))), close();
},
),
], ],
onCancel: close, onCancel: close,
); );
@ -195,14 +193,12 @@ Future<String> changeDirectAccessPort(
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton( dialogButton("OK", onPressed: () async {
onPressed: () async { await bind.mainSetOption(
await bind.mainSetOption( key: 'direct-access-port', value: controller.text);
key: 'direct-access-port', value: controller.text); close();
close(); }),
},
child: Text(translate("OK"))),
], ],
onCancel: close, onCancel: close,
); );

@ -550,7 +550,7 @@ Future<bool?> loginDialog() async {
), ),
], ],
), ),
actions: [msgBoxButton(translate('Close'), onDialogCancel)], actions: [dialogButton('Close', onPressed: onDialogCancel)],
onCancel: onDialogCancel, onCancel: onDialogCancel,
); );
}); });
@ -667,8 +667,8 @@ Future<bool?> verificationCodeDialog(UserPayload? user) async {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: onVerify, child: Text(translate("Verify"))), dialogButton("Verify", onPressed: onVerify),
]); ]);
}); });

@ -662,8 +662,8 @@ abstract class BasePeerCard extends StatelessWidget {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,
@ -931,8 +931,8 @@ class AddressBookPeerCard extends BasePeerCard {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,
@ -1095,8 +1095,8 @@ void _rdpDialog(String id, CardType card) async {
), ),
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -627,8 +627,8 @@ void setPasswordDialog() async {
), ),
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -1671,8 +1671,8 @@ void changeSocks5Proxy() async {
), ),
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate('Cancel'))), dialogButton('Cancel', onPressed: close, isOutline: true),
TextButton(onPressed: submit, child: Text(translate('OK'))), dialogButton('OK', onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -802,14 +802,9 @@ class _FileManagerPageState extends State<FileManagerPage>
], ],
), ),
actions: [ actions: [
TextButton( dialogButton("Cancel",
style: flatButtonStyle, onPressed: cancel, isOutline: true),
onPressed: cancel, dialogButton("OK", onPressed: submit)
child: Text(translate("Cancel"))),
ElevatedButton(
style: flatButtonStyle,
onPressed: submit,
child: Text(translate("OK")))
], ],
onSubmit: submit, onSubmit: submit,
onCancel: cancel, onCancel: cancel,

@ -218,7 +218,7 @@ showKBLayoutTypeChooser(
KBLayoutType.value = bind.getLocalKbLayoutType(); KBLayoutType.value = bind.getLocalKbLayoutType();
return v == KBLayoutType.value; return v == KBLayoutType.value;
}), }),
actions: [msgBoxButton(translate('Close'), close)], actions: [dialogButton('Close', onPressed: close)],
onCancel: close, onCancel: close,
); );
}); });

@ -809,7 +809,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
} }
if (newValue == kRemoteImageQualityCustom) { if (newValue == kRemoteImageQualityCustom) {
final btnClose = msgBoxButton(translate('Close'), () async { final btnClose = dialogButton('Close', onPressed: () async {
await setCustomValues(); await setCustomValues();
widget.ffi.dialogManager.dismissAll(); widget.ffi.dialogManager.dismissAll();
}); });
@ -1326,16 +1326,8 @@ void showSetOSPassword(
), ),
]), ]),
actions: [ actions: [
TextButton( dialogButton('Cancel', onPressed: close, isOutline: true),
style: flatButtonStyle, dialogButton('OK', onPressed: submit),
onPressed: close,
child: Text(translate('Cancel')),
),
TextButton(
style: flatButtonStyle,
onPressed: submit,
child: Text(translate('OK')),
),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -687,8 +687,8 @@ Future<bool> closeConfirmDialog() async {
]), ]),
// confirm checkbox // confirm checkbox
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
ElevatedButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -174,23 +174,18 @@ class _FileManagerPageState extends State<FileManagerPage> {
], ],
), ),
actions: [ actions: [
TextButton( dialogButton("Cancel",
style: flatButtonStyle,
onPressed: () => close(false), onPressed: () => close(false),
child: Text(translate("Cancel"))), isOutline: true),
ElevatedButton( dialogButton("OK", onPressed: () {
style: flatButtonStyle, if (name.value.text.isNotEmpty) {
onPressed: () { model.createDir(PathUtil.join(
if (name.value.text.isNotEmpty) { model.currentDir.path,
model.createDir(PathUtil.join( name.value.text,
model.currentDir.path, model.getCurrentIsWindows()));
name.value.text, close();
model }
.getCurrentIsWindows())); })
close();
}
},
child: Text(translate("OK")))
])); ]));
} else if (v == "hidden") { } else if (v == "hidden") {
model.toggleShowHidden(); model.toggleShowHidden();

@ -1098,15 +1098,9 @@ void showSetOSPassword(
), ),
]), ]),
actions: [ actions: [
TextButton( dialogButton('Cancel', onPressed: close, isOutline: true),
style: flatButtonStyle, dialogButton(
onPressed: () { 'OK',
close();
},
child: Text(translate('Cancel')),
),
TextButton(
style: flatButtonStyle,
onPressed: () { onPressed: () {
var text = controller.text.trim(); var text = controller.text.trim();
bind.sessionPeerOption(id: id, name: "os-password", value: text); bind.sessionPeerOption(id: id, name: "os-password", value: text);
@ -1117,7 +1111,6 @@ void showSetOSPassword(
} }
close(); close();
}, },
child: Text(translate('OK')),
), ),
]); ]);
}); });

@ -273,13 +273,12 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
content: Text(translate( content: Text(translate(
"android_open_battery_optimizations_tip")), "android_open_battery_optimizations_tip")),
actions: [ actions: [
TextButton( dialogButton("Cancel",
onPressed: () => close(), onPressed: () => close(), isOutline: true),
child: Text(translate("Cancel"))), dialogButton(
ElevatedButton( "Open System Setting",
onPressed: () => close(true), onPressed: () => close(true),
child: ),
Text(translate("Open System Setting"))),
], ],
)); ));
if (res == true) { if (res == true) {

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hbb/desktop/widgets/button.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../common.dart'; import '../../common.dart';
@ -33,10 +34,8 @@ void showRestartRemoteDevice(
content: Text( content: Text(
"${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"), "${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"),
actions: [ actions: [
TextButton( dialogButton("Cancel", onPressed: () => close(), isOutline: true),
onPressed: () => close(), child: Text(translate("Cancel"))), dialogButton("OK", onPressed: () => close(true)),
ElevatedButton(
onPressed: () => close(true), child: Text(translate("OK"))),
], ],
)); ));
if (res == true) bind.sessionRestartRemoteDevice(id: id); if (res == true) bind.sessionRestartRemoteDevice(id: id);
@ -96,15 +95,15 @@ void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
), ),
])), ])),
actions: [ actions: [
TextButton( dialogButton(
style: flatButtonStyle, 'Cancel',
onPressed: () { onPressed: () {
close(); close();
}, },
child: Text(translate('Cancel')), isOutline: true,
), ),
TextButton( dialogButton(
style: flatButtonStyle, 'OK',
onPressed: (validateLength && validateSame) onPressed: (validateLength && validateSame)
? () async { ? () async {
close(); close();
@ -118,7 +117,6 @@ void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
} }
} }
: null, : null,
child: Text(translate('OK')),
), ),
], ],
); );
@ -198,16 +196,8 @@ void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async {
), ),
]), ]),
actions: [ actions: [
TextButton( dialogButton('Cancel', onPressed: cancel, isOutline: true),
style: flatButtonStyle, dialogButton('OK', onPressed: submit),
onPressed: cancel,
child: Text(translate('Cancel')),
),
TextButton(
style: flatButtonStyle,
onPressed: submit,
child: Text(translate('OK')),
),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: cancel, onCancel: cancel,
@ -220,20 +210,19 @@ void wrongPasswordDialog(String id, OverlayDialogManager dialogManager) {
title: Text(translate('Wrong Password')), title: Text(translate('Wrong Password')),
content: Text(translate('Do you want to enter again?')), content: Text(translate('Do you want to enter again?')),
actions: [ actions: [
TextButton( dialogButton(
style: flatButtonStyle, 'Cancel',
onPressed: () { onPressed: () {
close(); close();
closeConnection(); closeConnection();
}, },
child: Text(translate('Cancel')), isOutline: true,
), ),
TextButton( dialogButton(
style: flatButtonStyle, 'Retry',
onPressed: () { onPressed: () {
enterPasswordDialog(id, dialogManager); enterPasswordDialog(id, dialogManager);
}, },
child: Text(translate('Retry')),
), ),
])); ]));
} }
@ -321,15 +310,11 @@ void showServerSettingsWithValue(
child: LinearProgressIndicator()) child: LinearProgressIndicator())
])), ])),
actions: [ actions: [
TextButton( dialogButton('Cancel', onPressed: () {
style: flatButtonStyle, close();
onPressed: () { }, isOutline: true),
close(); dialogButton(
}, 'OK',
child: Text(translate('Cancel')),
),
TextButton(
style: flatButtonStyle,
onPressed: () async { onPressed: () async {
setState(() { setState(() {
idServerMsg = null; idServerMsg = null;
@ -361,7 +346,6 @@ void showServerSettingsWithValue(
isInProgress = false; isInProgress = false;
}); });
}, },
child: Text(translate('OK')),
), ),
], ],
); );
@ -512,17 +496,8 @@ void _showRequestElevationDialog(
title: Text(translate('Request Elevation')), title: Text(translate('Request Elevation')),
content: content, content: content,
actions: [ actions: [
ElevatedButton( dialogButton('Cancel', onPressed: close, isOutline: true),
style: ElevatedButton.styleFrom(elevation: 0), dialogButton('OK', onPressed: submit),
onPressed: submit,
child: Text(translate('OK')),
),
OutlinedButton(
onPressed: () {
close();
},
child: Text(translate('Cancel')),
),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,
@ -561,17 +536,10 @@ void showOnBlockDialog(
title: Text(translate(title)), title: Text(translate(title)),
content: content, content: content,
actions: [ actions: [
ElevatedButton( dialogButton('Wait', onPressed: () {
style: ElevatedButton.styleFrom(elevation: 0), close();
onPressed: submit, }, isOutline: true),
child: Text(translate('Request Elevation')), dialogButton('Request Elevation', onPressed: submit),
),
OutlinedButton(
onPressed: () {
close();
},
child: Text(translate('Wait')),
),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,
@ -591,17 +559,10 @@ void showElevationError(String id, String type, String title, String text,
title: Text(translate(title)), title: Text(translate(title)),
content: Text(translate(text)), content: Text(translate(text)),
actions: [ actions: [
ElevatedButton( dialogButton('Cancel', onPressed: () {
style: ElevatedButton.styleFrom(elevation: 0), close();
onPressed: submit, }, isOutline: true),
child: Text(translate('Retry')), dialogButton('Retry', onPressed: submit),
),
OutlinedButton(
onPressed: () {
close();
},
child: Text(translate('Cancel')),
),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -665,14 +665,8 @@ class FileModel extends ChangeNotifier {
: const SizedBox.shrink() : const SizedBox.shrink()
]), ]),
actions: [ actions: [
TextButton( dialogButton("Cancel", onPressed: cancel, isOutline: true),
style: flatButtonStyle, dialogButton("OK", onPressed: submit),
onPressed: cancel,
child: Text(translate("Cancel"))),
TextButton(
style: flatButtonStyle,
onPressed: submit,
child: Text(translate("OK"))),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: cancel, onCancel: cancel,
@ -724,18 +718,9 @@ class FileModel extends ChangeNotifier {
: const SizedBox.shrink() : const SizedBox.shrink()
]), ]),
actions: [ actions: [
TextButton( dialogButton("Cancel", onPressed: cancel, isOutline: true),
style: flatButtonStyle, dialogButton("Skip", onPressed: () => close(null), isOutline: true),
onPressed: cancel, dialogButton("OK", onPressed: submit),
child: Text(translate("Cancel"))),
TextButton(
style: flatButtonStyle,
onPressed: () => close(null),
child: Text(translate("Skip"))),
TextButton(
style: flatButtonStyle,
onPressed: submit,
child: Text(translate("OK"))),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: cancel, onCancel: cancel,

@ -271,7 +271,7 @@ class FfiModel with ChangeNotifier {
hasCancel: false); hasCancel: false);
} else if (type == 'wait-remote-accept-nook') { } else if (type == 'wait-remote-accept-nook') {
msgBoxCommon(dialogManager, title, Text(translate(text)), msgBoxCommon(dialogManager, title, Text(translate(text)),
[msgBoxButton("Cancel", closeConnection)]); [dialogButton("Cancel", onPressed: closeConnection)]);
} else if (type == 'on-uac' || type == 'on-foreground-elevated') { } else if (type == 'on-uac' || type == 'on-foreground-elevated') {
showOnBlockDialog(id, type, title, text, dialogManager); showOnBlockDialog(id, type, title, text, dialogManager);
} else if (type == 'wait-uac') { } else if (type == 'wait-uac') {

@ -304,8 +304,8 @@ class ServerModel with ChangeNotifier {
]), ]),
content: Text(translate("android_service_will_start_tip")), content: Text(translate("android_service_will_start_tip")),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
ElevatedButton(onPressed: submit, child: Text(translate("OK"))), dialogButton("OK", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,
@ -501,8 +501,8 @@ class ServerModel with ChangeNotifier {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: cancel, child: Text(translate("Dismiss"))), dialogButton("Dismiss", onPressed: cancel, isOutline: true),
ElevatedButton(onPressed: submit, child: Text(translate("Accept"))), dialogButton("Accept", onPressed: submit),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: cancel, onCancel: cancel,
@ -674,9 +674,8 @@ showInputWarnAlert(FFI ffi) {
], ],
), ),
actions: [ actions: [
TextButton(onPressed: close, child: Text(translate("Cancel"))), dialogButton("Cancel", onPressed: close, isOutline: true),
ElevatedButton( dialogButton("Open System Setting", onPressed: submit),
onPressed: submit, child: Text(translate("Open System Setting"))),
], ],
onSubmit: submit, onSubmit: submit,
onCancel: close, onCancel: close,

@ -54,6 +54,7 @@ async fn start_hbbs_sync_async() {
last_send = Instant::now(); last_send = Instant::now();
let mut v = Value::default(); let mut v = Value::default();
v["id"] = json!(Config::get_id()); v["id"] = json!(Config::get_id());
v["ver"] = json!(hbb_common::get_version_number(crate::VERSION));
if !conns.is_empty() { if !conns.is_empty() {
v["conns"] = json!(conns); v["conns"] = json!(conns);
} }
@ -100,33 +101,16 @@ fn heartbeat_url() -> String {
} }
fn handle_config_options(config_options: HashMap<String, String>) { fn handle_config_options(config_options: HashMap<String, String>) {
let map = HashMap::from([
("enable-keyboard", ""),
("enable-clipboard", ""),
("enable-file-transfer", ""),
("enable-audio", ""),
("enable-tunnel", ""),
("enable-remote-restart", ""),
("enable-record-session", ""),
("allow-remote-config-modification", ""),
("approve-mode", ""),
("verification-method", "use-both-passwords"),
("enable-rdp", ""),
("enable-lan-discovery", ""),
("direct-server", ""),
("direct-access-port", ""),
]);
let mut options = Config::get_options(); let mut options = Config::get_options();
for (k, v) in map { config_options
if let Some(v2) = config_options.get(k) { .iter()
if v == v2 { .map(|(k, v)| {
if v.is_empty() {
options.remove(k); options.remove(k);
} else { } else {
options.insert(k.to_string(), v2.to_string()); options.insert(k.to_string(), v.to_string());
} }
} else { })
options.remove(k); .count();
}
}
Config::set_options(options); Config::set_options(options);
} }