mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
flutter_desktop: fix global envet stream shading && refactor platform ffi
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/models/model.dart';
|
||||
import 'package:flutter_hbb/models/platform_model.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@@ -46,7 +47,7 @@ class AbModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<String> getApiServer() async {
|
||||
return await _ffi?.bind.mainGetApiServer() ?? "";
|
||||
return await bind.mainGetApiServer() ?? "";
|
||||
}
|
||||
|
||||
void reset() {
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:get/get.dart';
|
||||
import 'package:path/path.dart' as Path;
|
||||
|
||||
import 'model.dart';
|
||||
import 'platform_model.dart';
|
||||
|
||||
enum SortBy { Name, Type, Modified, Size }
|
||||
|
||||
@@ -50,7 +51,7 @@ class FileModel extends ChangeNotifier {
|
||||
|
||||
bool get localSortAscending => _localSortAscending;
|
||||
|
||||
SortBy getSortStyle(bool isLocal){
|
||||
SortBy getSortStyle(bool isLocal) {
|
||||
return isLocal ? _localSortStyle : _remoteSortStyle;
|
||||
}
|
||||
|
||||
@@ -164,7 +165,7 @@ class FileModel extends ChangeNotifier {
|
||||
// Desktop uses jobTable
|
||||
// id = index + 1
|
||||
final jobIndex = getJob(id);
|
||||
if (jobIndex >= 0 && _jobTable.length > jobIndex){
|
||||
if (jobIndex >= 0 && _jobTable.length > jobIndex) {
|
||||
final job = _jobTable[jobIndex];
|
||||
job.fileNum = int.parse(evt['file_num']);
|
||||
job.speed = double.parse(evt['speed']);
|
||||
@@ -203,8 +204,7 @@ class FileModel extends ChangeNotifier {
|
||||
debugPrint("init remote home:${fd.path}");
|
||||
_currentRemoteDir = fd;
|
||||
}
|
||||
}
|
||||
finally {}
|
||||
} finally {}
|
||||
}
|
||||
_fileFetcher.tryCompleteTask(evt['value'], evt['is_local']);
|
||||
notifyListeners();
|
||||
@@ -260,7 +260,7 @@ class FileModel extends ChangeNotifier {
|
||||
final id = int.tryParse(evt['id']) ?? 0;
|
||||
if (false == resp) {
|
||||
final jobIndex = getJob(id);
|
||||
if (jobIndex != -1){
|
||||
if (jobIndex != -1) {
|
||||
cancelJob(id);
|
||||
final job = jobTable[jobIndex];
|
||||
job.state = JobState.done;
|
||||
@@ -274,9 +274,12 @@ class FileModel extends ChangeNotifier {
|
||||
// overwrite
|
||||
need_override = true;
|
||||
}
|
||||
_ffi.target?.bind.sessionSetConfirmOverrideFile(id: _ffi.target?.id ?? "",
|
||||
actId: id, fileNum: int.parse(evt['file_num']),
|
||||
needOverride: need_override, remember: fileConfirmCheckboxRemember,
|
||||
bind.sessionSetConfirmOverrideFile(
|
||||
id: _ffi.target?.id ?? "",
|
||||
actId: id,
|
||||
fileNum: int.parse(evt['file_num']),
|
||||
needOverride: need_override,
|
||||
remember: fileConfirmCheckboxRemember,
|
||||
isUpload: evt['is_upload'] == "true");
|
||||
}
|
||||
}
|
||||
@@ -288,21 +291,27 @@ class FileModel extends ChangeNotifier {
|
||||
|
||||
onReady() async {
|
||||
_localOption.home = _ffi.target?.getByName("get_home_dir") ?? "";
|
||||
_localOption.showHidden = (await _ffi.target?.bind.sessionGetPeerOption
|
||||
(id: _ffi.target?.id ?? "", name: "local_show_hidden"))?.isNotEmpty ?? false;
|
||||
_localOption.showHidden = (await bind.sessionGetPeerOption(
|
||||
id: _ffi.target?.id ?? "", name: "local_show_hidden"))
|
||||
?.isNotEmpty ??
|
||||
false;
|
||||
|
||||
_remoteOption.showHidden = (await _ffi.target?.bind.sessionGetPeerOption
|
||||
(id: _ffi.target?.id ?? "", name: "remote_show_hidden"))?.isNotEmpty ?? false;
|
||||
_remoteOption.showHidden = (await bind.sessionGetPeerOption(
|
||||
id: _ffi.target?.id ?? "", name: "remote_show_hidden"))
|
||||
?.isNotEmpty ??
|
||||
false;
|
||||
_remoteOption.isWindows = _ffi.target?.ffiModel.pi.platform == "Windows";
|
||||
|
||||
debugPrint("remote platform: ${_ffi.target?.ffiModel.pi.platform}");
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
|
||||
final local = (await _ffi.target?.bind.sessionGetPeerOption
|
||||
(id: _ffi.target?.id ?? "", name: "local_dir")) ?? "";
|
||||
final remote = (await _ffi.target?.bind.sessionGetPeerOption
|
||||
(id: _ffi.target?.id ?? "", name: "remote_dir")) ?? "";
|
||||
final local = (await bind.sessionGetPeerOption(
|
||||
id: _ffi.target?.id ?? "", name: "local_dir")) ??
|
||||
"";
|
||||
final remote = (await bind.sessionGetPeerOption(
|
||||
id: _ffi.target?.id ?? "", name: "remote_dir")) ??
|
||||
"";
|
||||
openDirectory(local.isEmpty ? _localOption.home : local, isLocal: true);
|
||||
openDirectory(remote.isEmpty ? _remoteOption.home : remote, isLocal: false);
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
@@ -313,7 +322,7 @@ class FileModel extends ChangeNotifier {
|
||||
openDirectory(_remoteOption.home, isLocal: false);
|
||||
}
|
||||
// load last transfer jobs
|
||||
await _ffi.target?.bind.sessionLoadLastTransferJobs(id: '${_ffi.target?.id}');
|
||||
await bind.sessionLoadLastTransferJobs(id: '${_ffi.target?.id}');
|
||||
}
|
||||
|
||||
onClose() {
|
||||
@@ -327,8 +336,8 @@ class FileModel extends ChangeNotifier {
|
||||
msgMap["remote_dir"] = _currentRemoteDir.path;
|
||||
msgMap["remote_show_hidden"] = _remoteOption.showHidden ? "Y" : "";
|
||||
final id = _ffi.target?.id ?? "";
|
||||
for(final msg in msgMap.entries) {
|
||||
_ffi.target?.bind.sessionPeerOption(id: id, name: msg.key, value: msg.value);
|
||||
for (final msg in msgMap.entries) {
|
||||
bind.sessionPeerOption(id: id, name: msg.key, value: msg.value);
|
||||
}
|
||||
_currentLocalDir.clear();
|
||||
_currentRemoteDir.clear();
|
||||
@@ -339,8 +348,9 @@ class FileModel extends ChangeNotifier {
|
||||
Future refresh({bool? isLocal}) async {
|
||||
if (isDesktop) {
|
||||
isLocal = isLocal ?? _isLocal;
|
||||
await isLocal ? openDirectory(currentLocalDir.path, isLocal: isLocal) :
|
||||
openDirectory(currentRemoteDir.path, isLocal: isLocal);
|
||||
await isLocal
|
||||
? openDirectory(currentLocalDir.path, isLocal: isLocal)
|
||||
: openDirectory(currentRemoteDir.path, isLocal: isLocal);
|
||||
} else {
|
||||
await openDirectory(currentDir.path);
|
||||
}
|
||||
@@ -353,7 +363,9 @@ class FileModel extends ChangeNotifier {
|
||||
final isWindows =
|
||||
isLocal ? _localOption.isWindows : _remoteOption.isWindows;
|
||||
// process /C:\ -> C:\ on Windows
|
||||
if (isLocal ? _localOption.isWindows : _remoteOption.isWindows && path.length > 1 && path[0] == '/') {
|
||||
if (isLocal
|
||||
? _localOption.isWindows
|
||||
: _remoteOption.isWindows && path.length > 1 && path[0] == '/') {
|
||||
path = path.substring(1);
|
||||
if (path[path.length - 1] != '\\') {
|
||||
path = path + "\\";
|
||||
@@ -380,7 +392,8 @@ class FileModel extends ChangeNotifier {
|
||||
|
||||
goToParentDirectory({bool? isLocal}) {
|
||||
isLocal = isLocal ?? _isLocal;
|
||||
final isWindows = isLocal ? _localOption.isWindows : _remoteOption.isWindows;
|
||||
final isWindows =
|
||||
isLocal ? _localOption.isWindows : _remoteOption.isWindows;
|
||||
final currDir = isLocal ? currentLocalDir : currentRemoteDir;
|
||||
var parent = PathUtil.dirname(currDir.path, isWindows);
|
||||
// specially for C:\, D:\, goto '/'
|
||||
@@ -395,12 +408,11 @@ class FileModel extends ChangeNotifier {
|
||||
sendFiles(SelectedItems items, {bool isRemote = false}) {
|
||||
if (isDesktop) {
|
||||
// desktop sendFiles
|
||||
final toPath =
|
||||
isRemote ? currentLocalDir.path : currentRemoteDir.path;
|
||||
final toPath = isRemote ? currentLocalDir.path : currentRemoteDir.path;
|
||||
final isWindows =
|
||||
isRemote ? _localOption.isWindows : _remoteOption.isWindows;
|
||||
isRemote ? _localOption.isWindows : _remoteOption.isWindows;
|
||||
final showHidden =
|
||||
isRemote ? _localOption.showHidden : _remoteOption.showHidden;
|
||||
isRemote ? _localOption.showHidden : _remoteOption.showHidden;
|
||||
items.items.forEach((from) async {
|
||||
final jobId = ++_jobId;
|
||||
_jobTable.add(JobProgress()
|
||||
@@ -408,11 +420,17 @@ class FileModel extends ChangeNotifier {
|
||||
..totalSize = from.size
|
||||
..state = JobState.inProgress
|
||||
..id = jobId
|
||||
..isRemote = isRemote
|
||||
);
|
||||
_ffi.target?.bind.sessionSendFiles(id: '${_ffi.target?.id}', actId: _jobId, path: from.path, to: PathUtil.join(toPath, from.name, isWindows)
|
||||
,fileNum: 0, includeHidden: showHidden, isRemote: isRemote);
|
||||
print("path:${from.path}, toPath:${toPath}, to:${PathUtil.join(toPath, from.name, isWindows)}");
|
||||
..isRemote = isRemote);
|
||||
bind.sessionSendFiles(
|
||||
id: '${_ffi.target?.id}',
|
||||
actId: _jobId,
|
||||
path: from.path,
|
||||
to: PathUtil.join(toPath, from.name, isWindows),
|
||||
fileNum: 0,
|
||||
includeHidden: showHidden,
|
||||
isRemote: isRemote);
|
||||
print(
|
||||
"path:${from.path}, toPath:${toPath}, to:${PathUtil.join(toPath, from.name, isWindows)}");
|
||||
});
|
||||
} else {
|
||||
if (items.isLocal == null) {
|
||||
@@ -421,15 +439,21 @@ class FileModel extends ChangeNotifier {
|
||||
}
|
||||
_jobProgress.state = JobState.inProgress;
|
||||
final toPath =
|
||||
items.isLocal! ? currentRemoteDir.path : currentLocalDir.path;
|
||||
items.isLocal! ? currentRemoteDir.path : currentLocalDir.path;
|
||||
final isWindows =
|
||||
items.isLocal! ? _localOption.isWindows : _remoteOption.isWindows;
|
||||
items.isLocal! ? _localOption.isWindows : _remoteOption.isWindows;
|
||||
final showHidden =
|
||||
items.isLocal! ? _localOption.showHidden : _remoteOption.showHidden;
|
||||
items.isLocal! ? _localOption.showHidden : _remoteOption.showHidden;
|
||||
items.items.forEach((from) async {
|
||||
_jobId++;
|
||||
await _ffi.target?.bind.sessionSendFiles(id: '${_ffi.target?.getId()}', actId: _jobId, path: from.path, to: PathUtil.join(toPath, from.name, isWindows)
|
||||
,fileNum: 0, includeHidden: showHidden, isRemote: !(items.isLocal!));
|
||||
await bind.sessionSendFiles(
|
||||
id: '${_ffi.target?.getId()}',
|
||||
actId: _jobId,
|
||||
path: from.path,
|
||||
to: PathUtil.join(toPath, from.name, isWindows),
|
||||
fileNum: 0,
|
||||
includeHidden: showHidden,
|
||||
isRemote: !(items.isLocal!));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -626,21 +650,34 @@ class FileModel extends ChangeNotifier {
|
||||
}
|
||||
|
||||
sendRemoveFile(String path, int fileNum, bool isLocal) {
|
||||
_ffi.target?.bind.sessionRemoveFile(id: '${_ffi.target?.id}', actId: _jobId, path: path, isRemote: !isLocal, fileNum: fileNum);
|
||||
bind.sessionRemoveFile(
|
||||
id: '${_ffi.target?.id}',
|
||||
actId: _jobId,
|
||||
path: path,
|
||||
isRemote: !isLocal,
|
||||
fileNum: fileNum);
|
||||
}
|
||||
|
||||
sendRemoveEmptyDir(String path, int fileNum, bool isLocal) {
|
||||
_ffi.target?.bind.sessionRemoveAllEmptyDirs(id: '${_ffi.target?.id}', actId: _jobId, path: path, isRemote: !isLocal);
|
||||
bind.sessionRemoveAllEmptyDirs(
|
||||
id: '${_ffi.target?.id}',
|
||||
actId: _jobId,
|
||||
path: path,
|
||||
isRemote: !isLocal);
|
||||
}
|
||||
|
||||
createDir(String path, {bool? isLocal}) async {
|
||||
isLocal = isLocal ?? this.isLocal;
|
||||
_jobId++;
|
||||
_ffi.target?.bind.sessionCreateDir(id: '${_ffi.target?.id}', actId: _jobId, path: path, isRemote: !isLocal);
|
||||
bind.sessionCreateDir(
|
||||
id: '${_ffi.target?.id}',
|
||||
actId: _jobId,
|
||||
path: path,
|
||||
isRemote: !isLocal);
|
||||
}
|
||||
|
||||
cancelJob(int id) async {
|
||||
_ffi.target?.bind.sessionCancelJob(id: '${_ffi.target?.id}', actId: id);
|
||||
bind.sessionCancelJob(id: '${_ffi.target?.id}', actId: id);
|
||||
jobReset();
|
||||
}
|
||||
|
||||
@@ -650,14 +687,18 @@ class FileModel extends ChangeNotifier {
|
||||
// compatible for mobile logic
|
||||
_currentLocalDir.changeSortStyle(sort, ascending: ascending);
|
||||
_currentRemoteDir.changeSortStyle(sort, ascending: ascending);
|
||||
_localSortStyle = sort; _localSortAscending = ascending;
|
||||
_remoteSortStyle = sort; _remoteSortAscending = ascending;
|
||||
_localSortStyle = sort;
|
||||
_localSortAscending = ascending;
|
||||
_remoteSortStyle = sort;
|
||||
_remoteSortAscending = ascending;
|
||||
} else if (isLocal) {
|
||||
_currentLocalDir.changeSortStyle(sort, ascending: ascending);
|
||||
_localSortStyle = sort; _localSortAscending = ascending;
|
||||
_localSortStyle = sort;
|
||||
_localSortAscending = ascending;
|
||||
} else {
|
||||
_currentRemoteDir.changeSortStyle(sort, ascending: ascending);
|
||||
_remoteSortStyle = sort; _remoteSortAscending = ascending;
|
||||
_remoteSortStyle = sort;
|
||||
_remoteSortAscending = ascending;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -668,7 +709,7 @@ class FileModel extends ChangeNotifier {
|
||||
|
||||
void updateFolderFiles(Map<String, dynamic> evt) {
|
||||
// ret: "{\"id\":1,\"num_entries\":12,\"total_size\":1264822.0}"
|
||||
Map<String,dynamic> info = json.decode(evt['info']);
|
||||
Map<String, dynamic> info = json.decode(evt['info']);
|
||||
int id = info['id'];
|
||||
int num_entries = info['num_entries'];
|
||||
double total_size = info['total_size'];
|
||||
@@ -685,7 +726,7 @@ class FileModel extends ChangeNotifier {
|
||||
|
||||
void loadLastJob(Map<String, dynamic> evt) {
|
||||
debugPrint("load last job: ${evt}");
|
||||
Map<String,dynamic> jobDetail = json.decode(evt['value']);
|
||||
Map<String, dynamic> jobDetail = json.decode(evt['value']);
|
||||
// int id = int.parse(jobDetail['id']);
|
||||
String remote = jobDetail['remote'];
|
||||
String to = jobDetail['to'];
|
||||
@@ -703,13 +744,14 @@ class FileModel extends ChangeNotifier {
|
||||
..showHidden = showHidden
|
||||
..state = JobState.paused;
|
||||
jobTable.add(jobProgress);
|
||||
_ffi.target?.bind.sessionAddJob(id: '${_ffi.target?.id}',
|
||||
isRemote: isRemote,
|
||||
includeHidden: showHidden,
|
||||
actId: currJobId,
|
||||
path: isRemote ? remote : to,
|
||||
to: isRemote ? to: remote,
|
||||
fileNum: fileNum,
|
||||
bind.sessionAddJob(
|
||||
id: '${_ffi.target?.id}',
|
||||
isRemote: isRemote,
|
||||
includeHidden: showHidden,
|
||||
actId: currJobId,
|
||||
path: isRemote ? remote : to,
|
||||
to: isRemote ? to : remote,
|
||||
fileNum: fileNum,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -717,9 +759,8 @@ class FileModel extends ChangeNotifier {
|
||||
final jobIndex = getJob(jobId);
|
||||
if (jobIndex != -1) {
|
||||
final job = jobTable[jobIndex];
|
||||
_ffi.target?.bind.sessionResumeJob(id: '${_ffi.target?.id}',
|
||||
actId: job.id,
|
||||
isRemote: job.isRemote);
|
||||
bind.sessionResumeJob(
|
||||
id: '${_ffi.target?.id}', actId: job.id, isRemote: job.isRemote);
|
||||
job.state = JobState.inProgress;
|
||||
} else {
|
||||
debugPrint("jobId ${jobId} is not exists");
|
||||
@@ -844,12 +885,12 @@ class FileFetcher {
|
||||
String path, bool isLocal, bool showHidden) async {
|
||||
try {
|
||||
if (isLocal) {
|
||||
final res = await _ffi.bind.sessionReadLocalDirSync(
|
||||
final res = await bind.sessionReadLocalDirSync(
|
||||
id: id ?? "", path: path, showHidden: showHidden);
|
||||
final fd = FileDirectory.fromJson(jsonDecode(res));
|
||||
return fd;
|
||||
} else {
|
||||
await _ffi.bind.sessionReadRemoteDir(
|
||||
await bind.sessionReadRemoteDir(
|
||||
id: id ?? "", path: path, includeHidden: showHidden);
|
||||
return registerReadTask(isLocal, path);
|
||||
}
|
||||
@@ -862,7 +903,12 @@ class FileFetcher {
|
||||
int id, String path, bool isLocal, bool showHidden) async {
|
||||
// TODO test Recursive is show hidden default?
|
||||
try {
|
||||
await _ffi.bind.sessionReadDirRecursive(id: _ffi.id, actId: id, path: path, isRemote: !isLocal, showHidden: showHidden);
|
||||
await bind.sessionReadDirRecursive(
|
||||
id: _ffi.id,
|
||||
actId: id,
|
||||
path: path,
|
||||
isRemote: !isLocal,
|
||||
showHidden: showHidden);
|
||||
return registerReadRecursiveTask(id);
|
||||
} catch (e) {
|
||||
return Future.error(e);
|
||||
@@ -1033,7 +1079,9 @@ List<Entry> _sortList(List<Entry> list, SortBy sortType, bool ascending) {
|
||||
files.sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
|
||||
|
||||
// first folders will go to list (if available) then files will go to list.
|
||||
return ascending ? [...dirs, ...files] : [...dirs.reversed.toList(), ...files.reversed.toList()];
|
||||
return ascending
|
||||
? [...dirs, ...files]
|
||||
: [...dirs.reversed.toList(), ...files.reversed.toList()];
|
||||
} else if (sortType == SortBy.Modified) {
|
||||
// making the list of Path & DateTime
|
||||
List<_PathStat> _pathStat = [];
|
||||
@@ -1065,7 +1113,9 @@ List<Entry> _sortList(List<Entry> list, SortBy sortType, bool ascending) {
|
||||
.split('.')
|
||||
.last
|
||||
.compareTo(b.name.toLowerCase().split('.').last));
|
||||
return ascending ? [...dirs, ...files]: [...dirs.reversed.toList(), ...files.reversed.toList()];
|
||||
return ascending
|
||||
? [...dirs, ...files]
|
||||
: [...dirs.reversed.toList(), ...files.reversed.toList()];
|
||||
} else if (sortType == SortBy.Size) {
|
||||
// create list of path and size
|
||||
Map<String, int> _sizeMap = {};
|
||||
@@ -1090,7 +1140,9 @@ List<Entry> _sortList(List<Entry> list, SortBy sortType, bool ascending) {
|
||||
.indexWhere((element) => element.key == a.name)
|
||||
.compareTo(
|
||||
_sizeMapList.indexWhere((element) => element.key == b.name)));
|
||||
return ascending ? [...dirs, ...files]: [...dirs.reversed.toList(), ...files.reversed.toList()];
|
||||
return ascending
|
||||
? [...dirs, ...files]
|
||||
: [...dirs.reversed.toList(), ...files.reversed.toList()];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ import 'package:tuple/tuple.dart';
|
||||
import '../common.dart';
|
||||
import '../mobile/widgets/dialog.dart';
|
||||
import '../mobile/widgets/overlay.dart';
|
||||
import 'native_model.dart' if (dart.library.html) 'web_model.dart';
|
||||
import 'peer_model.dart';
|
||||
import 'platform_model.dart';
|
||||
|
||||
typedef HandleMsgBox = void Function(Map<String, dynamic> evt, String id);
|
||||
bool _waitForImage = false;
|
||||
@@ -29,7 +29,6 @@ bool _waitForImage = false;
|
||||
class FfiModel with ChangeNotifier {
|
||||
PeerInfo _pi = PeerInfo();
|
||||
Display _display = Display();
|
||||
PlatformFFI _platformFFI = PlatformFFI();
|
||||
|
||||
var _inputBlocked = false;
|
||||
final _permissions = Map<String, bool>();
|
||||
@@ -44,12 +43,6 @@ class FfiModel with ChangeNotifier {
|
||||
|
||||
Display get display => _display;
|
||||
|
||||
PlatformFFI get platformFFI => _platformFFI;
|
||||
|
||||
set platformFFI(PlatformFFI value) {
|
||||
_platformFFI = value;
|
||||
}
|
||||
|
||||
bool? get secure => _secure;
|
||||
|
||||
bool? get direct => _direct;
|
||||
@@ -71,10 +64,6 @@ class FfiModel with ChangeNotifier {
|
||||
clear();
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
await _platformFFI.init();
|
||||
}
|
||||
|
||||
void toggleTouchMode() {
|
||||
if (!isPeerAndroid) {
|
||||
_touchMode = !_touchMode;
|
||||
@@ -280,7 +269,7 @@ class FfiModel with ChangeNotifier {
|
||||
_timer?.cancel();
|
||||
if (hasRetry) {
|
||||
_timer = Timer(Duration(seconds: _reconnects), () {
|
||||
parent.target?.bind.sessionReconnect(id: id);
|
||||
bind.sessionReconnect(id: id);
|
||||
clearPermissions();
|
||||
showLoading(translate('Connecting...'));
|
||||
});
|
||||
@@ -306,9 +295,8 @@ class FfiModel with ChangeNotifier {
|
||||
Timer(Duration(milliseconds: 100), showMobileActionsOverlay);
|
||||
}
|
||||
} else {
|
||||
_touchMode = await parent.target?.bind
|
||||
.getSessionOption(id: peerId, arg: "touch-mode") !=
|
||||
'';
|
||||
_touchMode =
|
||||
await bind.getSessionOption(id: peerId, arg: "touch-mode") != '';
|
||||
}
|
||||
|
||||
if (evt['is_file_transfer'] == "true") {
|
||||
@@ -387,8 +375,7 @@ class ImageModel with ChangeNotifier {
|
||||
}
|
||||
Future.delayed(Duration(milliseconds: 1), () {
|
||||
if (parent.target?.ffiModel.isPeerAndroid ?? false) {
|
||||
parent.target?.bind
|
||||
.sessionPeerOption(id: _id, name: "view-style", value: "shrink");
|
||||
bind.sessionPeerOption(id: _id, name: "view-style", value: "shrink");
|
||||
parent.target?.canvasModel.updateViewStyle();
|
||||
}
|
||||
});
|
||||
@@ -439,8 +426,7 @@ class CanvasModel with ChangeNotifier {
|
||||
double get tabBarHeight => _tabBarHeight;
|
||||
|
||||
void updateViewStyle() async {
|
||||
final s =
|
||||
await parent.target?.bind.getSessionOption(id: id, arg: 'view-style');
|
||||
final s = await bind.getSessionOption(id: id, arg: 'view-style');
|
||||
if (s == null) {
|
||||
return;
|
||||
}
|
||||
@@ -844,13 +830,6 @@ class FFI {
|
||||
this.userModel = UserModel(WeakReference(this));
|
||||
}
|
||||
|
||||
static FFI newFFI() {
|
||||
final ffi = FFI();
|
||||
// keep platformFFI only once
|
||||
ffi.ffiModel.platformFFI = gFFI.ffiModel.platformFFI;
|
||||
return ffi;
|
||||
}
|
||||
|
||||
/// Get the remote id for current client.
|
||||
String getId() {
|
||||
return getByName('remote_id'); // TODO
|
||||
@@ -1008,16 +987,16 @@ class FFI {
|
||||
/// Send **get** command to the Rust core based on [name] and [arg].
|
||||
/// Return the result as a string.
|
||||
String getByName(String name, [String arg = '']) {
|
||||
return ffiModel.platformFFI.getByName(name, arg);
|
||||
return platformFFI.getByName(name, arg);
|
||||
}
|
||||
|
||||
/// Send **set** command to the Rust core based on [name] and [value].
|
||||
void setByName(String name, [String value = '']) {
|
||||
ffiModel.platformFFI.setByName(name, value);
|
||||
platformFFI.setByName(name, value);
|
||||
}
|
||||
|
||||
String getOption(String name) {
|
||||
return ffiModel.platformFFI.getByName("option", name);
|
||||
return platformFFI.getByName("option", name);
|
||||
}
|
||||
|
||||
Future<String> getLocalOption(String name) {
|
||||
@@ -1040,11 +1019,9 @@ class FFI {
|
||||
Map<String, String> res = Map()
|
||||
..["name"] = name
|
||||
..["value"] = value;
|
||||
return ffiModel.platformFFI.setByName('option', jsonEncode(res));
|
||||
return platformFFI.setByName('option', jsonEncode(res));
|
||||
}
|
||||
|
||||
RustdeskImpl get bind => ffiModel.platformFFI.ffiBind;
|
||||
|
||||
handleMouse(Map<String, dynamic> evt, {double tabBarHeight = 0.0}) {
|
||||
var type = '';
|
||||
var isMove = false;
|
||||
@@ -1102,18 +1079,18 @@ class FFI {
|
||||
|
||||
listenToMouse(bool yesOrNo) {
|
||||
if (yesOrNo) {
|
||||
ffiModel.platformFFI.startDesktopWebListener();
|
||||
platformFFI.startDesktopWebListener();
|
||||
} else {
|
||||
ffiModel.platformFFI.stopDesktopWebListener();
|
||||
platformFFI.stopDesktopWebListener();
|
||||
}
|
||||
}
|
||||
|
||||
void setMethodCallHandler(FMethod callback) {
|
||||
ffiModel.platformFFI.setMethodCallHandler(callback);
|
||||
platformFFI.setMethodCallHandler(callback);
|
||||
}
|
||||
|
||||
Future<bool> invokeMethod(String method, [dynamic arguments]) async {
|
||||
return await ffiModel.platformFFI.invokeMethod(method, arguments);
|
||||
return await platformFFI.invokeMethod(method, arguments);
|
||||
}
|
||||
|
||||
Future<List<String>> getAudioInputs() async {
|
||||
|
||||
@@ -27,17 +27,24 @@ typedef HandleEvent = void Function(Map<String, dynamic> evt);
|
||||
/// FFI wrapper around the native Rust core.
|
||||
/// Hides the platform differences.
|
||||
class PlatformFFI {
|
||||
Pointer<RgbaFrame>? _lastRgbaFrame;
|
||||
String _dir = '';
|
||||
String _homeDir = '';
|
||||
F2? _getByName;
|
||||
F3? _setByName;
|
||||
var _eventHandlers = Map<String, Map<String, HandleEvent>>();
|
||||
late RustdeskImpl _ffiBind;
|
||||
late String _appType;
|
||||
void Function(Map<String, dynamic>)? _eventCallback;
|
||||
|
||||
PlatformFFI._();
|
||||
|
||||
static final PlatformFFI instance = PlatformFFI._();
|
||||
final _toAndroidChannel = MethodChannel("mChannel");
|
||||
|
||||
RustdeskImpl get ffiBind => _ffiBind;
|
||||
|
||||
static get localeName => Platform.localeName;
|
||||
|
||||
static Future<String> getVersion() async {
|
||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
return packageInfo.version;
|
||||
@@ -94,10 +101,8 @@ class PlatformFFI {
|
||||
}
|
||||
|
||||
/// Init the FFI class, loads the native Rust core library.
|
||||
Future<Null> init() async {
|
||||
isIOS = Platform.isIOS;
|
||||
isAndroid = Platform.isAndroid;
|
||||
isDesktop = Platform.isWindows || Platform.isMacOS || Platform.isLinux;
|
||||
Future<Null> init(String appType) async {
|
||||
_appType = appType;
|
||||
// if (isDesktop) {
|
||||
// // TODO
|
||||
// return;
|
||||
@@ -111,7 +116,7 @@ class PlatformFFI {
|
||||
: Platform.isMacOS
|
||||
? DynamicLibrary.open("librustdesk.dylib")
|
||||
: DynamicLibrary.process();
|
||||
print('initializing FFI');
|
||||
debugPrint('initializing FFI ${_appType}');
|
||||
try {
|
||||
_getByName = dylib.lookupFunction<F2, F2>('get_by_name');
|
||||
_setByName =
|
||||
@@ -155,7 +160,8 @@ class PlatformFFI {
|
||||
name = macOsInfo.computerName;
|
||||
id = macOsInfo.systemGUID ?? "";
|
||||
}
|
||||
print("info1-id:$id,info2-name:$name,dir:$_dir,homeDir:$_homeDir");
|
||||
print(
|
||||
"_appType:$_appType,info1-id:$id,info2-name:$name,dir:$_dir,homeDir:$_homeDir");
|
||||
setByName('info1', id);
|
||||
setByName('info2', name);
|
||||
setByName('home_dir', _homeDir);
|
||||
@@ -185,17 +191,18 @@ class PlatformFFI {
|
||||
/// Start listening to the Rust core's events and frames.
|
||||
void _startListenEvent(RustdeskImpl rustdeskImpl) {
|
||||
() async {
|
||||
await for (final message in rustdeskImpl.startGlobalEventStream()) {
|
||||
if (_eventCallback != null) {
|
||||
try {
|
||||
Map<String, dynamic> event = json.decode(message);
|
||||
// _tryHandle here may be more flexible than _eventCallback
|
||||
if (!_tryHandle(event)) {
|
||||
await for (final message
|
||||
in rustdeskImpl.startGlobalEventStream(appType: _appType)) {
|
||||
try {
|
||||
Map<String, dynamic> event = json.decode(message);
|
||||
// _tryHandle here may be more flexible than _eventCallback
|
||||
if (!_tryHandle(event)) {
|
||||
if (_eventCallback != null) {
|
||||
_eventCallback!(event);
|
||||
}
|
||||
} catch (e) {
|
||||
print('json.decode fail(): $e');
|
||||
}
|
||||
} catch (e) {
|
||||
print('json.decode fail(): $e');
|
||||
}
|
||||
}
|
||||
}();
|
||||
@@ -212,7 +219,7 @@ class PlatformFFI {
|
||||
void stopDesktopWebListener() {}
|
||||
|
||||
void setMethodCallHandler(FMethod callback) {
|
||||
toAndroidChannel.setMethodCallHandler((call) async {
|
||||
_toAndroidChannel.setMethodCallHandler((call) async {
|
||||
callback(call.method, call.arguments);
|
||||
return null;
|
||||
});
|
||||
@@ -220,9 +227,6 @@ class PlatformFFI {
|
||||
|
||||
invokeMethod(String method, [dynamic arguments]) async {
|
||||
if (!isAndroid) return Future<bool>(() => false);
|
||||
return await toAndroidChannel.invokeMethod(method, arguments);
|
||||
return await _toAndroidChannel.invokeMethod(method, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
final localeName = Platform.localeName;
|
||||
final toAndroidChannel = MethodChannel("mChannel");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import '../../common.dart';
|
||||
import 'platform_model.dart';
|
||||
|
||||
class Peer {
|
||||
final String id;
|
||||
@@ -44,11 +44,10 @@ class Peers extends ChangeNotifier {
|
||||
_name = name;
|
||||
_loadEvent = loadEvent;
|
||||
_peers = _initPeers;
|
||||
gFFI.ffiModel.platformFFI.registerEventHandler(_cbQueryOnlines, _name,
|
||||
(evt) {
|
||||
platformFFI.registerEventHandler(_cbQueryOnlines, _name, (evt) {
|
||||
_updateOnlineState(evt);
|
||||
});
|
||||
gFFI.ffiModel.platformFFI.registerEventHandler(_loadEvent, _name, (evt) {
|
||||
platformFFI.registerEventHandler(_loadEvent, _name, (evt) {
|
||||
_updatePeers(evt);
|
||||
});
|
||||
}
|
||||
@@ -57,8 +56,8 @@ class Peers extends ChangeNotifier {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
gFFI.ffiModel.platformFFI.unregisterEventHandler(_cbQueryOnlines, _name);
|
||||
gFFI.ffiModel.platformFFI.unregisterEventHandler(_loadEvent, _name);
|
||||
platformFFI.unregisterEventHandler(_cbQueryOnlines, _name);
|
||||
platformFFI.unregisterEventHandler(_loadEvent, _name);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
7
flutter/lib/models/platform_model.dart
Normal file
7
flutter/lib/models/platform_model.dart
Normal file
@@ -0,0 +1,7 @@
|
||||
import 'package:flutter_hbb/generated_bridge.dart';
|
||||
import 'native_model.dart' if (dart.library.html) 'web_model.dart';
|
||||
|
||||
final platformFFI = PlatformFFI.instance;
|
||||
final localeName = PlatformFFI.localeName;
|
||||
|
||||
RustdeskImpl get bind => platformFFI.ffiBind;
|
||||
@@ -6,6 +6,7 @@ import 'package:get/get.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'model.dart';
|
||||
import 'platform_model.dart';
|
||||
|
||||
class UserModel extends ChangeNotifier {
|
||||
var userName = "".obs;
|
||||
@@ -17,8 +18,7 @@ class UserModel extends ChangeNotifier {
|
||||
if (userName.isNotEmpty) {
|
||||
return userName.value;
|
||||
}
|
||||
final userInfo =
|
||||
await parent.target?.bind.mainGetLocalOption(key: 'user_info') ?? "{}";
|
||||
final userInfo = await bind.mainGetLocalOption(key: 'user_info') ?? "{}";
|
||||
if (userInfo.trim().isEmpty) {
|
||||
return "";
|
||||
}
|
||||
@@ -29,10 +29,6 @@ class UserModel extends ChangeNotifier {
|
||||
|
||||
Future<void> logOut() async {
|
||||
debugPrint("start logout");
|
||||
final bind = parent.target?.bind;
|
||||
if (bind == null) {
|
||||
return;
|
||||
}
|
||||
final url = await bind.mainGetApiServer();
|
||||
final _ = await http.post(Uri.parse("$url/api/logout"),
|
||||
body: {
|
||||
@@ -55,10 +51,6 @@ class UserModel extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> login(String userName, String pass) async {
|
||||
final bind = parent.target?.bind;
|
||||
if (bind == null) {
|
||||
return {"error": "no context"};
|
||||
}
|
||||
final url = await bind.mainGetApiServer();
|
||||
try {
|
||||
final resp = await http.post(Uri.parse("$url/api/login"),
|
||||
|
||||
@@ -20,7 +20,12 @@ class PlatformFFI {
|
||||
context.callMethod('setByName', [name, value]);
|
||||
}
|
||||
|
||||
static Future<Null> init() async {
|
||||
PlatformFFI._();
|
||||
static final PlatformFFI instance = PlatformFFI._();
|
||||
|
||||
static get localeName => window.navigator.language;
|
||||
|
||||
static Future<Null> init(String _appType) async {
|
||||
isWeb = true;
|
||||
isWebDesktop = !context.callMethod('isMobile');
|
||||
context.callMethod('init');
|
||||
@@ -68,5 +73,3 @@ class PlatformFFI {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final localeName = window.navigator.language;
|
||||
|
||||
Reference in New Issue
Block a user