mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-04-08 17:21:29 +03:00
fix merge
This commit is contained in:
@@ -44,13 +44,22 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
||||
|
||||
/// Update url. If it's not null, means an update is available.
|
||||
var _updateUrl = '';
|
||||
var _menuPos;
|
||||
|
||||
Timer? _updateTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (_idController.text.isEmpty) {
|
||||
() async {
|
||||
final lastRemoteId = await bind.mainGetLastRemoteId();
|
||||
if (lastRemoteId != _idController.text) {
|
||||
setState(() {
|
||||
_idController.text = lastRemoteId;
|
||||
});
|
||||
}
|
||||
}();
|
||||
}
|
||||
_updateTimer = Timer.periodic(Duration(seconds: 1), (timer) {
|
||||
updateStatus();
|
||||
});
|
||||
@@ -58,9 +67,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Provider.of<FfiModel>(context);
|
||||
|
||||
if (_idController.text.isEmpty) _idController.text = gFFI.getId();
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: isDarkTheme() ? null : MyTheme.grayBg),
|
||||
child: Column(
|
||||
@@ -430,7 +436,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
||||
}
|
||||
|
||||
updateStatus() async {
|
||||
svcStopped.value = gFFI.getOption("stop-service") == "Y";
|
||||
svcStopped.value = bind.mainGetOption(key: "stop-service") == "Y";
|
||||
final status =
|
||||
jsonDecode(await bind.mainGetConnectStatus()) as Map<String, dynamic>;
|
||||
svcStatusCode.value = status["status_num"];
|
||||
@@ -446,7 +452,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
||||
}
|
||||
|
||||
Future<Widget> buildAddressBook(BuildContext context) async {
|
||||
final token = await gFFI.getLocalOption('access_token');
|
||||
final token = await bind.mainGetLocalOption(key: 'access_token');
|
||||
if (token.trim().isEmpty) {
|
||||
return Center(
|
||||
child: InkWell(
|
||||
@@ -819,10 +825,34 @@ class WebMenu extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _WebMenuState extends State<WebMenu> {
|
||||
String? username;
|
||||
String url = "";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
() async {
|
||||
final usernameRes = await getUsername();
|
||||
final urlRes = await getUrl();
|
||||
var update = false;
|
||||
if (usernameRes != username) {
|
||||
username = usernameRes;
|
||||
update = true;
|
||||
}
|
||||
if (urlRes != url) {
|
||||
url = urlRes;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
setState(() {});
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Provider.of<FfiModel>(context);
|
||||
final username = getUsername();
|
||||
return PopupMenuButton<String>(
|
||||
icon: Icon(Icons.more_vert),
|
||||
itemBuilder: (context) {
|
||||
@@ -840,7 +870,7 @@ class _WebMenuState extends State<WebMenu> {
|
||||
value: "server",
|
||||
)
|
||||
] +
|
||||
(getUrl().contains('admin.rustdesk.com')
|
||||
(url.contains('admin.rustdesk.com')
|
||||
? <PopupMenuItem<String>>[]
|
||||
: [
|
||||
PopupMenuItem(
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
import 'package:flutter_hbb/desktop/pages/connection_page.dart';
|
||||
import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart';
|
||||
import 'package:flutter_hbb/models/model.dart';
|
||||
import 'package:flutter_hbb/models/platform_model.dart';
|
||||
import 'package:flutter_hbb/models/server_model.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -156,6 +155,8 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
},
|
||||
onTap: () async {
|
||||
final userName = await gFFI.userModel.getUserName();
|
||||
final enabledInput = await bind.mainGetOption(key: 'enable-audio');
|
||||
final defaultInput = await gFFI.getDefaultAudioInput();
|
||||
var menu = <PopupMenuEntry>[
|
||||
genEnablePopupMenuItem(
|
||||
translate("Enable Keyboard/Mouse"),
|
||||
@@ -173,7 +174,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
translate("Enable TCP Tunneling"),
|
||||
'enable-tunnel',
|
||||
),
|
||||
genAudioInputPopupMenuItem(),
|
||||
genAudioInputPopupMenuItem(enabledInput != "N", defaultInput),
|
||||
PopupMenuDivider(),
|
||||
PopupMenuItem(
|
||||
child: Text(translate("ID/Relay Server")),
|
||||
@@ -274,9 +275,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.refresh),
|
||||
onPressed: () {
|
||||
gFFI.setByName("temporary_password");
|
||||
},
|
||||
onPressed: () => bind.mainUpdateTemporaryPassword(),
|
||||
),
|
||||
FutureBuilder<Widget>(
|
||||
future: buildPasswordPopupMenu(context),
|
||||
@@ -359,7 +358,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
if (gFFI.serverModel.temporaryPasswordLength !=
|
||||
e) {
|
||||
gFFI.serverModel.temporaryPasswordLength = e;
|
||||
gFFI.setByName("temporary_password");
|
||||
bind.mainUpdateTemporaryPassword();
|
||||
}
|
||||
},
|
||||
))
|
||||
@@ -465,49 +464,60 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
Get.find<SharedPreferences>().setString("darkTheme", choice);
|
||||
}
|
||||
|
||||
void onSelectMenu(String value) {
|
||||
if (value.startsWith('enable-')) {
|
||||
final option = gFFI.getOption(value);
|
||||
gFFI.setOption(value, option == "N" ? "" : "N");
|
||||
} else if (value.startsWith('allow-')) {
|
||||
final option = gFFI.getOption(value);
|
||||
void onSelectMenu(String key) async {
|
||||
if (key.startsWith('enable-')) {
|
||||
final option = await bind.mainGetOption(key: key);
|
||||
bind.mainSetOption(key: key, value: option == "N" ? "" : "N");
|
||||
} else if (key.startsWith('allow-')) {
|
||||
final option = await bind.mainGetOption(key: key);
|
||||
final choice = option == "Y" ? "" : "Y";
|
||||
gFFI.setOption(value, choice);
|
||||
bind.mainSetOption(key: key, value: choice);
|
||||
changeTheme(choice);
|
||||
} else if (value == "stop-service") {
|
||||
final option = gFFI.getOption(value);
|
||||
gFFI.setOption(value, option == "Y" ? "" : "Y");
|
||||
} else if (value == "change-id") {
|
||||
} else if (key == "stop-service") {
|
||||
final option = await bind.mainGetOption(key: key);
|
||||
bind.mainSetOption(key: key, value: option == "Y" ? "" : "Y");
|
||||
} else if (key == "change-id") {
|
||||
changeId();
|
||||
} else if (value == "custom-server") {
|
||||
} else if (key == "custom-server") {
|
||||
changeServer();
|
||||
} else if (value == "whitelist") {
|
||||
} else if (key == "whitelist") {
|
||||
changeWhiteList();
|
||||
} else if (value == "socks5-proxy") {
|
||||
} else if (key == "socks5-proxy") {
|
||||
changeSocks5Proxy();
|
||||
} else if (value == "about") {
|
||||
} else if (key == "about") {
|
||||
about();
|
||||
} else if (value == "logout") {
|
||||
} else if (key == "logout") {
|
||||
logOut();
|
||||
} else if (value == "login") {
|
||||
} else if (key == "login") {
|
||||
login();
|
||||
}
|
||||
}
|
||||
|
||||
PopupMenuItem<String> genEnablePopupMenuItem(String label, String value) {
|
||||
final v = gFFI.getOption(value);
|
||||
final isEnable = value.startsWith('enable-') ? v != "N" : v == "Y";
|
||||
PopupMenuItem<String> genEnablePopupMenuItem(String label, String key) {
|
||||
Future<bool> getOptionEnable(String key) async {
|
||||
final v = await bind.mainGetOption(key: key);
|
||||
return key.startsWith('enable-') ? v != "N" : v == "Y";
|
||||
}
|
||||
|
||||
return PopupMenuItem(
|
||||
child: Row(
|
||||
children: [
|
||||
Offstage(offstage: !isEnable, child: Icon(Icons.check)),
|
||||
Text(
|
||||
label,
|
||||
style: genTextStyle(isEnable),
|
||||
),
|
||||
],
|
||||
),
|
||||
value: value,
|
||||
child: FutureBuilder<bool>(
|
||||
future: getOptionEnable(key),
|
||||
builder: (context, snapshot) {
|
||||
var enable = false;
|
||||
if (snapshot.hasData && snapshot.data!) {
|
||||
enable = true;
|
||||
}
|
||||
return Row(
|
||||
children: [
|
||||
Offstage(offstage: !enable, child: Icon(Icons.check)),
|
||||
Text(
|
||||
label,
|
||||
style: genTextStyle(enable),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
value: key,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -518,10 +528,11 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
color: Colors.redAccent, decoration: TextDecoration.lineThrough);
|
||||
}
|
||||
|
||||
PopupMenuItem<String> genAudioInputPopupMenuItem() {
|
||||
final _enabledInput = gFFI.getOption('enable-audio');
|
||||
var defaultInput = gFFI.getDefaultAudioInput().obs;
|
||||
var enabled = (_enabledInput != "N").obs;
|
||||
PopupMenuItem<String> genAudioInputPopupMenuItem(
|
||||
bool enableInput, String defaultAudioInput) {
|
||||
final defaultInput = defaultAudioInput.obs;
|
||||
final enabled = enableInput.obs;
|
||||
|
||||
return PopupMenuItem(
|
||||
child: FutureBuilder<List<String>>(
|
||||
future: gFFI.getAudioInputs(),
|
||||
@@ -569,12 +580,13 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(translate("Audio Input"))),
|
||||
itemBuilder: (context) => inputList,
|
||||
onSelected: (dev) {
|
||||
onSelected: (dev) async {
|
||||
if (dev == "Mute") {
|
||||
gFFI.setOption(
|
||||
'enable-audio', _enabledInput == 'N' ? '' : 'N');
|
||||
enabled.value = gFFI.getOption('enable-audio') != 'N';
|
||||
} else if (dev != gFFI.getDefaultAudioInput()) {
|
||||
await bind.mainSetOption(
|
||||
key: 'enable-audio', value: enabled.value ? '' : 'N');
|
||||
enabled.value =
|
||||
await bind.mainGetOption(key: 'enable-audio') != 'N';
|
||||
} else if (dev != await gFFI.getDefaultAudioInput()) {
|
||||
gFFI.setDefaultAudioInput(dev);
|
||||
defaultInput.value = dev;
|
||||
}
|
||||
@@ -1322,8 +1334,8 @@ Future<bool> loginDialog() async {
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
void setPasswordDialog() {
|
||||
final pw = gFFI.getByName("permanent_password");
|
||||
void setPasswordDialog() async {
|
||||
final pw = await bind.mainGetPermanentPassword();
|
||||
final p0 = TextEditingController(text: pw);
|
||||
final p1 = TextEditingController(text: pw);
|
||||
var errMsg0 = "";
|
||||
@@ -1413,7 +1425,7 @@ void setPasswordDialog() {
|
||||
});
|
||||
return;
|
||||
}
|
||||
gFFI.setByName("permanent_password", pass);
|
||||
bind.mainSetPermanentPassword(password: pass);
|
||||
close();
|
||||
},
|
||||
child: Text(translate("OK"))),
|
||||
|
||||
@@ -346,8 +346,9 @@ class _RemotePageState extends State<RemotePage>
|
||||
if (dy > 0)
|
||||
dy = -1;
|
||||
else if (dy < 0) dy = 1;
|
||||
_ffi.setByName('send_mouse',
|
||||
'{"id": "${widget.id}", "type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
bind.sessionSendMouse(
|
||||
id: widget.id,
|
||||
msg: '{"type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
}
|
||||
},
|
||||
child: Consumer<FfiModel>(
|
||||
@@ -896,32 +897,6 @@ class ImagePainter extends CustomPainter {
|
||||
}
|
||||
}
|
||||
|
||||
CheckboxListTile getToggle(
|
||||
String id, void Function(void Function()) setState, option, name) {
|
||||
final opt = bind.getSessionToggleOptionSync(id: id, arg: option);
|
||||
return CheckboxListTile(
|
||||
value: opt,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
bind.sessionToggleOption(id: id, value: option);
|
||||
});
|
||||
},
|
||||
dense: true,
|
||||
title: Text(translate(name)));
|
||||
}
|
||||
|
||||
RadioListTile<String> getRadio(String name, String toValue, String curValue,
|
||||
void Function(String?) onChange) {
|
||||
return RadioListTile<String>(
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: Text(translate(name)),
|
||||
value: toValue,
|
||||
groupValue: curValue,
|
||||
onChanged: onChange,
|
||||
dense: true,
|
||||
);
|
||||
}
|
||||
|
||||
void showOptions(String id) async {
|
||||
String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced';
|
||||
if (quality == '') quality = 'balanced';
|
||||
|
||||
@@ -89,7 +89,8 @@ class _PeerCardState extends State<_PeerCard>
|
||||
children: [
|
||||
Expanded(
|
||||
child: FutureBuilder<String>(
|
||||
future: gFFI.getPeerOption(peer.id, 'alias'),
|
||||
future: bind.mainGetPeerOption(
|
||||
id: peer.id, key: 'alias'),
|
||||
builder: (_, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final name = snapshot.data!.isEmpty
|
||||
@@ -186,7 +187,7 @@ class _PeerCardState extends State<_PeerCard>
|
||||
elevation: 8,
|
||||
);
|
||||
if (value == 'remove') {
|
||||
setState(() => gFFI.setByName('remove', '$id'));
|
||||
setState(() => bind.mainRemovePeer(id: id));
|
||||
() async {
|
||||
removePreference(id);
|
||||
}();
|
||||
@@ -304,7 +305,7 @@ class _PeerCardState extends State<_PeerCard>
|
||||
|
||||
void _rename(String id) async {
|
||||
var isInProgress = false;
|
||||
var name = await gFFI.getPeerOption(id, 'alias');
|
||||
var name = await bind.mainGetPeerOption(id: id, key: 'alias');
|
||||
if (widget.type == PeerType.ab) {
|
||||
final peer = gFFI.abModel.peers.firstWhere((p) => id == p['id']);
|
||||
if (peer == null) {
|
||||
@@ -359,7 +360,8 @@ class _PeerCardState extends State<_PeerCard>
|
||||
if (k.currentState != null) {
|
||||
if (k.currentState!.validate()) {
|
||||
k.currentState!.save();
|
||||
await gFFI.setPeerOption(id, 'alias', name);
|
||||
await bind.mainSetPeerOption(
|
||||
id: id, key: 'alias', value: name);
|
||||
if (widget.type == PeerType.ab) {
|
||||
gFFI.abModel.setPeerOption(id, 'alias', name);
|
||||
await gFFI.abModel.updateAb();
|
||||
|
||||
Reference in New Issue
Block a user