mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
pubsub for bulk rename
This commit is contained in:
parent
013d00f577
commit
6919b2f193
2 changed files with 40 additions and 2 deletions
|
|
@ -1,9 +1,10 @@
|
||||||
use std::time::Duration;
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use tokio::{pin, select, sync::mpsc};
|
use tokio::{pin, select, sync::mpsc};
|
||||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
use yazi_fs::{File, FilesOp};
|
||||||
use yazi_shared::{RoCell, url::Url};
|
use yazi_shared::{RoCell, url::Url};
|
||||||
|
|
||||||
use crate::{Pubsub, body::BodyMoveItem};
|
use crate::{Pubsub, body::BodyMoveItem};
|
||||||
|
|
@ -12,6 +13,7 @@ static CT: RoCell<CancellationToken> = RoCell::new();
|
||||||
static MOVE_TX: Mutex<Option<mpsc::UnboundedSender<BodyMoveItem>>> = Mutex::new(None);
|
static MOVE_TX: Mutex<Option<mpsc::UnboundedSender<BodyMoveItem>>> = Mutex::new(None);
|
||||||
static TRASH_TX: Mutex<Option<mpsc::UnboundedSender<Url>>> = Mutex::new(None);
|
static TRASH_TX: Mutex<Option<mpsc::UnboundedSender<Url>>> = Mutex::new(None);
|
||||||
static DELETE_TX: Mutex<Option<mpsc::UnboundedSender<Url>>> = Mutex::new(None);
|
static DELETE_TX: Mutex<Option<mpsc::UnboundedSender<Url>>> = Mutex::new(None);
|
||||||
|
static BULK_RENAME_TX: Mutex<Option<mpsc::UnboundedSender<(Url, File)>>> = Mutex::new(None);
|
||||||
|
|
||||||
pub struct Pump;
|
pub struct Pump;
|
||||||
|
|
||||||
|
|
@ -37,15 +39,24 @@ impl Pump {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn push_bulk_rename_pair(from: Url, to: File) {
|
||||||
|
if let Some(tx) = &*BULK_RENAME_TX.lock() {
|
||||||
|
tx.send((from, to)).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn serve() {
|
pub(super) fn serve() {
|
||||||
let (move_tx, move_rx) = mpsc::unbounded_channel();
|
let (move_tx, move_rx) = mpsc::unbounded_channel();
|
||||||
let (trash_tx, trash_rx) = mpsc::unbounded_channel();
|
let (trash_tx, trash_rx) = mpsc::unbounded_channel();
|
||||||
let (delete_tx, delete_rx) = mpsc::unbounded_channel();
|
let (delete_tx, delete_rx) = mpsc::unbounded_channel();
|
||||||
|
let (bulk_rename_tx, bulk_rename_rx) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
CT.with(<_>::default);
|
CT.with(<_>::default);
|
||||||
MOVE_TX.lock().replace(move_tx);
|
MOVE_TX.lock().replace(move_tx);
|
||||||
TRASH_TX.lock().replace(trash_tx);
|
TRASH_TX.lock().replace(trash_tx);
|
||||||
DELETE_TX.lock().replace(delete_tx);
|
DELETE_TX.lock().replace(delete_tx);
|
||||||
|
BULK_RENAME_TX.lock().replace(bulk_rename_tx);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let move_rx =
|
let move_rx =
|
||||||
|
|
@ -54,16 +65,23 @@ impl Pump {
|
||||||
UnboundedReceiverStream::new(trash_rx).chunks_timeout(1000, Duration::from_millis(500));
|
UnboundedReceiverStream::new(trash_rx).chunks_timeout(1000, Duration::from_millis(500));
|
||||||
let delete_rx =
|
let delete_rx =
|
||||||
UnboundedReceiverStream::new(delete_rx).chunks_timeout(1000, Duration::from_millis(500));
|
UnboundedReceiverStream::new(delete_rx).chunks_timeout(1000, Duration::from_millis(500));
|
||||||
|
let bulk_rename_rx = UnboundedReceiverStream::new(bulk_rename_rx)
|
||||||
|
.chunks_timeout(1000, Duration::from_millis(500));
|
||||||
|
|
||||||
pin!(move_rx);
|
pin!(move_rx);
|
||||||
pin!(trash_rx);
|
pin!(trash_rx);
|
||||||
pin!(delete_rx);
|
pin!(delete_rx);
|
||||||
|
pin!(bulk_rename_rx);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
select! {
|
select! {
|
||||||
Some(items) = move_rx.next() => Pubsub::pub_from_move(items),
|
Some(items) = move_rx.next() => Pubsub::pub_from_move(items),
|
||||||
Some(urls) = trash_rx.next() => Pubsub::pub_from_trash(urls),
|
Some(urls) = trash_rx.next() => Pubsub::pub_from_trash(urls),
|
||||||
Some(urls) = delete_rx.next() => Pubsub::pub_from_delete(urls),
|
Some(urls) = delete_rx.next() => Pubsub::pub_from_delete(urls),
|
||||||
|
Some(items) = bulk_rename_rx.next() => {
|
||||||
|
Pubsub::pub_from_bulk(items.iter().map(|(from, to)| (from, &to.url)).collect());
|
||||||
|
FilesOp::rename(HashMap::from_iter(items));
|
||||||
|
}
|
||||||
else => {
|
else => {
|
||||||
CT.cancel();
|
CT.cancel();
|
||||||
break;
|
break;
|
||||||
|
|
@ -77,6 +95,7 @@ impl Pump {
|
||||||
drop(MOVE_TX.lock().take());
|
drop(MOVE_TX.lock().take());
|
||||||
drop(TRASH_TX.lock().take());
|
drop(TRASH_TX.lock().take());
|
||||||
drop(DELETE_TX.lock().take());
|
drop(DELETE_TX.lock().take());
|
||||||
|
drop(BULK_RENAME_TX.lock().take());
|
||||||
CT.cancelled().await;
|
CT.cancelled().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -210,13 +210,32 @@ impl Scheduler {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_rename_at(&self, root: &Path, old: &Path, new: &Path) {
|
pub fn file_rename_at(&self, root: &Path, old: &Path, new: &Path) {
|
||||||
let id = self.ongoing.lock().add(
|
let mut ongoing = self.ongoing.lock();
|
||||||
|
let id = ongoing.add(
|
||||||
TaskKind::User,
|
TaskKind::User,
|
||||||
format!("Rename at {}: {} -> {} ", root.display(), old.display(), new.display()),
|
format!("Rename at {}: {} -> {} ", root.display(), old.display(), new.display()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (from, to): (Url, Url) = (root.join(old).into(), root.join(new).into());
|
let (from, to): (Url, Url) = (root.join(old).into(), root.join(new).into());
|
||||||
|
|
||||||
|
ongoing.hooks.insert(id, {
|
||||||
|
let from = from.clone();
|
||||||
|
let to = to.clone();
|
||||||
|
let ongoing = self.ongoing.clone();
|
||||||
|
|
||||||
|
Box::new(move |canceled: bool| {
|
||||||
|
async move {
|
||||||
|
if !canceled {
|
||||||
|
if let Ok(to) = yazi_fs::File::from(to).await {
|
||||||
|
Pump::push_bulk_rename_pair(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ongoing.lock().try_remove(id, TaskStage::Hooked);
|
||||||
|
}
|
||||||
|
.boxed()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let file = self.file.clone();
|
let file = self.file.clone();
|
||||||
self.send_micro(id, LOW, async move { file.rename(FileOpRename { id, from, to }).await });
|
self.send_micro(id, LOW, async move { file.rename(FileOpRename { id, from, to }).await });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue