From 0e26f5d3c73c4c9a5cfb849c321311b5fd1b2da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Fri, 3 May 2024 23:51:43 +0800 Subject: [PATCH] feat: close confirmation prompts and exit automatically when the ongoing task gone (#997) --- yazi-core/src/manager/commands/quit.rs | 31 ++++++++++++++++++++++--- yazi-core/src/tasks/commands/cancel.rs | 2 +- yazi-core/src/tasks/commands/inspect.rs | 10 ++++---- yazi-core/src/tasks/tasks.rs | 8 +++---- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/yazi-core/src/manager/commands/quit.rs b/yazi-core/src/manager/commands/quit.rs index 04d5be98..d2691f2f 100644 --- a/yazi-core/src/manager/commands/quit.rs +++ b/yazi-core/src/manager/commands/quit.rs @@ -1,3 +1,6 @@ +use std::time::Duration; + +use tokio::{select, time}; use yazi_config::popup::InputCfg; use yazi_proxy::InputProxy; use yazi_shared::{emit, event::{Cmd, EventQuit}}; @@ -19,14 +22,36 @@ impl Manager { pub fn quit(&self, opt: impl Into, tasks: &Tasks) { let opt = EventQuit { no_cwd_file: opt.into().no_cwd_file, ..Default::default() }; - let tasks = tasks.len(); - if tasks == 0 { + let ongoing = tasks.ongoing().clone(); + let left = ongoing.lock().len(); + + if left == 0 { emit!(Quit(opt)); return; } 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 choice == "y" || choice == "Y" { emit!(Quit(opt)); diff --git a/yazi-core/src/tasks/commands/cancel.rs b/yazi-core/src/tasks/commands/cancel.rs index e8c9aca6..5b4fb30a 100644 --- a/yazi-core/src/tasks/commands/cancel.rs +++ b/yazi-core/src/tasks/commands/cancel.rs @@ -4,7 +4,7 @@ use crate::tasks::Tasks; impl Tasks { 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) { return; } diff --git a/yazi-core/src/tasks/commands/inspect.rs b/yazi-core/src/tasks/commands/inspect.rs index b17f3cce..9eea7831 100644 --- a/yazi-core/src/tasks/commands/inspect.rs +++ b/yazi-core/src/tasks/commands/inspect.rs @@ -10,17 +10,17 @@ use crate::tasks::Tasks; impl Tasks { 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; }; - let scheduler = self.scheduler.clone(); tokio::spawn(async move { let _permit = HIDER.acquire().await.unwrap(); let (tx, mut rx) = mpsc::unbounded_channel(); let mut buffered = { - let mut ongoing = scheduler.ongoing.lock(); + let mut ongoing = ongoing.lock(); let Some(task) = ongoing.get_mut(id) else { return }; task.logger = Some(tx); @@ -46,7 +46,7 @@ impl Tasks { stderr.write_all(b"\r\n").ok(); } _ = 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(); 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; } while answer != b'q' { diff --git a/yazi-core/src/tasks/tasks.rs b/yazi-core/src/tasks/tasks.rs index 1f137867..0f4acff9 100644 --- a/yazi-core/src/tasks/tasks.rs +++ b/yazi-core/src/tasks/tasks.rs @@ -1,7 +1,8 @@ use std::{sync::Arc, time::Duration}; +use parking_lot::Mutex; 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 super::{TasksProgress, TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT}; @@ -56,10 +57,9 @@ impl Tasks { } pub fn paginate(&self) -> Vec { - let ongoing = self.scheduler.ongoing.lock(); - ongoing.values().take(Self::limit()).map(Into::into).collect() + self.ongoing().lock().values().take(Self::limit()).map(Into::into).collect() } #[inline] - pub fn len(&self) -> usize { self.scheduler.ongoing.lock().len() } + pub fn ongoing(&self) -> &Arc> { &self.scheduler.ongoing } }