From d49068706ecf510aefc32de380e04e81d167c383 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Fri, 1 Jul 2022 11:26:32 +0800 Subject: [PATCH] add: include_hidden parameters, migrate to bridge --- flutter/lib/models/file_model.dart | 68 ++++++++++++------------------ src/client.rs | 8 ++-- src/client/file_trait.rs | 7 +-- src/flutter.rs | 39 ++++++++++------- src/flutter_ffi.rs | 47 ++++++++++++++------- src/ui/file_transfer.tis | 3 +- src/ui/remote.rs | 10 ++--- 7 files changed, 98 insertions(+), 84 deletions(-) diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 58ddd658a..adb44286d 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -170,19 +170,18 @@ class FileModel extends ChangeNotifier { if (false == resp) { cancelJob(int.tryParse(evt['id']) ?? 0); } else { - var msg = Map() - ..['id'] = evt['id'] - ..['file_num'] = evt['file_num'] - ..['is_upload'] = evt['is_upload'] - ..['remember'] = fileConfirmCheckboxRemember.toString(); + var need_override = false; if (resp == null) { // skip - msg['need_override'] = 'false'; + need_override = false; } else { // overwrite - msg['need_override'] = 'true'; + need_override = true; } - _ffi.target?.setByName("set_confirm_override_file", jsonEncode(msg)); + _ffi.target?.bind.sessionSetConfirmOverrideFile(id: _ffi.target?.id ?? "", + actId: evt['id'], fileNum: evt['file_num'], + needOverride: need_override, remember: fileConfirmCheckboxRemember, + isUpload: evt['is_upload']); } } @@ -193,22 +192,21 @@ class FileModel extends ChangeNotifier { onReady() async { _localOption.home = _ffi.target?.getByName("get_home_dir") ?? ""; - _localOption.showHidden = - _ffi.target?.getByName("peer_option", "local_show_hidden").isNotEmpty ?? - false; + _localOption.showHidden = (await _ffi.target?.bind.sessionGetPeerOption + (id: _ffi.target?.id ?? "", name: "local_show_hidden"))?.isNotEmpty ?? false; - _remoteOption.showHidden = _ffi.target - ?.getByName("peer_option", "remote_show_hidden") - .isNotEmpty ?? - false; + _remoteOption.showHidden = (await _ffi.target?.bind.sessionGetPeerOption + (id: _ffi.target?.id ?? "", name: "remote_show_hidden"))?.isNotEmpty ?? false; _remoteOption.isWindows = _ffi.target?.ffiModel.pi.platform == "Windows"; debugPrint("remote platform: ${_ffi.target?.ffiModel.pi.platform}"); await Future.delayed(Duration(milliseconds: 100)); - final local = _ffi.target?.getByName("peer_option", "local_dir") ?? ""; - final remote = _ffi.target?.getByName("peer_option", "remote_dir") ?? ""; + final local = (await _ffi.target?.bind.sessionGetPeerOption + (id: _ffi.target?.id ?? "", name: "local_dir")) ?? ""; + final remote = (await _ffi.target?.bind.sessionGetPeerOption + (id: _ffi.target?.id ?? "", name: "remote_dir")) ?? ""; openDirectory(local.isEmpty ? _localOption.home : local, isLocal: true); openDirectory(remote.isEmpty ? _remoteOption.home : remote, isLocal: false); await Future.delayed(Duration(seconds: 1)); @@ -224,23 +222,16 @@ class FileModel extends ChangeNotifier { SmartDialog.dismiss(); // save config - Map msg = Map(); + Map msgMap = Map(); - msg["name"] = "local_dir"; - msg["value"] = _currentLocalDir.path; - _ffi.target?.setByName('peer_option', jsonEncode(msg)); - - msg["name"] = "local_show_hidden"; - msg["value"] = _localOption.showHidden ? "Y" : ""; - _ffi.target?.setByName('peer_option', jsonEncode(msg)); - - msg["name"] = "remote_dir"; - msg["value"] = _currentRemoteDir.path; - _ffi.target?.setByName('peer_option', jsonEncode(msg)); - - msg["name"] = "remote_show_hidden"; - msg["value"] = _remoteOption.showHidden ? "Y" : ""; - _ffi.target?.setByName('peer_option', jsonEncode(msg)); + msgMap["local_dir"] = _currentLocalDir.path; + msgMap["local_show_hidden"] = _localOption.showHidden ? "Y" : ""; + msgMap["remote_dir"] = _currentRemoteDir.path; + msgMap["remote_show_hidden"] = _remoteOption.showHidden ? "Y" : ""; + final id = _ffi.target?.id ?? ""; + for(final msg in msgMap.entries) { + _ffi.target?.bind.sessionPeerOption(id: id, name: msg.key, value: msg.value); + } _currentLocalDir.clear(); _currentRemoteDir.clear(); _localOption.clear(); @@ -583,7 +574,7 @@ class FileFetcher { } // if id == null, means to fetch global FFI - FFI get _ffi => ffi(_id == null ? "" : 'ft_${_id}'); + FFI get _ffi => ffi(_id ?? ""); Future registerReadTask(bool isLocal, String path) { // final jobs = isLocal?localJobs:remoteJobs; // maybe we will use read local dir async later @@ -663,14 +654,7 @@ class FileFetcher { int id, String path, bool isLocal, bool showHidden) async { // TODO test Recursive is show hidden default? try { - final msg = { - "id": id.toString(), - "path": path, - "show_hidden": showHidden.toString(), - "is_remote": (!isLocal).toString() - }; - // TODO - _ffi.setByName("read_dir_recursive", jsonEncode(msg)); + await _ffi.bind.sessionReadDirRecursive(id: _ffi.id, actId: id, path: path, isRemote: !isLocal, showHidden: showHidden); return registerReadRecursiveTask(id); } catch (e) { return Future.error(e); diff --git a/src/client.rs b/src/client.rs index 247e2702c..8457fcd38 100644 --- a/src/client.rs +++ b/src/client.rs @@ -15,6 +15,7 @@ use magnum_opus::{Channels::*, Decoder as AudioDecoder}; use sha2::{Digest, Sha256}; use uuid::Uuid; +pub use file_trait::FileManager; use hbb_common::{ allow_err, anyhow::{anyhow, Context}, @@ -30,13 +31,14 @@ use hbb_common::{ tokio::time::Duration, AddrMangle, ResultType, Stream, }; +pub use helper::LatencyController; use scrap::{Decoder, Image, VideoCodecId}; pub use super::lang::*; + pub mod file_trait; -pub use file_trait::FileManager; pub mod helper; -pub use helper::LatencyController; + pub const SEC30: Duration = Duration::from_secs(30); /// Client of the remote desktop. @@ -1535,7 +1537,7 @@ pub enum Data { Login((String, bool)), Message(Message), SendFiles((i32, String, String, i32, bool, bool)), - RemoveDirAll((i32, String, bool)), + RemoveDirAll((i32, String, bool, bool)), ConfirmDeleteFiles((i32, i32)), SetNoConfirm(i32), RemoveDir((i32, String)), diff --git a/src/client/file_trait.rs b/src/client/file_trait.rs index 6666a2d91..1d5be47da 100644 --- a/src/client/file_trait.rs +++ b/src/client/file_trait.rs @@ -1,6 +1,7 @@ -use super::{Data, Interface}; use hbb_common::{fs, message_proto::*}; +use super::{Data, Interface}; + pub trait FileManager: Interface { fn get_home_dir(&self) -> String { fs::get_home_as_string() @@ -48,8 +49,8 @@ pub trait FileManager: Interface { self.send(Data::RemoveFile((id, path, file_num, is_remote))); } - fn remove_dir_all(&self, id: i32, path: String, is_remote: bool) { - self.send(Data::RemoveDirAll((id, path, is_remote))); + fn remove_dir_all(&self, id: i32, path: String, is_remote: bool, include_hidden: bool) { + self.send(Data::RemoveDirAll((id, path, is_remote, include_hidden))); } fn confirm_delete_files(&self, id: i32, file_num: i32) { diff --git a/src/flutter.rs b/src/flutter.rs index 4854a0e42..4877cce58 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -1,6 +1,10 @@ -use crate::common::make_fd_to_json; -use crate::{client::*, flutter_ffi::EventToUI}; +use std::{ + collections::{HashMap, VecDeque}, + sync::{Arc, Mutex, RwLock}, +}; + use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer}; + use hbb_common::{ allow_err, compress::decompress, @@ -21,10 +25,9 @@ use hbb_common::{ }, Stream, }; -use std::{ - collections::{HashMap, VecDeque}, - sync::{Arc, Mutex, RwLock}, -}; + +use crate::common::make_fd_to_json; +use crate::{client::*, flutter_ffi::EventToUI}; lazy_static::lazy_static! { // static ref SESSION: Arc>> = Default::default(); @@ -52,9 +55,9 @@ impl Session { /// * `id` - The identifier of the remote session with prefix. Regex: [\w]*[\_]*[\d]+ /// * `is_file_transfer` - If the session is used for file transfer. pub fn start(identifier: &str, is_file_transfer: bool, events2ui: StreamSink) { - LocalConfig::set_remote_id(&identifier); // TODO check same id let session_id = get_session_id(identifier.to_owned()); + LocalConfig::set_remote_id(&session_id); // TODO close // Self::close(); let events2ui = Arc::new(RwLock::new(events2ui)); @@ -502,7 +505,11 @@ impl Interface for Session { if lc.is_file_transfer { if pi.username.is_empty() { - self.msgbox("error", "Error", "No active console user logged on, please connect and logon first."); + self.msgbox( + "error", + "Error", + "No active console user logged on, please connect and logon first.", + ); return; } } else { @@ -992,20 +999,20 @@ impl Connection { } } } - Data::RemoveDirAll((id, path, is_remote)) => { + Data::RemoveDirAll((id, path, is_remote, include_hidden)) => { if is_remote { let mut msg_out = Message::new(); let mut file_action = FileAction::new(); file_action.set_all_files(ReadAllFiles { id, path: path.clone(), - include_hidden: true, + include_hidden, ..Default::default() }); msg_out.set_file_action(file_action); allow_err!(peer.send(&msg_out).await); } else { - match fs::get_recursive_files(&path, true) { + match fs::get_recursive_files(&path, include_hidden) { Ok(entries) => { let mut fd = FileDirectory::new(); fd.id = id; @@ -1235,9 +1242,8 @@ pub mod connection_manager { sync::{Mutex, RwLock}, }; - use crate::ipc; - use crate::ipc::Data; - use crate::server::Connection as Conn; + use serde_derive::Serialize; + use hbb_common::{ allow_err, config::Config, @@ -1254,7 +1260,10 @@ pub mod connection_manager { }; #[cfg(any(target_os = "android"))] use scrap::android::call_main_service_set_by_name; - use serde_derive::Serialize; + + use crate::ipc; + use crate::ipc::Data; + use crate::server::Connection as Conn; use super::GLOBAL_EVENT_STREAM; diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 650a7b0b0..9bc533336 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1,21 +1,24 @@ +use std::{ + collections::HashMap, + ffi::{CStr, CString}, + os::raw::c_char, +}; + +use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer}; +use serde_json::{Number, Value}; + +use hbb_common::ResultType; +use hbb_common::{ + config::{self, Config, LocalConfig, PeerConfig, ONLINE}, + fs, log, +}; + use crate::client::file_trait::FileManager; use crate::common::make_fd_to_json; use crate::flutter::connection_manager::{self, get_clients_length, get_clients_state}; use crate::flutter::{self, Session, SESSIONS}; use crate::start_server; use crate::ui_interface; -use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer}; -use hbb_common::ResultType; -use hbb_common::{ - config::{self, Config, LocalConfig, PeerConfig, ONLINE}, - fs, log, -}; -use serde_json::{Number, Value}; -use std::{ - collections::HashMap, - ffi::{CStr, CString}, - os::raw::c_char, -}; fn initialize(app_dir: &str) { *config::APP_DIR.write().unwrap() = app_dir.to_owned(); @@ -244,6 +247,13 @@ pub fn session_peer_option(id: String, name: String, value: String) { } } +pub fn session_get_peer_option(id: String, name: String) -> String { + if let Some(session) = SESSIONS.read().unwrap().get(&id) { + return session.get_option(&name); + } + "".to_string() +} + pub fn session_input_os_password(id: String, value: String) { if let Some(session) = SESSIONS.read().unwrap().get(&id) { session.input_os_password(value, true); @@ -290,9 +300,15 @@ pub fn session_remove_file(id: String, act_id: i32, path: String, file_num: i32, } } -pub fn session_read_dir_recursive(id: String, act_id: i32, path: String, is_remote: bool) { +pub fn session_read_dir_recursive( + id: String, + act_id: i32, + path: String, + is_remote: bool, + show_hidden: bool, +) { if let Some(session) = SESSIONS.read().unwrap().get(&id) { - session.remove_dir_all(act_id, path, is_remote); + session.remove_dir_all(act_id, path, is_remote, show_hidden); } } @@ -814,13 +830,14 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) { #[cfg(target_os = "android")] pub mod server_side { - use hbb_common::{config::Config, log}; use jni::{ objects::{JClass, JString}, sys::jstring, JNIEnv, }; + use hbb_common::{config::Config, log}; + use crate::start_server; #[no_mangle] diff --git a/src/ui/file_transfer.tis b/src/ui/file_transfer.tis index 7d50bdf7a..f32540b33 100644 --- a/src/ui/file_transfer.tis +++ b/src/ui/file_transfer.tis @@ -188,7 +188,8 @@ class JobTable: Reactor.Component { job.confirmed = true; return; }else if (job.type == "del-dir"){ - handler.remove_dir_all(job.id, job.path, job.is_remote); + // TODO: include_hidden is always true + handler.remove_dir_all(job.id, job.path, job.is_remote, true); job.confirmed = true; return; } diff --git a/src/ui/remote.rs b/src/ui/remote.rs index a073b81c6..44c3e6c3f 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -201,7 +201,7 @@ impl sciter::EventHandler for Handler { fn read_remote_dir(String, bool); fn send_chat(String); fn switch_display(i32); - fn remove_dir_all(i32, String, bool); + fn remove_dir_all(i32, String, bool, bool); fn confirm_delete_files(i32, i32); fn set_no_confirm(i32); fn cancel_job(i32); @@ -1793,7 +1793,7 @@ impl Remote { } } } - Data::RemoveDirAll((id, path, is_remote)) => { + Data::RemoveDirAll((id, path, is_remote, include_hidden)) => { let sep = self.handler.get_path_sep(is_remote); if is_remote { let mut msg_out = Message::new(); @@ -1801,7 +1801,7 @@ impl Remote { file_action.set_all_files(ReadAllFiles { id, path: path.clone(), - include_hidden: true, + include_hidden, ..Default::default() }); msg_out.set_file_action(file_action); @@ -1809,7 +1809,7 @@ impl Remote { self.remove_jobs .insert(id, RemoveJob::new(Vec::new(), path, sep, is_remote)); } else { - match fs::get_recursive_files(&path, true) { + match fs::get_recursive_files(&path, include_hidden) { Ok(entries) => { let m = make_fd(id, &entries, true); self.handler.call("updateFolderFiles", &make_args!(m)); @@ -2370,7 +2370,7 @@ impl Remote { } back_notification::PrivacyModeState::OffSucceeded => { self.handler - .msgbox("custom-nocancel", "Privacy mode", "Out privacy mode"); + .msgbox("custom-nocancel", "Privacy mode", "Out privacy mode"); self.update_privacy_mode(false); } back_notification::PrivacyModeState::OffByPeer => {