Create empty dir on send files in local (#9993)

* feat: Add empty dirs on sendfiles

* Update connection.rs

---------

Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
This commit is contained in:
zuiyu
2024-11-23 23:09:11 +08:00
committed by GitHub
parent b64f6271e2
commit 314c93b210
13 changed files with 311 additions and 6 deletions

View File

@@ -43,6 +43,18 @@ pub trait FileManager: Interface {
self.send(Data::CancelJob(id));
}
fn read_empty_dirs(&self, path: String, include_hidden: bool) {
let mut msg_out = Message::new();
let mut file_action = FileAction::new();
file_action.set_read_empty_dirs(ReadEmptyDirs {
path,
include_hidden,
..Default::default()
});
msg_out.set_file_action(file_action);
self.send(Data::Message(msg_out));
}
fn read_remote_dir(&self, path: String, include_hidden: bool) {
let mut msg_out = Message::new();
let mut file_action = FileAction::new();

View File

@@ -1299,6 +1299,9 @@ impl<T: InvokeUiSession> Remote<T> {
}
Some(message::Union::FileResponse(fr)) => {
match fr.union {
Some(file_response::Union::EmptyDirs(res)) => {
self.handler.update_empty_dirs(res);
}
Some(file_response::Union::Dir(fd)) => {
#[cfg(windows)]
let entries = fd.entries.to_vec();

View File

@@ -5,7 +5,7 @@ use std::{
task::Poll,
};
use serde_json::Value;
use serde_json::{json, Map, Value};
use hbb_common::{
allow_err,
@@ -1051,6 +1051,11 @@ pub fn get_supported_keyboard_modes(version: i64, peer_platform: &str) -> Vec<Ke
}
pub fn make_fd_to_json(id: i32, path: String, entries: &Vec<FileEntry>) -> String {
let fd_json = _make_fd_to_json(id, path, entries);
serde_json::to_string(&fd_json).unwrap_or("".into())
}
pub fn _make_fd_to_json(id: i32, path: String, entries: &Vec<FileEntry>) -> Map<String, Value> {
use serde_json::json;
let mut fd_json = serde_json::Map::new();
fd_json.insert("id".into(), json!(id));
@@ -1066,7 +1071,33 @@ pub fn make_fd_to_json(id: i32, path: String, entries: &Vec<FileEntry>) -> Strin
entries_out.push(entry_map);
}
fd_json.insert("entries".into(), json!(entries_out));
serde_json::to_string(&fd_json).unwrap_or("".into())
fd_json
}
pub fn make_vec_fd_to_json(fds: &[FileDirectory]) -> String {
let mut fd_jsons = vec![];
for fd in fds.iter() {
let fd_json = _make_fd_to_json(fd.id, fd.path.clone(), &fd.entries);
fd_jsons.push(fd_json);
}
serde_json::to_string(&fd_jsons).unwrap_or("".into())
}
pub fn make_empty_dirs_response_to_json(res: &ReadEmptyDirsResponse) -> String {
let mut map: Map<String, Value> = serde_json::Map::new();
map.insert("path".into(), json!(res.path));
let mut fd_jsons = vec![];
for fd in res.empty_dirs.iter() {
let fd_json = _make_fd_to_json(fd.id, fd.path.clone(), &fd.entries);
fd_jsons.push(fd_json);
}
map.insert("empty_dirs".into(), fd_jsons.into());
serde_json::to_string(&map).unwrap_or("".into())
}
/// The function to handle the url scheme sent by the system.

View File

@@ -726,6 +726,20 @@ impl InvokeUiSession for FlutterHandler {
}
}
fn update_empty_dirs(&self, res: ReadEmptyDirsResponse) {
self.push_event(
"empty_dirs",
&[
("is_local", "false"),
(
"value",
&crate::common::make_empty_dirs_response_to_json(&res),
),
],
&[],
);
}
// unused in flutter
fn update_transfer_list(&self) {}

View File

@@ -1,6 +1,6 @@
use crate::{
client::file_trait::FileManager,
common::make_fd_to_json,
common::{make_fd_to_json, make_vec_fd_to_json},
flutter::{
self, session_add, session_add_existed, session_start_, sessions, try_sync_peer_option,
},
@@ -682,6 +682,27 @@ pub fn session_read_local_dir_sync(
"".to_string()
}
pub fn session_read_local_empty_dirs_recursive_sync(
_session_id: SessionID,
path: String,
include_hidden: bool,
) -> String {
if let Ok(fds) = fs::get_empty_dirs_recursive(&path, include_hidden) {
return make_vec_fd_to_json(&fds);
}
"".to_string()
}
pub fn session_read_remote_empty_dirs_recursive_sync(
session_id: SessionID,
path: String,
include_hidden: bool,
) {
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
session.read_empty_dirs(path, include_hidden);
}
}
pub fn session_get_platform(session_id: SessionID, is_remote: bool) -> String {
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
return session.get_platform(is_remote);

View File

@@ -45,6 +45,10 @@ pub static EXIT_RECV_CLOSE: AtomicBool = AtomicBool::new(true);
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(tag = "t", content = "c")]
pub enum FS {
ReadEmptyDirs {
dir: String,
include_hidden: bool,
},
ReadDir {
dir: String,
include_hidden: bool,

View File

@@ -2149,6 +2149,9 @@ impl Connection {
}
}
match fa.union {
Some(file_action::Union::ReadEmptyDirs(rd)) => {
self.read_empty_dirs(&rd.path, rd.include_hidden);
}
Some(file_action::Union::ReadDir(rd)) => {
self.read_dir(&rd.path, rd.include_hidden);
}
@@ -3145,6 +3148,14 @@ impl Connection {
raii::AuthedConnID::check_remove_session(self.inner.id(), self.session_key());
}
fn read_empty_dirs(&mut self, dir: &str, include_hidden: bool) {
let dir = dir.to_string();
self.send_fs(ipc::FS::ReadEmptyDirs {
dir,
include_hidden,
});
}
fn read_dir(&mut self, dir: &str, include_hidden: bool) {
let dir = dir.to_string();
self.send_fs(ipc::FS::ReadDir {

View File

@@ -751,6 +751,12 @@ async fn handle_fs(
use hbb_common::fs::serialize_transfer_job;
match fs {
ipc::FS::ReadEmptyDirs {
dir,
include_hidden,
} => {
read_empty_dirs(&dir, include_hidden, tx).await;
}
ipc::FS::ReadDir {
dir,
include_hidden,
@@ -907,6 +913,26 @@ async fn handle_fs(
}
}
#[cfg(not(any(target_os = "ios")))]
async fn read_empty_dirs(dir: &str, include_hidden: bool, tx: &UnboundedSender<Data>) {
let path = dir.to_owned();
let path_clone = dir.to_owned();
if let Ok(Ok(fds)) =
spawn_blocking(move || fs::get_empty_dirs_recursive(&path, include_hidden)).await
{
let mut msg_out = Message::new();
let mut file_response = FileResponse::new();
file_response.set_empty_dirs(ReadEmptyDirsResponse {
path: path_clone,
empty_dirs: fds,
..Default::default()
});
msg_out.set_file_response(file_response);
send_raw(msg_out, tx);
}
}
#[cfg(not(any(target_os = "ios")))]
async fn read_dir(dir: &str, include_hidden: bool, tx: &UnboundedSender<Data>) {
let path = {

View File

@@ -1555,6 +1555,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
#[cfg(feature = "flutter")]
fn is_multi_ui_session(&self) -> bool;
fn update_record_status(&self, start: bool);
fn update_empty_dirs(&self, _res: ReadEmptyDirsResponse) {}
}
impl<T: InvokeUiSession> Deref for Session<T> {