Use replace dialog in all required places, part of #180

This commit is contained in:
Jeremy Soller 2024-07-08 13:43:11 -06:00
parent 35fcb011c5
commit 97444c3572
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
4 changed files with 149 additions and 116 deletions

80
Cargo.lock generated
View file

@ -502,7 +502,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -537,7 +537,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -772,7 +772,7 @@ checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -1381,7 +1381,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.11.1",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -1392,7 +1392,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [
"darling_core",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -1443,7 +1443,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -1532,7 +1532,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -1651,7 +1651,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -1977,7 +1977,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -2053,7 +2053,7 @@ dependencies = [
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "git+https://github.com/pop-os/fs_extra.git#209d2e349842a10366c8c9c3ece72482129d372e"
source = "git+https://github.com/pop-os/fs_extra.git#7e7222eb2b7830d40b67cd02e6ebd156524ee866"
[[package]]
name = "fsevent-sys"
@ -2149,7 +2149,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -2339,7 +2339,7 @@ dependencies = [
"proc-macro-crate 3.1.0",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -2612,7 +2612,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.10.0",
"syn 2.0.69",
"syn 2.0.70",
"unic-langid",
]
@ -2626,7 +2626,7 @@ dependencies = [
"i18n-config",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -3251,7 +3251,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -4210,7 +4210,7 @@ dependencies = [
"proc-macro-crate 3.1.0",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -4393,7 +4393,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -4433,7 +4433,7 @@ dependencies = [
"by_address",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -4538,7 +4538,7 @@ dependencies = [
"phf_shared",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -5021,7 +5021,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.69",
"syn 2.0.70",
"walkdir",
]
@ -5195,7 +5195,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -5218,7 +5218,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -5545,9 +5545,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.69"
version = "2.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6"
checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16"
dependencies = [
"proc-macro2",
"quote",
@ -5562,7 +5562,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -5650,7 +5650,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -5676,7 +5676,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -5833,7 +5833,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -5931,7 +5931,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -6318,7 +6318,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
"wasm-bindgen-shared",
]
@ -6352,7 +6352,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -6779,7 +6779,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -6801,7 +6801,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -7242,7 +7242,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
"synstructure",
]
@ -7350,7 +7350,7 @@ dependencies = [
"proc-macro-crate 3.1.0",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
"zvariant_utils 2.0.0",
]
@ -7399,7 +7399,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -7419,7 +7419,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
"synstructure",
]
@ -7453,7 +7453,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]
@ -7515,7 +7515,7 @@ dependencies = [
"proc-macro-crate 3.1.0",
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
"zvariant_utils 2.0.0",
]
@ -7538,5 +7538,5 @@ checksum = "fc242db087efc22bd9ade7aa7809e4ba828132edc312871584a6b4391bdf8786"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]

View file

@ -81,6 +81,9 @@ tempfile = "3"
test-log = "0.2"
tokio = { version = "1", features = ["rt", "macros"] }
# [patch.'https://github.com/pop-os/fs_extra']
# fs_extra = { path = "../fs_extra" }
# [patch.'https://github.com/pop-os/libcosmic']
# libcosmic = { path = "../libcosmic" }
# cosmic-config = { path = "../libcosmic/cosmic-config" }

View file

@ -51,7 +51,7 @@ use crate::{
key_bind::key_binds,
menu, mime_app,
mounter::{mounters, MounterItem, MounterItems, MounterKey, Mounters},
operation::Operation,
operation::{Operation, ReplaceResult},
spawn_detached::spawn_detached,
tab::{self, HeadingOptions, ItemMetadata, Location, Tab},
};
@ -300,7 +300,7 @@ pub enum DialogPage {
Replace {
from: tab::Item,
to: tab::Item,
tx: mpsc::Sender<fs_extra::dir::TransitProcessResult>,
tx: mpsc::Sender<ReplaceResult>,
},
}
@ -1207,9 +1207,7 @@ impl Application for App {
DialogPage::Replace { tx, .. } => {
return Command::perform(
async move {
let _ = tx
.send(fs_extra::dir::TransitProcessResult::Overwrite)
.await;
let _ = tx.send(ReplaceResult::Replace).await;
message::none()
},
|x| x,

View file

@ -19,6 +19,86 @@ fn err_str<T: ToString>(err: T) -> String {
err.to_string()
}
fn handle_replace(
msg_tx: &Arc<Mutex<Sender<Message>>>,
file_from: PathBuf,
file_to: PathBuf,
) -> ReplaceResult {
let item_from = match tab::item_from_path(file_from, IconSizes::default()) {
Ok(ok) => ok,
Err(err) => {
log::warn!("{}", err);
return ReplaceResult::Cancel;
}
};
let item_to = match tab::item_from_path(file_to, IconSizes::default()) {
Ok(ok) => ok,
Err(err) => {
log::warn!("{}", err);
return ReplaceResult::Cancel;
}
};
executor::block_on(async {
let (tx, mut rx) = mpsc::channel(1);
let _ = msg_tx
.lock()
.await
.send(Message::DialogPush(DialogPage::Replace {
from: item_from,
to: item_to,
tx,
}))
.await;
rx.recv().await.unwrap_or(ReplaceResult::Cancel)
})
}
fn handle_progress_state(
msg_tx: &Arc<Mutex<Sender<Message>>>,
progress: &fs_extra::TransitProcess,
) -> fs_extra::dir::TransitProcessResult {
log::warn!("{:?}", progress);
match progress.state {
fs_extra::dir::TransitState::Normal => fs_extra::dir::TransitProcessResult::ContinueOrAbort,
fs_extra::dir::TransitState::Exists => {
let Some(file_from) = progress.file_from.clone() else {
log::warn!("missing file_from in progress");
return fs_extra::dir::TransitProcessResult::Abort;
};
let Some(file_to) = progress.file_to.clone() else {
log::warn!("missing file_to in progress");
return fs_extra::dir::TransitProcessResult::Abort;
};
handle_replace(msg_tx, file_from, file_to).into()
}
fs_extra::dir::TransitState::NoAccess => {
//TODO: permission error dialog
fs_extra::dir::TransitProcessResult::ContinueOrAbort
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum ReplaceResult {
Replace,
Skip,
Cancel,
}
impl From<ReplaceResult> for fs_extra::dir::TransitProcessResult {
fn from(f: ReplaceResult) -> fs_extra::dir::TransitProcessResult {
match f {
ReplaceResult::Replace => fs_extra::dir::TransitProcessResult::Overwrite,
ReplaceResult::Skip => fs_extra::dir::TransitProcessResult::Skip,
ReplaceResult::Cancel => fs_extra::dir::TransitProcessResult::Abort,
}
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum Operation {
/// Copy items
@ -135,9 +215,6 @@ impl Operation {
let msg_tx = msg_tx.clone();
tokio::task::spawn_blocking(move || -> fs_extra::error::Result<()> {
log::info!("Copy {:?} to {:?}", paths, to);
//TODO: set options as desired
let dir_options = fs_extra::dir::CopyOptions::default().copy_inside(true);
let file_options = fs_extra::file::CopyOptions::default();
let copied_bytes = AtomicU64::default();
let total_bytes = paths
.iter()
@ -164,24 +241,32 @@ impl Operation {
let dir_handler = |progress: fs_extra::TransitProcess| {
copied_bytes.fetch_add(progress.copied_bytes, atomic::Ordering::Relaxed);
handler();
//TODO: handle exceptions
fs_extra::dir::TransitProcessResult::ContinueOrAbort
handle_progress_state(&msg_tx, &progress)
};
for (from, to) in paths.into_iter().zip(to.into_iter()) {
if from.is_dir() {
fs_extra::copy_items_with_progress(
&[from],
to,
&dir_options,
dir_handler,
)?;
let options = fs_extra::dir::CopyOptions::default().copy_inside(true);
fs_extra::copy_items_with_progress(&[from], to, &options, dir_handler)?;
} else {
fs_extra::file::copy_with_progress(
from,
to,
&file_options,
file_handler,
)?;
let mut options = fs_extra::file::CopyOptions::default();
if to.exists() {
match handle_replace(&msg_tx, from.clone(), to.clone()) {
ReplaceResult::Replace => {
options.overwrite = true;
}
ReplaceResult::Skip => {
options.skip_exist = true;
}
ReplaceResult::Cancel => {
//TODO: be silent, but collect actual changes made for undo
return Err(fs_extra::error::Error::new(
fs_extra::error::ErrorKind::Interrupted,
"operation cancelled",
));
}
}
}
fs_extra::file::copy_with_progress(from, to, &options, file_handler)?;
}
}
Ok(())
@ -239,7 +324,6 @@ impl Operation {
tokio::task::spawn_blocking(move || {
log::info!("Move {:?} to {:?}", paths, to);
let options = fs_extra::dir::CopyOptions::default();
//TODO: set options as desired
fs_extra::move_items_with_progress(&paths, &to, &options, |progress| {
executor::block_on(async {
let _ = msg_tx
@ -252,59 +336,7 @@ impl Operation {
))
.await;
});
match progress.state {
fs_extra::dir::TransitState::Normal => {
fs_extra::dir::TransitProcessResult::ContinueOrAbort
}
fs_extra::dir::TransitState::Exists => {
let Some(file_from) = progress.file_from.clone() else {
log::warn!("missing file_from in progress");
return fs_extra::dir::TransitProcessResult::Abort;
};
let item_from =
match tab::item_from_path(file_from, IconSizes::default()) {
Ok(ok) => ok,
Err(err) => {
log::warn!("{}", err);
return fs_extra::dir::TransitProcessResult::Abort;
}
};
let Some(file_to) = progress.file_to.clone() else {
log::warn!("missing file_to in progress");
return fs_extra::dir::TransitProcessResult::Abort;
};
let item_to =
match tab::item_from_path(file_to, IconSizes::default()) {
Ok(ok) => ok,
Err(err) => {
log::warn!("{}", err);
return fs_extra::dir::TransitProcessResult::Abort;
}
};
executor::block_on(async {
let (tx, mut rx) = mpsc::channel(1);
let _ = msg_tx
.lock()
.await
.send(Message::DialogPush(DialogPage::Replace {
from: item_from,
to: item_to,
tx,
}))
.await;
rx.recv()
.await
.unwrap_or(fs_extra::dir::TransitProcessResult::Abort)
})
}
fs_extra::dir::TransitState::NoAccess => {
//TODO: permission error dialog
fs_extra::dir::TransitProcessResult::ContinueOrAbort
}
}
handle_progress_state(&msg_tx, &progress)
})
})
.await