plugin_framework, show remote toolbar widget
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
eb96b0d451
commit
cbeebea7a5
@ -123,6 +123,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ffi.ffiModel.updateEventListener(widget.id);
|
_ffi.ffiModel.updateEventListener(widget.id);
|
||||||
|
bind.pluginSyncUi(syncTo: kAppTypeDesktopRemote);
|
||||||
_ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id);
|
_ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id);
|
||||||
// Session option should be set after models.dart/FFI.start
|
// Session option should be set after models.dart/FFI.start
|
||||||
_showRemoteCursor.value = bind.sessionGetToggleOptionSync(
|
_showRemoteCursor.value = bind.sessionGetToggleOptionSync(
|
||||||
|
@ -124,6 +124,7 @@ void runMainApp(bool startService) async {
|
|||||||
if (startService) {
|
if (startService) {
|
||||||
// await windowManager.ensureInitialized();
|
// await windowManager.ensureInitialized();
|
||||||
gFFI.serverModel.startService();
|
gFFI.serverModel.startService();
|
||||||
|
bind.pluginSyncUi(syncTo: kAppTypeMain);
|
||||||
}
|
}
|
||||||
gFFI.userModel.refreshCurrentUser();
|
gFFI.userModel.refreshCurrentUser();
|
||||||
runApp(App());
|
runApp(App());
|
||||||
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
|
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
|
||||||
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/models/file_model.dart';
|
import 'package:flutter_hbb/models/file_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:toggle_switch/toggle_switch.dart';
|
import 'package:toggle_switch/toggle_switch.dart';
|
||||||
|
@ -341,7 +341,6 @@ class ServerModel with ChangeNotifier {
|
|||||||
_isStart = true;
|
_isStart = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
parent.target?.ffiModel.updateEventListener("");
|
parent.target?.ffiModel.updateEventListener("");
|
||||||
bind.pluginSyncUi();
|
|
||||||
await parent.target?.invokeMethod("init_service");
|
await parent.target?.invokeMethod("init_service");
|
||||||
// ugly is here, because for desktop, below is useless
|
// ugly is here, because for desktop, below is useless
|
||||||
await bind.mainStartService();
|
await bind.mainStartService();
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hbb/models/model.dart';
|
import 'package:flutter_hbb/models/model.dart';
|
||||||
@ -198,7 +200,14 @@ void handleReloading(Map<String, dynamic> evt, String peer) {
|
|||||||
if (evt['id'] == null || evt['location'] == null) {
|
if (evt['id'] == null || evt['location'] == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addLocationUi(evt['location']!, evt['id']!, UiType.fromJson(evt));
|
try {
|
||||||
|
final ui = UiType.create(json.decode(evt['ui'] as String));
|
||||||
|
if (ui != null) {
|
||||||
|
addLocationUi(evt['location']!, evt['id']!, ui);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Failed handleReloading, json decode of ui, $e ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleOption(Map<String, dynamic> evt, String peer) {
|
void handleOption(Map<String, dynamic> evt, String peer) {
|
||||||
|
@ -1573,12 +1573,12 @@ pub fn plugin_feature_is_enabled() -> SyncReturn<bool> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn plugin_sync_ui() {
|
pub fn plugin_sync_ui(_sync_to: String) {
|
||||||
#[cfg(feature = "plugin_framework")]
|
#[cfg(feature = "plugin_framework")]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
{
|
{
|
||||||
if plugin_feature_is_enabled().0 {
|
if plugin_feature_is_enabled().0 {
|
||||||
crate::plugin::sync_ui();
|
crate::plugin::sync_ui(_sync_to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,8 @@ impl SharedConfig {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn load(id: &str) {
|
pub fn load(id: &str) {
|
||||||
let mut conf = hbb_common::config::load_path::<SharedConfig>(Self::path(id));
|
let conf = hbb_common::config::load_path::<HashMap<String, String>>(Self::path(id));
|
||||||
|
let mut conf = SharedConfig(conf);
|
||||||
if let Some(items) = CONFIG_SHARED_ITEMS.lock().unwrap().get(id) {
|
if let Some(items) = CONFIG_SHARED_ITEMS.lock().unwrap().get(id) {
|
||||||
for item in items {
|
for item in items {
|
||||||
if !conf.contains_key(&item.key) {
|
if !conf.contains_key(&item.key) {
|
||||||
@ -116,7 +117,8 @@ impl PeerConfig {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn load(id: &str, peer: &str) {
|
pub fn load(id: &str, peer: &str) {
|
||||||
let mut conf = hbb_common::config::load_path::<PeerConfig>(Self::path(id, peer));
|
let conf = hbb_common::config::load_path::<HashMap<String, String>>(Self::path(id, peer));
|
||||||
|
let mut conf = PeerConfig(conf);
|
||||||
if let Some(items) = CONFIG_PEER_ITEMS.lock().unwrap().get(id) {
|
if let Some(items) = CONFIG_PEER_ITEMS.lock().unwrap().get(id) {
|
||||||
for item in items {
|
for item in items {
|
||||||
if !conf.contains_key(&item.key) {
|
if !conf.contains_key(&item.key) {
|
||||||
@ -124,16 +126,15 @@ impl PeerConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match CONFIG_PEERS.lock().unwrap().get_mut(id) {
|
|
||||||
Some(peers) => {
|
if let Some(peers) = CONFIG_PEERS.lock().unwrap().get_mut(id) {
|
||||||
peers.insert(peer.to_owned(), conf);
|
peers.insert(peer.to_owned(), conf);
|
||||||
}
|
return;
|
||||||
None => {
|
|
||||||
let mut peers = HashMap::new();
|
|
||||||
peers.insert(peer.to_owned(), conf);
|
|
||||||
CONFIG_PEERS.lock().unwrap().insert(id.to_owned(), peers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut peers = HashMap::new();
|
||||||
|
peers.insert(peer.to_owned(), conf);
|
||||||
|
CONFIG_PEERS.lock().unwrap().insert(id.to_owned(), peers);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -36,7 +36,6 @@ pub struct Location {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ConfigItem {
|
pub struct ConfigItem {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
pub value: String,
|
|
||||||
pub default: String,
|
pub default: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// to-do: Interdependence(This mod and crate::ipc) is not good practice here.
|
// to-do: Interdependence(This mod and crate::ipc) is not good practice here.
|
||||||
use crate::ipc::{connect, Connection, Data};
|
use crate::ipc::{connect, Connection, Data};
|
||||||
use hbb_common::{allow_err, bail, bytes, log, tokio, ResultType};
|
use hbb_common::{allow_err, log, tokio, ResultType};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use std::{fs::File, io::prelude::*};
|
use std::{fs::File, io::prelude::*};
|
||||||
|
@ -224,10 +224,10 @@ fn load_plugin_path(path: &str) -> ResultType<()> {
|
|||||||
(plugin.set_cb_msg)(callback_msg::callback_msg);
|
(plugin.set_cb_msg)(callback_msg::callback_msg);
|
||||||
(plugin.set_cb_get_id)(get_local_peer_id as _);
|
(plugin.set_cb_get_id)(get_local_peer_id as _);
|
||||||
// Ui may be not ready now, so we need to update again once ui is ready.
|
// Ui may be not ready now, so we need to update again once ui is ready.
|
||||||
update_ui_plugin_desc(&desc);
|
update_ui_plugin_desc(&desc, None);
|
||||||
update_config(&desc);
|
update_config(&desc);
|
||||||
// Ui may be not ready now, so we need to reload again once ui is ready.
|
// Ui may be not ready now, so we need to reload again once ui is ready.
|
||||||
reload_ui(&desc);
|
reload_ui(&desc, None);
|
||||||
let plugin_info = PluginInfo {
|
let plugin_info = PluginInfo {
|
||||||
path: path.to_string(),
|
path: path.to_string(),
|
||||||
desc,
|
desc,
|
||||||
@ -238,10 +238,10 @@ fn load_plugin_path(path: &str) -> ResultType<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_ui() {
|
pub fn sync_ui(sync_to: String) {
|
||||||
for plugin in PLUGIN_INFO.read().unwrap().values() {
|
for plugin in PLUGIN_INFO.read().unwrap().values() {
|
||||||
update_ui_plugin_desc(&plugin.desc);
|
update_ui_plugin_desc(&plugin.desc, Some(&sync_to));
|
||||||
reload_ui(&plugin.desc);
|
reload_ui(&plugin.desc, Some(&sync_to));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,44 +369,70 @@ fn update_config(desc: &Desc) {
|
|||||||
super::config::set_peer_items(desc.id(), &desc.config().peer);
|
super::config::set_peer_items(desc.id(), &desc.config().peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reload_ui(desc: &Desc) {
|
fn reload_ui(desc: &Desc, sync_to: Option<&str>) {
|
||||||
for (location, ui) in desc.location().ui.iter() {
|
for (location, ui) in desc.location().ui.iter() {
|
||||||
let v: Vec<&str> = location.split('|').collect();
|
if let Ok(ui) = serde_json::to_string(&ui) {
|
||||||
// The first element is the "client" or "host".
|
let make_event = |ui: &str| {
|
||||||
// The second element is the "main", "remote", "cm", "file transfer", "port forward".
|
let mut m = HashMap::new();
|
||||||
if v.len() >= 2 {
|
m.insert("name", MSG_TO_UI_TYPE_PLUGIN_RELOAD);
|
||||||
let available_channels = vec![
|
m.insert("id", desc.id());
|
||||||
flutter::APP_TYPE_MAIN,
|
m.insert("location", &location);
|
||||||
flutter::APP_TYPE_DESKTOP_REMOTE,
|
// Do not depend on the "location" and plugin desc on the ui side.
|
||||||
flutter::APP_TYPE_CM,
|
// Send the ui field to ensure the ui is valid.
|
||||||
flutter::APP_TYPE_DESKTOP_FILE_TRANSFER,
|
m.insert("ui", ui);
|
||||||
flutter::APP_TYPE_DESKTOP_PORT_FORWARD,
|
serde_json::to_string(&m).unwrap_or("".to_owned())
|
||||||
];
|
};
|
||||||
if available_channels.contains(&v[1]) {
|
match sync_to {
|
||||||
if let Ok(ui) = serde_json::to_string(&ui) {
|
Some(channel) => {
|
||||||
let mut m = HashMap::new();
|
let _res = flutter::push_global_event(channel, make_event(&ui));
|
||||||
m.insert("name", MSG_TO_UI_TYPE_PLUGIN_RELOAD);
|
}
|
||||||
m.insert("id", desc.id());
|
None => {
|
||||||
m.insert("location", &location);
|
let v: Vec<&str> = location.split('|').collect();
|
||||||
m.insert("ui", &ui);
|
// The first element is the "client" or "host".
|
||||||
flutter::push_global_event(v[1], serde_json::to_string(&m).unwrap());
|
// The second element is the "main", "remote", "cm", "file transfer", "port forward".
|
||||||
|
if v.len() >= 2 {
|
||||||
|
let available_channels = vec![
|
||||||
|
flutter::APP_TYPE_MAIN,
|
||||||
|
flutter::APP_TYPE_DESKTOP_REMOTE,
|
||||||
|
flutter::APP_TYPE_CM,
|
||||||
|
flutter::APP_TYPE_DESKTOP_FILE_TRANSFER,
|
||||||
|
flutter::APP_TYPE_DESKTOP_PORT_FORWARD,
|
||||||
|
];
|
||||||
|
if available_channels.contains(&v[1]) {
|
||||||
|
let _res = flutter::push_global_event(v[1], make_event(&ui));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_ui_plugin_desc(desc: &Desc) {
|
fn update_ui_plugin_desc(desc: &Desc, sync_to: Option<&str>) {
|
||||||
// This function is rarely used. There's no need to care about serialization efficiency here.
|
// This function is rarely used. There's no need to care about serialization efficiency here.
|
||||||
if let Ok(desc_str) = serde_json::to_string(desc) {
|
if let Ok(desc_str) = serde_json::to_string(desc) {
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
m.insert("name", MSG_TO_UI_TYPE_PLUGIN_DESC);
|
m.insert("name", MSG_TO_UI_TYPE_PLUGIN_DESC);
|
||||||
m.insert("desc", &desc_str);
|
m.insert("desc", &desc_str);
|
||||||
flutter::push_global_event(flutter::APP_TYPE_MAIN, serde_json::to_string(&m).unwrap());
|
let event = serde_json::to_string(&m).unwrap_or("".to_owned());
|
||||||
flutter::push_global_event(
|
match sync_to {
|
||||||
flutter::APP_TYPE_DESKTOP_REMOTE,
|
Some(channel) => {
|
||||||
serde_json::to_string(&m).unwrap(),
|
let _res = flutter::push_global_event(channel, serde_json::to_string(&m).unwrap());
|
||||||
);
|
}
|
||||||
flutter::push_global_event(flutter::APP_TYPE_CM, serde_json::to_string(&m).unwrap());
|
None => {
|
||||||
|
let _res = flutter::push_global_event(
|
||||||
|
flutter::APP_TYPE_MAIN,
|
||||||
|
serde_json::to_string(&m).unwrap(),
|
||||||
|
);
|
||||||
|
let _res = flutter::push_global_event(
|
||||||
|
flutter::APP_TYPE_DESKTOP_REMOTE,
|
||||||
|
serde_json::to_string(&m).unwrap(),
|
||||||
|
);
|
||||||
|
let _res = flutter::push_global_event(
|
||||||
|
flutter::APP_TYPE_CM,
|
||||||
|
serde_json::to_string(&m).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user