Merge pull request #2830 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

View File

@ -668,24 +668,25 @@ void msgBox(String id, String type, String title, String text, String link,
if (type != "connecting" && type != "success" && !type.contains("nook")) {
hasOk = true;
buttons.insert(0, msgBoxButton(translate('OK'), submit));
buttons.insert(0, dialogButton('OK', onPressed: submit));
}
hasCancel ??= !type.contains("error") &&
!type.contains("nocancel") &&
type != "restarting";
if (hasCancel) {
buttons.insert(0, msgBoxButton(translate('Cancel'), cancel));
buttons.insert(
0, dialogButton('Cancel', onPressed: cancel, isOutline: true));
}
// TODO: test this button
if (type.contains("hasclose")) {
buttons.insert(
0,
msgBoxButton(translate('Close'), () {
dialogButton('Close', onPressed: () {
dialogManager.dismissAll();
}));
}
if (link.isNotEmpty) {
buttons.insert(0, msgBoxButton(translate('JumpLink'), jumplink));
buttons.insert(0, dialogButton('JumpLink', onPressed: jumplink));
}
dialogManager.show(
(setState, close) => CustomAlertDialog(
@ -1566,3 +1567,30 @@ class ServerConfig {
apiServer = options['api-server'] ?? "",
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,
));
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -54,6 +54,7 @@ async fn start_hbbs_sync_async() {
last_send = Instant::now();
let mut v = Value::default();
v["id"] = json!(Config::get_id());
v["ver"] = json!(hbb_common::get_version_number(crate::VERSION));
if !conns.is_empty() {
v["conns"] = json!(conns);
}
@ -100,33 +101,16 @@ fn heartbeat_url() -> 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();
for (k, v) in map {
if let Some(v2) = config_options.get(k) {
if v == v2 {
config_options
.iter()
.map(|(k, v)| {
if v.is_empty() {
options.remove(k);
} 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);
}