mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-12-14 11:39:04 +08:00
set id/relay server with a dialog (#10150)
Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
parent
bd0a33e467
commit
34d2c62781
@ -11,6 +11,7 @@ import 'package:flutter_hbb/common/widgets/setting_widgets.dart';
|
|||||||
import 'package:flutter_hbb/consts.dart';
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
|
import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
||||||
|
import 'package:flutter_hbb/mobile/widgets/dialog.dart';
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
import 'package:flutter_hbb/models/server_model.dart';
|
import 'package:flutter_hbb/models/server_model.dart';
|
||||||
import 'package:flutter_hbb/plugin/manager.dart';
|
import 'package:flutter_hbb/plugin/manager.dart';
|
||||||
@ -1363,34 +1364,10 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
|||||||
bool locked = !isWeb && bind.mainIsInstalled();
|
bool locked = !isWeb && bind.mainIsInstalled();
|
||||||
|
|
||||||
final scrollController = ScrollController();
|
final scrollController = ScrollController();
|
||||||
late final TextEditingController idController;
|
|
||||||
late final TextEditingController relayController;
|
|
||||||
late final TextEditingController apiController;
|
|
||||||
late final TextEditingController keyController;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
Map<String, dynamic> oldOptions = jsonDecode(bind.mainGetOptionsSync());
|
|
||||||
old(String key) {
|
|
||||||
return (oldOptions[key] ?? '').trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
idController = TextEditingController(text: old('custom-rendezvous-server'));
|
|
||||||
relayController = TextEditingController(text: old('relay-server'));
|
|
||||||
apiController = TextEditingController(text: old('api-server'));
|
|
||||||
keyController = TextEditingController(text: old('key'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
bool enabled = !locked;
|
|
||||||
final hideServer =
|
|
||||||
bind.mainGetBuildinOption(key: kOptionHideServerSetting) == 'Y';
|
|
||||||
// TODO: support web proxy
|
|
||||||
final hideProxy =
|
|
||||||
isWeb || bind.mainGetBuildinOption(key: kOptionHideProxySetting) == 'Y';
|
|
||||||
return ListView(controller: scrollController, children: [
|
return ListView(controller: scrollController, children: [
|
||||||
_lock(locked, 'Unlock Network Settings', () {
|
_lock(locked, 'Unlock Network Settings', () {
|
||||||
locked = false;
|
locked = false;
|
||||||
@ -1399,80 +1376,69 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
|||||||
AbsorbPointer(
|
AbsorbPointer(
|
||||||
absorbing: locked,
|
absorbing: locked,
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
if (!hideServer) server(enabled),
|
network(context),
|
||||||
if (!hideProxy)
|
|
||||||
_Card(title: 'Proxy', children: [
|
|
||||||
_Button('Socks5/Http(s) Proxy', changeSocks5Proxy,
|
|
||||||
enabled: enabled),
|
|
||||||
]),
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
]).marginOnly(bottom: _kListViewBottomMargin);
|
]).marginOnly(bottom: _kListViewBottomMargin);
|
||||||
}
|
}
|
||||||
|
|
||||||
server(bool enabled) {
|
Widget network(BuildContext context) {
|
||||||
// Simple temp wrapper for PR check
|
final hideServer =
|
||||||
tmpWrapper() {
|
bind.mainGetBuildinOption(key: kOptionHideServerSetting) == 'Y';
|
||||||
// Setting page is not modal, oldOptions should only be used when getting options, never when setting.
|
final hideProxy =
|
||||||
|
isWeb || bind.mainGetBuildinOption(key: kOptionHideProxySetting) == 'Y';
|
||||||
|
|
||||||
RxString idErrMsg = ''.obs;
|
if (hideServer && hideProxy) {
|
||||||
RxString relayErrMsg = ''.obs;
|
return Offstage();
|
||||||
RxString apiErrMsg = ''.obs;
|
|
||||||
final controllers = [
|
|
||||||
idController,
|
|
||||||
relayController,
|
|
||||||
apiController,
|
|
||||||
keyController,
|
|
||||||
];
|
|
||||||
final errMsgs = [
|
|
||||||
idErrMsg,
|
|
||||||
relayErrMsg,
|
|
||||||
apiErrMsg,
|
|
||||||
];
|
|
||||||
|
|
||||||
submit() async {
|
|
||||||
bool result = await setServerConfig(
|
|
||||||
null,
|
|
||||||
errMsgs,
|
|
||||||
ServerConfig(
|
|
||||||
idServer: idController.text,
|
|
||||||
relayServer: relayController.text,
|
|
||||||
apiServer: apiController.text,
|
|
||||||
key: keyController.text));
|
|
||||||
if (result) {
|
|
||||||
setState(() {});
|
|
||||||
showToast(translate('Successful'));
|
|
||||||
} else {
|
|
||||||
showToast(translate('Failed'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool secure = !enabled;
|
|
||||||
return _Card(
|
|
||||||
title: 'ID/Relay Server',
|
|
||||||
title_suffix: ServerConfigImportExportWidgets(controllers, errMsgs),
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Obx(() => _LabeledTextField(context, 'ID Server', idController,
|
|
||||||
idErrMsg.value, enabled, secure)),
|
|
||||||
if (!isWeb)
|
|
||||||
Obx(() => _LabeledTextField(context, 'Relay Server',
|
|
||||||
relayController, relayErrMsg.value, enabled, secure)),
|
|
||||||
Obx(() => _LabeledTextField(context, 'API Server',
|
|
||||||
apiController, apiErrMsg.value, enabled, secure)),
|
|
||||||
_LabeledTextField(
|
|
||||||
context, 'Key', keyController, '', enabled, secure),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [_Button('Apply', submit, enabled: enabled)],
|
|
||||||
).marginOnly(top: 10),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmpWrapper();
|
return _Card(
|
||||||
|
title: 'Network',
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (!hideServer)
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(Icons.dns_outlined, color: _accentColor),
|
||||||
|
title: Text(
|
||||||
|
translate('ID/Relay Server'),
|
||||||
|
style: TextStyle(fontSize: _kContentFontSize),
|
||||||
|
),
|
||||||
|
enabled: !locked,
|
||||||
|
onTap: () => showServerSettings(gFFI.dialogManager),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
minLeadingWidth: 0,
|
||||||
|
horizontalTitleGap: 10,
|
||||||
|
),
|
||||||
|
if (!hideServer && !hideProxy)
|
||||||
|
Divider(height: 1, indent: 16, endIndent: 16),
|
||||||
|
if (!hideProxy)
|
||||||
|
ListTile(
|
||||||
|
leading:
|
||||||
|
Icon(Icons.network_ping_outlined, color: _accentColor),
|
||||||
|
title: Text(
|
||||||
|
translate('Socks5/Http(s) Proxy'),
|
||||||
|
style: TextStyle(fontSize: _kContentFontSize),
|
||||||
|
),
|
||||||
|
enabled: !locked,
|
||||||
|
onTap: changeSocks5Proxy,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
minLeadingWidth: 0,
|
||||||
|
horizontalTitleGap: 10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,11 +828,6 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showServerSettings(OverlayDialogManager dialogManager) async {
|
|
||||||
Map<String, dynamic> options = jsonDecode(await bind.mainGetOptions());
|
|
||||||
showServerSettingsWithValue(ServerConfig.fromOptions(options), dialogManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
void showLanguageSettings(OverlayDialogManager dialogManager) async {
|
void showLanguageSettings(OverlayDialogManager dialogManager) async {
|
||||||
try {
|
try {
|
||||||
final langs = json.decode(await bind.mainGetLangs()) as List<dynamic>;
|
final langs = json.decode(await bind.mainGetLangs()) as List<dynamic>;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/common/widgets/setting_widgets.dart';
|
import 'package:flutter_hbb/common/widgets/setting_widgets.dart';
|
||||||
import 'package:flutter_hbb/common/widgets/toolbar.dart';
|
import 'package:flutter_hbb/common/widgets/toolbar.dart';
|
||||||
@ -146,6 +147,16 @@ void setTemporaryPasswordLengthDialog(
|
|||||||
}, backDismiss: true, clickMaskDismiss: true);
|
}, backDismiss: true, clickMaskDismiss: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showServerSettings(OverlayDialogManager dialogManager) async {
|
||||||
|
Map<String, dynamic> options = {};
|
||||||
|
try {
|
||||||
|
options = jsonDecode(await bind.mainGetOptions());
|
||||||
|
} catch (e) {
|
||||||
|
print("Invalid server config: $e");
|
||||||
|
}
|
||||||
|
showServerSettingsWithValue(ServerConfig.fromOptions(options), dialogManager);
|
||||||
|
}
|
||||||
|
|
||||||
void showServerSettingsWithValue(
|
void showServerSettingsWithValue(
|
||||||
ServerConfig serverConfig, OverlayDialogManager dialogManager) async {
|
ServerConfig serverConfig, OverlayDialogManager dialogManager) async {
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
@ -184,6 +195,43 @@ void showServerSettingsWithValue(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildField(
|
||||||
|
String label, TextEditingController controller, String errorMsg,
|
||||||
|
{String? Function(String?)? validator, bool autofocus = false}) {
|
||||||
|
if (isDesktop || isWeb) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 120,
|
||||||
|
child: Text(label),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
controller: controller,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
errorText: errorMsg.isEmpty ? null : errorMsg,
|
||||||
|
contentPadding:
|
||||||
|
EdgeInsets.symmetric(horizontal: 8, vertical: 12),
|
||||||
|
),
|
||||||
|
validator: validator,
|
||||||
|
autofocus: autofocus,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TextFormField(
|
||||||
|
controller: controller,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: label,
|
||||||
|
errorText: errorMsg.isEmpty ? null : errorMsg,
|
||||||
|
),
|
||||||
|
validator: validator,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -191,56 +239,45 @@ void showServerSettingsWithValue(
|
|||||||
...ServerConfigImportExportWidgets(controllers, errMsgs),
|
...ServerConfigImportExportWidgets(controllers, errMsgs),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
content: Form(
|
content: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(minWidth: 500),
|
||||||
|
child: Form(
|
||||||
child: Obx(() => Column(
|
child: Obx(() => Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: [
|
||||||
TextFormField(
|
buildField(translate('ID Server'), idCtrl, idServerMsg.value,
|
||||||
controller: idCtrl,
|
autofocus: true),
|
||||||
decoration: InputDecoration(
|
SizedBox(height: 8),
|
||||||
labelText: translate('ID Server'),
|
if (!isIOS && !isWeb) ...[
|
||||||
errorText: idServerMsg.value.isEmpty
|
buildField(translate('Relay Server'), relayCtrl,
|
||||||
? null
|
relayServerMsg.value),
|
||||||
: idServerMsg.value),
|
SizedBox(height: 8),
|
||||||
)
|
],
|
||||||
] +
|
buildField(
|
||||||
[
|
translate('API Server'),
|
||||||
if (isAndroid)
|
apiCtrl,
|
||||||
TextFormField(
|
apiServerMsg.value,
|
||||||
controller: relayCtrl,
|
validator: (v) {
|
||||||
decoration: InputDecoration(
|
if (v != null && v.isNotEmpty) {
|
||||||
labelText: translate('Relay Server'),
|
if (!(v.startsWith('http://') ||
|
||||||
errorText: relayServerMsg.value.isEmpty
|
v.startsWith("https://"))) {
|
||||||
? null
|
return translate("invalid_http");
|
||||||
: relayServerMsg.value),
|
|
||||||
)
|
|
||||||
] +
|
|
||||||
[
|
|
||||||
TextFormField(
|
|
||||||
controller: apiCtrl,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: translate('API Server'),
|
|
||||||
),
|
|
||||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
|
||||||
validator: (v) {
|
|
||||||
if (v != null && v.isNotEmpty) {
|
|
||||||
if (!(v.startsWith('http://') ||
|
|
||||||
v.startsWith("https://"))) {
|
|
||||||
return translate("invalid_http");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
},
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
buildField('Key', keyCtrl, ''),
|
||||||
|
if (isInProgress)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 8),
|
||||||
|
child: LinearProgressIndicator(),
|
||||||
),
|
),
|
||||||
TextFormField(
|
],
|
||||||
controller: keyCtrl,
|
)),
|
||||||
decoration: InputDecoration(
|
),
|
||||||
labelText: 'Key',
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
// NOT use Offstage to wrap LinearProgressIndicator
|
|
||||||
if (isInProgress) const LinearProgressIndicator(),
|
|
||||||
]))),
|
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton('Cancel', onPressed: () {
|
dialogButton('Cancel', onPressed: () {
|
||||||
close();
|
close();
|
||||||
|
Loading…
Reference in New Issue
Block a user