mobile virtual display, resolution menu, proxy setting (#8717)
1. Merge code of mobile and desktop virtual display menu. 2. Mobile add seperate resolution menu, only support changing resolutions. 3. Android add proxy setting Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
parent
eec879a801
commit
09466680d3
@ -6,6 +6,7 @@ import 'package:flutter_hbb/common.dart';
|
|||||||
import 'package:flutter_hbb/common/shared_state.dart';
|
import 'package:flutter_hbb/common/shared_state.dart';
|
||||||
import 'package:flutter_hbb/common/widgets/dialog.dart';
|
import 'package:flutter_hbb/common/widgets/dialog.dart';
|
||||||
import 'package:flutter_hbb/consts.dart';
|
import 'package:flutter_hbb/consts.dart';
|
||||||
|
import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart';
|
||||||
import 'package:flutter_hbb/models/model.dart';
|
import 'package:flutter_hbb/models/model.dart';
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@ -802,3 +803,106 @@ List<TToggleMenu> toolbarKeyboardToggles(FFI ffi) {
|
|||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool showVirtualDisplayMenu(FFI ffi) {
|
||||||
|
if (ffi.ffiModel.pi.platform != kPeerPlatformWindows) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ffi.ffiModel.pi.isInstalled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ffi.ffiModel.pi.isRustDeskIdd || ffi.ffiModel.pi.isAmyuniIdd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> getVirtualDisplayMenuChildren(
|
||||||
|
FFI ffi, String id, VoidCallback? clickCallBack) {
|
||||||
|
if (!showVirtualDisplayMenu(ffi)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
final pi = ffi.ffiModel.pi;
|
||||||
|
final privacyModeState = PrivacyModeState.find(id);
|
||||||
|
if (pi.isRustDeskIdd) {
|
||||||
|
final virtualDisplays = ffi.ffiModel.pi.RustDeskVirtualDisplays;
|
||||||
|
final children = <Widget>[];
|
||||||
|
for (var i = 0; i < kMaxVirtualDisplayCount; i++) {
|
||||||
|
children.add(Obx(() => CkbMenuButton(
|
||||||
|
value: virtualDisplays.contains(i + 1),
|
||||||
|
onChanged: privacyModeState.isNotEmpty
|
||||||
|
? null
|
||||||
|
: (bool? value) async {
|
||||||
|
if (value != null) {
|
||||||
|
bind.sessionToggleVirtualDisplay(
|
||||||
|
sessionId: ffi.sessionId, index: i + 1, on: value);
|
||||||
|
clickCallBack?.call();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text('${translate('Virtual display')} ${i + 1}'),
|
||||||
|
ffi: ffi,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
children.add(Divider());
|
||||||
|
children.add(Obx(() => MenuButton(
|
||||||
|
onPressed: privacyModeState.isNotEmpty
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
bind.sessionToggleVirtualDisplay(
|
||||||
|
sessionId: ffi.sessionId,
|
||||||
|
index: kAllVirtualDisplay,
|
||||||
|
on: false);
|
||||||
|
clickCallBack?.call();
|
||||||
|
},
|
||||||
|
ffi: ffi,
|
||||||
|
child: Text(translate('Plug out all')),
|
||||||
|
)));
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
if (pi.isAmyuniIdd) {
|
||||||
|
final count = ffi.ffiModel.pi.amyuniVirtualDisplayCount;
|
||||||
|
final children = <Widget>[
|
||||||
|
Obx(() => Row(
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: privacyModeState.isNotEmpty || count == 0
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
bind.sessionToggleVirtualDisplay(
|
||||||
|
sessionId: ffi.sessionId, index: 0, on: false);
|
||||||
|
clickCallBack?.call();
|
||||||
|
},
|
||||||
|
child: Icon(Icons.remove),
|
||||||
|
),
|
||||||
|
Text(count.toString()),
|
||||||
|
TextButton(
|
||||||
|
onPressed: privacyModeState.isNotEmpty || count == 4
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
bind.sessionToggleVirtualDisplay(
|
||||||
|
sessionId: ffi.sessionId, index: 0, on: true);
|
||||||
|
clickCallBack?.call();
|
||||||
|
},
|
||||||
|
child: Icon(Icons.add),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Divider(),
|
||||||
|
Obx(() => MenuButton(
|
||||||
|
onPressed: privacyModeState.isNotEmpty || count == 0
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
bind.sessionToggleVirtualDisplay(
|
||||||
|
sessionId: ffi.sessionId,
|
||||||
|
index: kAllVirtualDisplay,
|
||||||
|
on: false);
|
||||||
|
clickCallBack?.call();
|
||||||
|
},
|
||||||
|
ffi: ffi,
|
||||||
|
child: Text(translate('Plug out all')),
|
||||||
|
)),
|
||||||
|
];
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
@ -136,6 +136,8 @@ const String kOptionAllowRemoveWallpaper = "allow-remove-wallpaper";
|
|||||||
const String kOptionStopService = "stop-service";
|
const String kOptionStopService = "stop-service";
|
||||||
const String kOptionDirectxCapture = "enable-directx-capture";
|
const String kOptionDirectxCapture = "enable-directx-capture";
|
||||||
const String kOptionAllowRemoteCmModification = "allow-remote-cm-modification";
|
const String kOptionAllowRemoteCmModification = "allow-remote-cm-modification";
|
||||||
|
const String kOptionHideServerSetting = "hide-server-settings";
|
||||||
|
const String kOptionHideProxySetting = "hide-proxy-settings";
|
||||||
|
|
||||||
const String kOptionToggleViewOnly = "view-only";
|
const String kOptionToggleViewOnly = "view-only";
|
||||||
|
|
||||||
|
@ -1274,9 +1274,9 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
|||||||
bool enabled = !locked;
|
bool enabled = !locked;
|
||||||
final scrollController = ScrollController();
|
final scrollController = ScrollController();
|
||||||
final hideServer =
|
final hideServer =
|
||||||
bind.mainGetLocalOption(key: "hide-server-settings") == 'Y';
|
bind.mainGetLocalOption(key: kOptionHideServerSetting) == 'Y';
|
||||||
final hideProxy =
|
final hideProxy =
|
||||||
bind.mainGetLocalOption(key: "hide-proxy-settings") == 'Y';
|
bind.mainGetLocalOption(key: kOptionHideProxySetting) == 'Y';
|
||||||
return DesktopScrollWrapper(
|
return DesktopScrollWrapper(
|
||||||
scrollController: scrollController,
|
scrollController: scrollController,
|
||||||
child: ListView(
|
child: ListView(
|
||||||
@ -2328,6 +2328,7 @@ void changeSocks5Proxy() async {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
if (!isMobile)
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: const BoxConstraints(minWidth: 140),
|
constraints: const BoxConstraints(minWidth: 140),
|
||||||
child: Align(
|
child: Align(
|
||||||
@ -2357,6 +2358,10 @@ void changeSocks5Proxy() async {
|
|||||||
child: TextField(
|
child: TextField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
errorText: proxyMsg.isNotEmpty ? proxyMsg : null,
|
errorText: proxyMsg.isNotEmpty ? proxyMsg : null,
|
||||||
|
labelText: isMobile ? translate('Server') : null,
|
||||||
|
helperText:
|
||||||
|
isMobile ? translate("default_proxy_tip") : null,
|
||||||
|
helperMaxLines: isMobile ? 3 : null,
|
||||||
),
|
),
|
||||||
controller: proxyController,
|
controller: proxyController,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -2367,6 +2372,7 @@ void changeSocks5Proxy() async {
|
|||||||
).marginOnly(bottom: 8),
|
).marginOnly(bottom: 8),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
if (!isMobile)
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: const BoxConstraints(minWidth: 140),
|
constraints: const BoxConstraints(minWidth: 140),
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -2376,6 +2382,9 @@ void changeSocks5Proxy() async {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: userController,
|
controller: userController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: isMobile ? translate('Username') : null,
|
||||||
|
),
|
||||||
enabled: !isOptFixed,
|
enabled: !isOptFixed,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2383,6 +2392,7 @@ void changeSocks5Proxy() async {
|
|||||||
).marginOnly(bottom: 8),
|
).marginOnly(bottom: 8),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
if (!isMobile)
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: const BoxConstraints(minWidth: 140),
|
constraints: const BoxConstraints(minWidth: 140),
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -2393,6 +2403,7 @@ void changeSocks5Proxy() async {
|
|||||||
child: Obx(() => TextField(
|
child: Obx(() => TextField(
|
||||||
obscureText: obscure.value,
|
obscureText: obscure.value,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
labelText: isMobile ? translate('Password') : null,
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
onPressed: () => obscure.value = !obscure.value,
|
onPressed: () => obscure.value = !obscure.value,
|
||||||
icon: Icon(obscure.value
|
icon: Icon(obscure.value
|
||||||
|
@ -1052,15 +1052,11 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
|||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
screenAdjustor: _screenAdjustor,
|
screenAdjustor: _screenAdjustor,
|
||||||
),
|
),
|
||||||
if (pi.isRustDeskIdd)
|
if (showVirtualDisplayMenu(ffi))
|
||||||
_RustDeskVirtualDisplayMenu(
|
_SubmenuButton(
|
||||||
id: widget.id,
|
|
||||||
ffi: widget.ffi,
|
|
||||||
),
|
|
||||||
if (pi.isAmyuniIdd)
|
|
||||||
_AmyuniVirtualDisplayMenu(
|
|
||||||
id: widget.id,
|
|
||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
|
menuChildren: getVirtualDisplayMenuChildren(ffi, id, null),
|
||||||
|
child: Text(translate("Virtual display")),
|
||||||
),
|
),
|
||||||
cursorToggles(),
|
cursorToggles(),
|
||||||
Divider(),
|
Divider(),
|
||||||
@ -1559,155 +1555,6 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RustDeskVirtualDisplayMenu extends StatefulWidget {
|
|
||||||
final String id;
|
|
||||||
final FFI ffi;
|
|
||||||
|
|
||||||
_RustDeskVirtualDisplayMenu({
|
|
||||||
Key? key,
|
|
||||||
required this.id,
|
|
||||||
required this.ffi,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<_RustDeskVirtualDisplayMenu> createState() =>
|
|
||||||
_RustDeskVirtualDisplayMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RustDeskVirtualDisplayMenuState
|
|
||||||
extends State<_RustDeskVirtualDisplayMenu> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if (widget.ffi.ffiModel.pi.platform != kPeerPlatformWindows) {
|
|
||||||
return Offstage();
|
|
||||||
}
|
|
||||||
if (!widget.ffi.ffiModel.pi.isInstalled) {
|
|
||||||
return Offstage();
|
|
||||||
}
|
|
||||||
|
|
||||||
final virtualDisplays = widget.ffi.ffiModel.pi.RustDeskVirtualDisplays;
|
|
||||||
final privacyModeState = PrivacyModeState.find(widget.id);
|
|
||||||
|
|
||||||
final children = <Widget>[];
|
|
||||||
for (var i = 0; i < kMaxVirtualDisplayCount; i++) {
|
|
||||||
children.add(Obx(() => CkbMenuButton(
|
|
||||||
value: virtualDisplays.contains(i + 1),
|
|
||||||
onChanged: privacyModeState.isNotEmpty
|
|
||||||
? null
|
|
||||||
: (bool? value) async {
|
|
||||||
if (value != null) {
|
|
||||||
bind.sessionToggleVirtualDisplay(
|
|
||||||
sessionId: widget.ffi.sessionId,
|
|
||||||
index: i + 1,
|
|
||||||
on: value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Text('${translate('Virtual display')} ${i + 1}'),
|
|
||||||
ffi: widget.ffi,
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
children.add(Divider());
|
|
||||||
children.add(Obx(() => MenuButton(
|
|
||||||
onPressed: privacyModeState.isNotEmpty
|
|
||||||
? null
|
|
||||||
: () {
|
|
||||||
bind.sessionToggleVirtualDisplay(
|
|
||||||
sessionId: widget.ffi.sessionId,
|
|
||||||
index: kAllVirtualDisplay,
|
|
||||||
on: false);
|
|
||||||
},
|
|
||||||
ffi: widget.ffi,
|
|
||||||
child: Text(translate('Plug out all')),
|
|
||||||
)));
|
|
||||||
return _SubmenuButton(
|
|
||||||
ffi: widget.ffi,
|
|
||||||
menuChildren: children,
|
|
||||||
child: Text(translate("Virtual display")),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AmyuniVirtualDisplayMenu extends StatefulWidget {
|
|
||||||
final String id;
|
|
||||||
final FFI ffi;
|
|
||||||
|
|
||||||
_AmyuniVirtualDisplayMenu({
|
|
||||||
Key? key,
|
|
||||||
required this.id,
|
|
||||||
required this.ffi,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<_AmyuniVirtualDisplayMenu> createState() =>
|
|
||||||
_AmiyuniVirtualDisplayMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AmiyuniVirtualDisplayMenuState extends State<_AmyuniVirtualDisplayMenu> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if (widget.ffi.ffiModel.pi.platform != kPeerPlatformWindows) {
|
|
||||||
return Offstage();
|
|
||||||
}
|
|
||||||
if (!widget.ffi.ffiModel.pi.isInstalled) {
|
|
||||||
return Offstage();
|
|
||||||
}
|
|
||||||
|
|
||||||
final count = widget.ffi.ffiModel.pi.amyuniVirtualDisplayCount;
|
|
||||||
final privacyModeState = PrivacyModeState.find(widget.id);
|
|
||||||
|
|
||||||
final children = <Widget>[
|
|
||||||
Obx(() => Row(
|
|
||||||
children: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: privacyModeState.isNotEmpty || count == 0
|
|
||||||
? null
|
|
||||||
: () => bind.sessionToggleVirtualDisplay(
|
|
||||||
sessionId: widget.ffi.sessionId, index: 0, on: false),
|
|
||||||
child: Icon(Icons.remove),
|
|
||||||
),
|
|
||||||
Text(count.toString()),
|
|
||||||
TextButton(
|
|
||||||
onPressed: privacyModeState.isNotEmpty || count == 4
|
|
||||||
? null
|
|
||||||
: () => bind.sessionToggleVirtualDisplay(
|
|
||||||
sessionId: widget.ffi.sessionId, index: 0, on: true),
|
|
||||||
child: Icon(Icons.add),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
Divider(),
|
|
||||||
Obx(() => MenuButton(
|
|
||||||
onPressed: privacyModeState.isNotEmpty || count == 0
|
|
||||||
? null
|
|
||||||
: () {
|
|
||||||
bind.sessionToggleVirtualDisplay(
|
|
||||||
sessionId: widget.ffi.sessionId,
|
|
||||||
index: kAllVirtualDisplay,
|
|
||||||
on: false);
|
|
||||||
},
|
|
||||||
ffi: widget.ffi,
|
|
||||||
child: Text(translate('Plug out all')),
|
|
||||||
)),
|
|
||||||
];
|
|
||||||
|
|
||||||
return _SubmenuButton(
|
|
||||||
ffi: widget.ffi,
|
|
||||||
menuChildren: children,
|
|
||||||
child: Text(translate("Virtual display")),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _KeyboardMenu extends StatelessWidget {
|
class _KeyboardMenu extends StatelessWidget {
|
||||||
final String id;
|
final String id;
|
||||||
final FFI ffi;
|
final FFI ffi;
|
||||||
|
@ -1158,14 +1158,110 @@ void showOptions(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var popupDialogMenus = List<Widget>.empty(growable: true);
|
||||||
|
final resolution = getResolutionMenu(gFFI, id);
|
||||||
|
if (resolution != null) {
|
||||||
|
popupDialogMenus.add(ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
title: resolution.child,
|
||||||
|
onTap: () {
|
||||||
|
close();
|
||||||
|
resolution.onPressed();
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
final virtualDisplayMenu = getVirtualDisplayMenu(gFFI, id);
|
||||||
|
if (virtualDisplayMenu != null) {
|
||||||
|
popupDialogMenus.add(ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
title: virtualDisplayMenu.child,
|
||||||
|
onTap: () {
|
||||||
|
close();
|
||||||
|
virtualDisplayMenu.onPressed();
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (popupDialogMenus.isNotEmpty) {
|
||||||
|
popupDialogMenus.add(const Divider(color: MyTheme.border));
|
||||||
|
}
|
||||||
|
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: displays + radios + toggles + [privacyModeWidget]),
|
children: displays +
|
||||||
|
radios +
|
||||||
|
popupDialogMenus +
|
||||||
|
toggles +
|
||||||
|
[privacyModeWidget]),
|
||||||
);
|
);
|
||||||
}, clickMaskDismiss: true, backDismiss: true);
|
}, clickMaskDismiss: true, backDismiss: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTextMenu? getVirtualDisplayMenu(FFI ffi, String id) {
|
||||||
|
if (!showVirtualDisplayMenu(ffi)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return TTextMenu(
|
||||||
|
child: Text(translate("Virtual display")),
|
||||||
|
onPressed: () {
|
||||||
|
ffi.dialogManager.show((setState, close, context) {
|
||||||
|
final children = getVirtualDisplayMenuChildren(ffi, id, close);
|
||||||
|
return CustomAlertDialog(
|
||||||
|
title: Text(translate('Virtual display')),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, clickMaskDismiss: true, backDismiss: true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TTextMenu? getResolutionMenu(FFI ffi, String id) {
|
||||||
|
final ffiModel = ffi.ffiModel;
|
||||||
|
final pi = ffiModel.pi;
|
||||||
|
final resolutions = pi.resolutions;
|
||||||
|
final display = pi.tryGetDisplayIfNotAllDisplay(display: pi.currentDisplay);
|
||||||
|
|
||||||
|
final visible =
|
||||||
|
ffiModel.keyboard && (resolutions.length > 1) && display != null;
|
||||||
|
if (!visible) return null;
|
||||||
|
|
||||||
|
return TTextMenu(
|
||||||
|
child: Text(translate("Resolution")),
|
||||||
|
onPressed: () {
|
||||||
|
ffi.dialogManager.show((setState, close, context) {
|
||||||
|
final children = resolutions
|
||||||
|
.map((e) => getRadio<String>(
|
||||||
|
Text('${e.width}x${e.height}'),
|
||||||
|
'${e.width}x${e.height}',
|
||||||
|
'${display.width}x${display.height}',
|
||||||
|
(value) {
|
||||||
|
close();
|
||||||
|
bind.sessionChangeResolution(
|
||||||
|
sessionId: ffi.sessionId,
|
||||||
|
display: pi.currentDisplay,
|
||||||
|
width: e.width,
|
||||||
|
height: e.height,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
return CustomAlertDialog(
|
||||||
|
title: Text(translate('Resolution')),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, clickMaskDismiss: true, backDismiss: true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void sendPrompt(bool isMac, String key) {
|
void sendPrompt(bool isMac, String key) {
|
||||||
final old = isMac ? gFFI.inputModel.command : gFFI.inputModel.ctrl;
|
final old = isMac ? gFFI.inputModel.command : gFFI.inputModel.ctrl;
|
||||||
if (isMac) {
|
if (isMac) {
|
||||||
|
@ -3,6 +3,7 @@ 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/desktop/pages/desktop_setting_page.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:settings_ui/settings_ui.dart';
|
import 'package:settings_ui/settings_ui.dart';
|
||||||
@ -83,6 +84,8 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
var _fingerprint = "";
|
var _fingerprint = "";
|
||||||
var _buildDate = "";
|
var _buildDate = "";
|
||||||
var _autoDisconnectTimeout = "";
|
var _autoDisconnectTimeout = "";
|
||||||
|
var _hideServer = false;
|
||||||
|
var _hideProxy = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -109,6 +112,8 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
bind.mainGetOptionSync(key: kOptionAllowAutoDisconnect));
|
bind.mainGetOptionSync(key: kOptionAllowAutoDisconnect));
|
||||||
_autoDisconnectTimeout =
|
_autoDisconnectTimeout =
|
||||||
bind.mainGetOptionSync(key: kOptionAutoDisconnectTimeout);
|
bind.mainGetOptionSync(key: kOptionAutoDisconnectTimeout);
|
||||||
|
_hideServer = bind.mainGetLocalOption(key: kOptionHideServerSetting) == 'Y';
|
||||||
|
_hideProxy = bind.mainGetLocalOption(key: kOptionHideProxySetting) == 'Y';
|
||||||
|
|
||||||
() async {
|
() async {
|
||||||
var update = false;
|
var update = false;
|
||||||
@ -553,13 +558,20 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
SettingsSection(title: Text(translate("Settings")), tiles: [
|
SettingsSection(title: Text(translate("Settings")), tiles: [
|
||||||
if (!disabledSettings)
|
if (!disabledSettings && !_hideServer)
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title: Text(translate('ID/Relay Server')),
|
title: Text(translate('ID/Relay Server')),
|
||||||
leading: Icon(Icons.cloud),
|
leading: Icon(Icons.cloud),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
showServerSettings(gFFI.dialogManager);
|
showServerSettings(gFFI.dialogManager);
|
||||||
}),
|
}),
|
||||||
|
if (!isIOS && !_hideProxy)
|
||||||
|
SettingsTile(
|
||||||
|
title: Text(translate('Socks5/Http(s) Proxy')),
|
||||||
|
leading: Icon(Icons.network_ping),
|
||||||
|
onPressed: (context) {
|
||||||
|
changeSocks5Proxy();
|
||||||
|
}),
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title: Text(translate('Language')),
|
title: Text(translate('Language')),
|
||||||
leading: Icon(Icons.translate),
|
leading: Icon(Icons.translate),
|
||||||
|
@ -415,11 +415,12 @@ pub fn install_path() -> String {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_socks() -> Vec<String> {
|
pub fn get_socks() -> Vec<String> {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
|
||||||
return Vec::new();
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
{
|
|
||||||
let s = ipc::get_socks();
|
let s = ipc::get_socks();
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
let s = Config::get_socks();
|
||||||
|
#[cfg(target_os = "ios")]
|
||||||
|
let s: Option<config::Socks5Server> = None;
|
||||||
match s {
|
match s {
|
||||||
None => Vec::new(),
|
None => Vec::new(),
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
@ -431,17 +432,27 @@ pub fn get_socks() -> Vec<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
|
||||||
pub fn set_socks(proxy: String, username: String, password: String) {
|
pub fn set_socks(proxy: String, username: String, password: String) {
|
||||||
ipc::set_socks(config::Socks5Server {
|
let socks = config::Socks5Server {
|
||||||
proxy,
|
proxy,
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
})
|
};
|
||||||
.ok();
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
ipc::set_socks(socks).ok();
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
{
|
||||||
|
if socks.proxy.is_empty() {
|
||||||
|
Config::set_socks(None);
|
||||||
|
} else {
|
||||||
|
Config::set_socks(Some(socks));
|
||||||
|
}
|
||||||
|
crate::common::test_nat_type();
|
||||||
|
crate::RendezvousMediator::restart();
|
||||||
|
log::info!("socks updated");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -454,9 +465,6 @@ pub fn get_proxy_status() -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
|
||||||
pub fn set_socks(_: String, _: String, _: String) {}
|
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_installed() -> bool {
|
pub fn is_installed() -> bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user