commit
1c170366e7
@ -24,7 +24,5 @@ void main(List<String> args) async {
|
|||||||
gFFI.serverModel.clients
|
gFFI.serverModel.clients
|
||||||
.add(Client(3, false, false, "UserD", "441123123", true, false, false));
|
.add(Client(3, false, false, "UserD", "441123123", true, false, false));
|
||||||
runApp(GetMaterialApp(
|
runApp(GetMaterialApp(
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false, home: DesktopServerPage()));
|
||||||
theme: getCurrentTheme(),
|
|
||||||
home: DesktopServerPage()));
|
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ var isWeb = false;
|
|||||||
var isWebDesktop = false;
|
var isWebDesktop = false;
|
||||||
var version = "";
|
var version = "";
|
||||||
int androidVersion = 0;
|
int androidVersion = 0;
|
||||||
|
late final DesktopType? desktopType;
|
||||||
|
|
||||||
typedef F = String Function(String);
|
typedef F = String Function(String);
|
||||||
typedef FMethod = String Function(String, dynamic);
|
typedef FMethod = String Function(String, dynamic);
|
||||||
@ -42,6 +43,15 @@ late final iconFile = MemoryImage(Uint8List.fromList(base64Decode(
|
|||||||
late final iconRestart = MemoryImage(Uint8List.fromList(base64Decode(
|
late final iconRestart = MemoryImage(Uint8List.fromList(base64Decode(
|
||||||
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAB7BAAAewQHDaVRTAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAbhJREFUWIXVlrFqFGEUhb+7UYxaWCQKlrKKxaZSQVGDJih2tj6MD2DnMwiWvoAIRnENIpZiYxEro6IooiS7SPwsMgNLkk3mjmYmnmb45/73nMNwz/x/qH3gMu2gH6rAU+Blw+Lngau4jpmGxVF7qp1iPWjaQKnZ2WnXbuP/NqAeUPc3ZkA9XDwvqc+BVWCgPlJ7tRwUKThZce819b46VH+pfXVRXVO/q2cSul3VOgZUl0ejq86r39TXI8mqZKDuDEwCw3IREQvAbWAGmMsQZQ0sAl3gHPB1Q+0e8BuYzRDuy2yOiFVgaUxtRf0ETGc4syk4rc6PqU0Cx9j8Zf6dAeAK8Fi9sUXtFjABvEgxJlNwRP2svlNPjbw/q35U36oTFbnyMSwabxb/gB/qA3VBHagrauV7RW0DRfP1IvMlXqkXkhz1DYyQTKtHa/Z2VVMx3IiI+PI3/bCHjuOpFrSnAMpL6QfgTcMGesDx0kBr2BMzsNyi/vtQu8CJlgwsRbZDnWP90NkKaxHxJMOXMqAeAn5u0ydwMCKGY+qbkB3C2W3EKWoXk5zVoHbUZ+6Mh7tl4G4F8RJ3qvL+AfV3r5Vdpj70AAAAAElFTkSuQmCC')));
|
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAB7BAAAewQHDaVRTAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAbhJREFUWIXVlrFqFGEUhb+7UYxaWCQKlrKKxaZSQVGDJih2tj6MD2DnMwiWvoAIRnENIpZiYxEro6IooiS7SPwsMgNLkk3mjmYmnmb45/73nMNwz/x/qH3gMu2gH6rAU+Blw+Lngau4jpmGxVF7qp1iPWjaQKnZ2WnXbuP/NqAeUPc3ZkA9XDwvqc+BVWCgPlJ7tRwUKThZce819b46VH+pfXVRXVO/q2cSul3VOgZUl0ejq86r39TXI8mqZKDuDEwCw3IREQvAbWAGmMsQZQ0sAl3gHPB1Q+0e8BuYzRDuy2yOiFVgaUxtRf0ETGc4syk4rc6PqU0Cx9j8Zf6dAeAK8Fi9sUXtFjABvEgxJlNwRP2svlNPjbw/q35U36oTFbnyMSwabxb/gB/qA3VBHagrauV7RW0DRfP1IvMlXqkXkhz1DYyQTKtHa/Z2VVMx3IiI+PI3/bCHjuOpFrSnAMpL6QfgTcMGesDx0kBr2BMzsNyi/vtQu8CJlgwsRbZDnWP90NkKaxHxJMOXMqAeAn5u0ydwMCKGY+qbkB3C2W3EKWoXk5zVoHbUZ+6Mh7tl4G4F8RJ3qvL+AfV3r5Vdpj70AAAAAElFTkSuQmCC')));
|
||||||
|
|
||||||
|
enum DesktopType {
|
||||||
|
main,
|
||||||
|
remote,
|
||||||
|
fileTransfer,
|
||||||
|
cm,
|
||||||
|
portForward,
|
||||||
|
rdp,
|
||||||
|
}
|
||||||
|
|
||||||
class IconFont {
|
class IconFont {
|
||||||
static const _family1 = 'Tabbar';
|
static const _family1 = 'Tabbar';
|
||||||
static const _family2 = 'PeerSearchbar';
|
static const _family2 = 'PeerSearchbar';
|
||||||
@ -182,6 +192,32 @@ class MyTheme {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static changeTo(bool dark) {
|
||||||
|
if (Get.isDarkMode != dark) {
|
||||||
|
Get.find<SharedPreferences>().setString("darkTheme", dark ? "Y" : "");
|
||||||
|
Get.changeThemeMode(dark ? ThemeMode.dark : ThemeMode.light);
|
||||||
|
if (desktopType == DesktopType.main) {
|
||||||
|
bind.mainChangeTheme(dark: dark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _themeInitialed = false;
|
||||||
|
|
||||||
|
static ThemeMode initialThemeMode({bool mainPage = false}) {
|
||||||
|
bool dark;
|
||||||
|
// Brightnesss is always light on windows, Flutter 3.0.5
|
||||||
|
if (_themeInitialed || !mainPage || Platform.isWindows) {
|
||||||
|
dark = "Y" == Get.find<SharedPreferences>().getString("darkTheme");
|
||||||
|
} else {
|
||||||
|
dark = WidgetsBinding.instance.platformDispatcher.platformBrightness ==
|
||||||
|
Brightness.dark;
|
||||||
|
Get.find<SharedPreferences>().setString("darkTheme", dark ? "Y" : "");
|
||||||
|
}
|
||||||
|
_themeInitialed = true;
|
||||||
|
return dark ? ThemeMode.dark : ThemeMode.light;
|
||||||
|
}
|
||||||
|
|
||||||
static ColorThemeExtension color(BuildContext context) {
|
static ColorThemeExtension color(BuildContext context) {
|
||||||
return Theme.of(context).extension<ColorThemeExtension>()!;
|
return Theme.of(context).extension<ColorThemeExtension>()!;
|
||||||
}
|
}
|
||||||
@ -192,8 +228,7 @@ class MyTheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isDarkTheme() {
|
bool isDarkTheme() {
|
||||||
final isDark = "Y" == Get.find<SharedPreferences>().getString("darkTheme");
|
return Get.isDarkMode;
|
||||||
return isDark;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final ButtonStyle flatButtonStyle = TextButton.styleFrom(
|
final ButtonStyle flatButtonStyle = TextButton.styleFrom(
|
||||||
@ -478,7 +513,9 @@ void msgBox(
|
|||||||
submit() {
|
submit() {
|
||||||
dialogManager.dismissAll();
|
dialogManager.dismissAll();
|
||||||
// https://github.com/fufesou/rustdesk/blob/5e9a31340b899822090a3731769ae79c6bf5f3e5/src/ui/common.tis#L263
|
// https://github.com/fufesou/rustdesk/blob/5e9a31340b899822090a3731769ae79c6bf5f3e5/src/ui/common.tis#L263
|
||||||
if (!type.contains("custom")) {
|
if (!type.contains("custom") &&
|
||||||
|
!(desktopType == DesktopType.portForward ||
|
||||||
|
desktopType == DesktopType.rdp)) {
|
||||||
closeConnection();
|
closeConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ const String kAppTypeMain = "main";
|
|||||||
const String kAppTypeDesktopRemote = "remote";
|
const String kAppTypeDesktopRemote = "remote";
|
||||||
const String kAppTypeDesktopFileTransfer = "file transfer";
|
const String kAppTypeDesktopFileTransfer = "file transfer";
|
||||||
const String kAppTypeDesktopPortForward = "port forward";
|
const String kAppTypeDesktopPortForward = "port forward";
|
||||||
|
const String kAppTypeDesktopRDP = "rdp";
|
||||||
|
|
||||||
const String kTabLabelHomePage = "Home";
|
const String kTabLabelHomePage = "Home";
|
||||||
const String kTabLabelSettingPage = "Settings";
|
const String kTabLabelSettingPage = "Settings";
|
||||||
|
|
||||||
|
@ -218,27 +218,25 @@ class _UserInterfaceState extends State<_UserInterface>
|
|||||||
onChanged: (key) async {
|
onChanged: (key) async {
|
||||||
await bind.mainSetLocalOption(key: "lang", value: key);
|
await bind.mainSetLocalOption(key: "lang", value: key);
|
||||||
Get.forceAppUpdate();
|
Get.forceAppUpdate();
|
||||||
|
bind.mainChangeLanguage(lang: key);
|
||||||
},
|
},
|
||||||
).marginOnly(left: _kContentHMargin);
|
).marginOnly(left: _kContentHMargin);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget theme() {
|
Widget theme() {
|
||||||
var change = () {
|
change() {
|
||||||
bool dark = !isDarkTheme();
|
MyTheme.changeTo(!isDarkTheme());
|
||||||
Get.changeTheme(dark ? MyTheme.darkTheme : MyTheme.lightTheme);
|
}
|
||||||
Get.find<SharedPreferences>().setString("darkTheme", dark ? "Y" : "");
|
|
||||||
Get.forceAppUpdate();
|
|
||||||
};
|
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
onTap: change,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Checkbox(value: isDarkTheme(), onChanged: (_) => change()),
|
Checkbox(value: isDarkTheme(), onChanged: (_) => change()),
|
||||||
Expanded(child: Text(translate('Dark Theme'))),
|
Expanded(child: Text(translate('Dark Theme'))),
|
||||||
],
|
],
|
||||||
).marginOnly(left: _kCheckBoxLeftMargin),
|
).marginOnly(left: _kCheckBoxLeftMargin),
|
||||||
onTap: change,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ class _DesktopTabPageState extends State<DesktopTabPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final dark = isDarkTheme();
|
|
||||||
RxBool fullscreen = false.obs;
|
RxBool fullscreen = false.obs;
|
||||||
Get.put(fullscreen, tag: 'fullscreen');
|
Get.put(fullscreen, tag: 'fullscreen');
|
||||||
return Obx(() => DragToResizeArea(
|
return Obx(() => DragToResizeArea(
|
||||||
|
@ -70,45 +70,38 @@ class _PortForwardPageState extends State<PortForwardPage>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
return Overlay(initialEntries: [
|
return Scaffold(
|
||||||
OverlayEntry(builder: (context) {
|
backgroundColor: MyTheme.color(context).grayBg,
|
||||||
_ffi.dialogManager.setOverlayState(Overlay.of(context));
|
body: FutureBuilder(future: () async {
|
||||||
return Scaffold(
|
if (!isRdp) {
|
||||||
backgroundColor: MyTheme.color(context).grayBg,
|
refreshTunnelConfig();
|
||||||
body: FutureBuilder(future: () async {
|
}
|
||||||
if (!isRdp) {
|
}(), builder: (context, snapshot) {
|
||||||
refreshTunnelConfig();
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
}
|
return Container(
|
||||||
}(), builder: (context, snapshot) {
|
decoration: BoxDecoration(
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
border: Border.all(
|
||||||
return Container(
|
width: 20, color: MyTheme.color(context).grayBg!)),
|
||||||
decoration: BoxDecoration(
|
child: Column(
|
||||||
border: Border.all(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
width: 20, color: MyTheme.color(context).grayBg!)),
|
children: [
|
||||||
child: Column(
|
buildPrompt(context),
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
Flexible(
|
||||||
children: [
|
child: Container(
|
||||||
buildPrompt(context),
|
decoration: BoxDecoration(
|
||||||
Flexible(
|
color: MyTheme.color(context).bg,
|
||||||
child: Container(
|
border: Border.all(width: 1, color: MyTheme.border)),
|
||||||
decoration: BoxDecoration(
|
child:
|
||||||
color: MyTheme.color(context).bg,
|
widget.isRDP ? buildRdp(context) : buildTunnel(context),
|
||||||
border:
|
),
|
||||||
Border.all(width: 1, color: MyTheme.border)),
|
|
||||||
child: widget.isRDP
|
|
||||||
? buildRdp(context)
|
|
||||||
: buildTunnel(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
],
|
||||||
}
|
),
|
||||||
return const Offstage();
|
);
|
||||||
}),
|
}
|
||||||
);
|
return const Offstage();
|
||||||
})
|
}),
|
||||||
]);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildPrompt(BuildContext context) {
|
buildPrompt(BuildContext context) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
||||||
import 'package:flutter_hbb/mobile/pages/chat_page.dart';
|
import 'package:flutter_hbb/mobile/pages/chat_page.dart';
|
||||||
import 'package:flutter_hbb/models/chat_model.dart';
|
import 'package:flutter_hbb/models/chat_model.dart';
|
||||||
@ -63,20 +64,15 @@ class _DesktopServerPageState extends State<DesktopServerPage>
|
|||||||
border: Border.all(color: MyTheme.color(context).border!)),
|
border: Border.all(color: MyTheme.color(context).border!)),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: MyTheme.color(context).bg,
|
backgroundColor: MyTheme.color(context).bg,
|
||||||
body: Overlay(initialEntries: [
|
body: Center(
|
||||||
OverlayEntry(builder: (context) {
|
child: Column(
|
||||||
gFFI.dialogManager.setOverlayState(Overlay.of(context));
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
return Center(
|
children: [
|
||||||
child: Column(
|
Expanded(child: ConnectionManager()),
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
SizedBox.fromSize(size: Size(0, 15.0)),
|
||||||
children: [
|
],
|
||||||
Expanded(child: ConnectionManager()),
|
),
|
||||||
SizedBox.fromSize(size: Size(0, 15.0)),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
})
|
|
||||||
]),
|
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +107,7 @@ class ConnectionManagerState extends State<ConnectionManager> {
|
|||||||
return serverModel.clients.isEmpty
|
return serverModel.clients.isEmpty
|
||||||
? Column(
|
? Column(
|
||||||
children: [
|
children: [
|
||||||
buildTitleBar(Offstage()),
|
buildTitleBar(),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(translate("Waiting")),
|
child: Text(translate("Waiting")),
|
||||||
@ -134,20 +130,27 @@ class ConnectionManagerState extends State<ConnectionManager> {
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildTitleBar(Widget middle) {
|
Widget buildTitleBar() {
|
||||||
return GestureDetector(
|
return SizedBox(
|
||||||
onPanDown: (d) {
|
height: kDesktopRemoteTabBarHeight,
|
||||||
windowManager.startDragging();
|
|
||||||
},
|
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_AppIcon(),
|
const _AppIcon(),
|
||||||
Expanded(child: middle),
|
Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onPanStart: (d) {
|
||||||
|
windowManager.startDragging();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: MyTheme.color(context).bg,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 4.0,
|
width: 4.0,
|
||||||
),
|
),
|
||||||
_CloseButton()
|
const _CloseButton()
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -209,15 +212,16 @@ class _CloseButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Ink(
|
return IconButton(
|
||||||
child: InkWell(
|
onPressed: () {
|
||||||
onTap: () {
|
windowManager.close();
|
||||||
windowManager.close();
|
},
|
||||||
},
|
icon: const Icon(
|
||||||
child: Icon(
|
IconFont.close,
|
||||||
Icons.close,
|
size: 18,
|
||||||
size: 30,
|
),
|
||||||
)),
|
splashColor: Colors.transparent,
|
||||||
|
hoverColor: Colors.transparent,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,12 +43,16 @@ Future<Null> main(List<String> args) async {
|
|||||||
WindowType wType = type.windowType;
|
WindowType wType = type.windowType;
|
||||||
switch (wType) {
|
switch (wType) {
|
||||||
case WindowType.RemoteDesktop:
|
case WindowType.RemoteDesktop:
|
||||||
|
desktopType = DesktopType.remote;
|
||||||
runRemoteScreen(argument);
|
runRemoteScreen(argument);
|
||||||
break;
|
break;
|
||||||
case WindowType.FileTransfer:
|
case WindowType.FileTransfer:
|
||||||
|
desktopType = DesktopType.fileTransfer;
|
||||||
runFileTransferScreen(argument);
|
runFileTransferScreen(argument);
|
||||||
break;
|
break;
|
||||||
case WindowType.PortForward:
|
case WindowType.PortForward:
|
||||||
|
desktopType =
|
||||||
|
argument['isRDP'] ? DesktopType.rdp : DesktopType.portForward;
|
||||||
runPortForwardScreen(argument);
|
runPortForwardScreen(argument);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -56,19 +60,17 @@ Future<Null> main(List<String> args) async {
|
|||||||
}
|
}
|
||||||
} else if (args.isNotEmpty && args.first == '--cm') {
|
} else if (args.isNotEmpty && args.first == '--cm') {
|
||||||
print("--cm started");
|
print("--cm started");
|
||||||
|
desktopType = DesktopType.cm;
|
||||||
await windowManager.ensureInitialized();
|
await windowManager.ensureInitialized();
|
||||||
runConnectionManagerScreen();
|
runConnectionManagerScreen();
|
||||||
} else {
|
} else {
|
||||||
|
desktopType = DesktopType.main;
|
||||||
await windowManager.ensureInitialized();
|
await windowManager.ensureInitialized();
|
||||||
windowManager.setPreventClose(true);
|
windowManager.setPreventClose(true);
|
||||||
runMainApp(true);
|
runMainApp(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeData getCurrentTheme() {
|
|
||||||
return isDarkTheme() ? MyTheme.darkTheme : MyTheme.lightTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> initEnv(String appType) async {
|
Future<void> initEnv(String appType) async {
|
||||||
await platformFFI.init(appType);
|
await platformFFI.init(appType);
|
||||||
// global FFI, use this **ONLY** for global configuration
|
// global FFI, use this **ONLY** for global configuration
|
||||||
@ -77,6 +79,7 @@ Future<void> initEnv(String appType) async {
|
|||||||
await initGlobalFFI();
|
await initGlobalFFI();
|
||||||
// await Firebase.initializeApp();
|
// await Firebase.initializeApp();
|
||||||
refreshCurrentUser();
|
refreshCurrentUser();
|
||||||
|
_registerEventHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void runMainApp(bool startService) async {
|
void runMainApp(bool startService) async {
|
||||||
@ -111,7 +114,9 @@ void runRemoteScreen(Map<String, dynamic> argument) async {
|
|||||||
navigatorKey: globalKey,
|
navigatorKey: globalKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'RustDesk - Remote Desktop',
|
title: 'RustDesk - Remote Desktop',
|
||||||
theme: getCurrentTheme(),
|
theme: MyTheme.lightTheme,
|
||||||
|
darkTheme: MyTheme.darkTheme,
|
||||||
|
themeMode: MyTheme.initialThemeMode(),
|
||||||
home: DesktopRemoteScreen(
|
home: DesktopRemoteScreen(
|
||||||
params: argument,
|
params: argument,
|
||||||
),
|
),
|
||||||
@ -129,7 +134,9 @@ void runFileTransferScreen(Map<String, dynamic> argument) async {
|
|||||||
navigatorKey: globalKey,
|
navigatorKey: globalKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'RustDesk - File Transfer',
|
title: 'RustDesk - File Transfer',
|
||||||
theme: getCurrentTheme(),
|
theme: MyTheme.lightTheme,
|
||||||
|
darkTheme: MyTheme.darkTheme,
|
||||||
|
themeMode: MyTheme.initialThemeMode(),
|
||||||
home: DesktopFileTransferScreen(params: argument),
|
home: DesktopFileTransferScreen(params: argument),
|
||||||
navigatorObservers: [
|
navigatorObservers: [
|
||||||
// FirebaseAnalyticsObserver(analytics: analytics),
|
// FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
@ -146,7 +153,9 @@ void runPortForwardScreen(Map<String, dynamic> argument) async {
|
|||||||
navigatorKey: globalKey,
|
navigatorKey: globalKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'RustDesk - Port Forward',
|
title: 'RustDesk - Port Forward',
|
||||||
theme: getCurrentTheme(),
|
theme: MyTheme.lightTheme,
|
||||||
|
darkTheme: MyTheme.darkTheme,
|
||||||
|
themeMode: MyTheme.initialThemeMode(),
|
||||||
home: DesktopPortForwardScreen(params: argument),
|
home: DesktopPortForwardScreen(params: argument),
|
||||||
navigatorObservers: [
|
navigatorObservers: [
|
||||||
// FirebaseAnalyticsObserver(analytics: analytics),
|
// FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
@ -170,7 +179,9 @@ void runConnectionManagerScreen() async {
|
|||||||
]);
|
]);
|
||||||
runApp(GetMaterialApp(
|
runApp(GetMaterialApp(
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: getCurrentTheme(),
|
theme: MyTheme.lightTheme,
|
||||||
|
darkTheme: MyTheme.darkTheme,
|
||||||
|
themeMode: MyTheme.initialThemeMode(),
|
||||||
home: DesktopServerPage(),
|
home: DesktopServerPage(),
|
||||||
builder: _keepScaleBuilder()));
|
builder: _keepScaleBuilder()));
|
||||||
}
|
}
|
||||||
@ -185,7 +196,26 @@ WindowOptions getHiddenTitleBarWindowOptions(Size size) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<App> createState() => _AppState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppState extends State<App> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.window.onPlatformBrightnessChanged = () {
|
||||||
|
WidgetsBinding.instance.handlePlatformBrightnessChanged();
|
||||||
|
var system =
|
||||||
|
WidgetsBinding.instance.platformDispatcher.platformBrightness;
|
||||||
|
var current = isDarkTheme() ? Brightness.dark : Brightness.light;
|
||||||
|
if (current != system) {
|
||||||
|
MyTheme.changeTo(system == Brightness.dark);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// final analytics = FirebaseAnalytics.instance;
|
// final analytics = FirebaseAnalytics.instance;
|
||||||
@ -204,7 +234,9 @@ class App extends StatelessWidget {
|
|||||||
navigatorKey: globalKey,
|
navigatorKey: globalKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'RustDesk',
|
title: 'RustDesk',
|
||||||
theme: getCurrentTheme(),
|
theme: MyTheme.lightTheme,
|
||||||
|
darkTheme: MyTheme.darkTheme,
|
||||||
|
themeMode: MyTheme.initialThemeMode(mainPage: true),
|
||||||
home: isDesktop
|
home: isDesktop
|
||||||
? const DesktopTabPage()
|
? const DesktopTabPage()
|
||||||
: !isAndroid
|
: !isAndroid
|
||||||
@ -238,3 +270,17 @@ _keepScaleBuilder() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_registerEventHandler() {
|
||||||
|
if (desktopType != DesktopType.main) {
|
||||||
|
platformFFI.registerEventHandler('theme', 'theme', (evt) {
|
||||||
|
String? dark = evt['dark'];
|
||||||
|
if (dark != null) {
|
||||||
|
MyTheme.changeTo(dark == 'true');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
platformFFI.registerEventHandler('language', 'language', (_) {
|
||||||
|
Get.forceAppUpdate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include "my_application.h"
|
#include "my_application.h"
|
||||||
|
|
||||||
#define RUSTDESK_LIB_PATH "ibrustdesk.so"
|
#define RUSTDESK_LIB_PATH "librustdesk.so"
|
||||||
// #define RUSTDESK_LIB_PATH "/usr/lib/rustdesk/librustdesk.so"
|
// #define RUSTDESK_LIB_PATH "/usr/lib/rustdesk/librustdesk.so"
|
||||||
typedef bool (*RustDeskCoreMain)();
|
typedef bool (*RustDeskCoreMain)();
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ use crate::{client::*, flutter_ffi::EventToUI};
|
|||||||
pub(super) const APP_TYPE_MAIN: &str = "main";
|
pub(super) const APP_TYPE_MAIN: &str = "main";
|
||||||
pub(super) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
|
pub(super) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
|
||||||
pub(super) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
|
pub(super) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
|
||||||
|
pub(super) const APP_TYPE_DESKTOP_PORT_FORWARD: &str = "port forward";
|
||||||
|
pub(super) const APP_TYPE_DESKTOP_RDP: &str = "rdp";
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref SESSIONS: RwLock<HashMap<String,Session<FlutterHandler>>> = Default::default();
|
pub static ref SESSIONS: RwLock<HashMap<String,Session<FlutterHandler>>> = Default::default();
|
||||||
@ -376,6 +378,14 @@ pub mod connection_manager {
|
|||||||
vec![("id", &id.to_string()), ("text", &text)],
|
vec![("id", &id.to_string()), ("text", &text)],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn change_theme(&self, dark: bool) {
|
||||||
|
self.push_event("theme", vec![("dark", &dark.to_string())]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_language(&self) {
|
||||||
|
self.push_event("language", vec![]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlutterHandler {
|
impl FlutterHandler {
|
||||||
|
@ -23,7 +23,7 @@ use crate::ui_interface::{
|
|||||||
get_app_name, get_async_job_status, get_connect_status, get_fav, get_id, get_lan_peers,
|
get_app_name, get_async_job_status, get_connect_status, get_fav, get_id, get_lan_peers,
|
||||||
get_langs, get_license, get_local_option, get_mouse_time, get_option, get_options, get_peer,
|
get_langs, get_license, get_local_option, get_mouse_time, get_option, get_options, get_peer,
|
||||||
get_peer_option, get_socks, get_sound_inputs, get_uuid, get_version, has_hwcodec,
|
get_peer_option, get_socks, get_sound_inputs, get_uuid, get_version, has_hwcodec,
|
||||||
has_rendezvous_service, post_request, set_local_option, set_option, set_options,
|
has_rendezvous_service, post_request, send_to_cm, set_local_option, set_option, set_options,
|
||||||
set_peer_option, set_permanent_password, set_socks, store_fav, test_if_valid_server,
|
set_peer_option, set_permanent_password, set_socks, store_fav, test_if_valid_server,
|
||||||
update_temporary_password, using_public_server,
|
update_temporary_password, using_public_server,
|
||||||
};
|
};
|
||||||
@ -659,6 +659,34 @@ pub fn main_load_lan_peers() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main_broadcast_message(data: &HashMap<&str, &str>) {
|
||||||
|
let apps = vec![
|
||||||
|
flutter::APP_TYPE_DESKTOP_REMOTE,
|
||||||
|
flutter::APP_TYPE_DESKTOP_FILE_TRANSFER,
|
||||||
|
flutter::APP_TYPE_DESKTOP_PORT_FORWARD,
|
||||||
|
flutter::APP_TYPE_DESKTOP_RDP,
|
||||||
|
];
|
||||||
|
|
||||||
|
for app in apps {
|
||||||
|
if let Some(s) = flutter::GLOBAL_EVENT_STREAM.read().unwrap().get(app) {
|
||||||
|
s.add(serde_json::ser::to_string(data).unwrap_or("".to_owned()));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main_change_theme(dark: bool) {
|
||||||
|
main_broadcast_message(&HashMap::from([
|
||||||
|
("name", "theme"),
|
||||||
|
("dark", &dark.to_string()),
|
||||||
|
]));
|
||||||
|
send_to_cm(&crate::ipc::Data::Theme(dark));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main_change_language(lang: String) {
|
||||||
|
main_broadcast_message(&HashMap::from([("name", "language"), ("lang", &lang)]));
|
||||||
|
send_to_cm(&crate::ipc::Data::Language(lang));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn session_add_port_forward(
|
pub fn session_add_port_forward(
|
||||||
id: String,
|
id: String,
|
||||||
local_port: i32,
|
local_port: i32,
|
||||||
|
@ -182,6 +182,8 @@ pub enum Data {
|
|||||||
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
||||||
Mouse(DataMouse),
|
Mouse(DataMouse),
|
||||||
Control(DataControl),
|
Control(DataControl),
|
||||||
|
Theme(bool),
|
||||||
|
Language(String),
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,14 @@ impl InvokeUiCM for SciterHandler {
|
|||||||
fn new_message(&self, id: i32, text: String) {
|
fn new_message(&self, id: i32, text: String) {
|
||||||
self.call("newMessage", &make_args!(id, text));
|
self.call("newMessage", &make_args!(id, text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn change_theme(&self, _dark: bool) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_language(&self) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SciterHandler {
|
impl SciterHandler {
|
||||||
|
@ -63,7 +63,7 @@ class MsgboxComponent: Reactor.Component {
|
|||||||
var ts = this.auto_login ? { checked: true } : {};
|
var ts = this.auto_login ? { checked: true } : {};
|
||||||
return <div .form>
|
return <div .form>
|
||||||
<PasswordComponent value={this.content} />
|
<PasswordComponent value={this.content} />
|
||||||
<div><button|checkbox(auto_login) {ts}>{translate('Auto Login')}</button></div>
|
<div><button|checkbox(auto_login) {ts} style="width: *; word-wrap: break-word; overflow-wrap: break-word; white-space: normal; height: auto; overflow: hidden;">{translate('Auto Login')}</button></div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
return this.content;
|
return this.content;
|
||||||
|
@ -60,6 +60,10 @@ pub trait InvokeUiCM: Send + Clone + 'static + Sized {
|
|||||||
fn remove_connection(&self, id: i32);
|
fn remove_connection(&self, id: i32);
|
||||||
|
|
||||||
fn new_message(&self, id: i32, text: String);
|
fn new_message(&self, id: i32, text: String);
|
||||||
|
|
||||||
|
fn change_theme(&self, dark: bool);
|
||||||
|
|
||||||
|
fn change_language(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: InvokeUiCM> Deref for ConnectionManager<T> {
|
impl<T: InvokeUiCM> Deref for ConnectionManager<T> {
|
||||||
@ -198,6 +202,8 @@ pub enum ClipboardFileData {
|
|||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
||||||
|
use hbb_common::config::LocalConfig;
|
||||||
|
|
||||||
let (tx_file, _rx_file) = mpsc::unbounded_channel::<ClipboardFileData>();
|
let (tx_file, _rx_file) = mpsc::unbounded_channel::<ClipboardFileData>();
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let cm_clip = cm.clone();
|
let cm_clip = cm.clone();
|
||||||
@ -280,6 +286,13 @@ pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
|||||||
.send(ClipboardFileData::Enable((conn_id, enabled)))
|
.send(ClipboardFileData::Enable((conn_id, enabled)))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
Data::Theme(dark) => {
|
||||||
|
cm.change_theme(dark);
|
||||||
|
}
|
||||||
|
Data::Language(lang) => {
|
||||||
|
LocalConfig::set_option("lang".to_owned(), lang);
|
||||||
|
cm.change_language();
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,8 @@ pub fn get_mouse_time() -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_mouse_time() {
|
pub fn check_mouse_time() {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]{
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
{
|
||||||
let sender = SENDER.lock().unwrap();
|
let sender = SENDER.lock().unwrap();
|
||||||
allow_err!(sender.send(ipc::Data::MouseMoveTime(0)));
|
allow_err!(sender.send(ipc::Data::MouseMoveTime(0)));
|
||||||
}
|
}
|
||||||
@ -779,6 +780,13 @@ pub(crate) async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
pub(crate) async fn send_to_cm(data: &ipc::Data) {
|
||||||
|
if let Ok(mut c) = ipc::connect(1000, "_cm").await {
|
||||||
|
c.send(data).await.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const INVALID_FORMAT: &'static str = "Invalid format";
|
const INVALID_FORMAT: &'static str = "Invalid format";
|
||||||
const UNKNOWN_ERROR: &'static str = "Unknown error";
|
const UNKNOWN_ERROR: &'static str = "Unknown error";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user