Partially implement copy and move, debounce events

This commit is contained in:
Jeremy Soller 2024-03-20 11:54:37 -06:00
parent a2560db6ba
commit 244291be79
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
7 changed files with 311 additions and 131 deletions

View file

@ -1,5 +1,5 @@
use cosmic::iced::futures::{channel::mpsc, SinkExt};
use std::{fs, path::PathBuf};
use cosmic::iced::futures::{channel::mpsc, executor, SinkExt};
use std::{fs, path::PathBuf, sync::Arc};
use crate::app::Message;
@ -41,12 +41,46 @@ pub enum Operation {
impl Operation {
/// Perform the operation
pub async fn perform(self, id: u64, msg_tx: &mut mpsc::Sender<Message>) -> Result<(), String> {
let _ = msg_tx.send(Message::PendingProgress(id, 0.0)).await;
pub async fn perform(
self,
id: u64,
msg_tx: &Arc<tokio::sync::Mutex<mpsc::Sender<Message>>>,
) -> Result<(), String> {
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(id, 0.0))
.await;
//TODO: IF ERROR, RETURN AN Operation THAT CAN UNDO THE CURRENT STATE
//TODO: SAFELY HANDLE CANCEL
match self {
Self::Copy { paths, to } => {
let msg_tx = msg_tx.clone();
tokio::task::spawn_blocking(move || {
log::info!("Copy {:?} to {:?}", paths, to);
let options = fs_extra::dir::CopyOptions::default();
//TODO: set options as desired
fs_extra::copy_items_with_progress(&paths, &to, &options, |progress| {
executor::block_on(async {
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(
id,
100.0 * (progress.copied_bytes as f32)
/ (progress.total_bytes as f32),
))
.await;
});
//TODO: handle exceptions
fs_extra::dir::TransitProcessResult::ContinueOrAbort
})
})
.await
.map_err(err_str)?
.map_err(err_str)?;
}
Self::Delete { paths } => {
let total = paths.len();
let mut count = 0;
@ -57,6 +91,8 @@ impl Operation {
.map_err(err_str)?;
count += 1;
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(
id,
100.0 * (count as f32) / (total as f32),
@ -64,26 +100,64 @@ impl Operation {
.await;
}
}
Self::Move { paths, to } => {
let msg_tx = msg_tx.clone();
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
.lock()
.await
.send(Message::PendingProgress(
id,
100.0 * (progress.copied_bytes as f32)
/ (progress.total_bytes as f32),
))
.await;
});
//TODO: handle exceptions
fs_extra::dir::TransitProcessResult::ContinueOrAbort
})
})
.await
.map_err(err_str)?
.map_err(err_str)?;
}
Self::NewFolder { path } => {
tokio::task::spawn_blocking(|| fs::create_dir(path))
.await
.map_err(err_str)?
.map_err(err_str)?;
let _ = msg_tx.send(Message::PendingProgress(id, 100.0)).await;
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(id, 100.0))
.await;
}
Self::NewFile { path } => {
tokio::task::spawn_blocking(|| fs::File::create(path))
.await
.map_err(err_str)?
.map_err(err_str)?;
let _ = msg_tx.send(Message::PendingProgress(id, 100.0)).await;
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(id, 100.0))
.await;
}
Self::Rename { from, to } => {
tokio::task::spawn_blocking(|| fs::rename(from, to))
.await
.map_err(err_str)?
.map_err(err_str)?;
let _ = msg_tx.send(Message::PendingProgress(id, 100.0)).await;
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(id, 100.0))
.await;
}
Self::Restore { paths } => {
let total = paths.len();
@ -95,6 +169,8 @@ impl Operation {
.map_err(err_str)?;
count += 1;
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(
id,
100.0 * (count as f32) / (total as f32),
@ -102,12 +178,13 @@ impl Operation {
.await;
}
}
_ => {
return Err("not implemented".to_string());
}
}
let _ = msg_tx.send(Message::PendingProgress(id, 100.0)).await;
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(id, 100.0))
.await;
Ok(())
}