Refact. Flutter web, mid commit (#7482)

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou
2024-03-23 10:08:55 +08:00
committed by GitHub
parent 1c3a2e475d
commit a15cd62fd4
8 changed files with 187 additions and 68 deletions

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:back_button_interceptor/back_button_interceptor.dart';
@@ -1544,7 +1543,7 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
late Size sz;
late bool isMaximized;
bool isFullscreen = stateGlobal.fullscreen.isTrue ||
(Platform.isMacOS && stateGlobal.closeOnFullscreen == true);
(isMacOS && stateGlobal.closeOnFullscreen == true);
setFrameIfMaximized() {
if (isMaximized) {
final pos = bind.getLocalFlutterOption(k: windowFramePrefix + type.name);
@@ -1583,7 +1582,7 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
setFrameIfMaximized();
break;
}
if (Platform.isWindows) {
if (isWindows) {
const kMinOffset = -10000;
const kMaxOffset = 10000;
if (position.dx < kMinOffset ||
@@ -1854,7 +1853,7 @@ Future<bool> restoreWindowPosition(WindowType type,
/// initUniLinks should only be used on macos/windows.
/// we use dbus for linux currently.
Future<bool> initUniLinks() async {
if (Platform.isLinux) {
if (isLinux) {
return false;
}
// check cold boot
@@ -1876,7 +1875,7 @@ Future<bool> initUniLinks() async {
///
/// Returns a [StreamSubscription] which can listen the uni links.
StreamSubscription? listenUniLinks({handleByFlutter = true}) {
if (Platform.isLinux) {
if (isLinux) {
return null;
}
@@ -2024,7 +2023,7 @@ List<String>? urlLinkToCmdArgs(Uri uri) {
command = '--connect';
id = uri.path.substring("/new/".length);
} else if (uri.authority == "config") {
if (Platform.isAndroid || Platform.isIOS) {
if (isAndroid || isIOS) {
final config = uri.path.substring("/".length);
// add a timer to make showToast work
Timer(Duration(seconds: 1), () {
@@ -2033,7 +2032,7 @@ List<String>? urlLinkToCmdArgs(Uri uri) {
}
return null;
} else if (uri.authority == "password") {
if (Platform.isAndroid || Platform.isIOS) {
if (isAndroid || isIOS) {
final password = uri.path.substring("/".length);
if (password.isNotEmpty) {
Timer(Duration(seconds: 1), () async {
@@ -2253,7 +2252,7 @@ Future<void> reloadAllWindows() async {
/// [Note]
/// Portable build is only available on Windows.
bool isRunningInPortableMode() {
if (!Platform.isWindows) {
if (!isWindows) {
return false;
}
return bool.hasEnvironment(kEnvPortableExecutable);
@@ -2266,7 +2265,7 @@ Future<void> onActiveWindowChanged() async {
if (rustDeskWinManager.getActiveWindows().isEmpty) {
// close all sub windows
try {
if (Platform.isLinux) {
if (isLinux) {
await Future.wait([
saveWindowPosition(WindowType.Main),
rustDeskWinManager.closeAllSubWindows()
@@ -2280,7 +2279,7 @@ Future<void> onActiveWindowChanged() async {
debugPrint("Start closing RustDesk...");
await windowManager.setPreventClose(false);
await windowManager.close();
if (Platform.isMacOS) {
if (isMacOS) {
RdPlatformChannel.instance.terminate();
}
}
@@ -2296,7 +2295,7 @@ Timer periodic_immediate(Duration duration, Future<void> Function() callback) {
/// return a human readable windows version
WindowsTarget getWindowsTarget(int buildNumber) {
if (!Platform.isWindows) {
if (!isWindows) {
return WindowsTarget.naw;
}
if (buildNumber >= 22000) {
@@ -2330,7 +2329,7 @@ int getWindowsTargetBuildNumber() {
/// [Conditions]
/// - Windows 7, window will overflow when we use frameless ui.
bool get kUseCompatibleUiMode =>
Platform.isWindows &&
isWindows &&
const [WindowsTarget.w7].contains(windowsBuildNumber.windowsVersion);
class ServerConfig {
@@ -2460,7 +2459,7 @@ Future<void> updateSystemWindowTheme() async {
// Set system window theme for macOS.
final userPreference = MyTheme.getThemeModePreference();
if (userPreference != ThemeMode.system) {
if (Platform.isMacOS) {
if (isMacOS) {
await RdPlatformChannel.instance.changeSystemWindowTheme(
userPreference == ThemeMode.light
? SystemWindowTheme.light
@@ -2548,7 +2547,7 @@ void onCopyFingerprint(String value) {
Future<bool> callMainCheckSuperUserPermission() async {
bool checked = await bind.mainCheckSuperUserPermission();
if (Platform.isMacOS) {
if (isMacOS) {
await windowManager.show();
}
return checked;
@@ -2556,7 +2555,7 @@ Future<bool> callMainCheckSuperUserPermission() async {
Future<void> start_service(bool is_start) async {
bool checked = !bind.mainIsInstalled() ||
!Platform.isMacOS ||
!isMacOS ||
await callMainCheckSuperUserPermission();
if (checked) {
bind.mainSetOption(key: "stop-service", value: is_start ? "" : "Y");
@@ -3114,7 +3113,7 @@ Widget loadIcon(double size) {
var imcomingOnlyHomeSize = Size(280, 300);
Size getIncomingOnlyHomeSize() {
final magicWidth = Platform.isWindows ? 11.0 : 2.0;
final magicWidth = isWindows ? 11.0 : 2.0;
final magicHeight = 10.0;
return imcomingOnlyHomeSize +
Offset(magicWidth, kDesktopRemoteTabBarHeight + magicHeight);

View File

@@ -125,6 +125,10 @@ void runMainApp(bool startService) async {
await Future.wait([gFFI.abModel.loadCache(), gFFI.groupModel.loadCache()]);
gFFI.userModel.refreshCurrentUser();
runApp(App());
if (isWeb) {
// Web does not support window manager.
return;
}
// Set window option.
WindowOptions windowOptions = getHiddenTitleBarWindowOptions();
windowManager.waitUntilReadyToShow(windowOptions, () async {
@@ -150,11 +154,11 @@ void runMainApp(bool startService) async {
void runMobileApp() async {
await initEnv(kAppTypeMain);
if (isAndroid) androidChannelInit();
platformFFI.syncAndroidServiceAppDirConfigPath();
if (isAndroid) platformFFI.syncAndroidServiceAppDirConfigPath();
await Future.wait([gFFI.abModel.loadCache(), gFFI.groupModel.loadCache()]);
gFFI.userModel.refreshCurrentUser();
runApp(App());
await initUniLinks();
if (!isWeb) await initUniLinks();
}
void runMultiWindow(

View File

@@ -53,7 +53,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
@override
void initState() {
super.initState();
_uniLinksSubscription = listenUniLinks();
if (!isWeb) _uniLinksSubscription = listenUniLinks();
if (_idController.text.isEmpty) {
() async {
final lastRemoteId = await bind.mainGetLastRemoteId();

View File

@@ -18,7 +18,7 @@ typedef HandleEvent = Future<void> Function(Map<String, dynamic> evt);
class PlatformFFI {
final _eventHandlers = <String, Map<String, HandleEvent>>{};
late RustdeskImpl _ffiBind;
final RustdeskImpl _ffiBind = RustdeskImpl();
static String getByName(String name, [String arg = '']) {
return context.callMethod('getByName', [name, arg]);
@@ -101,6 +101,15 @@ class PlatformFFI {
isWebDesktop = !context.callMethod('isMobile');
context.callMethod('init');
version = getByName('version');
context['onRegisteredEvent'] = (String message) {
try {
Map<String, dynamic> event = json.decode(message);
tryHandle(event);
} catch (e) {
print('json.decode fail(): $e');
}
};
}
void setEventCallback(void Function(Map<String, dynamic>) fun) {
@@ -145,7 +154,5 @@ class PlatformFFI {
}
// just for compilation
void syncAndroidServiceAppDirConfigPath() {
throw UnimplementedError();
}
void syncAndroidServiceAppDirConfigPath() {}
}

View File

@@ -1,4 +1,6 @@
import 'dart:async';
import 'dart:js' as js;
import 'dart:convert';
import 'dart:typed_data';
import 'package:uuid/uuid.dart';
@@ -176,29 +178,35 @@ class RustdeskImpl {
Future<String?> sessionGetFlutterOptionByPeerId(
{required String id, required String k, dynamic hint}) {
throw UnimplementedError();
return Future.value(null);
}
int getNextTextureKey({dynamic hint}) {
throw UnimplementedError();
return 0;
}
String getLocalFlutterOption({required String k, dynamic hint}) {
throw UnimplementedError();
return js.context.callMethod('getByName', ['option:flutter:local', k]);
}
Future<void> setLocalFlutterOption(
{required String k, required String v, dynamic hint}) {
throw UnimplementedError();
return Future(() => js.context.callMethod('setByName', [
'option:flutter:local',
jsonEncode({'name': k, 'value': v})
]));
}
String getLocalKbLayoutType({dynamic hint}) {
throw UnimplementedError();
throw js.context.callMethod('getByName', ['option:local', 'kb_layout']);
}
Future<void> setLocalKbLayoutType(
{required String kbLayoutType, dynamic hint}) {
throw UnimplementedError();
return Future(() => js.context.callMethod('setByName', [
'option:local',
jsonEncode({'name': 'kb_layout', 'value': kbLayoutType})
]));
}
Future<String?> sessionGetViewStyle(
@@ -538,11 +546,11 @@ class RustdeskImpl {
}
Future<String> mainGetOption({required String key, dynamic hint}) {
throw UnimplementedError();
return Future.value(mainGetOptionSync(key: key));
}
String mainGetOptionSync({required String key, dynamic hint}) {
throw UnimplementedError();
return js.context.callMethod('getByName', ['option', key]);
}
Future<String> mainGetError({dynamic hint}) {
@@ -555,7 +563,10 @@ class RustdeskImpl {
Future<void> mainSetOption(
{required String key, required String value, dynamic hint}) {
throw UnimplementedError();
return js.context.callMethod('setByName', [
'option',
jsonEncode({'name': key, 'value': value})
]);
}
Future<String> mainGetOptions({dynamic hint}) {
@@ -623,11 +634,13 @@ class RustdeskImpl {
}
Future<String> mainGetConnectStatus({dynamic hint}) {
throw UnimplementedError();
return Future(
() => js.context.callMethod('getByName', ["get_conn_status"]));
}
Future<void> mainCheckConnectStatus({dynamic hint}) {
throw UnimplementedError();
return Future(
() => js.context.callMethod('setByName', ["check_conn_status"]));
}
Future<bool> mainIsUsingPublicServer({dynamic hint}) {
@@ -635,7 +648,7 @@ class RustdeskImpl {
}
Future<void> mainDiscover({dynamic hint}) {
throw UnimplementedError();
return Future(() => js.context.callMethod('setByName', ['discover']));
}
Future<String> mainGetApiServer({dynamic hint}) {
@@ -651,7 +664,7 @@ class RustdeskImpl {
}
String mainGetLocalOption({required String key, dynamic hint}) {
throw UnimplementedError();
return js.context.callMethod('getByName', ['option:local', key]);
}
String mainGetEnv({required String key, dynamic hint}) {
@@ -660,7 +673,10 @@ class RustdeskImpl {
Future<void> mainSetLocalOption(
{required String key, required String value, dynamic hint}) {
throw UnimplementedError();
return Future(() => js.context.callMethod('setByName', [
'option:local',
jsonEncode({'name': key, 'value': value})
]));
}
String mainGetInputSource({dynamic hint}) {
@@ -741,15 +757,16 @@ class RustdeskImpl {
}
Future<void> mainLoadRecentPeers({dynamic hint}) {
throw UnimplementedError();
return Future(
() => js.context.callMethod('getByName', ['load_recent_peers']));
}
String mainLoadRecentPeersSync({dynamic hint}) {
throw UnimplementedError();
return js.context.callMethod('getByName', ['load_recent_peers_sync']);
}
String mainLoadLanPeersSync({dynamic hint}) {
throw UnimplementedError();
return js.context.callMethod('getByName', ['load_lan_peers_sync']);
}
Future<String> mainLoadRecentPeersForAb(
@@ -758,15 +775,16 @@ class RustdeskImpl {
}
Future<void> mainLoadFavPeers({dynamic hint}) {
throw UnimplementedError();
return Future(() => js.context.callMethod('getByName', ['load_fav_peers']));
}
Future<void> mainLoadLanPeers({dynamic hint}) {
throw UnimplementedError();
return Future(() => js.context.callMethod('getByName', ['load_lan_peers']));
}
Future<void> mainRemoveDiscovered({required String id, dynamic hint}) {
throw UnimplementedError();
return Future(
() => js.context.callMethod('getByName', ['remove_discovered']));
}
Future<void> mainChangeTheme({required String dark, dynamic hint}) {
@@ -840,7 +858,8 @@ class RustdeskImpl {
}
Future<String> mainGetLastRemoteId({dynamic hint}) {
throw UnimplementedError();
return Future(
() => js.context.callMethod('getByName', ['option', 'last_remote_id']));
}
Future<String> mainGetSoftwareUpdateUrl({dynamic hint}) {
@@ -848,7 +867,7 @@ class RustdeskImpl {
}
Future<String> mainGetHomeDir({dynamic hint}) {
throw UnimplementedError();
return Future.value('');
}
Future<String> mainGetLangs({dynamic hint}) {
@@ -856,11 +875,11 @@ class RustdeskImpl {
}
Future<String> mainGetTemporaryPassword({dynamic hint}) {
throw UnimplementedError();
return Future.value('');
}
Future<String> mainGetPermanentPassword({dynamic hint}) {
throw UnimplementedError();
return Future.value('');
}
Future<String> mainGetFingerprint({dynamic hint}) {
@@ -880,7 +899,7 @@ class RustdeskImpl {
}
Future<void> mainInit({required String appDir, dynamic hint}) {
throw UnimplementedError();
return Future.value();
}
Future<void> mainDeviceId({required String id, dynamic hint}) {
@@ -1093,7 +1112,10 @@ class RustdeskImpl {
String translate(
{required String name, required String locale, dynamic hint}) {
throw UnimplementedError();
return js.context.callMethod('getByName', [
'translate',
jsonEncode({'locale': locale, 'text': name})
]);
}
int sessionGetRgbaSize(
@@ -1131,7 +1153,7 @@ class RustdeskImpl {
}
Future<bool> optionSynced({dynamic hint}) {
throw UnimplementedError();
return Future.value(true);
}
bool mainIsInstalled({dynamic hint}) {
@@ -1257,43 +1279,45 @@ class RustdeskImpl {
}
Future<void> mainTestWallpaper({required int second, dynamic hint}) {
throw UnimplementedError();
// TODO: implement mainTestWallpaper
return Future.value();
}
Future<bool> mainSupportRemoveWallpaper({dynamic hint}) {
throw UnimplementedError();
// TODO: implement mainSupportRemoveWallpaper
return Future.value(false);
}
bool isIncomingOnly({dynamic hint}) {
throw UnimplementedError();
return false;
}
bool isOutgoingOnly({dynamic hint}) {
throw UnimplementedError();
return false;
}
bool isCustomClient({dynamic hint}) {
throw UnimplementedError();
return false;
}
bool isDisableSettings({dynamic hint}) {
throw UnimplementedError();
return false;
}
bool isDisableAb({dynamic hint}) {
throw UnimplementedError();
return false;
}
bool isDisableAccount({dynamic hint}) {
throw UnimplementedError();
return false;
}
bool isDisableInstallation({dynamic hint}) {
throw UnimplementedError();
return false;
}
Future<bool> isPresetPassword({dynamic hint}) {
throw UnimplementedError();
return Future.value(false);
}
Future<void> sendUrlScheme({required String url, dynamic hint}) {