Merge pull request #4154 from fufesou/feat/plugin_framework

more granular control over ui option update.
This commit is contained in:
RustDesk 2023-04-22 08:48:27 +08:00 committed by GitHub
commit a5e948a7d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 49 deletions

View File

@ -3,17 +3,19 @@ import './common.dart';
import './desc.dart'; import './desc.dart';
final Map<String, LocationModel> locationModels = {}; final Map<String, LocationModel> locationModels = {};
final Map<String, KvModel> kvModels = {}; final Map<String, OptionModel> optionModels = {};
class KvModel with ChangeNotifier { class OptionModel with ChangeNotifier {
final Map<String, String> kv = {}; String? v;
String? get(String key) => kv.remove(key); String? get value => v;
set value(String? v) {
void set(String key, String value) { this.v = v;
kv[key] = value;
notifyListeners(); notifyListeners();
} }
static String key(String location, PluginId id, String peer, String k) =>
'$location|$id|$peer|$k';
} }
class PluginModel with ChangeNotifier { class PluginModel with ChangeNotifier {
@ -58,19 +60,17 @@ LocationModel addLocation(String location) {
return locationModels[location]!; return locationModels[location]!;
} }
String makeKvModelInstance(String location, PluginId id, String peer) => OptionModel addOptionModel(
'$location|$id|$peer'; String location, PluginId pluginId, String peer, String key) {
final k = OptionModel.key(location, pluginId, peer, key);
KvModel addKvModel(String location, PluginId pluginId, String peer) { if (optionModels[k] == null) {
final instance = makeKvModelInstance(location, pluginId, peer); optionModels[k] = OptionModel();
if (kvModels[instance] == null) {
kvModels[instance] = KvModel();
} }
return kvModels[instance]!; return optionModels[k]!;
} }
void updateOption( void updateOption(
String location, PluginId id, String peer, String key, String value) { String location, PluginId id, String peer, String key, String value) {
final instance = makeKvModelInstance(location, id, peer); final k = OptionModel.key(location, id, peer, key);
kvModels[instance]?.set(key, value); optionModels[k]?.value = value;
} }

View File

@ -66,7 +66,6 @@ class PluginItem extends StatelessWidget {
final FFI ffi; final FFI ffi;
final String location; final String location;
final PluginModel pluginModel; final PluginModel pluginModel;
final KvModel kvModel;
PluginItem({ PluginItem({
Key? key, Key? key,
@ -75,20 +74,16 @@ class PluginItem extends StatelessWidget {
required this.ffi, required this.ffi,
required this.location, required this.location,
required this.pluginModel, required this.pluginModel,
}) : kvModel = addKvModel(location, pluginId, peerId), }) : super(key: key);
super(key: key);
bool get isEmpty => pluginModel.isEmpty; bool get isEmpty => pluginModel.isEmpty;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiProvider( return ChangeNotifierProvider.value(
providers: [ value: pluginModel,
ChangeNotifierProvider.value(value: pluginModel), child: Consumer<PluginModel>(
ChangeNotifierProvider.value(value: kvModel), builder: (context, pluginModel, child) {
],
child: Consumer2<PluginModel, KvModel>(
builder: (context, pluginModel, kvModel, child) {
return Column( return Column(
children: pluginModel.uiList.map((ui) => _buildItem(ui)).toList(), children: pluginModel.uiList.map((ui) => _buildItem(ui)).toList(),
); );
@ -144,34 +139,50 @@ class PluginItem extends StatelessWidget {
); );
} }
Widget _buildCheckboxMenuButton(UiCheckbox ui) { String? getOption(OptionModel model, String key) {
var v = kvModel.get(ui.key); var v = model.value;
if (v == null) { if (v == null) {
if (peerId.isEmpty) { if (peerId.isEmpty) {
v = bind.pluginGetLocalOption(id: pluginId, key: ui.key); v = bind.pluginGetLocalOption(id: pluginId, key: key);
} else { } else {
v = bind.pluginGetSessionOption( v = bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: key);
id: pluginId, peer: peerId, key: ui.key);
} }
} }
if (v == null) { return v;
// session or plugin not found }
return Container();
Widget _buildCheckboxMenuButton(UiCheckbox ui) {
getChild(OptionModel model) {
final v = getOption(model, ui.key);
if (v == null) {
// session or plugin not found
return Container();
}
return CkbMenuButton(
value: ConfigItem.isTrue(v),
onChanged: (v) {
if (v != null) {
bind.pluginEvent(
id: pluginId,
peer: peerId,
event: _makeEvent(ui.key, v: v),
);
}
},
// to-do: RustDesk translate or plugin translate ?
child: Text(ui.text),
ffi: ffi,
);
} }
return CkbMenuButton(
value: ConfigItem.isTrue(v), final optionModel = addOptionModel(location, pluginId, peerId, ui.key);
onChanged: (v) { return ChangeNotifierProvider.value(
if (v != null) { value: optionModel,
bind.pluginEvent( child: Consumer<OptionModel>(
id: pluginId, builder: (context, model, child) {
peer: peerId, return getChild(model);
event: _makeEvent(ui.key, v: v), },
); ),
}
},
// to-do: RustDesk translate or plugin translate ?
child: Text(ui.text),
ffi: ffi,
); );
} }
} }

View File

@ -107,6 +107,7 @@ pub fn callback_msg(
if let Ok(s) = if let Ok(s) =
std::str::from_utf8(unsafe { std::slice::from_raw_parts(content as _, len) }) std::str::from_utf8(unsafe { std::slice::from_raw_parts(content as _, len) })
{ {
// No need to merge the msgs. Handling the msg one by one is ok.
if let Ok(msg) = serde_json::from_str::<MsgToConfig>(s) { if let Ok(msg) = serde_json::from_str::<MsgToConfig>(s) {
match &msg.r#type as _ { match &msg.r#type as _ {
config::CONFIG_TYPE_LOCAL => { config::CONFIG_TYPE_LOCAL => {