mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
use new event channel for mobile and web
This commit is contained in:
5
flutter/.gitignore
vendored
5
flutter/.gitignore
vendored
@@ -41,4 +41,7 @@ app.*.symbols
|
||||
app.*.map.json
|
||||
jniLibs
|
||||
|
||||
.vscode
|
||||
.vscode
|
||||
|
||||
# flutter rust bridge
|
||||
lib/generated_bridge.dart
|
||||
@@ -120,11 +120,9 @@ class FfiModel with ChangeNotifier {
|
||||
_permissions.clear();
|
||||
}
|
||||
|
||||
void update(String peerId) {
|
||||
var pos;
|
||||
for (;;) {
|
||||
var evt = FFI.popEvent();
|
||||
if (evt == null) break;
|
||||
void updateEventListener(String peerId) {
|
||||
final void Function(Map<String, dynamic>) cb = (evt) {
|
||||
var pos;
|
||||
var name = evt['name'];
|
||||
if (name == 'msgbox') {
|
||||
handleMsgBox(evt, peerId);
|
||||
@@ -165,31 +163,33 @@ class FfiModel with ChangeNotifier {
|
||||
} else if (name == 'on_client_remove') {
|
||||
FFI.serverModel.onClientRemove(evt);
|
||||
}
|
||||
}
|
||||
if (pos != null) FFI.cursorModel.updateCursorPosition(pos);
|
||||
if (!_decoding) {
|
||||
var rgba = PlatformFFI.getRgba();
|
||||
if (rgba != null) {
|
||||
if (_waitForImage) {
|
||||
_waitForImage = false;
|
||||
SmartDialog.dismiss();
|
||||
}
|
||||
_decoding = true;
|
||||
final pid = FFI.id;
|
||||
ui.decodeImageFromPixels(rgba, _display.width, _display.height,
|
||||
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888, (image) {
|
||||
PlatformFFI.clearRgbaFrame();
|
||||
_decoding = false;
|
||||
if (FFI.id != pid) return;
|
||||
try {
|
||||
// my throw exception, because the listener maybe already dispose
|
||||
FFI.imageModel.update(image);
|
||||
} catch (e) {
|
||||
print('update image: $e');
|
||||
if (pos != null) FFI.cursorModel.updateCursorPosition(pos);
|
||||
if (!_decoding) {
|
||||
var rgba = PlatformFFI.getRgba();
|
||||
if (rgba != null) {
|
||||
if (_waitForImage) {
|
||||
_waitForImage = false;
|
||||
SmartDialog.dismiss();
|
||||
}
|
||||
});
|
||||
_decoding = true;
|
||||
final pid = FFI.id;
|
||||
ui.decodeImageFromPixels(rgba, _display.width, _display.height,
|
||||
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888,
|
||||
(image) {
|
||||
PlatformFFI.clearRgbaFrame();
|
||||
_decoding = false;
|
||||
if (FFI.id != pid) return;
|
||||
try {
|
||||
// my throw exception, because the listener maybe already dispose
|
||||
FFI.imageModel.update(image);
|
||||
} catch (e) {
|
||||
print('update image: $e');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
PlatformFFI.setEventCallback(cb);
|
||||
}
|
||||
|
||||
void handleSwitchDisplay(Map<String, dynamic> evt) {
|
||||
@@ -214,7 +214,6 @@ class FfiModel with ChangeNotifier {
|
||||
enterPasswordDialog(id);
|
||||
} else {
|
||||
var hasRetry = evt['hasRetry'] == 'true';
|
||||
print(evt);
|
||||
showMsgBox(type, title, text, hasRetry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ffi';
|
||||
@@ -7,6 +8,7 @@ import 'package:device_info/device_info.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
import 'package:external_path/external_path.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../generated_bridge.dart';
|
||||
import '../common.dart';
|
||||
|
||||
class RgbaFrame extends Struct {
|
||||
@@ -28,6 +30,7 @@ class PlatformFFI {
|
||||
static F3? _setByName;
|
||||
static F4? _freeRgba;
|
||||
static F5? _getRgba;
|
||||
static void Function(Map<String, dynamic>)? _eventCallback;
|
||||
|
||||
static void clearRgbaFrame() {
|
||||
if (_lastRgbaFrame != null &&
|
||||
@@ -86,6 +89,7 @@ class PlatformFFI {
|
||||
.lookupFunction<Void Function(Pointer<RgbaFrame>), F4>('free_rgba');
|
||||
_getRgba = dylib.lookupFunction<F5, F5>('get_rgba');
|
||||
_dir = (await getApplicationDocumentsDirectory()).path;
|
||||
_startListenEvent(RustdeskImpl(dylib));
|
||||
try {
|
||||
_homeDir = (await ExternalPath.getExternalStorageDirectories())[0];
|
||||
} catch (e) {
|
||||
@@ -115,6 +119,23 @@ class PlatformFFI {
|
||||
version = await getVersion();
|
||||
}
|
||||
|
||||
static void _startListenEvent(RustdeskImpl rustdeskImpl) async {
|
||||
await for (final message in rustdeskImpl.startEventStream()) {
|
||||
if (_eventCallback != null) {
|
||||
try {
|
||||
Map<String, dynamic> event = json.decode(message);
|
||||
_eventCallback!(event);
|
||||
} catch (e) {
|
||||
print('json.decode fail(): $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
|
||||
_eventCallback = fun;
|
||||
}
|
||||
|
||||
static void startDesktopWebListener() {}
|
||||
|
||||
static void stopDesktopWebListener() {}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:dash_chat/dash_chat.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wakelock/wakelock.dart';
|
||||
import '../common.dart';
|
||||
@@ -11,7 +10,6 @@ const loginDialogTag = "LOGIN";
|
||||
final _emptyIdShow = translate("Generating ...");
|
||||
|
||||
class ServerModel with ChangeNotifier {
|
||||
Timer? _interval;
|
||||
bool _isStart = false; // Android MainService status
|
||||
bool _mediaOk = false;
|
||||
bool _inputOk = false;
|
||||
@@ -201,10 +199,7 @@ class ServerModel with ChangeNotifier {
|
||||
_isStart = true;
|
||||
notifyListeners();
|
||||
FFI.setByName("ensure_init_event_queue");
|
||||
_interval?.cancel();
|
||||
_interval = Timer.periodic(Duration(milliseconds: 30), (timer) {
|
||||
FFI.ffiModel.update("");
|
||||
});
|
||||
FFI.ffiModel.updateEventListener("");
|
||||
await FFI.invokeMethod("init_service");
|
||||
FFI.setByName("start_service");
|
||||
getIDPasswd();
|
||||
@@ -214,8 +209,6 @@ class ServerModel with ChangeNotifier {
|
||||
|
||||
Future<Null> stopService() async {
|
||||
_isStart = false;
|
||||
_interval?.cancel();
|
||||
_interval = null;
|
||||
FFI.serverModel.closeAll();
|
||||
await FFI.invokeMethod("stop_service");
|
||||
FFI.setByName("stop_service");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:js' as js;
|
||||
import 'dart:js';
|
||||
|
||||
import '../common.dart';
|
||||
import 'dart:html';
|
||||
@@ -7,39 +8,46 @@ import 'dart:async';
|
||||
|
||||
final List<StreamSubscription<MouseEvent>> mouseListeners = [];
|
||||
final List<StreamSubscription<KeyboardEvent>> keyListeners = [];
|
||||
int lastMouseDownButtons = 0;
|
||||
bool mouseIn = false;
|
||||
|
||||
class PlatformFFI {
|
||||
static void clearRgbaFrame() {}
|
||||
|
||||
static Uint8List? getRgba() {
|
||||
return js.context.callMethod('getRgba');
|
||||
return context.callMethod('getRgba');
|
||||
}
|
||||
|
||||
static String getByName(String name, [String arg = '']) {
|
||||
return js.context.callMethod('getByName', [name, arg]);
|
||||
return context.callMethod('getByName', [name, arg]);
|
||||
}
|
||||
|
||||
static void setByName(String name, [String value = '']) {
|
||||
js.context.callMethod('setByName', [name, value]);
|
||||
context.callMethod('setByName', [name, value]);
|
||||
}
|
||||
|
||||
static Future<Null> init() async {
|
||||
isWeb = true;
|
||||
isDesktop = !js.context.callMethod('isMobile');
|
||||
js.context.callMethod('init');
|
||||
isDesktop = !context.callMethod('isMobile');
|
||||
context.callMethod('init');
|
||||
version = getByName('version');
|
||||
}
|
||||
|
||||
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
|
||||
context["onGlobalEvent"] = (String message) {
|
||||
try {
|
||||
Map<String, dynamic> event = json.decode(message);
|
||||
fun(event);
|
||||
} catch (e) {
|
||||
print('json.decode fail(): $e');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void startDesktopWebListener() {
|
||||
mouseIn = true;
|
||||
mouseListeners.add(
|
||||
window.document.onContextMenu.listen((evt) => evt.preventDefault()));
|
||||
}
|
||||
|
||||
static void stopDesktopWebListener() {
|
||||
mouseIn = true;
|
||||
mouseListeners.forEach((l) {
|
||||
l.cancel();
|
||||
});
|
||||
|
||||
@@ -22,25 +22,19 @@ class FileManagerPage extends StatefulWidget {
|
||||
class _FileManagerPageState extends State<FileManagerPage> {
|
||||
final model = FFI.fileModel;
|
||||
final _selectedItems = SelectedItems();
|
||||
Timer? _interval;
|
||||
final _breadCrumbScroller = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
FFI.connect(widget.id, isFileTransfer: true);
|
||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||
showLoading(translate('Connecting...'));
|
||||
_interval = Timer.periodic(Duration(milliseconds: 30),
|
||||
(timer) => FFI.ffiModel.update(widget.id));
|
||||
});
|
||||
FFI.ffiModel.updateEventListener(widget.id);
|
||||
Wakelock.enable();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
model.onClose();
|
||||
_interval?.cancel();
|
||||
FFI.close();
|
||||
SmartDialog.dismiss();
|
||||
Wakelock.disable();
|
||||
|
||||
@@ -53,6 +53,7 @@ class _RemotePageState extends State<RemotePage> {
|
||||
});
|
||||
Wakelock.enable();
|
||||
_physicalFocusNode.requestFocus();
|
||||
FFI.ffiModel.updateEventListener(widget.id);
|
||||
FFI.listenToMouse(true);
|
||||
}
|
||||
|
||||
@@ -99,7 +100,6 @@ class _RemotePageState extends State<RemotePage> {
|
||||
}
|
||||
});
|
||||
}
|
||||
FFI.ffiModel.update(widget.id);
|
||||
}
|
||||
|
||||
void interval() {
|
||||
|
||||
@@ -223,6 +223,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
flutter_rust_bridge:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_rust_bridge
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.30.0"
|
||||
flutter_smart_dialog:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -738,5 +745,5 @@ packages:
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
sdks:
|
||||
dart: ">=2.16.0 <3.0.0"
|
||||
dart: ">=2.16.1 <3.0.0"
|
||||
flutter: ">=2.10.0"
|
||||
|
||||
@@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 1.1.10+27
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
sdk: ">=2.16.1 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
@@ -53,6 +53,7 @@ dependencies:
|
||||
flutter_smart_dialog:
|
||||
git:
|
||||
url: https://github.com/Heap-Hop/flutter_smart_dialog.git
|
||||
flutter_rust_bridge: ^1.30.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_launcher_icons: ^0.9.1
|
||||
|
||||
5
flutter/web/.gitignore
vendored
5
flutter/web/.gitignore
vendored
@@ -2,3 +2,8 @@ assets
|
||||
js/src/gen_js_from_hbb.ts
|
||||
js/src/message.ts
|
||||
js/src/rendezvous.ts
|
||||
ogvjs-1.8.6
|
||||
libopus.js
|
||||
libopus.wasm
|
||||
yuv-canvas-1.2.6.js
|
||||
.yarn
|
||||
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 375 375" style="width:32px;height:32px;margin:0 4px 4px 0" xmlns="http://www.w3.org/2000/svg"><rect transform="matrix(.91553 0 0 .91553 -152.92 116.76)" x="167.03" y="-127.54" width="409.6" height="409.6" rx="64" ry="64" fill="#0071ff"></rect><path d="M150.428 322.264c-29.063-6.202-53.897-22.439-73.115-47.804-19.507-25.746-27.838-55.355-25.723-91.414 6.655-62.013 47.667-106.753 99.687-120.411 4.509-.989 8.353-3.462 12.55-1.322 3.22 1.64 6.028 4.467 7.206 7.251 1.25 2.955 1.877 21.54.99 29.331-1.076 9.46-3.877 12.418-14.566 15.388-29.723 10.195-48.105 34.07-53.697 61.017-4.8 29.668 2.951 59.729 21.528 78.727 8.966 8.993 17.92 14.24 30.869 18.086 8.646 2.57 13.393 5.758 15.036 10.102 1.085 2.867 1.63 22.984.779 28.772-1.33 9.046-1.702 9.796-5.792 11.667-5.029 2.3-7.404 2.392-15.752.61zm50.708.29c-3.092-1.402-5.673-4.83-6.73-8.94-.134-9.408-2.366-25.754 1.02-33.373 1.88-4.128 4.65-5.999 12.433-8.396 21.267-6.551 37.593-19.88 46.806-38.213 11.11-22.108 11.877-55.183 1.808-77.975-9.154-20.723-25.7-35.217-48.555-42.534-8.872-2.84-12.004-5.065-12.968-9.21-1.002-4.31-1.435-19.87-.785-28.218.682-8.766 1.249-9.99 6.162-13.318 3.701-2.505 5.482-2.446 17.223.575 36.718 10.077 65.97 33.597 83.026 66.68 18.495 37.034 19.191 86.11 1.742 122.655-17.233 36.09-50.591 62.511-88.622 70.194-8.172 1.65-9.07 1.656-12.56.073z" fill="#fff"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1 +0,0 @@
|
||||
#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50;margin-top:60px}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -33,8 +33,8 @@
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<script src="ogvjs-1.8.6/ogv.js"></script>
|
||||
<script src="yuv.js"></script>
|
||||
<script type="module" crossorigin src="assets/index.a0538fcc.js"></script>
|
||||
<link rel="modulepreload" href="assets/vendor.32e42528.js">
|
||||
<script type="module" crossorigin src="js/dist/index.js"></script>
|
||||
<link rel="modulepreload" href="js/dist/vendor.js">
|
||||
<script src="yuv-canvas-1.2.6.js"></script>
|
||||
<style>
|
||||
.loading {
|
||||
|
||||
1
flutter/web/js/.yarnrc.yml
Normal file
1
flutter/web/js/.yarnrc.yml
Normal file
@@ -0,0 +1 @@
|
||||
nodeLinker: node-modules
|
||||
@@ -7,7 +7,6 @@ import { initZstd, translate } from "./common";
|
||||
import PCMPlayer from "pcm-player";
|
||||
|
||||
var currentFrame = undefined;
|
||||
var events = [];
|
||||
|
||||
window.curConn = undefined;
|
||||
window.getRgba = () => {
|
||||
@@ -25,11 +24,10 @@ export function isDesktop() {
|
||||
}
|
||||
|
||||
export function msgbox(type, title, text) {
|
||||
if (!events) return;
|
||||
if (!type || (type == 'error' && !text)) return;
|
||||
const text2 = text.toLowerCase();
|
||||
var hasRetry = checkIfRetry(type, title, text) ? 'true' : '';
|
||||
events.push({ name: 'msgbox', type, title, text, hasRetry });
|
||||
onGlobalEvent(JSON.stringify({ name: 'msgbox', type, title, text, hasRetry }));
|
||||
}
|
||||
|
||||
function jsonfyForDart(payload) {
|
||||
@@ -42,10 +40,9 @@ function jsonfyForDart(payload) {
|
||||
}
|
||||
|
||||
export function pushEvent(name, payload) {
|
||||
if (!events) return;
|
||||
payload = jsonfyForDart(payload);
|
||||
payload.name = name;
|
||||
events.push(payload);
|
||||
onGlobalEvent(JSON.stringify(payload));
|
||||
}
|
||||
|
||||
let yuvWorker;
|
||||
@@ -120,7 +117,6 @@ export function getConn() {
|
||||
|
||||
export async function startConn(id) {
|
||||
currentFrame = undefined;
|
||||
events = [];
|
||||
setByName('remote_id', id);
|
||||
await curConn.start(id);
|
||||
}
|
||||
@@ -129,7 +125,6 @@ export function close() {
|
||||
getConn()?.close();
|
||||
setConn(undefined);
|
||||
currentFrame = undefined;
|
||||
events = undefined;
|
||||
}
|
||||
|
||||
export function newConn() {
|
||||
@@ -310,13 +305,6 @@ function _getByName(name, arg) {
|
||||
return localStorage.getItem('remote-id');
|
||||
case 'remember':
|
||||
return curConn.getRemember();
|
||||
case 'event':
|
||||
if (events && events.length) {
|
||||
const e = events[0];
|
||||
events.splice(0, 1);
|
||||
return JSON.stringify(e);
|
||||
}
|
||||
break;
|
||||
case 'toggle_option':
|
||||
return curConn.getOption(arg) || false;
|
||||
case 'option':
|
||||
|
||||
14
flutter/web/js/vite.config.js
Normal file
14
flutter/web/js/vite.config.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
manifest: false,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
entryFileNames: `[name].js`,
|
||||
chunkFileNames: `[name].js`,
|
||||
assetFileNames: `[name].[ext]`,
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user