2022-07-27 14:29:47 +08:00
|
|
|
import 'dart:async';
|
2022-06-02 16:23:20 +08:00
|
|
|
import 'dart:io';
|
2022-10-09 19:27:30 +08:00
|
|
|
import 'dart:convert';
|
2022-06-02 16:23:20 +08:00
|
|
|
|
2022-11-21 14:06:32 +08:00
|
|
|
import 'package:auto_size_text/auto_size_text.dart';
|
2022-06-02 16:23:20 +08:00
|
|
|
import 'package:flutter/material.dart' hide MenuItem;
|
2022-07-14 12:32:01 +08:00
|
|
|
import 'package:flutter/services.dart';
|
2022-05-25 00:28:59 +08:00
|
|
|
import 'package:flutter_hbb/common.dart';
|
2022-10-26 14:39:13 +08:00
|
|
|
import 'package:flutter_hbb/consts.dart';
|
2022-05-29 04:39:12 +08:00
|
|
|
import 'package:flutter_hbb/desktop/pages/connection_page.dart';
|
2022-09-23 18:28:40 +08:00
|
|
|
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
|
|
|
|
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
2022-09-28 11:20:57 +08:00
|
|
|
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
|
2022-08-03 22:03:31 +08:00
|
|
|
import 'package:flutter_hbb/models/platform_model.dart';
|
2022-08-01 20:42:30 +08:00
|
|
|
import 'package:flutter_hbb/models/server_model.dart';
|
2022-08-09 09:01:06 +08:00
|
|
|
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
2022-11-02 10:22:41 +08:00
|
|
|
import 'package:flutter_hbb/utils/tray_manager.dart';
|
2022-07-14 12:32:01 +08:00
|
|
|
import 'package:get/get.dart';
|
2022-05-25 00:28:59 +08:00
|
|
|
import 'package:provider/provider.dart';
|
2022-06-02 16:23:20 +08:00
|
|
|
import 'package:tray_manager/tray_manager.dart';
|
2022-08-09 13:39:30 +08:00
|
|
|
import 'package:window_manager/window_manager.dart';
|
2022-09-25 21:45:37 +08:00
|
|
|
import 'package:url_launcher/url_launcher.dart';
|
2022-10-09 19:27:30 +08:00
|
|
|
import 'package:window_size/window_size.dart' as window_size;
|
2022-05-23 16:44:23 +08:00
|
|
|
|
2022-09-23 20:18:11 +08:00
|
|
|
import '../widgets/button.dart';
|
|
|
|
|
2022-05-23 16:44:23 +08:00
|
|
|
class DesktopHomePage extends StatefulWidget {
|
2022-09-06 17:08:59 +08:00
|
|
|
const DesktopHomePage({Key? key}) : super(key: key);
|
2022-05-23 16:44:23 +08:00
|
|
|
|
|
|
|
@override
|
2022-09-07 12:20:53 +08:00
|
|
|
State<DesktopHomePage> createState() => _DesktopHomePageState();
|
2022-05-23 16:44:23 +08:00
|
|
|
}
|
|
|
|
|
2022-05-29 19:55:50 +08:00
|
|
|
const borderColor = Color(0xFF2F65BA);
|
|
|
|
|
2022-08-09 20:36:52 +08:00
|
|
|
class _DesktopHomePageState extends State<DesktopHomePage>
|
2022-11-06 17:39:19 +08:00
|
|
|
with TrayListener, AutomaticKeepAliveClientMixin {
|
2022-09-28 11:20:57 +08:00
|
|
|
final _leftPaneScrollController = ScrollController();
|
|
|
|
|
2022-08-13 12:43:35 +08:00
|
|
|
@override
|
|
|
|
bool get wantKeepAlive => true;
|
2022-09-23 17:28:22 +08:00
|
|
|
var updateUrl = '';
|
2022-10-18 10:29:33 +08:00
|
|
|
StreamSubscription? _uniLinksSubscription;
|
2022-08-13 12:43:35 +08:00
|
|
|
|
2022-05-23 16:44:23 +08:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2022-08-20 19:57:16 +08:00
|
|
|
super.build(context);
|
2022-08-11 16:03:04 +08:00
|
|
|
return Row(
|
2022-09-28 11:20:57 +08:00
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
2022-08-11 16:03:04 +08:00
|
|
|
children: [
|
2022-09-19 18:38:19 +08:00
|
|
|
buildLeftPane(context),
|
2022-09-03 18:19:50 +08:00
|
|
|
const VerticalDivider(
|
2022-08-20 19:57:16 +08:00
|
|
|
width: 1,
|
|
|
|
thickness: 1,
|
2022-08-11 16:03:04 +08:00
|
|
|
),
|
2022-08-20 19:57:16 +08:00
|
|
|
Expanded(
|
2022-09-19 18:38:19 +08:00
|
|
|
child: buildRightPane(context),
|
2022-08-11 16:03:04 +08:00
|
|
|
),
|
|
|
|
],
|
2022-05-25 00:28:59 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-28 11:20:57 +08:00
|
|
|
Widget buildLeftPane(BuildContext context) {
|
2022-05-25 00:28:59 +08:00
|
|
|
return ChangeNotifierProvider.value(
|
2022-06-13 21:07:26 +08:00
|
|
|
value: gFFI.serverModel,
|
2022-05-29 10:25:36 +08:00
|
|
|
child: Container(
|
2022-08-20 19:57:16 +08:00
|
|
|
width: 200,
|
2022-09-23 16:31:50 +08:00
|
|
|
color: Theme.of(context).backgroundColor,
|
2022-09-28 11:20:57 +08:00
|
|
|
child: DesktopScrollWrapper(
|
|
|
|
scrollController: _leftPaneScrollController,
|
|
|
|
child: SingleChildScrollView(
|
|
|
|
controller: _leftPaneScrollController,
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
buildTip(context),
|
|
|
|
buildIDBoard(context),
|
|
|
|
buildPasswordBoard(context),
|
|
|
|
buildHelpCards(),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
2022-05-29 10:25:36 +08:00
|
|
|
),
|
2022-05-25 00:28:59 +08:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-19 18:38:19 +08:00
|
|
|
buildRightPane(BuildContext context) {
|
2022-08-20 19:57:16 +08:00
|
|
|
return Container(
|
2022-09-23 16:31:50 +08:00
|
|
|
color: Theme.of(context).scaffoldBackgroundColor,
|
2022-09-07 12:20:53 +08:00
|
|
|
child: ConnectionPage(),
|
2022-05-25 00:28:59 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
buildIDBoard(BuildContext context) {
|
2022-06-13 21:07:26 +08:00
|
|
|
final model = gFFI.serverModel;
|
2022-05-29 10:25:36 +08:00
|
|
|
return Container(
|
2022-09-04 20:57:57 +08:00
|
|
|
margin: const EdgeInsets.only(left: 20, right: 11),
|
|
|
|
height: 57,
|
2022-05-29 10:25:36 +08:00
|
|
|
child: Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
|
|
textBaseline: TextBaseline.alphabetic,
|
|
|
|
children: [
|
|
|
|
Container(
|
2022-08-20 19:57:16 +08:00
|
|
|
width: 2,
|
2022-09-03 18:19:50 +08:00
|
|
|
decoration: const BoxDecoration(color: MyTheme.accent),
|
2022-09-04 20:57:57 +08:00
|
|
|
).marginOnly(top: 5),
|
2022-05-29 10:25:36 +08:00
|
|
|
Expanded(
|
|
|
|
child: Padding(
|
2022-09-04 20:57:57 +08:00
|
|
|
padding: const EdgeInsets.only(left: 7),
|
2022-05-29 10:25:36 +08:00
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
2022-09-07 12:20:53 +08:00
|
|
|
Container(
|
2022-08-24 11:01:58 +08:00
|
|
|
height: 25,
|
2022-08-20 19:57:16 +08:00
|
|
|
child: Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
2022-08-24 11:01:58 +08:00
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
2022-08-20 19:57:16 +08:00
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
translate("ID"),
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 14,
|
2022-09-23 16:31:50 +08:00
|
|
|
color: Theme.of(context)
|
|
|
|
.textTheme
|
|
|
|
.titleLarge
|
|
|
|
?.color
|
|
|
|
?.withOpacity(0.5)),
|
2022-09-04 20:57:57 +08:00
|
|
|
).marginOnly(top: 5),
|
2022-08-20 19:57:16 +08:00
|
|
|
buildPopupMenu(context)
|
|
|
|
],
|
|
|
|
),
|
2022-05-29 10:25:36 +08:00
|
|
|
),
|
2022-08-20 19:57:16 +08:00
|
|
|
Flexible(
|
|
|
|
child: GestureDetector(
|
2022-08-03 09:08:10 +08:00
|
|
|
onDoubleTap: () {
|
|
|
|
Clipboard.setData(
|
|
|
|
ClipboardData(text: model.serverId.text));
|
2022-08-15 14:39:31 +08:00
|
|
|
showToast(translate("Copied"));
|
2022-08-03 09:08:10 +08:00
|
|
|
},
|
|
|
|
child: TextFormField(
|
|
|
|
controller: model.serverId,
|
|
|
|
readOnly: true,
|
2022-09-07 12:20:53 +08:00
|
|
|
decoration: InputDecoration(
|
2022-08-20 19:57:16 +08:00
|
|
|
border: InputBorder.none,
|
2022-09-04 20:57:57 +08:00
|
|
|
contentPadding: EdgeInsets.only(bottom: 20),
|
2022-08-20 19:57:16 +08:00
|
|
|
),
|
2022-09-07 12:20:53 +08:00
|
|
|
style: TextStyle(
|
2022-08-20 19:57:16 +08:00
|
|
|
fontSize: 22,
|
|
|
|
),
|
2022-08-22 17:58:48 +08:00
|
|
|
),
|
2022-08-20 19:57:16 +08:00
|
|
|
),
|
|
|
|
)
|
2022-05-29 10:25:36 +08:00
|
|
|
],
|
|
|
|
),
|
2022-05-25 00:28:59 +08:00
|
|
|
),
|
2022-05-29 10:25:36 +08:00
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-09 20:36:52 +08:00
|
|
|
Widget buildPopupMenu(BuildContext context) {
|
2022-09-23 16:31:50 +08:00
|
|
|
final textColor = Theme.of(context).textTheme.titleLarge?.color;
|
2022-08-20 19:57:16 +08:00
|
|
|
RxBool hover = false.obs;
|
|
|
|
return InkWell(
|
2022-09-23 18:28:40 +08:00
|
|
|
onTap: DesktopTabPage.onAddSetting,
|
2022-08-20 19:57:16 +08:00
|
|
|
child: Obx(
|
2022-08-24 11:01:58 +08:00
|
|
|
() => CircleAvatar(
|
2022-09-04 20:57:57 +08:00
|
|
|
radius: 15,
|
2022-08-24 11:01:58 +08:00
|
|
|
backgroundColor: hover.value
|
2022-09-23 16:31:50 +08:00
|
|
|
? Theme.of(context).scaffoldBackgroundColor
|
|
|
|
: Theme.of(context).backgroundColor,
|
2022-08-24 11:01:58 +08:00
|
|
|
child: Icon(
|
|
|
|
Icons.more_vert_outlined,
|
|
|
|
size: 20,
|
2022-09-23 16:31:50 +08:00
|
|
|
color: hover.value ? textColor : textColor?.withOpacity(0.5),
|
2022-08-20 19:57:16 +08:00
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
onHover: (value) => hover.value = value,
|
|
|
|
);
|
2022-07-27 14:29:47 +08:00
|
|
|
}
|
|
|
|
|
2022-05-29 10:25:36 +08:00
|
|
|
buildPasswordBoard(BuildContext context) {
|
2022-06-13 21:07:26 +08:00
|
|
|
final model = gFFI.serverModel;
|
2022-08-20 19:57:16 +08:00
|
|
|
RxBool refreshHover = false.obs;
|
2022-09-19 18:38:19 +08:00
|
|
|
RxBool editHover = false.obs;
|
2022-09-23 16:31:50 +08:00
|
|
|
final textColor = Theme.of(context).textTheme.titleLarge?.color;
|
2022-05-29 10:25:36 +08:00
|
|
|
return Container(
|
2022-08-22 17:58:48 +08:00
|
|
|
margin: EdgeInsets.only(left: 20.0, right: 16, top: 13, bottom: 13),
|
2022-05-29 10:25:36 +08:00
|
|
|
child: Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
|
|
textBaseline: TextBaseline.alphabetic,
|
|
|
|
children: [
|
|
|
|
Container(
|
2022-08-20 19:57:16 +08:00
|
|
|
width: 2,
|
|
|
|
height: 52,
|
2022-05-29 10:25:36 +08:00
|
|
|
decoration: BoxDecoration(color: MyTheme.accent),
|
|
|
|
),
|
|
|
|
Expanded(
|
|
|
|
child: Padding(
|
2022-09-04 20:57:57 +08:00
|
|
|
padding: const EdgeInsets.only(left: 7),
|
2022-05-29 10:25:36 +08:00
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
2022-11-21 14:06:32 +08:00
|
|
|
AutoSizeText(
|
|
|
|
translate("One-time Password"),
|
2022-08-20 19:57:16 +08:00
|
|
|
style: TextStyle(
|
2022-09-23 16:31:50 +08:00
|
|
|
fontSize: 14, color: textColor?.withOpacity(0.5)),
|
2022-11-21 14:06:32 +08:00
|
|
|
maxLines: 1,
|
2022-05-29 10:25:36 +08:00
|
|
|
),
|
2022-08-01 20:42:30 +08:00
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
Expanded(
|
2022-08-03 09:08:10 +08:00
|
|
|
child: GestureDetector(
|
|
|
|
onDoubleTap: () {
|
2022-08-11 21:29:43 +08:00
|
|
|
if (model.verificationMethod !=
|
|
|
|
kUsePermanentPassword) {
|
|
|
|
Clipboard.setData(
|
|
|
|
ClipboardData(text: model.serverPasswd.text));
|
2022-08-15 14:39:31 +08:00
|
|
|
showToast(translate("Copied"));
|
2022-08-11 21:29:43 +08:00
|
|
|
}
|
2022-08-03 09:08:10 +08:00
|
|
|
},
|
|
|
|
child: TextFormField(
|
|
|
|
controller: model.serverPasswd,
|
|
|
|
readOnly: true,
|
2022-08-20 19:57:16 +08:00
|
|
|
decoration: InputDecoration(
|
|
|
|
border: InputBorder.none,
|
2022-09-04 20:57:57 +08:00
|
|
|
contentPadding: EdgeInsets.only(bottom: 2),
|
2022-08-20 19:57:16 +08:00
|
|
|
),
|
|
|
|
style: TextStyle(fontSize: 15),
|
2022-08-03 09:08:10 +08:00
|
|
|
),
|
2022-08-01 20:42:30 +08:00
|
|
|
),
|
|
|
|
),
|
2022-08-20 19:57:16 +08:00
|
|
|
InkWell(
|
|
|
|
child: Obx(
|
|
|
|
() => Icon(
|
|
|
|
Icons.refresh,
|
|
|
|
color: refreshHover.value
|
2022-09-23 16:31:50 +08:00
|
|
|
? textColor
|
|
|
|
: Color(0xFFDDDDDD), // TODO
|
2022-08-20 19:57:16 +08:00
|
|
|
size: 22,
|
2022-09-04 20:57:57 +08:00
|
|
|
).marginOnly(right: 8, bottom: 2),
|
2022-08-20 19:57:16 +08:00
|
|
|
),
|
|
|
|
onTap: () => bind.mainUpdateTemporaryPassword(),
|
|
|
|
onHover: (value) => refreshHover.value = value,
|
2022-08-01 20:42:30 +08:00
|
|
|
),
|
2022-09-19 18:38:19 +08:00
|
|
|
InkWell(
|
|
|
|
child: Obx(
|
|
|
|
() => Icon(
|
|
|
|
Icons.edit,
|
|
|
|
color: editHover.value
|
2022-09-23 16:31:50 +08:00
|
|
|
? textColor
|
|
|
|
: Color(0xFFDDDDDD), // TODO
|
2022-09-19 18:38:19 +08:00
|
|
|
size: 22,
|
|
|
|
).marginOnly(right: 8, bottom: 2),
|
|
|
|
),
|
2022-09-23 18:28:40 +08:00
|
|
|
onTap: () => DesktopSettingPage.switch2page(1),
|
2022-09-19 18:38:19 +08:00
|
|
|
onHover: (value) => editHover.value = value,
|
|
|
|
),
|
2022-08-01 20:42:30 +08:00
|
|
|
],
|
2022-08-22 17:58:48 +08:00
|
|
|
),
|
2022-05-29 10:25:36 +08:00
|
|
|
],
|
2022-05-25 00:28:59 +08:00
|
|
|
),
|
|
|
|
),
|
2022-05-29 10:25:36 +08:00
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
buildTip(BuildContext context) {
|
|
|
|
return Padding(
|
2022-08-22 17:58:48 +08:00
|
|
|
padding:
|
2022-09-04 20:57:57 +08:00
|
|
|
const EdgeInsets.only(left: 20.0, right: 16, top: 16.0, bottom: 5),
|
2022-05-29 10:25:36 +08:00
|
|
|
child: Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
translate("Your Desktop"),
|
2022-09-23 16:31:50 +08:00
|
|
|
style: Theme.of(context).textTheme.titleLarge,
|
|
|
|
// style: TextStyle(
|
|
|
|
// // color: MyTheme.color(context).text,
|
|
|
|
// fontWeight: FontWeight.normal,
|
|
|
|
// fontSize: 19),
|
2022-05-29 10:25:36 +08:00
|
|
|
),
|
|
|
|
SizedBox(
|
2022-08-22 17:58:48 +08:00
|
|
|
height: 10.0,
|
2022-05-29 10:25:36 +08:00
|
|
|
),
|
|
|
|
Text(
|
|
|
|
translate("desk_tip"),
|
|
|
|
overflow: TextOverflow.clip,
|
2022-09-23 16:31:50 +08:00
|
|
|
style: Theme.of(context).textTheme.bodySmall,
|
2022-05-29 10:25:36 +08:00
|
|
|
)
|
|
|
|
],
|
2022-05-25 00:28:59 +08:00
|
|
|
),
|
|
|
|
);
|
2022-05-23 16:44:23 +08:00
|
|
|
}
|
2022-06-02 16:23:20 +08:00
|
|
|
|
2022-09-23 17:28:22 +08:00
|
|
|
Widget buildHelpCards() {
|
|
|
|
if (Platform.isWindows) {
|
|
|
|
if (!bind.mainIsInstalled()) {
|
2022-09-25 21:45:37 +08:00
|
|
|
return buildInstallCard(
|
|
|
|
"", "install_tip", "Install", bind.mainGotoInstall);
|
2022-09-23 17:28:22 +08:00
|
|
|
} else if (bind.mainIsInstalledLowerVersion()) {
|
2022-09-25 21:45:37 +08:00
|
|
|
return buildInstallCard("Status", "Your installation is lower version.",
|
|
|
|
"Click to upgrade", bind.mainUpdateMe);
|
2022-09-23 17:28:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (updateUrl.isNotEmpty) {
|
2022-09-25 21:45:37 +08:00
|
|
|
return buildInstallCard(
|
|
|
|
"Status",
|
|
|
|
"There is a newer version of ${bind.mainGetAppNameSync()} ${bind.mainGetNewVersion()} available.",
|
|
|
|
"Click to download", () async {
|
|
|
|
final Uri url = Uri.parse('https://rustdesk.com');
|
|
|
|
await launchUrl(url);
|
|
|
|
});
|
2022-09-23 17:28:22 +08:00
|
|
|
}
|
|
|
|
if (Platform.isMacOS) {}
|
|
|
|
if (bind.mainIsInstalledLowerVersion()) {}
|
|
|
|
return Container();
|
|
|
|
}
|
|
|
|
|
2022-09-25 21:45:37 +08:00
|
|
|
Widget buildInstallCard(String title, String content, String btnText,
|
|
|
|
GestureTapCallback onPressed) {
|
2022-09-23 17:28:22 +08:00
|
|
|
return Container(
|
|
|
|
margin: EdgeInsets.only(top: 20),
|
2022-09-23 20:18:11 +08:00
|
|
|
child: Container(
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
gradient: LinearGradient(
|
|
|
|
begin: Alignment.centerLeft,
|
|
|
|
end: Alignment.centerRight,
|
|
|
|
colors: [
|
|
|
|
Color.fromARGB(255, 226, 66, 188),
|
|
|
|
Color.fromARGB(255, 244, 114, 124),
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
padding: EdgeInsets.all(20),
|
|
|
|
child: Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
2022-09-25 21:45:37 +08:00
|
|
|
children: (title.isNotEmpty
|
|
|
|
? <Widget>[
|
|
|
|
Center(
|
|
|
|
child: Text(
|
|
|
|
translate(title),
|
|
|
|
style: TextStyle(
|
|
|
|
color: Colors.white,
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
fontSize: 15),
|
|
|
|
).marginOnly(bottom: 6)),
|
|
|
|
]
|
|
|
|
: <Widget>[]) +
|
|
|
|
<Widget>[
|
|
|
|
Text(
|
|
|
|
translate(content),
|
|
|
|
style: TextStyle(
|
|
|
|
height: 1.5,
|
|
|
|
color: Colors.white,
|
|
|
|
fontWeight: FontWeight.normal,
|
|
|
|
fontSize: 13),
|
|
|
|
).marginOnly(bottom: 20),
|
|
|
|
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
2022-10-24 15:58:24 +08:00
|
|
|
FixedWidthButton(
|
|
|
|
width: 150,
|
2022-09-25 21:45:37 +08:00
|
|
|
padding: 8,
|
|
|
|
isOutline: true,
|
|
|
|
text: translate(btnText),
|
|
|
|
textColor: Colors.white,
|
|
|
|
borderColor: Colors.white,
|
|
|
|
textSize: 20,
|
|
|
|
radius: 10,
|
|
|
|
onTap: onPressed,
|
|
|
|
)
|
|
|
|
]),
|
|
|
|
],
|
2022-09-23 20:18:11 +08:00
|
|
|
)),
|
2022-09-23 17:28:22 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-11-02 10:22:41 +08:00
|
|
|
@override
|
|
|
|
void onTrayIconMouseDown() {
|
|
|
|
windowManager.show();
|
2022-11-02 11:10:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void onTrayIconRightMouseDown() {
|
|
|
|
// linux does not support popup menu manually.
|
|
|
|
// linux will handle popup action ifself.
|
|
|
|
if (Platform.isMacOS || Platform.isWindows) {
|
|
|
|
trayManager.popUpContextMenu();
|
|
|
|
}
|
2022-11-02 10:22:41 +08:00
|
|
|
}
|
|
|
|
|
2022-06-02 16:23:20 +08:00
|
|
|
@override
|
|
|
|
void onTrayMenuItemClick(MenuItem menuItem) {
|
|
|
|
switch (menuItem.key) {
|
2022-11-02 10:22:41 +08:00
|
|
|
case kTrayItemQuitKey:
|
|
|
|
windowManager.close();
|
|
|
|
break;
|
|
|
|
case kTrayItemShowKey:
|
|
|
|
windowManager.show();
|
|
|
|
windowManager.focus();
|
2022-06-02 16:23:20 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
2022-10-30 20:44:33 +08:00
|
|
|
bind.mainStartGrabKeyboard();
|
2022-09-23 17:28:22 +08:00
|
|
|
Timer(const Duration(seconds: 5), () async {
|
|
|
|
updateUrl = await bind.mainGetSoftwareUpdateUrl();
|
|
|
|
if (updateUrl.isNotEmpty) setState(() {});
|
|
|
|
});
|
2022-11-04 19:20:51 +08:00
|
|
|
// disable this tray because we use tray function provided by rust now
|
|
|
|
// initTray();
|
2022-06-02 16:23:20 +08:00
|
|
|
trayManager.addListener(this);
|
2022-11-05 23:41:22 +08:00
|
|
|
rustDeskWinManager.registerActiveWindowListener(onActiveWindowChanged);
|
2022-11-26 11:40:13 +08:00
|
|
|
// main window may be hidden because of the initial uni link or arguments.
|
|
|
|
// note that we must wrap this active window registration in future because
|
|
|
|
// we must ensure the execution is after `windowManager.hide/show()`.
|
|
|
|
Future.delayed(Duration.zero, () {
|
|
|
|
windowManager.isVisible().then((visibility) {
|
|
|
|
if (visibility) {
|
|
|
|
rustDeskWinManager.registerActiveWindow(kWindowMainId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-08-09 09:01:06 +08:00
|
|
|
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
|
2022-09-20 19:31:32 +08:00
|
|
|
debugPrint(
|
2022-11-05 23:41:22 +08:00
|
|
|
"[Main] call ${call.method} with args ${call.arguments} from window $fromWindowId");
|
2022-08-09 09:01:06 +08:00
|
|
|
if (call.method == "main_window_on_top") {
|
2022-08-09 19:32:19 +08:00
|
|
|
window_on_top(null);
|
2022-10-09 19:27:30 +08:00
|
|
|
} else if (call.method == "get_window_info") {
|
|
|
|
final screen = (await window_size.getWindowInfo()).screen;
|
|
|
|
if (screen == null) {
|
|
|
|
return "";
|
|
|
|
} else {
|
|
|
|
return jsonEncode({
|
|
|
|
'frame': {
|
|
|
|
'l': screen.frame.left,
|
|
|
|
't': screen.frame.top,
|
|
|
|
'r': screen.frame.right,
|
|
|
|
'b': screen.frame.bottom,
|
|
|
|
},
|
|
|
|
'visibleFrame': {
|
|
|
|
'l': screen.visibleFrame.left,
|
|
|
|
't': screen.visibleFrame.top,
|
|
|
|
'r': screen.visibleFrame.right,
|
|
|
|
'b': screen.visibleFrame.bottom,
|
|
|
|
},
|
|
|
|
'scaleFactor': screen.scaleFactor,
|
|
|
|
});
|
|
|
|
}
|
2022-10-26 14:39:13 +08:00
|
|
|
} else if (call.method == kWindowActionRebuild) {
|
|
|
|
reloadCurrentWindow();
|
2022-11-05 23:41:22 +08:00
|
|
|
} else if (call.method == kWindowEventShow) {
|
|
|
|
rustDeskWinManager.registerActiveWindow(call.arguments["id"]);
|
|
|
|
} else if (call.method == kWindowEventHide) {
|
|
|
|
rustDeskWinManager.unregisterActiveWindow(call.arguments["id"]);
|
2022-08-09 09:01:06 +08:00
|
|
|
}
|
|
|
|
});
|
2022-10-18 10:29:33 +08:00
|
|
|
_uniLinksSubscription = listenUniLinks();
|
2022-06-02 16:23:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
2022-11-05 23:41:22 +08:00
|
|
|
// destoryTray();
|
2022-11-06 17:39:19 +08:00
|
|
|
// fix: disable unregister to prevent from receiving events from other windows
|
|
|
|
// rustDeskWinManager.unregisterActiveWindowListener(onActiveWindowChanged);
|
2022-06-02 16:23:20 +08:00
|
|
|
trayManager.removeListener(this);
|
2022-10-18 10:29:33 +08:00
|
|
|
_uniLinksSubscription?.cancel();
|
2022-06-02 16:23:20 +08:00
|
|
|
super.dispose();
|
|
|
|
}
|
2022-05-23 16:44:23 +08:00
|
|
|
}
|
2022-07-27 14:29:47 +08:00
|
|
|
|
2022-08-08 22:27:27 +08:00
|
|
|
void setPasswordDialog() async {
|
|
|
|
final pw = await bind.mainGetPermanentPassword();
|
2022-08-01 20:42:30 +08:00
|
|
|
final p0 = TextEditingController(text: pw);
|
|
|
|
final p1 = TextEditingController(text: pw);
|
|
|
|
var errMsg0 = "";
|
|
|
|
var errMsg1 = "";
|
|
|
|
|
2022-08-12 18:42:02 +08:00
|
|
|
gFFI.dialogManager.show((setState, close) {
|
2022-09-03 18:19:50 +08:00
|
|
|
submit() {
|
|
|
|
setState(() {
|
|
|
|
errMsg0 = "";
|
|
|
|
errMsg1 = "";
|
|
|
|
});
|
|
|
|
final pass = p0.text.trim();
|
2022-11-21 16:37:15 +08:00
|
|
|
if (pass.length < 6 && pass.isNotEmpty) {
|
2022-09-03 18:19:50 +08:00
|
|
|
setState(() {
|
|
|
|
errMsg0 = translate("Too short, at least 6 characters.");
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (p1.text.trim() != pass) {
|
|
|
|
setState(() {
|
|
|
|
errMsg1 = translate("The confirmation is not identical.");
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
bind.mainSetPermanentPassword(password: pass);
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
2022-08-01 20:42:30 +08:00
|
|
|
return CustomAlertDialog(
|
|
|
|
title: Text(translate("Set Password")),
|
|
|
|
content: ConstrainedBox(
|
2022-09-03 18:19:50 +08:00
|
|
|
constraints: const BoxConstraints(minWidth: 500),
|
2022-08-01 20:42:30 +08:00
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
2022-09-03 18:19:50 +08:00
|
|
|
const SizedBox(
|
2022-08-01 20:42:30 +08:00
|
|
|
height: 8.0,
|
|
|
|
),
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
ConstrainedBox(
|
2022-09-03 18:19:50 +08:00
|
|
|
constraints: const BoxConstraints(minWidth: 100),
|
2022-08-01 20:42:30 +08:00
|
|
|
child: Text(
|
|
|
|
"${translate('Password')}:",
|
|
|
|
textAlign: TextAlign.start,
|
|
|
|
).marginOnly(bottom: 16.0)),
|
2022-09-03 18:19:50 +08:00
|
|
|
const SizedBox(
|
2022-08-01 20:42:30 +08:00
|
|
|
width: 24.0,
|
|
|
|
),
|
|
|
|
Expanded(
|
|
|
|
child: TextField(
|
|
|
|
obscureText: true,
|
|
|
|
decoration: InputDecoration(
|
2022-09-03 18:19:50 +08:00
|
|
|
border: const OutlineInputBorder(),
|
2022-08-01 20:42:30 +08:00
|
|
|
errorText: errMsg0.isNotEmpty ? errMsg0 : null),
|
|
|
|
controller: p0,
|
2022-09-03 18:19:50 +08:00
|
|
|
focusNode: FocusNode()..requestFocus(),
|
2022-08-01 20:42:30 +08:00
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
2022-09-03 18:19:50 +08:00
|
|
|
const SizedBox(
|
2022-08-01 20:42:30 +08:00
|
|
|
height: 8.0,
|
|
|
|
),
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
ConstrainedBox(
|
2022-09-03 18:19:50 +08:00
|
|
|
constraints: const BoxConstraints(minWidth: 100),
|
2022-08-01 20:42:30 +08:00
|
|
|
child: Text("${translate('Confirmation')}:")
|
|
|
|
.marginOnly(bottom: 16.0)),
|
2022-09-03 18:19:50 +08:00
|
|
|
const SizedBox(
|
2022-08-01 20:42:30 +08:00
|
|
|
width: 24.0,
|
|
|
|
),
|
|
|
|
Expanded(
|
|
|
|
child: TextField(
|
|
|
|
obscureText: true,
|
|
|
|
decoration: InputDecoration(
|
2022-09-03 18:19:50 +08:00
|
|
|
border: const OutlineInputBorder(),
|
2022-08-01 20:42:30 +08:00
|
|
|
errorText: errMsg1.isNotEmpty ? errMsg1 : null),
|
|
|
|
controller: p1,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
actions: [
|
2022-09-03 18:19:50 +08:00
|
|
|
TextButton(onPressed: close, child: Text(translate("Cancel"))),
|
|
|
|
TextButton(onPressed: submit, child: Text(translate("OK"))),
|
2022-08-01 20:42:30 +08:00
|
|
|
],
|
2022-09-03 18:19:50 +08:00
|
|
|
onSubmit: submit,
|
|
|
|
onCancel: close,
|
2022-08-01 20:42:30 +08:00
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|