feat: close confirmation prompts and exit automatically when the ongoing task gone (#997)

This commit is contained in:
三咲雅 · Misaki Masa 2024-05-03 23:51:43 +08:00 committed by GitHub
parent 2fdc0dd7bf
commit 0e26f5d3c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 13 deletions

View File

@ -1,3 +1,6 @@
use std::time::Duration;
use tokio::{select, time};
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_proxy::InputProxy; use yazi_proxy::InputProxy;
use yazi_shared::{emit, event::{Cmd, EventQuit}}; use yazi_shared::{emit, event::{Cmd, EventQuit}};
@ -19,14 +22,36 @@ impl Manager {
pub fn quit(&self, opt: impl Into<Opt>, tasks: &Tasks) { pub fn quit(&self, opt: impl Into<Opt>, tasks: &Tasks) {
let opt = EventQuit { no_cwd_file: opt.into().no_cwd_file, ..Default::default() }; let opt = EventQuit { no_cwd_file: opt.into().no_cwd_file, ..Default::default() };
let tasks = tasks.len(); let ongoing = tasks.ongoing().clone();
if tasks == 0 { let left = ongoing.lock().len();
if left == 0 {
emit!(Quit(opt)); emit!(Quit(opt));
return; return;
} }
tokio::spawn(async move { tokio::spawn(async move {
let mut result = InputProxy::show(InputCfg::quit(tasks)); let mut i = 0;
let mut result = InputProxy::show(InputCfg::quit(left));
loop {
select! {
_ = time::sleep(Duration::from_millis(100)) => {
i += 1;
if i > 30 { break }
else if ongoing.lock().len() == 0 {
emit!(Quit(opt));
return;
}
}
choice = result.recv() => {
if matches!(choice, Some(Ok(s)) if s == "y" || s == "Y") {
emit!(Quit(opt));
}
return;
}
}
}
if let Some(Ok(choice)) = result.recv().await { if let Some(Ok(choice)) = result.recv().await {
if choice == "y" || choice == "Y" { if choice == "y" || choice == "Y" {
emit!(Quit(opt)); emit!(Quit(opt));

View File

@ -4,7 +4,7 @@ use crate::tasks::Tasks;
impl Tasks { impl Tasks {
pub fn cancel(&mut self, _: Cmd) { pub fn cancel(&mut self, _: Cmd) {
let id = self.scheduler.ongoing.lock().get_id(self.cursor); let id = self.ongoing().lock().get_id(self.cursor);
if id.map(|id| self.scheduler.cancel(id)) != Some(true) { if id.map(|id| self.scheduler.cancel(id)) != Some(true) {
return; return;
} }

View File

@ -10,17 +10,17 @@ use crate::tasks::Tasks;
impl Tasks { impl Tasks {
pub fn inspect(&self, _: Cmd) { pub fn inspect(&self, _: Cmd) {
let Some(id) = self.scheduler.ongoing.lock().get_id(self.cursor) else { let ongoing = self.ongoing().clone();
let Some(id) = ongoing.lock().get_id(self.cursor) else {
return; return;
}; };
let scheduler = self.scheduler.clone();
tokio::spawn(async move { tokio::spawn(async move {
let _permit = HIDER.acquire().await.unwrap(); let _permit = HIDER.acquire().await.unwrap();
let (tx, mut rx) = mpsc::unbounded_channel(); let (tx, mut rx) = mpsc::unbounded_channel();
let mut buffered = { let mut buffered = {
let mut ongoing = scheduler.ongoing.lock(); let mut ongoing = ongoing.lock();
let Some(task) = ongoing.get_mut(id) else { return }; let Some(task) = ongoing.get_mut(id) else { return };
task.logger = Some(tx); task.logger = Some(tx);
@ -46,7 +46,7 @@ impl Tasks {
stderr.write_all(b"\r\n").ok(); stderr.write_all(b"\r\n").ok();
} }
_ = time::sleep(time::Duration::from_millis(500)) => { _ = time::sleep(time::Duration::from_millis(500)) => {
if scheduler.ongoing.lock().get(id).is_none() { if ongoing.lock().get(id).is_none() {
stderr().write_all(b"Task finished, press `q` to quit\r\n").ok(); stderr().write_all(b"Task finished, press `q` to quit\r\n").ok();
break; break;
} }
@ -60,7 +60,7 @@ impl Tasks {
} }
} }
if let Some(task) = scheduler.ongoing.lock().get_mut(id) { if let Some(task) = ongoing.lock().get_mut(id) {
task.logger = None; task.logger = None;
} }
while answer != b'q' { while answer != b'q' {

View File

@ -1,7 +1,8 @@
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use parking_lot::Mutex;
use tokio::{task::JoinHandle, time::sleep}; use tokio::{task::JoinHandle, time::sleep};
use yazi_scheduler::{Scheduler, TaskSummary}; use yazi_scheduler::{Ongoing, Scheduler, TaskSummary};
use yazi_shared::{emit, event::Cmd, term::Term, Layer}; use yazi_shared::{emit, event::Cmd, term::Term, Layer};
use super::{TasksProgress, TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT}; use super::{TasksProgress, TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT};
@ -56,10 +57,9 @@ impl Tasks {
} }
pub fn paginate(&self) -> Vec<TaskSummary> { pub fn paginate(&self) -> Vec<TaskSummary> {
let ongoing = self.scheduler.ongoing.lock(); self.ongoing().lock().values().take(Self::limit()).map(Into::into).collect()
ongoing.values().take(Self::limit()).map(Into::into).collect()
} }
#[inline] #[inline]
pub fn len(&self) -> usize { self.scheduler.ongoing.lock().len() } pub fn ongoing(&self) -> &Arc<Mutex<Ongoing>> { &self.scheduler.ongoing }
} }