mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-05-11 10:26:19 +02:00
Refact. Flutter web, mid commit (#7502)
* Refact. Flutter web, mid commit Signed-off-by: fufesou <shuanglongchen@yeah.net> * Refact. Flutter web, mid commit Signed-off-by: fufesou <shuanglongchen@yeah.net> --------- Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
d546b23bd8
commit
8dff263a0c
6 changed files with 181 additions and 87 deletions
|
@ -690,7 +690,7 @@ class FfiModel with ChangeNotifier {
|
||||||
// Because this function is asynchronous, there's an "await" in this function.
|
// Because this function is asynchronous, there's an "await" in this function.
|
||||||
cachedPeerData.peerInfo = {...evt};
|
cachedPeerData.peerInfo = {...evt};
|
||||||
|
|
||||||
// recent peer updated by handle_peer_info(ui_session_interface.rs) --> handle_peer_info(client.rs) --> save_config(client.rs)
|
// Recent peer is updated by handle_peer_info(ui_session_interface.rs) --> handle_peer_info(client.rs) --> save_config(client.rs)
|
||||||
bind.mainLoadRecentPeers();
|
bind.mainLoadRecentPeers();
|
||||||
|
|
||||||
parent.target?.dialogManager.dismissAll();
|
parent.target?.dialogManager.dismissAll();
|
||||||
|
@ -868,7 +868,16 @@ class FfiModel with ChangeNotifier {
|
||||||
|
|
||||||
handleResolutions(String id, dynamic resolutions) {
|
handleResolutions(String id, dynamic resolutions) {
|
||||||
try {
|
try {
|
||||||
final List<dynamic> dynamicArray = jsonDecode(resolutions as String);
|
final resolutionsObj = json.decode(resolutions as String);
|
||||||
|
late List<dynamic> dynamicArray;
|
||||||
|
if (resolutionsObj is Map) {
|
||||||
|
// The web version
|
||||||
|
dynamicArray = (resolutionsObj as Map<String, dynamic>)['resolutions']
|
||||||
|
as List<dynamic>;
|
||||||
|
} else {
|
||||||
|
// The rust version
|
||||||
|
dynamicArray = resolutionsObj as List<dynamic>;
|
||||||
|
}
|
||||||
List<Resolution> arr = List.empty(growable: true);
|
List<Resolution> arr = List.empty(growable: true);
|
||||||
for (int i = 0; i < dynamicArray.length; i++) {
|
for (int i = 0; i < dynamicArray.length; i++) {
|
||||||
var width = dynamicArray[i]["width"];
|
var width = dynamicArray[i]["width"];
|
||||||
|
@ -2236,6 +2245,10 @@ class FFI {
|
||||||
}
|
}
|
||||||
final stream = bind.sessionStart(sessionId: sessionId, id: id);
|
final stream = bind.sessionStart(sessionId: sessionId, id: id);
|
||||||
if (isWeb) {
|
if (isWeb) {
|
||||||
|
platformFFI.setRgbaCallback((int display, Uint8List data) {
|
||||||
|
onEvent2UIRgba();
|
||||||
|
imageModel.onRgba(display, data);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,7 @@ class PlatformFFI {
|
||||||
_eventCallback = fun;
|
_eventCallback = fun;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRgbaCallback(void Function(Uint8List) fun) async {}
|
void setRgbaCallback(void Function(int, Uint8List) fun) async {}
|
||||||
|
|
||||||
void startDesktopWebListener() {}
|
void startDesktopWebListener() {}
|
||||||
|
|
||||||
|
|
|
@ -123,10 +123,10 @@ class PlatformFFI {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRgbaCallback(void Function(Uint8List) fun) {
|
void setRgbaCallback(void Function(int, Uint8List) fun) {
|
||||||
context["onRgba"] = (Uint8List? rgba) {
|
context["onRgba"] = (int display, Uint8List? rgba) {
|
||||||
if (rgba != null) {
|
if (rgba != null) {
|
||||||
fun(rgba);
|
fun(display, rgba);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,20 +52,18 @@ class RustdeskImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
int peerGetDefaultSessionsCount({required String id, dynamic hint}) {
|
int peerGetDefaultSessionsCount({required String id, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String sessionAddExistedSync(
|
String sessionAddExistedSync(
|
||||||
{required String id, required UuidValue sessionId, dynamic hint}) {
|
{required String id, required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
void sessionTryAddDisplay(
|
void sessionTryAddDisplay(
|
||||||
{required UuidValue sessionId,
|
{required UuidValue sessionId,
|
||||||
required Int32List displays,
|
required Int32List displays,
|
||||||
dynamic hint}) {
|
dynamic hint}) {}
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
String sessionAddSync(
|
String sessionAddSync(
|
||||||
{required UuidValue sessionId,
|
{required UuidValue sessionId,
|
||||||
|
@ -95,7 +93,8 @@ class RustdeskImpl {
|
||||||
|
|
||||||
Future<bool?> sessionGetRemember(
|
Future<bool?> sessionGetRemember(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(
|
||||||
|
() => js.context.callMethod('getByName', ['remember']) == 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> sessionGetToggleOption(
|
Future<bool?> sessionGetToggleOption(
|
||||||
|
@ -122,7 +121,15 @@ class RustdeskImpl {
|
||||||
required String password,
|
required String password,
|
||||||
required bool remember,
|
required bool remember,
|
||||||
dynamic hint}) {
|
dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'login',
|
||||||
|
jsonEncode({
|
||||||
|
'os_username': osUsername,
|
||||||
|
'os_password': osPassword,
|
||||||
|
'password': password,
|
||||||
|
'remember': remember
|
||||||
|
})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSend2Fa(
|
Future<void> sessionSend2Fa(
|
||||||
|
@ -156,7 +163,7 @@ class RustdeskImpl {
|
||||||
|
|
||||||
Future<void> sessionReconnect(
|
Future<void> sessionReconnect(
|
||||||
{required UuidValue sessionId, required bool forceRelay, dynamic hint}) {
|
{required UuidValue sessionId, required bool forceRelay, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', ['reconnect']));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionToggleOption(
|
Future<void> sessionToggleOption(
|
||||||
|
@ -225,77 +232,110 @@ class RustdeskImpl {
|
||||||
|
|
||||||
Future<String?> sessionGetViewStyle(
|
Future<String?> sessionGetViewStyle(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
// TODO: default values
|
||||||
|
return Future(() =>
|
||||||
|
js.context.callMethod('getByName', ['option:peer', 'view_style']));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetViewStyle(
|
Future<void> sessionSetViewStyle(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': 'view_style', 'value': value})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> sessionGetScrollStyle(
|
Future<String?> sessionGetScrollStyle(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
// TODO: default values
|
||||||
|
return Future(() =>
|
||||||
|
js.context.callMethod('getByName', ['option:peer', 'scroll_style']));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetScrollStyle(
|
Future<void> sessionSetScrollStyle(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': 'scroll_style', 'value': value})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> sessionGetImageQuality(
|
Future<String?> sessionGetImageQuality(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
// TODO: default values
|
||||||
throw UnimplementedError();
|
{required UuidValue sessionId,
|
||||||
|
dynamic hint}) {
|
||||||
|
return Future(() =>
|
||||||
|
js.context.callMethod('getByName', ['option:peer', 'image_quality']));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetImageQuality(
|
Future<void> sessionSetImageQuality(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': 'image_quality', 'value': value})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> sessionGetKeyboardMode(
|
Future<String?> sessionGetKeyboardMode(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
// TODO: default values
|
||||||
|
return Future(() =>
|
||||||
|
js.context.callMethod('getByName', ['option:peer', 'keyboard_mode']));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetKeyboardMode(
|
Future<void> sessionSetKeyboardMode(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': 'keyboard_mode', 'value': value})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
String? sessionGetReverseMouseWheelSync(
|
String? sessionGetReverseMouseWheelSync(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return js.context
|
||||||
|
.callMethod('getByName', ['option:peer', 'reverse_mouse_wheel']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetReverseMouseWheel(
|
Future<void> sessionSetReverseMouseWheel(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': 'reverse_mouse_wheel', 'value': value})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
String? sessionGetDisplaysAsIndividualWindows(
|
String? sessionGetDisplaysAsIndividualWindows(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return js.context.callMethod(
|
||||||
|
'getByName', ['option:peer', 'displays_as_individual_windows']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetDisplaysAsIndividualWindows(
|
Future<void> sessionSetDisplaysAsIndividualWindows(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
String? sessionGetUseAllMyDisplaysForTheRemoteSession(
|
String? sessionGetUseAllMyDisplaysForTheRemoteSession(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetUseAllMyDisplaysForTheRemoteSession(
|
Future<void> sessionSetUseAllMyDisplaysForTheRemoteSession(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Int32List?> sessionGetCustomImageQuality(
|
Future<Int32List?> sessionGetCustomImageQuality(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
try {
|
||||||
|
return Future(() => Int32List.fromList([
|
||||||
|
int.parse(js.context.callMethod(
|
||||||
|
'getByName', ['option:peer', 'custom_image_quality']))
|
||||||
|
]));
|
||||||
|
} catch (e) {
|
||||||
|
return Future.value(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sessionIsKeyboardModeSupported(
|
bool sessionIsKeyboardModeSupported(
|
||||||
|
@ -305,12 +345,18 @@ class RustdeskImpl {
|
||||||
|
|
||||||
Future<void> sessionSetCustomImageQuality(
|
Future<void> sessionSetCustomImageQuality(
|
||||||
{required UuidValue sessionId, required int value, dynamic hint}) {
|
{required UuidValue sessionId, required int value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': 'custom_image_quality', 'value': value})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSetCustomFps(
|
Future<void> sessionSetCustomFps(
|
||||||
{required UuidValue sessionId, required int fps, dynamic hint}) {
|
{required UuidValue sessionId, required int fps, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': 'custom_fps', 'value': fps})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionLockScreen({required UuidValue sessionId, dynamic hint}) {
|
Future<void> sessionLockScreen({required UuidValue sessionId, dynamic hint}) {
|
||||||
|
@ -373,17 +419,22 @@ class RustdeskImpl {
|
||||||
required String name,
|
required String name,
|
||||||
required String value,
|
required String value,
|
||||||
dynamic hint}) {
|
dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(() => js.context.callMethod('SetByName', [
|
||||||
|
'option:peer',
|
||||||
|
jsonEncode({'name': name, 'value': value})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> sessionGetPeerOption(
|
Future<String> sessionGetPeerOption(
|
||||||
{required UuidValue sessionId, required String name, dynamic hint}) {
|
{required UuidValue sessionId, required String name, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(
|
||||||
|
() => js.context.callMethod('getByName', ['option:peer', name]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionInputOsPassword(
|
Future<void> sessionInputOsPassword(
|
||||||
{required UuidValue sessionId, required String value, dynamic hint}) {
|
{required UuidValue sessionId, required String value, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(
|
||||||
|
() => js.context.callMethod('setByName', ['input_os_password', value]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionReadRemoteDir(
|
Future<void> sessionReadRemoteDir(
|
||||||
|
@ -531,7 +582,7 @@ class RustdeskImpl {
|
||||||
required int width,
|
required int width,
|
||||||
required int height,
|
required int height,
|
||||||
dynamic hint}) {
|
dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionSendSelectedSessionId(
|
Future<void> sessionSendSelectedSessionId(
|
||||||
|
@ -991,7 +1042,8 @@ class RustdeskImpl {
|
||||||
|
|
||||||
Future<void> sessionSendMouse(
|
Future<void> sessionSendMouse(
|
||||||
{required UuidValue sessionId, required String msg, dynamic hint}) {
|
{required UuidValue sessionId, required String msg, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future(
|
||||||
|
() => js.context.callMethod('setByName', ['send_mouse', msg]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionRestartRemoteDevice(
|
Future<void> sessionRestartRemoteDevice(
|
||||||
|
@ -1021,7 +1073,7 @@ class RustdeskImpl {
|
||||||
|
|
||||||
Future<void> sessionOnWaitingForImageDialogShow(
|
Future<void> sessionOnWaitingForImageDialogShow(
|
||||||
{required UuidValue sessionId, dynamic hint}) {
|
{required UuidValue sessionId, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionToggleVirtualDisplay(
|
Future<void> sessionToggleVirtualDisplay(
|
||||||
|
@ -1142,36 +1194,55 @@ class RustdeskImpl {
|
||||||
|
|
||||||
int sessionGetRgbaSize(
|
int sessionGetRgbaSize(
|
||||||
{required UuidValue sessionId, required int display, dynamic hint}) {
|
{required UuidValue sessionId, required int display, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sessionNextRgba(
|
void sessionNextRgba(
|
||||||
{required UuidValue sessionId, required int display, dynamic hint}) {
|
{required UuidValue sessionId, required int display, dynamic hint}) {}
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sessionRegisterPixelbufferTexture(
|
void sessionRegisterPixelbufferTexture(
|
||||||
{required UuidValue sessionId,
|
{required UuidValue sessionId,
|
||||||
required int display,
|
required int display,
|
||||||
required int ptr,
|
required int ptr,
|
||||||
dynamic hint}) {
|
dynamic hint}) {}
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sessionRegisterGpuTexture(
|
void sessionRegisterGpuTexture(
|
||||||
{required UuidValue sessionId,
|
{required UuidValue sessionId,
|
||||||
required int display,
|
required int display,
|
||||||
required int ptr,
|
required int ptr,
|
||||||
dynamic hint}) {
|
dynamic hint}) {}
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> queryOnlines({required List<String> ids, dynamic hint}) {
|
Future<void> queryOnlines({required List<String> ids, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dup to the function in hbb_common, lib.rs
|
||||||
|
// Maybe we need to move this function to js part.
|
||||||
int versionToNumber({required String v, dynamic hint}) {
|
int versionToNumber({required String v, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
List<String> versions = v.split('-');
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
// The first part is the version number.
|
||||||
|
// 1.1.10 -> 1001100, 1.2.3 -> 1001030, multiple the last number by 10
|
||||||
|
// to leave space for patch version.
|
||||||
|
if (versions.isNotEmpty) {
|
||||||
|
int last = 0;
|
||||||
|
for (var x in versions[0].split('.')) {
|
||||||
|
last = int.tryParse(x) ?? 0;
|
||||||
|
n = n * 1000 + last;
|
||||||
|
}
|
||||||
|
n -= last;
|
||||||
|
n += last * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (versions.length > 1) {
|
||||||
|
n += int.tryParse(versions[1]) ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the rest
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> optionSynced({dynamic hint}) {
|
Future<bool> optionSynced({dynamic hint}) {
|
||||||
|
@ -1419,7 +1490,7 @@ class RustdeskImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSupportMultiUiSession({required String version, dynamic hint}) {
|
bool isSupportMultiUiSession({required String version, dynamic hint}) {
|
||||||
throw UnimplementedError();
|
return versionToNumber(v: version) > versionToNumber(v: '1.2.4');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSelinuxEnforcing({dynamic hint}) {
|
bool isSelinuxEnforcing({dynamic hint}) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ let HOST = localStorage.getItem("rendezvous-server") || HOSTS[0];
|
||||||
const SCHEMA = "ws://";
|
const SCHEMA = "ws://";
|
||||||
|
|
||||||
type MsgboxCallback = (type: string, title: string, text: string, link: string) => void;
|
type MsgboxCallback = (type: string, title: string, text: string, link: string) => void;
|
||||||
type DrawCallback = (data: Uint8Array) => void;
|
type DrawCallback = (display: number, data: Uint8Array) => void;
|
||||||
//const cursorCanvas = document.createElement("canvas");
|
//const cursorCanvas = document.createElement("canvas");
|
||||||
|
|
||||||
export default class Connection {
|
export default class Connection {
|
||||||
|
@ -41,7 +41,6 @@ export default class Connection {
|
||||||
this._msgs = [];
|
this._msgs = [];
|
||||||
this._id = "";
|
this._id = "";
|
||||||
this._videoTestSpeed = [0, 0];
|
this._videoTestSpeed = [0, 0];
|
||||||
this._options = {};
|
|
||||||
//this._cursors = {};
|
//this._cursors = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ export default class Connection {
|
||||||
try {
|
try {
|
||||||
this._password = Uint8Array.from(JSON.parse("[" + p + "]"));
|
this._password = Uint8Array.from(JSON.parse("[" + p + "]"));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error('Failed to get password, ' + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +170,7 @@ export default class Connection {
|
||||||
pk = undefined;
|
pk = undefined;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error('Failed to verify id pk, ', e);
|
||||||
pk = undefined;
|
pk = undefined;
|
||||||
}
|
}
|
||||||
if (!pk)
|
if (!pk)
|
||||||
|
@ -196,7 +195,7 @@ export default class Connection {
|
||||||
try {
|
try {
|
||||||
signedId = await globals.verify(signedId.id, Uint8Array.from(pk!));
|
signedId = await globals.verify(signedId.id, Uint8Array.from(pk!));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error('Failed to verify signed id pk, ', e);
|
||||||
// fall back to non-secure connection in case pk mismatch
|
// fall back to non-secure connection in case pk mismatch
|
||||||
console.error("pk mismatch, fall back to non-secure");
|
console.error("pk mismatch, fall back to non-secure");
|
||||||
const public_key = message.PublicKey.fromPartial({});
|
const public_key = message.PublicKey.fromPartial({});
|
||||||
|
@ -243,7 +242,7 @@ export default class Connection {
|
||||||
this.login();
|
this.login();
|
||||||
} else if (msg?.test_delay) {
|
} else if (msg?.test_delay) {
|
||||||
const test_delay = msg?.test_delay;
|
const test_delay = msg?.test_delay;
|
||||||
console.log(test_delay);
|
console.log('test delay: ', test_delay);
|
||||||
if (!test_delay.from_client) {
|
if (!test_delay.from_client) {
|
||||||
this._ws?.sendMessage({ test_delay });
|
this._ws?.sendMessage({ test_delay });
|
||||||
}
|
}
|
||||||
|
@ -275,7 +274,7 @@ export default class Connection {
|
||||||
try {
|
try {
|
||||||
globals.copyToClipboard(new TextDecoder().decode(cb.content));
|
globals.copyToClipboard(new TextDecoder().decode(cb.content));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error('Failed to copy to clipboard, ', e);
|
||||||
}
|
}
|
||||||
// globals.pushEvent("clipboard", cb);
|
// globals.pushEvent("clipboard", cb);
|
||||||
} else if (msg?.cursor_data) {
|
} else if (msg?.cursor_data) {
|
||||||
|
@ -323,9 +322,9 @@ export default class Connection {
|
||||||
this._msgbox?.(type_, title, text, link);
|
this._msgbox?.(type_, title, text, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(frame: any) {
|
draw(display: number, frame: any) {
|
||||||
this._draw?.(frame);
|
this._draw?.(display, frame);
|
||||||
globals.draw(frame);
|
globals.draw(display, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
@ -348,22 +347,25 @@ export default class Connection {
|
||||||
this._draw = callback;
|
this._draw = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
login(password: string | undefined = undefined) {
|
login(info?: {
|
||||||
if (password) {
|
os_login?: message.OSLogin,
|
||||||
|
password?: Uint8Array
|
||||||
|
}) {
|
||||||
|
if (info?.password) {
|
||||||
const salt = this._hash?.salt;
|
const salt = this._hash?.salt;
|
||||||
let p = hash([password, salt!]);
|
let p = hash([info.password, salt!]);
|
||||||
this._password = p;
|
this._password = p;
|
||||||
const challenge = this._hash?.challenge;
|
const challenge = this._hash?.challenge;
|
||||||
p = hash([p, challenge!]);
|
p = hash([p, challenge!]);
|
||||||
this.msgbox("connecting", "Connecting...", "Logging in...");
|
this.msgbox("connecting", "Connecting...", "Logging in...");
|
||||||
this._sendLoginMessage(p);
|
this._sendLoginMessage({ os_login: info.os_login, password: p });
|
||||||
} else {
|
} else {
|
||||||
let p = this._password;
|
let p = this._password;
|
||||||
if (p) {
|
if (p) {
|
||||||
const challenge = this._hash?.challenge;
|
const challenge = this._hash?.challenge;
|
||||||
p = hash([p, challenge!]);
|
p = hash([p, challenge!]);
|
||||||
}
|
}
|
||||||
this._sendLoginMessage(p);
|
this._sendLoginMessage({ os_login: info?.os_login, password: p });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,14 +374,18 @@ export default class Connection {
|
||||||
await this.start(this._id);
|
await this.start(this._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_sendLoginMessage(password: Uint8Array | undefined = undefined) {
|
_sendLoginMessage(login: {
|
||||||
|
os_login?: message.OSLogin,
|
||||||
|
password?: Uint8Array,
|
||||||
|
}) {
|
||||||
const login_request = message.LoginRequest.fromPartial({
|
const login_request = message.LoginRequest.fromPartial({
|
||||||
username: this._id!,
|
username: this._id!,
|
||||||
my_id: "web", // to-do
|
my_id: "web", // to-do
|
||||||
my_name: "web", // to-do
|
my_name: "web", // to-do
|
||||||
password,
|
password: login.password,
|
||||||
option: this.getOptionMessage(),
|
option: this.getOptionMessage(),
|
||||||
video_ack_required: true,
|
video_ack_required: true,
|
||||||
|
os_login: login.os_login,
|
||||||
});
|
});
|
||||||
this._ws?.sendMessage({ login_request });
|
this._ws?.sendMessage({ login_request });
|
||||||
}
|
}
|
||||||
|
@ -436,7 +442,7 @@ export default class Connection {
|
||||||
i++;
|
i++;
|
||||||
if (i == n) this.sendVideoReceived();
|
if (i == n) this.sendVideoReceived();
|
||||||
if (ok && dec.frameBuffer && n == i) {
|
if (ok && dec.frameBuffer && n == i) {
|
||||||
this.draw(dec.frameBuffer);
|
this.draw(vf.display, dec.frameBuffer);
|
||||||
const now = new Date().getTime();
|
const now = new Date().getTime();
|
||||||
var elapsed = now - tm;
|
var elapsed = now - tm;
|
||||||
this._videoTestSpeed[1] += elapsed;
|
this._videoTestSpeed[1] += elapsed;
|
||||||
|
@ -570,10 +576,8 @@ export default class Connection {
|
||||||
}
|
}
|
||||||
this._options["tm"] = new Date().getTime();
|
this._options["tm"] = new Date().getTime();
|
||||||
const peers = globals.getPeers();
|
const peers = globals.getPeers();
|
||||||
if (peers) {
|
peers[this._id] = this._options;
|
||||||
peers[this._id] = this._options;
|
localStorage.setItem("peers", JSON.stringify(peers));
|
||||||
localStorage.setItem("peers", JSON.stringify(peers));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inputKey(
|
inputKey(
|
||||||
|
@ -744,7 +748,7 @@ export default class Connection {
|
||||||
loadVp9((decoder: any) => {
|
loadVp9((decoder: any) => {
|
||||||
this._videoDecoder = decoder;
|
this._videoDecoder = decoder;
|
||||||
console.log("vp9 loaded");
|
console.log("vp9 loaded");
|
||||||
console.log(decoder);
|
console.log('The decoder: ', decoder);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,13 @@ function jsonfyForDart(payload) {
|
||||||
var tmp = {};
|
var tmp = {};
|
||||||
for (const [key, value] of Object.entries(payload)) {
|
for (const [key, value] of Object.entries(payload)) {
|
||||||
if (!key) continue;
|
if (!key) continue;
|
||||||
tmp[key] = value instanceof Uint8Array ? '[' + value.toString() + ']' : JSON.stringify(value);
|
if (value instanceof String || typeof value == 'string') {
|
||||||
|
tmp[key] = value;
|
||||||
|
} else if (value instanceof Uint8Array) {
|
||||||
|
tmp[key] = '[' + value.toString() + ']';
|
||||||
|
} else {
|
||||||
|
tmp[key] = JSON.stringify(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -54,10 +60,10 @@ if (YUVCanvas.WebGLFrameSink.isAvailable()) {
|
||||||
}
|
}
|
||||||
let testSpeed = [0, 0];
|
let testSpeed = [0, 0];
|
||||||
|
|
||||||
export function draw(frame) {
|
export function draw(display, frame) {
|
||||||
if (yuvWorker) {
|
if (yuvWorker) {
|
||||||
// frame's (y/u/v).bytes already detached, can not transferrable any more.
|
// frame's (y/u/v).bytes already detached, can not transferrable any more.
|
||||||
yuvWorker.postMessage(frame);
|
yuvWorker.postMessage({display, frame});
|
||||||
} else {
|
} else {
|
||||||
var tm0 = new Date().getTime();
|
var tm0 = new Date().getTime();
|
||||||
yuvCanvas.drawFrame(frame);
|
yuvCanvas.drawFrame(frame);
|
||||||
|
@ -75,7 +81,7 @@ export function draw(frame) {
|
||||||
for (let i = 0; i < size; i += row) {
|
for (let i = 0; i < size; i += row) {
|
||||||
flipPixels.set(pixels.subarray(i, i + row), end - i);
|
flipPixels.set(pixels.subarray(i, i + row), end - i);
|
||||||
}
|
}
|
||||||
onRgba(flipPixels);
|
onRgba(display, flipPixels);
|
||||||
testSpeed[1] += new Date().getTime() - tm0;
|
testSpeed[1] += new Date().getTime() - tm0;
|
||||||
testSpeed[0] += 1;
|
testSpeed[0] += 1;
|
||||||
if (testSpeed[0] > 30) {
|
if (testSpeed[0] > 30) {
|
||||||
|
@ -189,8 +195,14 @@ window.setByName = (name, value) => {
|
||||||
break;
|
break;
|
||||||
case 'login':
|
case 'login':
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
curConn.setRemember(value.remember == 'true');
|
curConn.setRemember(value.remember);
|
||||||
curConn.login(value.password);
|
curConn.login({
|
||||||
|
os_login: {
|
||||||
|
username: value.os_username,
|
||||||
|
password: value.os_password,
|
||||||
|
},
|
||||||
|
password: value.password,
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case 'close':
|
case 'close':
|
||||||
close();
|
close();
|
||||||
|
@ -270,7 +282,7 @@ window.setByName = (name, value) => {
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
localStorage.setItem(name + ':' + value.name, value.value);
|
localStorage.setItem(name + ':' + value.name, value.value);
|
||||||
break;
|
break;
|
||||||
case 'peer_option':
|
case 'option:peer':
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
curConn.setOption(value.name, value.value);
|
curConn.setOption(value.name, value.value);
|
||||||
break;
|
break;
|
||||||
|
@ -409,7 +421,7 @@ export function playAudio(packet) {
|
||||||
window.init = async () => {
|
window.init = async () => {
|
||||||
if (yuvWorker) {
|
if (yuvWorker) {
|
||||||
yuvWorker.onmessage = (e) => {
|
yuvWorker.onmessage = (e) => {
|
||||||
onRgba(e.data);
|
onRgba(e.data.display, e.data.frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opusWorker.onmessage = (e) => {
|
opusWorker.onmessage = (e) => {
|
||||||
|
@ -493,12 +505,6 @@ function sessionAdd(value) {
|
||||||
const data = JSON.parse(value);
|
const data = JSON.parse(value);
|
||||||
window.curConn?.close();
|
window.curConn?.close();
|
||||||
const conn = new Connection();
|
const conn = new Connection();
|
||||||
if (data['password']) {
|
|
||||||
// TODO: encrypt password
|
|
||||||
conn.setOption('password', data['password'])
|
|
||||||
} else {
|
|
||||||
conn.setOption('password', undefined);
|
|
||||||
}
|
|
||||||
setConn(conn);
|
setConn(conn);
|
||||||
return '';
|
return '';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue