flutter_desktop_online_state: refactor connection page

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou
2022-07-27 22:56:28 +08:00
parent b6d56790fe
commit 0ba8b4079b
15 changed files with 1152 additions and 101 deletions

View File

@@ -21,6 +21,7 @@ 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';
typedef HandleMsgBox = void Function(Map<String, dynamic> evt, String id);
bool _waitForImage = false;
@@ -1092,7 +1093,7 @@ class FFI {
Future<List<String>> getAudioInputs() async {
return await bind.mainGetSoundInputs();
}
String getDefaultAudioInput() {
final input = getOption('audio-input');
if (input.isEmpty && Platform.isWindows) {
@@ -1110,21 +1111,6 @@ class FFI {
}
}
class Peer {
final String id;
final String username;
final String hostname;
final String platform;
final List<dynamic> tags;
Peer.fromJson(String id, Map<String, dynamic> json)
: id = id,
username = json['username'] ?? '',
hostname = json['hostname'] ?? '',
platform = json['platform'] ?? '',
tags = json['tags'] ?? [];
}
class Display {
double x = 0;
double y = 0;

View File

@@ -6,6 +6,7 @@ import 'dart:typed_data';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:external_path/external_path.dart';
import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';
@@ -21,6 +22,7 @@ class RgbaFrame extends Struct {
typedef F2 = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>);
typedef F3 = void Function(Pointer<Utf8>, Pointer<Utf8>);
typedef HandleEvent = void Function(Map<String, dynamic> evt);
/// FFI wrapper around the native Rust core.
/// Hides the platform differences.
@@ -30,6 +32,7 @@ class PlatformFFI {
String _homeDir = '';
F2? _getByName;
F3? _setByName;
var _eventHandlers = Map<String, Map<String, HandleEvent>>();
late RustdeskImpl _ffiBind;
void Function(Map<String, dynamic>)? _eventCallback;
@@ -40,6 +43,31 @@ class PlatformFFI {
return packageInfo.version;
}
bool registerEventHandler(
String event_name, String handler_name, HandleEvent handler) {
debugPrint('registerEventHandler $event_name $handler_name');
var handlers = _eventHandlers[event_name];
if (handlers == null) {
_eventHandlers[event_name] = {handler_name: handler};
return true;
} else {
if (handlers.containsKey(handler_name)) {
return false;
} else {
handlers[handler_name] = handler;
return true;
}
}
}
void unregisterEventHandler(String event_name, String handler_name) {
debugPrint('unregisterEventHandler $event_name $handler_name');
var handlers = _eventHandlers[event_name];
if (handlers != null) {
handlers.remove(handler_name);
}
}
/// Send **get** command to the Rust core based on [name] and [arg].
/// Return the result as a string.
String getByName(String name, [String arg = '']) {
@@ -138,6 +166,22 @@ class PlatformFFI {
version = await getVersion();
}
bool _tryHandle(Map<String, dynamic> evt) {
final name = evt['name'];
if (name != null) {
final handlers = _eventHandlers[name];
if (handlers != null) {
if (handlers.isNotEmpty) {
handlers.values.forEach((handler) {
handler(evt);
});
return true;
}
}
}
return false;
}
/// Start listening to the Rust core's events and frames.
void _startListenEvent(RustdeskImpl rustdeskImpl) {
() async {
@@ -145,7 +189,10 @@ class PlatformFFI {
if (_eventCallback != null) {
try {
Map<String, dynamic> event = json.decode(message);
_eventCallback!(event);
// _tryHandle here may be more flexible than _eventCallback
if (!_tryHandle(event)) {
_eventCallback!(event);
}
} catch (e) {
print('json.decode fail(): $e');
}

View File

@@ -0,0 +1,89 @@
import 'package:flutter/foundation.dart';
import '../../common.dart';
class Peer {
final String id;
final String username;
final String hostname;
final String platform;
final List<dynamic> tags;
bool online = false;
Peer.fromJson(String id, Map<String, dynamic> json)
: id = id,
username = json['username'] ?? '',
hostname = json['hostname'] ?? '',
platform = json['platform'] ?? '',
tags = json['tags'] ?? [];
Peer({
required this.id,
required this.username,
required this.hostname,
required this.platform,
required this.tags,
});
Peer.loading()
: this(
id: '...',
username: '...',
hostname: '...',
platform: '...',
tags: []);
}
class Peers extends ChangeNotifier {
late String _name;
late var _peers;
static const cbQueryOnlines = 'callback_query_onlines';
Peers(String name, List<Peer> peers) {
_name = name;
_peers = peers;
gFFI.ffiModel.platformFFI.registerEventHandler(cbQueryOnlines, _name,
(evt) {
_updateOnlineState(evt);
});
}
List<Peer> get peers => _peers;
@override
void dispose() {
gFFI.ffiModel.platformFFI.unregisterEventHandler(cbQueryOnlines, _name);
super.dispose();
}
Peer getByIndex(int index) {
if (index < _peers.length) {
return _peers[index];
} else {
return Peer.loading();
}
}
int getPeersCount() {
return _peers.length;
}
void _updateOnlineState(Map<String, dynamic> evt) {
evt['onlines'].split(',').forEach((online) {
for (var i = 0; i < _peers.length; i++) {
if (_peers[i].id == online) {
_peers[i].online = true;
}
}
});
evt['offlines'].split(',').forEach((offline) {
for (var i = 0; i < _peers.length; i++) {
if (_peers[i].id == offline) {
_peers[i].online = false;
}
}
});
notifyListeners();
}
}