Merge pull request #4166 from fufesou/feat/plugin_framework

plugin_framework, load plugin
This commit is contained in:
RustDesk
2023-04-23 16:47:31 +08:00
committed by GitHub
13 changed files with 420 additions and 105 deletions

View File

@@ -1434,27 +1434,38 @@ class _PluginState extends State<_Plugin> {
final scrollController = ScrollController();
buildCards(DescModel model) {
final cards = <Widget>[
_Card(title: 'Plugin', children: [
_checkbox('Enable', bind.pluginIsEnabled, (bool v) async {
if (!v) {
clearLocations();
}
await bind.pluginEnable(v: v);
}),
]),
_Card(
title: 'Plugin',
children: [
_checkbox(
'Enable',
() => bind.pluginIsEnabled() ?? false,
(bool v) async {
if (!v) {
clearLocations();
}
await bind.pluginEnable(v: v);
},
),
],
),
];
model.all.forEach((key, value) {
cards.add(_Card(title: key, children: [
_Button('Reload', () {
bind.pluginReload(id: key);
}),
_checkbox('Enable', () => bind.pluginIdIsEnabled(id: key),
(bool v) async {
if (!v) {
clearPlugin(key);
}
await bind.pluginIdEnable(id: key, v: v);
}),
_Button(
'Reload',
() => bind.pluginReload(id: key),
),
_checkbox(
'Enable',
() => bind.pluginIdIsEnabled(id: key),
(bool v) async {
if (!v) {
clearPlugin(key);
}
await bind.pluginIdEnable(id: key, v: v);
},
),
]));
});
return cards;

View File

@@ -341,6 +341,7 @@ class ServerModel with ChangeNotifier {
_isStart = true;
notifyListeners();
parent.target?.ffiModel.updateEventListener("");
bind.pluginSyncUi();
await parent.target?.invokeMethod("init_service");
// ugly is here, because for desktop, below is useless
await bind.mainStartService();

View File

@@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:collection';
import 'package:flutter/foundation.dart';
@@ -64,7 +65,7 @@ class Location {
Location(this.ui);
Location.fromJson(Map<String, dynamic> json) : ui = HashMap() {
json.forEach((key, value) {
(json['ui'] as Map<String, dynamic>).forEach((key, value) {
var ui = UiType.create(value);
if (ui != null) {
this.ui[ui.key] = ui;
@@ -93,12 +94,12 @@ class ConfigItem {
}
class Config {
List<ConfigItem> local;
List<ConfigItem> shared;
List<ConfigItem> peer;
Config(this.local, this.peer);
Config(this.shared, this.peer);
Config.fromJson(Map<String, dynamic> json)
: local = (json['local'] as List<dynamic>)
: shared = (json['shared'] as List<dynamic>)
.map((e) => ConfigItem.fromJson(e))
.toList(),
peer = (json['peer'] as List<dynamic>)
@@ -145,14 +146,8 @@ class Desc {
published = json['published'] ?? '',
released = json['released'] ?? '',
github = json['github'] ?? '',
location = Location(HashMap<String, UiType>.from(json['location'])),
config = Config(
(json['config'] as List<dynamic>)
.map((e) => ConfigItem.fromJson(e))
.toList(),
(json['config'] as List<dynamic>)
.map((e) => ConfigItem.fromJson(e))
.toList());
location = Location.fromJson(json['location']),
config = Config.fromJson(json['config']);
}
class DescModel with ChangeNotifier {
@@ -161,9 +156,13 @@ class DescModel with ChangeNotifier {
DescModel._();
void _updateDesc(Map<String, dynamic> desc) {
Desc d = Desc.fromJson(desc);
data[d.id] = d;
notifyListeners();
try {
Desc d = Desc.fromJson(json.decode(desc['desc']));
data[d.id] = d;
notifyListeners();
} catch (e) {
debugPrint('DescModel json.decode fail(): $e');
}
}
Desc? _getDesc(String id) {

View File

@@ -131,8 +131,15 @@ class PluginItem extends StatelessWidget {
peer: peerId,
event: _makeEvent(ui.key),
),
trailingIcon: Icon(
IconData(int.parse(ui.icon, radix: 16), fontFamily: 'MaterialIcons')),
// to-do: support trailing icon, but it will cause tree shake error.
// ```
// This application cannot tree shake icons fonts. It has non-constant instances of IconData at the following locations:
// Target release_macos_bundle_flutter_assets failed: Exception: Avoid non-constant invocations of IconData or try to build again with --no-tree-shake-icons.
// ```
//
// trailingIcon: Icon(
// IconData(int.parse(ui.icon, radix: 16), fontFamily: 'MaterialIcons')),
//
// to-do: RustDesk translate or plugin translate ?
child: Text(ui.text),
ffi: ffi,
@@ -143,7 +150,7 @@ class PluginItem extends StatelessWidget {
var v = model.value;
if (v == null) {
if (peerId.isEmpty) {
v = bind.pluginGetLocalOption(id: pluginId, key: key);
v = bind.pluginGetSharedOption(id: pluginId, key: key);
} else {
v = bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: key);
}