Merge pull request #4154 from fufesou/feat/plugin_framework
more granular control over ui option update.
This commit is contained in:
commit
a5e948a7d6
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user