flutter_desktop: WOL & menu, mid commit
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
c474ac01cc
commit
a50482af5c
@ -22,10 +22,10 @@ import '../../models/platform_model.dart';
|
|||||||
|
|
||||||
/// Connection page for connecting to a remote peer.
|
/// Connection page for connecting to a remote peer.
|
||||||
class ConnectionPage extends StatefulWidget {
|
class ConnectionPage extends StatefulWidget {
|
||||||
ConnectionPage({Key? key}) : super(key: key);
|
const ConnectionPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ConnectionPageState createState() => _ConnectionPageState();
|
State<ConnectionPage> createState() => _ConnectionPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State for the connection page.
|
/// State for the connection page.
|
||||||
@ -101,7 +101,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
],
|
],
|
||||||
).marginSymmetric(horizontal: 22),
|
).marginSymmetric(horizontal: 22),
|
||||||
),
|
),
|
||||||
Divider(),
|
const Divider(),
|
||||||
SizedBox(height: 50, child: Obx(() => buildStatus()))
|
SizedBox(height: 50, child: Obx(() => buildStatus()))
|
||||||
.paddingSymmetric(horizontal: 12.0)
|
.paddingSymmetric(horizontal: 12.0)
|
||||||
]),
|
]),
|
||||||
|
@ -19,8 +19,15 @@ import 'package:tray_manager/tray_manager.dart';
|
|||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
|
class _PopupMenuTheme {
|
||||||
|
static const Color commonColor = MyTheme.accent;
|
||||||
|
// kMinInteractiveDimension
|
||||||
|
static const double height = 25.0;
|
||||||
|
static const double dividerHeight = 3.0;
|
||||||
|
}
|
||||||
|
|
||||||
class DesktopHomePage extends StatefulWidget {
|
class DesktopHomePage extends StatefulWidget {
|
||||||
DesktopHomePage({Key? key}) : super(key: key);
|
const DesktopHomePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _DesktopHomePageState();
|
State<StatefulWidget> createState() => _DesktopHomePageState();
|
||||||
@ -86,7 +93,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
buildServerBoard(BuildContext context) {
|
buildServerBoard(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
color: MyTheme.color(context).grayBg,
|
color: MyTheme.color(context).grayBg,
|
||||||
child: ConnectionPage(),
|
child: const ConnectionPage(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,8 +161,190 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Future<MenuEntryBase<String>> _genSwitchEntry(
|
||||||
|
// String label, String key) async {
|
||||||
|
|
||||||
|
// final v = await bind.mainGetOption(key: key);
|
||||||
|
// bool enable;
|
||||||
|
// if (key == "stop-service") {
|
||||||
|
// enable = v != "Y";
|
||||||
|
// } else if (key.startsWith("allow-")) {
|
||||||
|
// enable = v == "Y";
|
||||||
|
// } else {
|
||||||
|
// enable = v != "N";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return PopupMenuItem(
|
||||||
|
// child: Row(
|
||||||
|
// children: [
|
||||||
|
// Icon(Icons.check,
|
||||||
|
// color: enable ? null : MyTheme.accent.withAlpha(00)),
|
||||||
|
// Text(
|
||||||
|
// label,
|
||||||
|
// style: genTextStyle(enable),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// value: key,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
_popupMenu(BuildContext context, RelativeRect position) async {
|
||||||
|
TextStyle styleEnabled = const TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: MenuConfig.fontSize,
|
||||||
|
fontWeight: FontWeight.normal);
|
||||||
|
TextStyle styleDisabled = const TextStyle(
|
||||||
|
color: Colors.redAccent,
|
||||||
|
fontSize: MenuConfig.fontSize,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
decoration: TextDecoration.lineThrough);
|
||||||
|
|
||||||
|
enabledEntry(String label, String key) {
|
||||||
|
Rx<TextStyle> textStyle = styleEnabled.obs;
|
||||||
|
return MenuEntrySwitch<String>(
|
||||||
|
text: translate(label),
|
||||||
|
textStyle: textStyle,
|
||||||
|
getter: () async {
|
||||||
|
final opt = await bind.mainGetOption(key: key);
|
||||||
|
bool enabled;
|
||||||
|
if (key == 'stop-service') {
|
||||||
|
enabled = opt != 'Y';
|
||||||
|
} else if (key.startsWith("allow-")) {
|
||||||
|
enabled = opt == 'Y';
|
||||||
|
} else {
|
||||||
|
enabled = opt != 'N';
|
||||||
|
}
|
||||||
|
textStyle.value = enabled ? styleEnabled : styleDisabled;
|
||||||
|
return enabled;
|
||||||
|
},
|
||||||
|
setter: (bool v) async {
|
||||||
|
String opt;
|
||||||
|
if (key == 'stop-service') {
|
||||||
|
opt = v ? 'Y' : '';
|
||||||
|
} else if (key.startsWith("allow-")) {
|
||||||
|
opt = v ? 'Y' : '';
|
||||||
|
} else {
|
||||||
|
opt = v ? '' : 'N';
|
||||||
|
}
|
||||||
|
await bind.mainSetOption(key: key, value: opt);
|
||||||
|
if (key == 'allow-darktheme') {
|
||||||
|
changeTheme(opt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissOnClicked: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final userName = await gFFI.userModel.getUserName();
|
||||||
|
final enabledInput = await bind.mainGetOption(key: 'enable-audio');
|
||||||
|
final defaultInput = await gFFI.getDefaultAudioInput();
|
||||||
|
|
||||||
|
final List<MenuEntryBase<String>> menu = <MenuEntryBase<String>>[
|
||||||
|
enabledEntry('Enable Keyboard/Mouse', 'enable-keyboard'),
|
||||||
|
enabledEntry('Enable Clipboard', 'enable-clipboard'),
|
||||||
|
enabledEntry('Enable File Transfer', 'enable-file-transfer'),
|
||||||
|
enabledEntry('Enable TCP Tunneling', 'enable-tunnel'),
|
||||||
|
// TODO: audio sub menu?
|
||||||
|
// genAudioInputPopupMenuItem(enabledInput != "N", defaultInput),
|
||||||
|
MenuEntryDivider(),
|
||||||
|
MenuEntryButton(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('ID/Relay Server'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
changeServer();
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
),
|
||||||
|
MenuEntryButton(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('IP Whitelisting'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
changeWhiteList();
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
),
|
||||||
|
MenuEntryButton(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('Socks5 Proxy'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
changeSocks5Proxy();
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
),
|
||||||
|
MenuEntryDivider(),
|
||||||
|
enabledEntry('Enable Service', 'stop-service'),
|
||||||
|
enabledEntry('Always connected via relay', 'allow-always-relay'),
|
||||||
|
// FIXME: is this option correct?
|
||||||
|
enabledEntry('Start ID/relay service', 'stop-rendezvous-service'),
|
||||||
|
MenuEntryDivider(),
|
||||||
|
userName.isEmpty
|
||||||
|
? MenuEntryButton(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('Login'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
login();
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
)
|
||||||
|
: MenuEntryButton(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('Logout'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
logOut();
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
),
|
||||||
|
MenuEntryButton(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('Change ID'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
changeId();
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
),
|
||||||
|
MenuEntryDivider(),
|
||||||
|
enabledEntry('Dark Theme', 'allow-darktheme'),
|
||||||
|
MenuEntryButton(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('About'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
about();
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
await mod_menu.showMenu(
|
||||||
|
context: context,
|
||||||
|
position: position,
|
||||||
|
items: menu
|
||||||
|
.map((e) => e.build(
|
||||||
|
context,
|
||||||
|
const MenuConfig(
|
||||||
|
commonColor: _PopupMenuTheme.commonColor,
|
||||||
|
height: _PopupMenuTheme.height,
|
||||||
|
dividerHeight: _PopupMenuTheme.dividerHeight)))
|
||||||
|
.expand((i) => i)
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildPopupMenu(BuildContext context) {
|
Widget buildPopupMenu(BuildContext context) {
|
||||||
var position;
|
RelativeRect position = const RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0);
|
||||||
RxBool hover = false.obs;
|
RxBool hover = false.obs;
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTapDown: (detail) {
|
onTapDown: (detail) {
|
||||||
@ -164,83 +353,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
position = RelativeRect.fromLTRB(x, y, x, y);
|
position = RelativeRect.fromLTRB(x, y, x, y);
|
||||||
},
|
},
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final userName = await gFFI.userModel.getUserName();
|
await _popupMenu(context, position);
|
||||||
final enabledInput = await bind.mainGetOption(key: 'enable-audio');
|
|
||||||
final defaultInput = await gFFI.getDefaultAudioInput();
|
|
||||||
var menu = <PopupMenuEntry>[
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Enable Keyboard/Mouse"),
|
|
||||||
'enable-keyboard',
|
|
||||||
),
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Enable Clipboard"),
|
|
||||||
'enable-clipboard',
|
|
||||||
),
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Enable File Transfer"),
|
|
||||||
'enable-file-transfer',
|
|
||||||
),
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Enable TCP Tunneling"),
|
|
||||||
'enable-tunnel',
|
|
||||||
),
|
|
||||||
genAudioInputPopupMenuItem(enabledInput != "N", defaultInput),
|
|
||||||
PopupMenuDivider(),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Text(translate("ID/Relay Server")),
|
|
||||||
value: 'custom-server',
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Text(translate("IP Whitelisting")),
|
|
||||||
value: 'whitelist',
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Text(translate("Socks5 Proxy")),
|
|
||||||
value: 'socks5-proxy',
|
|
||||||
),
|
|
||||||
PopupMenuDivider(),
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Enable Service"),
|
|
||||||
'stop-service',
|
|
||||||
),
|
|
||||||
// TODO: direct server
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Always connected via relay"),
|
|
||||||
'allow-always-relay',
|
|
||||||
),
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Start ID/relay service"),
|
|
||||||
'stop-rendezvous-service',
|
|
||||||
),
|
|
||||||
PopupMenuDivider(),
|
|
||||||
userName.isEmpty
|
|
||||||
? PopupMenuItem(
|
|
||||||
child: Text(translate("Login")),
|
|
||||||
value: 'login',
|
|
||||||
)
|
|
||||||
: PopupMenuItem(
|
|
||||||
child: Text("${translate("Logout")} $userName"),
|
|
||||||
value: 'logout',
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Text(translate("Change ID")),
|
|
||||||
value: 'change-id',
|
|
||||||
),
|
|
||||||
PopupMenuDivider(),
|
|
||||||
await genEnablePopupMenuItem(
|
|
||||||
translate("Dark Theme"),
|
|
||||||
'allow-darktheme',
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Text(translate("About")),
|
|
||||||
value: 'about',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
final v =
|
|
||||||
await showMenu(context: context, position: position, items: menu);
|
|
||||||
if (v != null) {
|
|
||||||
onSelectMenu(v);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: Obx(
|
child: Obx(
|
||||||
() => CircleAvatar(
|
() => CircleAvatar(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
@ -17,7 +17,7 @@ import '../../models/platform_model.dart';
|
|||||||
enum LocationStatus { bread, textField }
|
enum LocationStatus { bread, textField }
|
||||||
|
|
||||||
class FileManagerPage extends StatefulWidget {
|
class FileManagerPage extends StatefulWidget {
|
||||||
FileManagerPage({Key? key, required this.id}) : super(key: key);
|
const FileManagerPage({Key? key, required this.id}) : super(key: key);
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -21,8 +21,8 @@ class FileManagerTabPage extends StatefulWidget {
|
|||||||
class _FileManagerTabPageState extends State<FileManagerTabPage> {
|
class _FileManagerTabPageState extends State<FileManagerTabPage> {
|
||||||
DesktopTabController get tabController => Get.find<DesktopTabController>();
|
DesktopTabController get tabController => Get.find<DesktopTabController>();
|
||||||
|
|
||||||
static final IconData selectedIcon = Icons.file_copy_sharp;
|
static const IconData selectedIcon = Icons.file_copy_sharp;
|
||||||
static final IconData unselectedIcon = Icons.file_copy_outlined;
|
static const IconData unselectedIcon = Icons.file_copy_outlined;
|
||||||
|
|
||||||
_FileManagerTabPageState(Map<String, dynamic> params) {
|
_FileManagerTabPageState(Map<String, dynamic> params) {
|
||||||
Get.put(DesktopTabController(tabType: DesktopTabType.fileTransfer));
|
Get.put(DesktopTabController(tabType: DesktopTabType.fileTransfer));
|
||||||
|
@ -8,6 +8,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
import 'package:flutter_custom_cursor/flutter_custom_cursor.dart';
|
||||||
|
|
||||||
// import 'package:window_manager/window_manager.dart';
|
// import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ import '../../common/shared_state.dart';
|
|||||||
final initText = '\1' * 1024;
|
final initText = '\1' * 1024;
|
||||||
|
|
||||||
class RemotePage extends StatefulWidget {
|
class RemotePage extends StatefulWidget {
|
||||||
RemotePage({
|
const RemotePage({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.tabBarHeight,
|
required this.tabBarHeight,
|
||||||
@ -32,7 +33,7 @@ class RemotePage extends StatefulWidget {
|
|||||||
final double tabBarHeight;
|
final double tabBarHeight;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_RemotePageState createState() => _RemotePageState();
|
State<RemotePage> createState() => _RemotePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RemotePageState extends State<RemotePage>
|
class _RemotePageState extends State<RemotePage>
|
||||||
@ -483,6 +484,8 @@ class ImagePaint extends StatelessWidget {
|
|||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s),
|
painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
Rx<Offset> pos = Rx<Offset>(Offset(0.0, 0.0));
|
||||||
return Center(
|
return Center(
|
||||||
child: NotificationListener<ScrollNotification>(
|
child: NotificationListener<ScrollNotification>(
|
||||||
onNotification: (notification) {
|
onNotification: (notification) {
|
||||||
@ -498,9 +501,15 @@ class ImagePaint extends StatelessWidget {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: Obx(() => MouseRegion(
|
child: Obx(() => MouseRegion(
|
||||||
cursor: (keyboardEnabled.isTrue && cursorOverImage.isTrue)
|
// cursor: (keyboardEnabled.isTrue && cursorOverImage.isTrue)
|
||||||
? SystemMouseCursors.none
|
// ? SystemMouseCursors.none
|
||||||
: MouseCursor.defer,
|
// : MouseCursor.defer,
|
||||||
|
/// cursor: MouseCursor.defer,
|
||||||
|
cursor: FlutterCustomCursor(
|
||||||
|
path: "assets/pencil.png", x: 1.0, y: 8.0),
|
||||||
|
onHover: (evt) {
|
||||||
|
pos.value = evt.position;
|
||||||
|
},
|
||||||
child: _buildCrossScrollbar(_buildListener(imageWidget)))),
|
child: _buildCrossScrollbar(_buildListener(imageWidget)))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -13,8 +13,10 @@ import '../../models/platform_model.dart';
|
|||||||
import '../../models/server_model.dart';
|
import '../../models/server_model.dart';
|
||||||
|
|
||||||
class DesktopServerPage extends StatefulWidget {
|
class DesktopServerPage extends StatefulWidget {
|
||||||
|
const DesktopServerPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _DesktopServerPageState();
|
State<DesktopServerPage> createState() => _DesktopServerPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DesktopServerPageState extends State<DesktopServerPage>
|
class _DesktopServerPageState extends State<DesktopServerPage>
|
||||||
|
@ -427,7 +427,7 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
icon: Icon(Icons.edit),
|
icon: const Icon(Icons.edit),
|
||||||
onPressed: () => _rdpDialog(id),
|
onPressed: () => _rdpDialog(id),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
@ -440,6 +440,20 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
MenuEntryBase<String> _wolAction(String id) {
|
||||||
|
return MenuEntryButton<String>(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('WOL'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () {
|
||||||
|
bind.mainWol(id: id);
|
||||||
|
},
|
||||||
|
dismissOnClicked: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
Future<MenuEntryBase<String>> _forceAlwaysRelayAction(String id) async {
|
Future<MenuEntryBase<String>> _forceAlwaysRelayAction(String id) async {
|
||||||
const option = 'force-always-relay';
|
const option = 'force-always-relay';
|
||||||
@ -620,11 +634,16 @@ class RecentPeerCard extends BasePeerCard {
|
|||||||
_transferFileAction(context, peer.id),
|
_transferFileAction(context, peer.id),
|
||||||
_tcpTunnelingAction(context, peer.id),
|
_tcpTunnelingAction(context, peer.id),
|
||||||
];
|
];
|
||||||
|
MenuEntryBase<String>? rdpAction;
|
||||||
if (peer.platform == 'Windows') {
|
if (peer.platform == 'Windows') {
|
||||||
menuItems.add(_rdpAction(context, peer.id));
|
rdpAction = _rdpAction(context, peer.id);
|
||||||
}
|
}
|
||||||
menuItems.add(MenuEntryDivider());
|
|
||||||
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
||||||
|
if (rdpAction != null) {
|
||||||
|
menuItems.add(rdpAction);
|
||||||
|
}
|
||||||
|
menuItems.add(_wolAction(peer.id));
|
||||||
|
menuItems.add(MenuEntryDivider());
|
||||||
menuItems.add(_renameAction(peer.id, false));
|
menuItems.add(_renameAction(peer.id, false));
|
||||||
menuItems.add(_removeAction(peer.id, () async {
|
menuItems.add(_removeAction(peer.id, () async {
|
||||||
await bind.mainLoadRecentPeers();
|
await bind.mainLoadRecentPeers();
|
||||||
@ -647,10 +666,16 @@ class FavoritePeerCard extends BasePeerCard {
|
|||||||
_transferFileAction(context, peer.id),
|
_transferFileAction(context, peer.id),
|
||||||
_tcpTunnelingAction(context, peer.id),
|
_tcpTunnelingAction(context, peer.id),
|
||||||
];
|
];
|
||||||
|
MenuEntryBase<String>? rdpAction;
|
||||||
if (peer.platform == 'Windows') {
|
if (peer.platform == 'Windows') {
|
||||||
menuItems.add(_rdpAction(context, peer.id));
|
rdpAction = _rdpAction(context, peer.id);
|
||||||
}
|
}
|
||||||
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
||||||
|
if (rdpAction != null) {
|
||||||
|
menuItems.add(rdpAction);
|
||||||
|
}
|
||||||
|
menuItems.add(_wolAction(peer.id));
|
||||||
|
menuItems.add(MenuEntryDivider());
|
||||||
menuItems.add(_renameAction(peer.id, false));
|
menuItems.add(_renameAction(peer.id, false));
|
||||||
menuItems.add(_removeAction(peer.id, () async {
|
menuItems.add(_removeAction(peer.id, () async {
|
||||||
await bind.mainLoadFavPeers();
|
await bind.mainLoadFavPeers();
|
||||||
@ -673,10 +698,16 @@ class DiscoveredPeerCard extends BasePeerCard {
|
|||||||
_transferFileAction(context, peer.id),
|
_transferFileAction(context, peer.id),
|
||||||
_tcpTunnelingAction(context, peer.id),
|
_tcpTunnelingAction(context, peer.id),
|
||||||
];
|
];
|
||||||
|
MenuEntryBase<String>? rdpAction;
|
||||||
if (peer.platform == 'Windows') {
|
if (peer.platform == 'Windows') {
|
||||||
menuItems.add(_rdpAction(context, peer.id));
|
rdpAction = _rdpAction(context, peer.id);
|
||||||
}
|
}
|
||||||
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
||||||
|
if (rdpAction != null) {
|
||||||
|
menuItems.add(rdpAction);
|
||||||
|
}
|
||||||
|
menuItems.add(_wolAction(peer.id));
|
||||||
|
menuItems.add(MenuEntryDivider());
|
||||||
menuItems.add(_renameAction(peer.id, false));
|
menuItems.add(_renameAction(peer.id, false));
|
||||||
menuItems.add(_removeAction(peer.id, () async {
|
menuItems.add(_removeAction(peer.id, () async {
|
||||||
await bind.mainLoadLanPeers();
|
await bind.mainLoadLanPeers();
|
||||||
@ -698,10 +729,16 @@ class AddressBookPeerCard extends BasePeerCard {
|
|||||||
_transferFileAction(context, peer.id),
|
_transferFileAction(context, peer.id),
|
||||||
_tcpTunnelingAction(context, peer.id),
|
_tcpTunnelingAction(context, peer.id),
|
||||||
];
|
];
|
||||||
|
MenuEntryBase<String>? rdpAction;
|
||||||
if (peer.platform == 'Windows') {
|
if (peer.platform == 'Windows') {
|
||||||
menuItems.add(_rdpAction(context, peer.id));
|
rdpAction = _rdpAction(context, peer.id);
|
||||||
}
|
}
|
||||||
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
menuItems.add(await _forceAlwaysRelayAction(peer.id));
|
||||||
|
if (rdpAction != null) {
|
||||||
|
menuItems.add(rdpAction);
|
||||||
|
}
|
||||||
|
menuItems.add(_wolAction(peer.id));
|
||||||
|
menuItems.add(MenuEntryDivider());
|
||||||
menuItems.add(_renameAction(peer.id, false));
|
menuItems.add(_renameAction(peer.id, false));
|
||||||
menuItems.add(_removeAction(peer.id, () async {}));
|
menuItems.add(_removeAction(peer.id, () async {}));
|
||||||
menuItems.add(_unrememberPasswordAction(peer.id));
|
menuItems.add(_unrememberPasswordAction(peer.id));
|
||||||
|
@ -325,8 +325,10 @@ typedef SwitchSetter = Future<void> Function(bool);
|
|||||||
|
|
||||||
abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
||||||
final String text;
|
final String text;
|
||||||
|
final Rx<TextStyle>? textStyle;
|
||||||
|
|
||||||
MenuEntrySwitchBase({required this.text, required dismissOnClicked})
|
MenuEntrySwitchBase(
|
||||||
|
{required this.text, required dismissOnClicked, this.textStyle})
|
||||||
: super(dismissOnClicked: dismissOnClicked);
|
: super(dismissOnClicked: dismissOnClicked);
|
||||||
|
|
||||||
RxBool get curOption;
|
RxBool get curOption;
|
||||||
@ -344,14 +346,23 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
|||||||
alignment: AlignmentDirectional.centerStart,
|
alignment: AlignmentDirectional.centerStart,
|
||||||
height: conf.height,
|
height: conf.height,
|
||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
// const SizedBox(width: MenuConfig.midPadding),
|
() {
|
||||||
Text(
|
if (textStyle != null) {
|
||||||
text,
|
final style = textStyle!;
|
||||||
style: TextStyle(
|
return Obx(() => Text(
|
||||||
color: MyTheme.color(context).text,
|
text,
|
||||||
fontSize: MenuConfig.fontSize,
|
style: style.value,
|
||||||
fontWeight: FontWeight.normal),
|
));
|
||||||
),
|
} else {
|
||||||
|
return Text(
|
||||||
|
text,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: MenuConfig.fontSize,
|
||||||
|
fontWeight: FontWeight.normal),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}(),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
@ -388,8 +399,12 @@ class MenuEntrySwitch<T> extends MenuEntrySwitchBase<T> {
|
|||||||
{required String text,
|
{required String text,
|
||||||
required this.getter,
|
required this.getter,
|
||||||
required this.setter,
|
required this.setter,
|
||||||
|
Rx<TextStyle>? textStyle,
|
||||||
dismissOnClicked = false})
|
dismissOnClicked = false})
|
||||||
: super(text: text, dismissOnClicked: dismissOnClicked) {
|
: super(
|
||||||
|
text: text,
|
||||||
|
textStyle: textStyle,
|
||||||
|
dismissOnClicked: dismissOnClicked) {
|
||||||
() async {
|
() async {
|
||||||
_curOption.value = await getter();
|
_curOption.value = await getter();
|
||||||
}();
|
}();
|
||||||
@ -418,8 +433,12 @@ class MenuEntrySwitch2<T> extends MenuEntrySwitchBase<T> {
|
|||||||
{required String text,
|
{required String text,
|
||||||
required this.getter,
|
required this.getter,
|
||||||
required this.setter,
|
required this.setter,
|
||||||
|
Rx<TextStyle>? textStyle,
|
||||||
dismissOnClicked = false})
|
dismissOnClicked = false})
|
||||||
: super(text: text, dismissOnClicked: dismissOnClicked);
|
: super(
|
||||||
|
text: text,
|
||||||
|
textStyle: textStyle,
|
||||||
|
dismissOnClicked: dismissOnClicked);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RxBool get curOption => getter();
|
RxBool get curOption => getter();
|
||||||
|
@ -75,20 +75,20 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
final List<Widget> menubarItems = [];
|
final List<Widget> menubarItems = [];
|
||||||
if (!isWebDesktop) {
|
if (!isWebDesktop) {
|
||||||
menubarItems.add(_buildFullscreen(context));
|
menubarItems.add(_buildFullscreen(context));
|
||||||
if (widget.ffi.ffiModel.isPeerAndroid) {
|
//if (widget.ffi.ffiModel.isPeerAndroid) {
|
||||||
menubarItems.add(IconButton(
|
menubarItems.add(IconButton(
|
||||||
tooltip: translate('Mobile Actions'),
|
tooltip: translate('Mobile Actions'),
|
||||||
color: _MenubarTheme.commonColor,
|
color: _MenubarTheme.commonColor,
|
||||||
icon: const Icon(Icons.build),
|
icon: const Icon(Icons.build),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (mobileActionsOverlayEntry == null) {
|
if (mobileActionsOverlayEntry == null) {
|
||||||
showMobileActionsOverlay();
|
showMobileActionsOverlay();
|
||||||
} else {
|
} else {
|
||||||
hideMobileActionsOverlay();
|
hideMobileActionsOverlay();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
menubarItems.add(_buildMonitor(context));
|
menubarItems.add(_buildMonitor(context));
|
||||||
menubarItems.add(_buildControl(context));
|
menubarItems.add(_buildControl(context));
|
||||||
|
@ -68,6 +68,10 @@ dependencies:
|
|||||||
git:
|
git:
|
||||||
url: https://github.com/Kingtous/rustdesk_tray_manager
|
url: https://github.com/Kingtous/rustdesk_tray_manager
|
||||||
ref: 3aa37c86e47ea748e7b5507cbe59f2c54ebdb23a
|
ref: 3aa37c86e47ea748e7b5507cbe59f2c54ebdb23a
|
||||||
|
flutter_custom_cursor:
|
||||||
|
git:
|
||||||
|
url: https://github.com/Kingtous/rustdesk_flutter_custom_cursor
|
||||||
|
ref: 7fe78c139c711bafbae52d924e9caf18bd193e28
|
||||||
get: ^4.6.5
|
get: ^4.6.5
|
||||||
visibility_detector: ^0.3.3
|
visibility_detector: ^0.3.3
|
||||||
contextmenu: ^3.0.0
|
contextmenu: ^3.0.0
|
||||||
|
@ -789,6 +789,10 @@ pub fn main_get_mouse_time() -> f64 {
|
|||||||
get_mouse_time()
|
get_mouse_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn main_wol(id: String) {
|
||||||
|
crate::lan::send_wol(id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cm_send_chat(conn_id: i32, msg: String) {
|
pub fn cm_send_chat(conn_id: i32, msg: String) {
|
||||||
crate::ui_cm_interface::send_chat(conn_id, msg);
|
crate::ui_cm_interface::send_chat(conn_id, msg);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user