Merge pull request #1788 from 21pages/fix-flutter-upgrade
Fix flutter upgrade
This commit is contained in:
commit
a2cb295a11
@ -2,6 +2,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/common/widgets/address_book.dart';
|
||||
@ -9,6 +10,7 @@ import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import '../../common.dart';
|
||||
import '../../common/formatter/id_formatter.dart';
|
||||
@ -27,7 +29,7 @@ class ConnectionPage extends StatefulWidget {
|
||||
|
||||
/// State for the connection page.
|
||||
class _ConnectionPageState extends State<ConnectionPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
with SingleTickerProviderStateMixin, WindowListener {
|
||||
/// Controller for the id input bar.
|
||||
final _idController = IDTextEditingController();
|
||||
|
||||
@ -43,6 +45,8 @@ class _ConnectionPageState extends State<ConnectionPage>
|
||||
var svcStatusCode = 0.obs;
|
||||
var svcIsUsingPublicServer = true.obs;
|
||||
|
||||
bool isWindowMinisized = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -63,6 +67,7 @@ class _ConnectionPageState extends State<ConnectionPage>
|
||||
_idInputFocused.value = _idFocusNode.hasFocus;
|
||||
});
|
||||
Get.put<RxBool>(svcStopped, tag: 'service-stop');
|
||||
windowManager.addListener(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -70,9 +75,24 @@ class _ConnectionPageState extends State<ConnectionPage>
|
||||
_idController.dispose();
|
||||
_updateTimer?.cancel();
|
||||
Get.delete<RxBool>(tag: 'service-stop');
|
||||
windowManager.removeListener(this);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void onWindowEvent(String eventName) {
|
||||
super.onWindowEvent(eventName);
|
||||
if (eventName == 'minimize') {
|
||||
isWindowMinisized = true;
|
||||
} else if (eventName == 'maximize' || eventName == 'restore') {
|
||||
if (isWindowMinisized && Platform.isWindows) {
|
||||
// windows can't update when minisized.
|
||||
Get.forceAppUpdate();
|
||||
}
|
||||
isWindowMinisized = false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
@ -282,23 +302,34 @@ class _ConnectionPageState extends State<ConnectionPage>
|
||||
.marginOnly(left: em),
|
||||
),
|
||||
// ready && public
|
||||
Offstage(
|
||||
offstage: !(!svcStopped.value &&
|
||||
svcStatusCode.value == 1 &&
|
||||
svcIsUsingPublicServer.value),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(', ', style: TextStyle(fontSize: em)),
|
||||
InkWell(
|
||||
onTap: onUsePublicServerGuide,
|
||||
child: Text(
|
||||
translate('setup_server_tip'),
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline, fontSize: em),
|
||||
),
|
||||
)
|
||||
],
|
||||
Flexible(
|
||||
child: Offstage(
|
||||
offstage: !(!svcStopped.value &&
|
||||
svcStatusCode.value == 1 &&
|
||||
svcIsUsingPublicServer.value),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(', ', style: TextStyle(fontSize: em)),
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: onUsePublicServerGuide,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
translate('setup_server_tip'),
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: em),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -321,6 +321,7 @@ class _GeneralState extends State<_General> {
|
||||
...devices.map((device) => _Radio<String>(context,
|
||||
value: device,
|
||||
groupValue: currentDevice,
|
||||
autoNewLine: false,
|
||||
label: device, onChanged: (value) {
|
||||
setDevice(value);
|
||||
setState(() {});
|
||||
@ -812,11 +813,7 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
||||
AbsorbPointer(
|
||||
absorbing: locked,
|
||||
child: Column(children: [
|
||||
_CardRow(title: 'Server', children: [
|
||||
_Button('ID/Relay Server', changeServer, enabled: enabled),
|
||||
_Button('Import Server Conf', importServer,
|
||||
enabled: enabled),
|
||||
]),
|
||||
server(enabled),
|
||||
_Card(title: 'Proxy', children: [
|
||||
_Button('Socks5 Proxy', changeSocks5Proxy,
|
||||
enabled: enabled),
|
||||
@ -825,6 +822,156 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
||||
),
|
||||
]).marginOnly(bottom: _kListViewBottomMargin));
|
||||
}
|
||||
|
||||
server(bool enabled) {
|
||||
return _futureBuilder(future: () async {
|
||||
return await bind.mainGetOptions();
|
||||
}(), hasData: (data) {
|
||||
// Setting page is not modal, oldOptions should only be used when getting options, never when setting.
|
||||
Map<String, dynamic> oldOptions = jsonDecode(data! as String);
|
||||
old(String key) {
|
||||
return (oldOptions[key] ?? "").trim();
|
||||
}
|
||||
|
||||
RxString idErrMsg = "".obs;
|
||||
RxString relayErrMsg = "".obs;
|
||||
RxString apiErrMsg = "".obs;
|
||||
var idController =
|
||||
TextEditingController(text: old('custom-rendezvous-server'));
|
||||
var relayController = TextEditingController(text: old('relay-server'));
|
||||
var apiController = TextEditingController(text: old('api-server'));
|
||||
var keyController = TextEditingController(text: old('key'));
|
||||
|
||||
set(String idServer, String relayServer, String apiServer,
|
||||
String key) async {
|
||||
idServer = idServer.trim();
|
||||
relayServer = relayServer.trim();
|
||||
apiServer = apiServer.trim();
|
||||
key = key.trim();
|
||||
if (idServer.isNotEmpty) {
|
||||
idErrMsg.value =
|
||||
translate(await bind.mainTestIfValidServer(server: idServer));
|
||||
if (idErrMsg.isNotEmpty) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (relayServer.isNotEmpty) {
|
||||
relayErrMsg.value =
|
||||
translate(await bind.mainTestIfValidServer(server: relayServer));
|
||||
if (relayErrMsg.isNotEmpty) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (apiServer.isNotEmpty) {
|
||||
if (!apiServer.startsWith('http://') ||
|
||||
!apiServer.startsWith("https://")) {
|
||||
apiErrMsg.value =
|
||||
"${translate("API Server")}: ${translate("invalid_http")}";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// should set one by one
|
||||
await bind.mainSetOption(
|
||||
key: 'custom-rendezvous-server', value: idServer);
|
||||
await bind.mainSetOption(key: 'relay-server', value: relayServer);
|
||||
await bind.mainSetOption(key: 'api-server', value: apiServer);
|
||||
await bind.mainSetOption(key: 'key', value: key);
|
||||
return true;
|
||||
}
|
||||
|
||||
submit() async {
|
||||
bool result = await set(idController.text, relayController.text,
|
||||
apiController.text, keyController.text);
|
||||
if (result) {
|
||||
setState(() {});
|
||||
showToast(translate('Successful'));
|
||||
} else {
|
||||
showToast(translate('Failed'));
|
||||
}
|
||||
}
|
||||
|
||||
import() {
|
||||
Clipboard.getData(Clipboard.kTextPlain).then((value) {
|
||||
TextEditingController mytext = TextEditingController();
|
||||
String? aNullableString = "";
|
||||
aNullableString = value?.text;
|
||||
mytext.text = aNullableString.toString();
|
||||
if (mytext.text.isNotEmpty) {
|
||||
try {
|
||||
Map<String, dynamic> config = jsonDecode(mytext.text);
|
||||
if (config.containsKey('IdServer')) {
|
||||
String id = config['IdServer'] ?? '';
|
||||
String relay = config['RelayServer'] ?? '';
|
||||
String api = config['ApiServer'] ?? '';
|
||||
String key = config['Key'] ?? '';
|
||||
idController.text = id;
|
||||
relayController.text = relay;
|
||||
apiController.text = api;
|
||||
keyController.text = key;
|
||||
Future<bool> success = set(id, relay, api, key);
|
||||
success.then((value) {
|
||||
if (value) {
|
||||
showToast(
|
||||
translate('Import server configuration successfully'));
|
||||
} else {
|
||||
showToast(translate('Invalid server configuration'));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showToast(translate("Invalid server configuration"));
|
||||
}
|
||||
} catch (e) {
|
||||
showToast(translate("Invalid server configuration"));
|
||||
}
|
||||
} else {
|
||||
showToast(translate("Clipboard is empty"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export() {
|
||||
Map<String, String> config = {};
|
||||
config['IdServer'] = idController.text.trim();
|
||||
config['RelayServer'] = relayController.text.trim();
|
||||
config['ApiServer'] = apiController.text.trim();
|
||||
config['Key'] = keyController.text.trim();
|
||||
Clipboard.setData(ClipboardData(text: jsonEncode(config)));
|
||||
showToast(translate("Export server configuration successfully"));
|
||||
}
|
||||
|
||||
bool secure = !enabled;
|
||||
return _Card(title: 'ID/Relay Server', title_suffix: [
|
||||
Tooltip(
|
||||
message: translate('Import Server Config'),
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.paste, color: Colors.grey),
|
||||
onPressed: enabled ? import : null),
|
||||
),
|
||||
Tooltip(
|
||||
message: translate('Export Server Config'),
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.copy, color: Colors.grey),
|
||||
onPressed: enabled ? export : null)),
|
||||
], children: [
|
||||
Column(
|
||||
children: [
|
||||
Obx(() => _LabeledTextField(context, 'ID Server', idController,
|
||||
idErrMsg.value, enabled, secure)),
|
||||
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: 15),
|
||||
],
|
||||
)
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _Account extends StatefulWidget {
|
||||
@ -955,63 +1102,37 @@ class _AboutState extends State<_About> {
|
||||
//#region components
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
Widget _Card({required String title, required List<Widget> children}) {
|
||||
Widget _Card(
|
||||
{required String title,
|
||||
required List<Widget> children,
|
||||
List<Widget>? title_suffix}) {
|
||||
return Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: _kCardFixedWidth,
|
||||
child: Card(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
translate(title),
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontSize: _kTitleFontSize,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
).marginOnly(left: _kContentHMargin, top: 10, bottom: 10),
|
||||
...children
|
||||
.map((e) => e.marginOnly(top: 4, right: _kContentHMargin)),
|
||||
],
|
||||
).marginOnly(bottom: 10),
|
||||
).marginOnly(left: _kCardLeftMargin, top: 15),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _CardRow({required String title, required List<Widget> children}) {
|
||||
return Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: _kCardFixedWidth,
|
||||
child: Card(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
translate(title),
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontSize: _kTitleFontSize,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
).marginOnly(left: _kContentHMargin, top: 10, bottom: 10),
|
||||
Row(children: [
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
width: _kCardFixedWidth,
|
||||
child: Card(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
translate(title),
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontSize: _kTitleFontSize,
|
||||
),
|
||||
)),
|
||||
...?title_suffix
|
||||
],
|
||||
).marginOnly(left: _kContentHMargin, top: 10, bottom: 10),
|
||||
...children
|
||||
.map((e) => e.marginOnly(top: 4, right: _kContentHMargin)),
|
||||
]),
|
||||
],
|
||||
).marginOnly(bottom: 10),
|
||||
).marginOnly(left: _kCardLeftMargin, top: 15),
|
||||
],
|
||||
).marginOnly(bottom: 10),
|
||||
).marginOnly(left: _kCardLeftMargin, top: 15),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -1085,6 +1206,7 @@ Widget _Radio<T>(BuildContext context,
|
||||
required T groupValue,
|
||||
required String label,
|
||||
required Function(T value) onChanged,
|
||||
bool autoNewLine = true,
|
||||
bool enabled = true}) {
|
||||
var onChange = enabled
|
||||
? (T? value) {
|
||||
@ -1099,8 +1221,7 @@ Widget _Radio<T>(BuildContext context,
|
||||
Radio<T>(value: value, groupValue: groupValue, onChanged: onChange),
|
||||
Expanded(
|
||||
child: Text(translate(label),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: autoNewLine ? null : TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: _kContentFontSize,
|
||||
color: _disabledTextColor(context, enabled)))
|
||||
@ -1116,12 +1237,11 @@ Widget _Radio<T>(BuildContext context,
|
||||
Widget _Button(String label, Function() onPressed,
|
||||
{bool enabled = true, String? tip}) {
|
||||
var button = ElevatedButton(
|
||||
onPressed: enabled ? onPressed : null,
|
||||
child: Container(
|
||||
child: Text(
|
||||
translate(label),
|
||||
).marginSymmetric(horizontal: 15),
|
||||
));
|
||||
onPressed: enabled ? onPressed : null,
|
||||
child: Text(
|
||||
translate(label),
|
||||
).marginSymmetric(horizontal: 15),
|
||||
);
|
||||
StatefulWidget child;
|
||||
if (tip == null) {
|
||||
child = button;
|
||||
@ -1138,12 +1258,11 @@ Widget _SubButton(String label, Function() onPressed, [bool enabled = true]) {
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: enabled ? onPressed : null,
|
||||
child: Container(
|
||||
child: Text(
|
||||
translate(label),
|
||||
).marginSymmetric(horizontal: 15),
|
||||
)),
|
||||
onPressed: enabled ? onPressed : null,
|
||||
child: Text(
|
||||
translate(label),
|
||||
).marginSymmetric(horizontal: 15),
|
||||
),
|
||||
],
|
||||
).marginOnly(left: _kContentHSubMargin);
|
||||
}
|
||||
@ -1215,34 +1334,72 @@ Widget _lock(
|
||||
offstage: !locked,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: _kCardFixedWidth,
|
||||
child: Card(
|
||||
child: ElevatedButton(
|
||||
child: SizedBox(
|
||||
height: 25,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.security_sharp,
|
||||
size: 20,
|
||||
),
|
||||
Text(translate(label)).marginOnly(left: 5),
|
||||
]).marginSymmetric(vertical: 2)),
|
||||
onPressed: () async {
|
||||
bool checked = await bind.mainCheckSuperUserPermission();
|
||||
if (checked) {
|
||||
onUnlock();
|
||||
}
|
||||
},
|
||||
).marginSymmetric(horizontal: 2, vertical: 4),
|
||||
).marginOnly(left: _kCardLeftMargin),
|
||||
).marginOnly(top: 10),
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
width: _kCardFixedWidth,
|
||||
child: Card(
|
||||
child: ElevatedButton(
|
||||
child: SizedBox(
|
||||
height: 25,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.security_sharp,
|
||||
size: 20,
|
||||
),
|
||||
Text(translate(label)).marginOnly(left: 5),
|
||||
]).marginSymmetric(vertical: 2)),
|
||||
onPressed: () async {
|
||||
bool checked = await bind.mainCheckSuperUserPermission();
|
||||
if (checked) {
|
||||
onUnlock();
|
||||
}
|
||||
},
|
||||
).marginSymmetric(horizontal: 2, vertical: 4),
|
||||
).marginOnly(left: _kCardLeftMargin),
|
||||
).marginOnly(top: 10),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
_LabeledTextField(
|
||||
BuildContext context,
|
||||
String lable,
|
||||
TextEditingController controller,
|
||||
String errorText,
|
||||
bool enabled,
|
||||
bool secure) {
|
||||
return Row(
|
||||
children: [
|
||||
Spacer(flex: 1),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Text(
|
||||
'${translate(lable)}:',
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(color: _disabledTextColor(context, enabled)),
|
||||
),
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
Expanded(
|
||||
flex: 10,
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
enabled: enabled,
|
||||
obscureText: secure,
|
||||
decoration: InputDecoration(
|
||||
errorText: errorText.isNotEmpty ? errorText : null),
|
||||
style: TextStyle(
|
||||
color: _disabledTextColor(context, enabled),
|
||||
)),
|
||||
),
|
||||
Spacer(flex: 1),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class _ComboBox extends StatelessWidget {
|
||||
late final List<String> keys;
|
||||
@ -1312,315 +1469,6 @@ class _ComboBox extends StatelessWidget {
|
||||
|
||||
//#region dialogs
|
||||
|
||||
void changeServer() async {
|
||||
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
|
||||
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 idController = TextEditingController(text: idServer);
|
||||
var relayController = TextEditingController(text: relayServer);
|
||||
var apiController = TextEditingController(text: apiServer);
|
||||
var keyController = TextEditingController(text: key);
|
||||
|
||||
var isInProgress = false;
|
||||
|
||||
gFFI.dialogManager.show((setState, close) {
|
||||
submit() async {
|
||||
setState(() {
|
||||
idServerMsg = "";
|
||||
relayServerMsg = "";
|
||||
apiServerMsg = "";
|
||||
isInProgress = true;
|
||||
});
|
||||
cancel() {
|
||||
setState(() {
|
||||
isInProgress = false;
|
||||
});
|
||||
}
|
||||
|
||||
idServer = idController.text.trim();
|
||||
relayServer = relayController.text.trim();
|
||||
apiServer = apiController.text.trim().toLowerCase();
|
||||
key = keyController.text.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();
|
||||
}
|
||||
|
||||
return CustomAlertDialog(
|
||||
title: Text(translate("ID/Relay Server")),
|
||||
content: ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 500),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 8.0,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 100),
|
||||
child: Text("${translate('ID Server')}:")
|
||||
.marginOnly(bottom: 16.0)),
|
||||
const SizedBox(
|
||||
width: 24.0,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
errorText: idServerMsg.isNotEmpty ? idServerMsg : null),
|
||||
controller: idController,
|
||||
focusNode: FocusNode()..requestFocus(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8.0,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 100),
|
||||
child: Text("${translate('Relay Server')}:")
|
||||
.marginOnly(bottom: 16.0)),
|
||||
const SizedBox(
|
||||
width: 24.0,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
errorText:
|
||||
relayServerMsg.isNotEmpty ? relayServerMsg : null),
|
||||
controller: relayController,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8.0,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 100),
|
||||
child: Text("${translate('API Server')}:")
|
||||
.marginOnly(bottom: 16.0)),
|
||||
const SizedBox(
|
||||
width: 24.0,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
errorText:
|
||||
apiServerMsg.isNotEmpty ? apiServerMsg : null),
|
||||
controller: apiController,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8.0,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 100),
|
||||
child:
|
||||
Text("${translate('Key')}:").marginOnly(bottom: 16.0)),
|
||||
const SizedBox(
|
||||
width: 24.0,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
controller: keyController,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4.0,
|
||||
),
|
||||
Offstage(
|
||||
offstage: !isInProgress, child: const LinearProgressIndicator())
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(onPressed: close, child: Text(translate("Cancel"))),
|
||||
TextButton(onPressed: submit, child: Text(translate("OK"))),
|
||||
],
|
||||
onSubmit: submit,
|
||||
onCancel: close,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void importServer() async {
|
||||
Future<void> importServerShow(String content) async {
|
||||
gFFI.dialogManager.show((setState, close) {
|
||||
return CustomAlertDialog(
|
||||
title: Text(content),
|
||||
content: ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 500),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 4.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(onPressed: close, child: Text(translate("OK"))),
|
||||
],
|
||||
onCancel: close,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<bool> submit(
|
||||
String idServer, String relayServer, String apiServer, String key) async {
|
||||
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
|
||||
var idServerMsg = "";
|
||||
var relayServerMsg = "";
|
||||
if (idServer.isNotEmpty) {
|
||||
idServerMsg =
|
||||
translate(await bind.mainTestIfValidServer(server: idServer));
|
||||
if (idServerMsg.isEmpty) {
|
||||
oldOptions['custom-rendezvous-server'] = idServer;
|
||||
} else {
|
||||
debugPrint('ID Server invalid return');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
oldOptions['custom-rendezvous-server'] = "";
|
||||
}
|
||||
|
||||
if (relayServer.isNotEmpty) {
|
||||
relayServerMsg =
|
||||
translate(await bind.mainTestIfValidServer(server: relayServer));
|
||||
if (relayServerMsg.isEmpty) {
|
||||
oldOptions['relay-server'] = relayServer;
|
||||
} else {
|
||||
debugPrint('Relay Server invalid return');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
oldOptions['relay-server'] = "";
|
||||
}
|
||||
|
||||
if (apiServer.isNotEmpty) {
|
||||
if (apiServer.startsWith('http://') || apiServer.startsWith("https://")) {
|
||||
oldOptions['api-server'] = apiServer;
|
||||
return false;
|
||||
} else {
|
||||
debugPrint('invalid_http');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
oldOptions['api-server'] = "";
|
||||
}
|
||||
// ok
|
||||
oldOptions['key'] = key;
|
||||
await bind.mainSetOptions(json: jsonEncode(oldOptions));
|
||||
debugPrint("set ID/Realy Server Ok");
|
||||
return true;
|
||||
}
|
||||
|
||||
Clipboard.getData(Clipboard.kTextPlain).then((value) {
|
||||
TextEditingController mytext = TextEditingController();
|
||||
String? aNullableString = "";
|
||||
aNullableString = value?.text;
|
||||
mytext.text = aNullableString.toString();
|
||||
if (mytext.text.isNotEmpty) {
|
||||
debugPrint('Clipboard is not empty');
|
||||
try {
|
||||
Map<String, dynamic> config = jsonDecode(mytext.text);
|
||||
if (config.containsKey('IdServer') &&
|
||||
config.containsKey('RelayServer')) {
|
||||
debugPrint('IdServer: ${config['IdServer']}');
|
||||
debugPrint('RelayServer: ${config['RelayServer']}');
|
||||
debugPrint('ApiServer: ${config['ApiServer']}');
|
||||
debugPrint('Key: ${config['Key']}');
|
||||
Future<bool> success = submit(config['IdServer'],
|
||||
config['RelayServer'], config['ApiServer'], config['Key']);
|
||||
success.then((value) {
|
||||
if (value) {
|
||||
importServerShow(
|
||||
translate('Import server configuration successfully'));
|
||||
} else {
|
||||
importServerShow(translate('Invalid server configuration'));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
debugPrint('invalid config info');
|
||||
importServerShow(translate("Invalid server configuration"));
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('invalid config info');
|
||||
importServerShow(translate("Invalid server configuration"));
|
||||
}
|
||||
} else {
|
||||
debugPrint('Clipboard is empty');
|
||||
importServerShow(translate("Clipboard is empty"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void changeSocks5Proxy() async {
|
||||
var socks = await bind.mainGetSocks();
|
||||
|
||||
|
@ -181,7 +181,7 @@ class _InstallPageState extends State<InstallPage> with WindowListener {
|
||||
void install() {
|
||||
btnEnabled.value = false;
|
||||
showProgress.value = true;
|
||||
String args = '--flutter';
|
||||
String args = '';
|
||||
if (startmenu.value) args += ' startmenu';
|
||||
if (desktopicon.value) args += ' desktopicon';
|
||||
bind.installInstallMe(options: args, path: controller.text);
|
||||
|
@ -16,15 +16,6 @@ typedef void (*FUNC_RUSTDESK_FREE_ARGS)( char**, int);
|
||||
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
_In_ wchar_t *command_line, _In_ int show_command)
|
||||
{
|
||||
// uni links dispatch
|
||||
HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"rustdesk");
|
||||
if (hwnd != NULL) {
|
||||
DispatchToUniLinksDesktop(hwnd);
|
||||
|
||||
::ShowWindow(hwnd, SW_NORMAL);
|
||||
::SetForegroundWindow(hwnd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
HINSTANCE hInstance = LoadLibraryA("librustdesk.dll");
|
||||
if (!hInstance)
|
||||
{
|
||||
@ -56,6 +47,16 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
std::vector<std::string> rust_args(c_args, c_args + args_len);
|
||||
free_c_args(c_args, args_len);
|
||||
|
||||
// uni links dispatch
|
||||
HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"rustdesk");
|
||||
if (hwnd != NULL) {
|
||||
DispatchToUniLinksDesktop(hwnd);
|
||||
|
||||
::ShowWindow(hwnd, SW_NORMAL);
|
||||
::SetForegroundWindow(hwnd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Attach to console when present (e.g., 'flutter run') or create a
|
||||
// new console when running with a debugger.
|
||||
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent())
|
||||
@ -78,7 +79,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
FlutterWindow window(project);
|
||||
Win32Window::Point origin(10, 10);
|
||||
Win32Window::Size size(800, 600);
|
||||
if (!window.CreateAndShow(L"rustdesk", origin, size))
|
||||
if (!window.CreateAndShow(L"RustDesk", origin, size))
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "允许建立TCP隧道"),
|
||||
("IP Whitelisting", "IP白名单"),
|
||||
("ID/Relay Server", "ID/中继服务器"),
|
||||
("Import Server Conf", "导入服务器配置"),
|
||||
("Import Server Config", "导入服务器配置"),
|
||||
("Export Server Config", "导出服务器配置"),
|
||||
("Import server configuration successfully", "导入服务器配置信息成功"),
|
||||
("Export server configuration successfully", "导出服务器配置信息成功"),
|
||||
("Invalid server configuration", "无效服务器配置,请修改后重新拷贝配置信息到剪贴板后点击此按钮"),
|
||||
("Clipboard is empty", "拷贝配置信息到剪贴板后点击此按钮,可以自动导入配置"),
|
||||
("Stop service", "停止服务"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Povolit TCP tunelování"),
|
||||
("IP Whitelisting", "Povolování pouze z daných IP adres)"),
|
||||
("ID/Relay Server", "Identifikátor / předávací (relay) server"),
|
||||
("Import Server Conf", "Importovat konfiguraci serveru"),
|
||||
("Import Server Config", "Importovat konfiguraci serveru"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Konfigurace serveru úspěšně importována"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Neplatná konfigurace serveru"),
|
||||
("Clipboard is empty", "Schránka je prázdná"),
|
||||
("Stop service", "Zastavit službu"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Slå TCP-tunneling til"),
|
||||
("IP Whitelisting", "IP-udgivelsesliste"),
|
||||
("ID/Relay Server", "ID/forbindelsesserver"),
|
||||
("Import Server Conf", "Importér serverkonfiguration"),
|
||||
("Import Server Config", "Importér serverkonfiguration"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Importér serverkonfigurationen"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Ugyldig serverkonfiguration"),
|
||||
("Clipboard is empty", "Udklipsholderen er tom"),
|
||||
("Stop service", "Sluk for forbindelsesserveren"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "TCP-Tunnel aktivieren"),
|
||||
("IP Whitelisting", "IP-Whitelist"),
|
||||
("ID/Relay Server", "ID/Vermittlungsserver"),
|
||||
("Import Server Conf", "Serverkonfiguration importieren"),
|
||||
("Import Server Config", "Serverkonfiguration importieren"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Serverkonfiguration erfolgreich importiert"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Ungültige Serverkonfiguration"),
|
||||
("Clipboard is empty", "Zwischenablage ist leer"),
|
||||
("Stop service", "Vermittlungsdienst deaktivieren"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Ebligi tunelado TCP"),
|
||||
("IP Whitelisting", "Listo de IP akceptataj"),
|
||||
("ID/Relay Server", "Identigila/Relajsa servilo"),
|
||||
("Import Server Conf", "Enporti servilan agordon"),
|
||||
("Import Server Config", "Enporti servilan agordon"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Importi servilan agordon sukcese"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Nevalida servila agordo"),
|
||||
("Clipboard is empty", "La poŝo estas malplena"),
|
||||
("Stop service", "Haltu servon"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Habilitar tunel TCP"),
|
||||
("IP Whitelisting", "Lista blanca de IP"),
|
||||
("ID/Relay Server", "Servidor ID/Relay"),
|
||||
("Import Server Conf", "Importar configuración de servidor"),
|
||||
("Import Server Config", "Importar configuración de servidor"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Configuración de servidor importada con éxito"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Configuración de servidor inválida"),
|
||||
("Clipboard is empty", "El portapapeles está vacío"),
|
||||
("Stop service", "Parar servicio"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Activer le tunneling TCP"),
|
||||
("IP Whitelisting", "Liste blanche IP"),
|
||||
("ID/Relay Server", "ID/Serveur Relais"),
|
||||
("Import Server Conf", "Importer la configuration du serveur"),
|
||||
("Import Server Config", "Importer la configuration du serveur"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Configuration du serveur importée avec succès"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Configuration du serveur non valide"),
|
||||
("Clipboard is empty", "Presse-papier vide"),
|
||||
("Stop service", "Arrêter le service"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "TCP Tunneling bekapcsolása"),
|
||||
("IP Whitelisting", "IP Fehérlista"),
|
||||
("ID/Relay Server", "ID/Relay Szerver"),
|
||||
("Import Server Conf", "Szerver Konfiguráció Importálása"),
|
||||
("Import Server Config", "Szerver Konfiguráció Importálása"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Szerver konfiguráció sikeresen importálva"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Érvénytelen szerver konfiguráció"),
|
||||
("Clipboard is empty", "A vágólap üres"),
|
||||
("Stop service", "Szolgáltatás Kikapcsolása"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Aktifkan TCP Tunneling"),
|
||||
("IP Whitelisting", "Daftar Putih IP"),
|
||||
("ID/Relay Server", "ID/Relay Server"),
|
||||
("Import Server Conf", "Impor Konfigurasi Server"),
|
||||
("Import Server Config", "Impor Konfigurasi Server"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Impor konfigurasi server berhasil"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Konfigurasi server tidak valid"),
|
||||
("Clipboard is empty", "Papan klip kosong"),
|
||||
("Stop service", "Hentikan Layanan"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Abilita tunnel TCP"),
|
||||
("IP Whitelisting", "IP autorizzati"),
|
||||
("ID/Relay Server", "Server ID/Relay"),
|
||||
("Import Server Conf", "Importa configurazione Server"),
|
||||
("Import Server Config", "Importa configurazione Server"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Configurazione Server importata con successo"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Configurazione Server non valida"),
|
||||
("Clipboard is empty", "Gli appunti sono vuoti"),
|
||||
("Stop service", "Arresta servizio"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "TCPトンネリングを有効化"),
|
||||
("IP Whitelisting", "IPホワイトリスト"),
|
||||
("ID/Relay Server", "認証・中継サーバー"),
|
||||
("Import Server Conf", "サーバー設定をインポート"),
|
||||
("Import Server Config", "サーバー設定をインポート"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "サーバー設定をインポートしました"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "無効なサーバー設定です"),
|
||||
("Clipboard is empty", "クリップボードは空です"),
|
||||
("Stop service", "サービスを停止"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "TCP 터널링 활성화"),
|
||||
("IP Whitelisting", "IP 화이트리스트"),
|
||||
("ID/Relay Server", "ID/Relay 서버"),
|
||||
("Import Server Conf", "서버 설정 가져오기"),
|
||||
("Import Server Config", "서버 설정 가져오기"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "서버 설정 가져오기 성공"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "잘못된 서버 설정"),
|
||||
("Clipboard is empty", "클립보드가 비어있습니다"),
|
||||
("Stop service", "서비스 중단"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "TCP тунелдеуді қосу"),
|
||||
("IP Whitelisting", "IP Ақ-тізімі"),
|
||||
("ID/Relay Server", "ID/Relay сербері"),
|
||||
("Import Server Conf", "Серверді импорттау"),
|
||||
("Import Server Config", "Серверді импорттау"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Сервердің конфигурациясы сәтті импортталды"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Жарамсыз сервердің конфигурациясы"),
|
||||
("Clipboard is empty", "Көшіру-тақта бос"),
|
||||
("Stop service", "Сербесті тоқтату"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Włącz tunelowanie TCP"),
|
||||
("IP Whitelisting", "Biała lista IP"),
|
||||
("ID/Relay Server", "Serwer ID/Pośredniczący"),
|
||||
("Import Server Conf", "Importuj konfigurację serwera"),
|
||||
("Import Server Config", "Importuj konfigurację serwera"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Importowanie konfiguracji serwera powiodło się"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Nieprawidłowa konfiguracja serwera"),
|
||||
("Clipboard is empty", "Schowek jest pusty"),
|
||||
("Stop service", "Zatrzymaj usługę"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Activar Túnel TCP"),
|
||||
("IP Whitelisting", "Whitelist de IP"),
|
||||
("ID/Relay Server", "Servidor ID/Relay"),
|
||||
("Import Server Conf", "Importar Configuração do Servidor"),
|
||||
("Import Server Config", "Importar Configuração do Servidor"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Configuração do servidor importada com sucesso"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Configuração do servidor inválida"),
|
||||
("Clipboard is empty", "A área de transferência está vazia"),
|
||||
("Stop service", "Parar serviço"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Habilitar Tunelamento TCP"),
|
||||
("IP Whitelisting", "Whitelist de IP"),
|
||||
("ID/Relay Server", "Servidor ID/Relay"),
|
||||
("Import Server Conf", "Importar Configuração do Servidor"),
|
||||
("Import Server Config", "Importar Configuração do Servidor"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Configuração do servidor importada com sucesso"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Configuração do servidor inválida"),
|
||||
("Clipboard is empty", "A área de transferência está vazia"),
|
||||
("Stop service", "Parar serviço"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Включить туннелирование TCP"),
|
||||
("IP Whitelisting", "Список разрешенных IP-адресов"),
|
||||
("ID/Relay Server", "ID/Сервер ретрансляции"),
|
||||
("Import Server Conf", "Импортировать конфигурацию сервера"),
|
||||
("Import Server Config", "Импортировать конфигурацию сервера"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Конфигурация сервера успешно импортирована"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Недопустимая конфигурация сервера"),
|
||||
("Clipboard is empty", "Буфер обмена пуст"),
|
||||
("Stop service", "Остановить службу"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Povoliť TCP tunelovanie"),
|
||||
("IP Whitelisting", "Zoznam povolených IP adries"),
|
||||
("ID/Relay Server", "ID/Prepojovací server"),
|
||||
("Import Server Conf", "Importovať konfiguráciu servera"),
|
||||
("Import Server Config", "Importovať konfiguráciu servera"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Konfigurácia servera bola úspešne importovaná"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Neplatná konfigurácia servera"),
|
||||
("Clipboard is empty", "Schránka je prázdna"),
|
||||
("Stop service", "Zastaviť službu"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", ""),
|
||||
("IP Whitelisting", ""),
|
||||
("ID/Relay Server", ""),
|
||||
("Import Server Conf", ""),
|
||||
("Import Server Config", ""),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", ""),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", ""),
|
||||
("Clipboard is empty", ""),
|
||||
("Stop service", ""),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "TCP Tüneline izin ver"),
|
||||
("IP Whitelisting", "İzinli IP listesi"),
|
||||
("ID/Relay Server", "ID/Relay Sunucusu"),
|
||||
("Import Server Conf", "Sunucu ayarlarını içe aktar"),
|
||||
("Import Server Config", "Sunucu ayarlarını içe aktar"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Sunucu ayarları başarıyla içe aktarıldı"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Geçersiz sunucu ayarı"),
|
||||
("Clipboard is empty", "Kopyalanan geçici veri boş"),
|
||||
("Stop service", "Servisi Durdur"),
|
||||
|
@ -29,8 +29,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "啟用 TCP 通道"),
|
||||
("IP Whitelisting", "IP 白名單"),
|
||||
("ID/Relay Server", "ID/轉送伺服器"),
|
||||
("Import Server Conf", "匯入伺服器設定"),
|
||||
("Import Server Config", "匯入伺服器設定"),
|
||||
("Export Server Config", "導出服務器配置"),
|
||||
("Import server configuration successfully", "匯入伺服器設定成功"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Export server configuration successfully", "導出服務器配置信息成功"),
|
||||
("Invalid server configuration", "無效的伺服器設定"),
|
||||
("Clipboard is empty", "剪貼簿是空的"),
|
||||
("Stop service", "停止服務"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Увімкнути тунелювання TCP"),
|
||||
("IP Whitelisting", "Список дозволених IP-адрес"),
|
||||
("ID/Relay Server", "ID/Сервер ретрансляції"),
|
||||
("Import Server Conf", "Імпортувати конфігурацію сервера"),
|
||||
("Import Server Config", "Імпортувати конфігурацію сервера"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Конфігурацію сервера успішно імпортовано"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Недійсна конфігурація сервера"),
|
||||
("Clipboard is empty", "Буфер обміну порожній"),
|
||||
("Stop service", "Зупинити службу"),
|
||||
|
@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Enable TCP Tunneling", "Cho phép TCP Tunneling"),
|
||||
("IP Whitelisting", "Cho phép IP"),
|
||||
("ID/Relay Server", "Máy chủ ID/Relay"),
|
||||
("Import Server Conf", "Nhập cấu hình máy chủ"),
|
||||
("Import Server Config", "Nhập cấu hình máy chủ"),
|
||||
("Export Server Config", ""),
|
||||
("Import server configuration successfully", "Nhập cấu hình máy chủ thành công"),
|
||||
("Export server configuration successfully", ""),
|
||||
("Invalid server configuration", "Cấu hình máy chủ không hợp lệ"),
|
||||
("Clipboard is empty", "Khay nhớ tạm trống"),
|
||||
("Stop service", "Dừng dịch vụ"),
|
||||
|
@ -878,6 +878,25 @@ fn get_install_info_with_subkey(subkey: String) -> (String, String, String, Stri
|
||||
(subkey, path, start_menu, exe)
|
||||
}
|
||||
|
||||
pub fn copy_exe_cmd(src_exe: &str, _exe: &str, _path: &str) -> String {
|
||||
#[cfg(feature = "flutter")]
|
||||
return format!(
|
||||
"XCOPY \"{}\" \"{}\" /Y /E /H /C /I /K /R /Z",
|
||||
PathBuf::from(src_exe)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
_path
|
||||
);
|
||||
#[cfg(not(feature = "flutter"))]
|
||||
return format!(
|
||||
"copy /Y \"{src_exe}\" \"{exe}\"",
|
||||
src_exe = src_exe,
|
||||
exe = _exe
|
||||
);
|
||||
}
|
||||
|
||||
pub fn update_me() -> ResultType<()> {
|
||||
let (_, path, _, exe) = get_install_info();
|
||||
let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned();
|
||||
@ -887,13 +906,13 @@ pub fn update_me() -> ResultType<()> {
|
||||
sc stop {app_name}
|
||||
taskkill /F /IM {broker_exe}
|
||||
taskkill /F /IM {app_name}.exe
|
||||
copy /Y \"{src_exe}\" \"{exe}\"
|
||||
{copy_exe}
|
||||
\"{src_exe}\" --extract \"{path}\"
|
||||
sc start {app_name}
|
||||
{lic}
|
||||
",
|
||||
src_exe = src_exe,
|
||||
exe = exe,
|
||||
copy_exe = copy_exe_cmd(&src_exe, &exe, &path),
|
||||
broker_exe = crate::ui::win_privacy::INJECTED_PROCESS_EXE,
|
||||
path = path,
|
||||
app_name = crate::get_app_name(),
|
||||
@ -1038,18 +1057,6 @@ copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{start_menu}\\\"
|
||||
app_name = crate::get_app_name(),
|
||||
);
|
||||
}
|
||||
let mut flutter_copy = Default::default();
|
||||
if options.contains("--flutter") {
|
||||
flutter_copy = format!(
|
||||
"XCOPY \"{}\" \"{}\" /Y /E /H /C /I /K /R /Z",
|
||||
std::env::current_exe()?
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
let meta = std::fs::symlink_metadata(std::env::current_exe()?)?;
|
||||
let size = meta.len() / 1024;
|
||||
@ -1072,13 +1079,14 @@ if exist \"{tmp_path}\\{app_name} Tray.lnk\" del /f /q \"{tmp_path}\\{app_name}
|
||||
tmp_path = tmp_path,
|
||||
app_name = crate::get_app_name(),
|
||||
);
|
||||
let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_string();
|
||||
|
||||
let cmds = format!(
|
||||
"
|
||||
{uninstall_str}
|
||||
chcp 65001
|
||||
md \"{path}\"
|
||||
{flutter_copy}
|
||||
copy /Y \"{src_exe}\" \"{exe}\"
|
||||
{copy_exe}
|
||||
copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
|
||||
\"{src_exe}\" --extract \"{path}\"
|
||||
reg add {subkey} /f
|
||||
@ -1111,7 +1119,7 @@ sc delete {app_name}
|
||||
",
|
||||
uninstall_str=uninstall_str,
|
||||
path=path,
|
||||
src_exe=std::env::current_exe()?.to_str().unwrap_or(""),
|
||||
src_exe=src_exe,
|
||||
exe=exe,
|
||||
ORIGIN_PROCESS_EXE = crate::ui::win_privacy::ORIGIN_PROCESS_EXE,
|
||||
broker_exe=crate::ui::win_privacy::INJECTED_PROCESS_EXE,
|
||||
@ -1140,7 +1148,7 @@ sc delete {app_name}
|
||||
} else {
|
||||
&dels
|
||||
},
|
||||
flutter_copy = flutter_copy,
|
||||
copy_exe = copy_exe_cmd(&src_exe, &exe, &path),
|
||||
);
|
||||
run_cmds(cmds, debug, "install")?;
|
||||
std::thread::sleep(std::time::Duration::from_millis(2000));
|
||||
@ -1478,7 +1486,13 @@ pub fn run_uac(exe: &str, arg: &str) -> ResultType<bool> {
|
||||
}
|
||||
|
||||
pub fn check_super_user_permission() -> ResultType<bool> {
|
||||
run_uac("cmd", "/c /q")
|
||||
run_uac(
|
||||
std::env::current_exe()?
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
.as_str(),
|
||||
"--version",
|
||||
)
|
||||
}
|
||||
|
||||
pub fn elevate(arg: &str) -> ResultType<bool> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user