123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- // The plugin manager is a singleton class that manages the plugins.
- // 1. It merge metadata and the desc of plugins.
- import 'dart:convert';
- import 'dart:collection';
- import 'package:flutter/material.dart';
- const String kValueTrue = '1';
- const String kValueFalse = '0';
- class ConfigItem {
- String key;
- String description;
- String defaultValue;
- ConfigItem(this.key, this.defaultValue, this.description);
- ConfigItem.fromJson(Map<String, dynamic> json)
- : key = json['key'] ?? '',
- description = json['description'] ?? '',
- defaultValue = json['default'] ?? '';
- static String get trueValue => kValueTrue;
- static String get falseValue => kValueFalse;
- static bool isTrue(String value) => value == kValueTrue;
- static bool isFalse(String value) => value == kValueFalse;
- }
- class UiType {
- String key;
- String text;
- String tooltip;
- String action;
- UiType(this.key, this.text, this.tooltip, this.action);
- UiType.fromJson(Map<String, dynamic> json)
- : key = json['key'] ?? '',
- text = json['text'] ?? '',
- tooltip = json['tooltip'] ?? '',
- action = json['action'] ?? '';
- static UiType? create(Map<String, dynamic> json) {
- if (json['t'] == 'Button') {
- return UiButton.fromJson(json['c']);
- } else if (json['t'] == 'Checkbox') {
- return UiCheckbox.fromJson(json['c']);
- } else {
- return null;
- }
- }
- }
- class UiButton extends UiType {
- String icon;
- UiButton(
- {required String key,
- required String text,
- required this.icon,
- required String tooltip,
- required String action})
- : super(key, text, tooltip, action);
- UiButton.fromJson(Map<String, dynamic> json)
- : icon = json['icon'] ?? '',
- super.fromJson(json);
- }
- class UiCheckbox extends UiType {
- UiCheckbox(
- {required String key,
- required String text,
- required String tooltip,
- required String action})
- : super(key, text, tooltip, action);
- UiCheckbox.fromJson(Map<String, dynamic> json) : super.fromJson(json);
- }
- class Location {
- // location key:
- // host|main|settings|plugin
- // client|remote|toolbar|display
- HashMap<String, UiType> ui;
- Location(this.ui);
- Location.fromJson(Map<String, dynamic> json) : ui = HashMap() {
- (json['ui'] as Map<String, dynamic>).forEach((key, value) {
- var ui = UiType.create(value);
- if (ui != null) {
- this.ui[ui.key] = ui;
- }
- });
- }
- }
- class PublishInfo {
- PublishInfo({
- required this.lastReleased,
- required this.published,
- });
- final DateTime lastReleased;
- final DateTime published;
- }
- class Meta {
- Meta({
- required this.id,
- required this.name,
- required this.version,
- required this.description,
- required this.author,
- required this.home,
- required this.license,
- required this.publishInfo,
- required this.source,
- });
- final String id;
- final String name;
- final String version;
- final String description;
- final String author;
- final String home;
- final String license;
- final PublishInfo publishInfo;
- final String source;
- }
- class SourceInfo {
- String name; // 1. RustDesk github 2. Local
- String url;
- String description;
- SourceInfo({
- required this.name,
- required this.url,
- required this.description,
- });
- }
- class PluginInfo with ChangeNotifier {
- SourceInfo sourceInfo;
- Meta meta;
- String installedVersion; // It is empty if not installed.
- String failedMsg;
- String invalidReason; // It is empty if valid.
- PluginInfo({
- required this.sourceInfo,
- required this.meta,
- required this.installedVersion,
- required this.invalidReason,
- this.failedMsg = '',
- });
- bool get installed => installedVersion.isNotEmpty;
- bool get needUpdate => installed && installedVersion != meta.version;
- void setInstall(String msg) {
- if (msg == "finished") {
- msg = '';
- }
- failedMsg = msg;
- if (msg.isEmpty) {
- installedVersion = meta.version;
- }
- notifyListeners();
- }
- void setUninstall(String msg) {
- failedMsg = msg;
- if (msg.isEmpty) {
- installedVersion = '';
- }
- notifyListeners();
- }
- }
- class PluginManager with ChangeNotifier {
- String failedReason = ''; // The reason of failed to load plugins.
- final List<PluginInfo> _plugins = [];
- PluginManager._();
- static final PluginManager _instance = PluginManager._();
- static PluginManager get instance => _instance;
- List<PluginInfo> get plugins => _plugins;
- PluginInfo? getPlugin(String id) {
- for (var p in _plugins) {
- if (p.meta.id == id) {
- return p;
- }
- }
- return null;
- }
- void handleEvent(Map<String, dynamic> evt) {
- if (evt['plugin_list'] != null) {
- _handlePluginList(evt['plugin_list']);
- } else if (evt['plugin_install'] != null && evt['id'] != null) {
- _handlePluginInstall(evt['id'], evt['plugin_install']);
- } else if (evt['plugin_uninstall'] != null && evt['id'] != null) {
- _handlePluginUninstall(evt['id'], evt['plugin_uninstall']);
- } else {
- debugPrint('Failed to handle manager event: $evt');
- }
- }
- void _sortPlugins() {
- plugins.sort((a, b) {
- if (a.installed) {
- return -1;
- } else if (b.installed) {
- return 1;
- } else {
- return 0;
- }
- });
- }
- void _handlePluginList(String pluginList) {
- _plugins.clear();
- try {
- for (var p in json.decode(pluginList) as List<dynamic>) {
- final plugin = _getPluginFromEvent(p);
- if (plugin == null) {
- continue;
- }
- _plugins.add(plugin);
- }
- } catch (e) {
- debugPrint('Failed to decode $e, plugin list \'$pluginList\'');
- }
- _sortPlugins();
- notifyListeners();
- }
- void _handlePluginInstall(String id, String msg) {
- debugPrint('Plugin \'$id\' install msg $msg');
- for (var i = 0; i < _plugins.length; i++) {
- if (_plugins[i].meta.id == id) {
- _plugins[i].setInstall(msg);
- _sortPlugins();
- notifyListeners();
- return;
- }
- }
- }
- void _handlePluginUninstall(String id, String msg) {
- debugPrint('Plugin \'$id\' uninstall msg $msg');
- for (var i = 0; i < _plugins.length; i++) {
- if (_plugins[i].meta.id == id) {
- _plugins[i].setUninstall(msg);
- _sortPlugins();
- notifyListeners();
- return;
- }
- }
- }
- PluginInfo? _getPluginFromEvent(Map<String, dynamic> evt) {
- final s = evt['source'];
- assert(s != null, 'Source is null');
- if (s == null) {
- return null;
- }
- final source = SourceInfo(
- name: s['name'],
- url: s['url'] ?? '',
- description: s['description'] ?? '',
- );
- final m = evt['meta'];
- assert(m != null, 'Meta is null');
- if (m == null) {
- return null;
- }
- late DateTime lastReleased;
- late DateTime published;
- try {
- lastReleased = DateTime.parse(
- m['publish_info']?['last_released'] ?? '1970-01-01T00+00:00');
- } catch (e) {
- lastReleased = DateTime.utc(1970);
- }
- try {
- published = DateTime.parse(
- m['publish_info']?['published'] ?? '1970-01-01T00+00:00');
- } catch (e) {
- published = DateTime.utc(1970);
- }
- final meta = Meta(
- id: m['id'],
- name: m['name'],
- version: m['version'],
- description: m['description'] ?? '',
- author: m['author'],
- home: m['home'] ?? '',
- license: m['license'] ?? '',
- source: m['source'] ?? '',
- publishInfo:
- PublishInfo(lastReleased: lastReleased, published: published),
- );
- return PluginInfo(
- sourceInfo: source,
- meta: meta,
- installedVersion: evt['installed_version'],
- invalidReason: evt['invalid_reason'] ?? '',
- );
- }
- }
- PluginManager get pluginManager => PluginManager.instance;
|