perf: truncate long lists in confirm dialogs (#1590)

This commit is contained in:
三咲雅 · Misaki Masa 2024-09-02 07:19:22 +08:00 committed by GitHub
parent 3a2dd30166
commit 5f4779cc90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 17 deletions

View file

@ -121,19 +121,19 @@ impl ConfirmCfg {
pub fn trash(urls: &[yazi_shared::fs::Url]) -> Self {
Self::new(
Self::replace_number(&CONFIRM.trash_title, urls.len(), usize::MAX),
Self::replace_number(&CONFIRM.trash_title, urls.len()),
(CONFIRM.trash_origin, CONFIRM.trash_offset),
None,
Some(urls.iter().map(ToString::to_string).collect()),
Self::truncate_list(urls.iter(), urls.len(), 100),
)
}
pub fn delete(urls: &[yazi_shared::fs::Url]) -> Self {
Self::new(
Self::replace_number(&CONFIRM.delete_title, urls.len(), usize::MAX),
Self::replace_number(&CONFIRM.delete_title, urls.len()),
(CONFIRM.delete_origin, CONFIRM.delete_offset),
None,
Some(urls.iter().map(ToString::to_string).collect()),
Self::truncate_list(urls.iter(), urls.len(), 100),
)
}
@ -146,18 +146,33 @@ impl ConfirmCfg {
)
}
pub fn quit(left: Vec<String>) -> Self {
pub fn quit(len: usize, names: Vec<String>) -> Self {
Self::new(
Self::replace_number(&CONFIRM.quit_title, left.len(), 10),
Self::replace_number(&CONFIRM.quit_title, len),
(CONFIRM.quit_origin, CONFIRM.quit_offset),
Some(Text::raw(&CONFIRM.quit_content)),
Some(left.into_iter().collect()),
Self::truncate_list(names.into_iter(), len, 10),
)
}
fn replace_number(tpl: &str, n: usize, max: usize) -> String {
let s = tpl.replace("{s}", if n > 1 { "s" } else { "" });
s.replace("{n}", &if n > max { format!("{max}+") } else { n.to_string() })
fn replace_number(tpl: &str, n: usize) -> String {
tpl.replace("{n}", &n.to_string()).replace("{s}", if n > 1 { "s" } else { "" })
}
fn truncate_list(
it: impl Iterator<Item = impl Into<String>>,
len: usize,
max: usize,
) -> Option<Text<'static>> {
let mut lines = Vec::with_capacity(len.min(max + 1));
for (i, s) in it.enumerate() {
if i >= max {
lines.push(format!("... and {} more", len - max));
break;
}
lines.push(s.into());
}
Some(Text::from_iter(lines))
}
}

View file

@ -23,16 +23,19 @@ impl Manager {
let opt = EventQuit { no_cwd_file: opt.into().no_cwd_file, ..Default::default() };
let ongoing = tasks.ongoing().clone();
let left: Vec<String> = ongoing.lock().values().take(11).map(|t| t.name.clone()).collect();
let (left, left_names) = {
let ongoing = ongoing.lock();
(ongoing.len(), ongoing.values().take(11).map(|t| t.name.clone()).collect())
};
if left.is_empty() {
if left == 0 {
emit!(Quit(opt));
return;
}
tokio::spawn(async move {
let mut i = 0;
let mut rx = ConfirmProxy::show_rx(ConfirmCfg::quit(left));
let mut rx = ConfirmProxy::show_rx(ConfirmCfg::quit(left, left_names));
loop {
select! {
_ = time::sleep(Duration::from_millis(100)) => {

View file

@ -35,7 +35,7 @@ impl Tabs {
}
let opt = opt.into() as Opt;
let mut tab = Tab::default();
let mut tab = Tab { idx: self.cursor + 1, ..Default::default() };
if !opt.current {
tab.cd(opt.url);

View file

@ -23,9 +23,9 @@ pub struct Tab {
pub history: HashMap<Url, Folder>,
pub selected: Selected,
pub preview: Preview,
pub finder: Option<Finder>,
pub(super) search: Option<JoinHandle<Result<()>>>,
pub preview: Preview,
pub finder: Option<Finder>,
pub search: Option<JoinHandle<Result<()>>>,
}
impl Tab {

View file

@ -118,6 +118,10 @@ impl Display for Url {
}
}
impl From<&Url> for String {
fn from(url: &Url) -> Self { url.to_string() }
}
impl Url {
#[inline]
pub fn join(&self, path: impl AsRef<Path>) -> Self {