feat: file size sorting under the simplified file system (#123)

This commit is contained in:
三咲雅 · Misaki Masa 2023-09-08 06:41:52 +08:00 committed by GitHub
parent d702cbcf9a
commit fa64047120
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 18 deletions

View File

@ -14,7 +14,7 @@ impl<'a> Left<'a> {
impl<'a> Widget for Left<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
let manager = self.cx.manager.current();
let folder = self.cx.manager.current();
let mode = self.cx.manager.active().mode();
// Colors
@ -33,10 +33,14 @@ impl<'a> Widget for Left<'a> {
primary.bg().fg(**secondary).add_modifier(Modifier::BOLD),
));
if let Some(h) = &manager.hovered {
if let Some(h) = &folder.hovered {
// Length
if let Some(len) = h.length() {
spans.push(Span::styled(format!(" {} ", readable_size(len)), body.bg().fg(**primary)));
{
let size = if h.is_dir() { folder.files.size(h.url()) } else { None };
spans.push(Span::styled(
format!(" {} ", readable_size(size.unwrap_or(h.length()))),
body.bg().fg(**primary),
));
spans.push(Span::styled(&separator.closing, body.fg()));
}

View File

@ -8,7 +8,7 @@ use tokio::fs;
pub struct File {
pub(super) url: Url,
pub(super) meta: Metadata,
pub(super) length: Option<u64>,
pub(super) length: u64,
pub(super) link_to: Option<Url>,
pub(super) is_link: bool,
pub(super) is_hidden: bool,
@ -30,7 +30,7 @@ impl File {
link_to = fs::read_link(&url).await.map(Url::from).ok();
}
let length = if meta.is_dir() { None } else { Some(meta.len()) };
let length = meta.len();
let is_hidden = url.file_name().map(|s| s.to_string_lossy().starts_with('.')).unwrap_or(false);
Self { url, meta, length, link_to, is_link, is_hidden }
}
@ -76,7 +76,7 @@ impl File {
// --- Length
#[inline]
pub fn length(&self) -> Option<u64> { self.length }
pub fn length(&self) -> u64 { self.length }
// --- Link to
#[inline]

View File

@ -126,7 +126,7 @@ impl Files {
if !self.show_hidden {
(self.hidden, items) = items.into_iter().partition(|f| f.is_hidden);
}
self.sorter.sort(&mut items);
self.sorter.sort(&mut items, &self.sizes);
self.items = items;
self.version = FILES_VERSION.fetch_add(1, Ordering::Relaxed);
true
@ -146,7 +146,7 @@ impl Files {
self.hidden.extend(hidden);
}
self.sorter.sort(&mut self.items);
self.sorter.sort(&mut self.items, &self.sizes);
return true;
}
@ -162,7 +162,7 @@ impl Files {
pub fn update_size(&mut self, items: BTreeMap<Url, u64>) -> bool {
self.sizes.extend(items);
if self.sorter.by == SortBy::Size {
self.sorter.sort(&mut self.items);
self.sorter.sort(&mut self.items, &self.sizes);
}
true
}
@ -186,6 +186,10 @@ impl Files {
#[inline]
pub fn duplicate(&self, idx: usize) -> Option<File> { self.items.get(idx).cloned() }
// --- Size
#[inline]
pub fn size(&self, url: &Url) -> Option<u64> { self.sizes.get(url).copied() }
// --- Selected
pub fn selected(&self, pending: &BTreeSet<usize>, unset: bool) -> Vec<&File> {
if self.selected.is_empty() && (unset || pending.is_empty()) {
@ -234,7 +238,7 @@ impl Files {
return false;
}
self.sorter = sorter;
self.sorter.sort(&mut self.items)
self.sorter.sort(&mut self.items, &self.sizes)
}
// --- Show hidden
@ -248,7 +252,7 @@ impl Files {
if state {
self.items.append(&mut self.hidden);
self.sorter.sort(&mut self.items);
self.sorter.sort(&mut self.items, &self.sizes);
} else {
let items = mem::take(&mut self.items);
(self.hidden, self.items) = items.into_iter().partition(|f| f.is_hidden);

View File

@ -1,6 +1,7 @@
use std::{cmp::Ordering, mem};
use std::{cmp::Ordering, collections::BTreeMap, mem};
use config::{manager::SortBy, MANAGER};
use shared::Url;
use super::File;
@ -22,7 +23,7 @@ impl Default for FilesSorter {
}
impl FilesSorter {
pub(super) fn sort(&self, items: &mut Vec<File>) -> bool {
pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &BTreeMap<Url, u64>) -> bool {
if items.is_empty() {
return false;
}
@ -45,7 +46,9 @@ impl FilesSorter {
}),
SortBy::Natural => self.sort_naturally(items),
SortBy::Size => items.sort_unstable_by(|a, b| {
self.cmp(a.length().unwrap_or(0), b.length().unwrap_or(0), self.promote(a, b))
let aa = if a.is_dir() { sizes.get(a.url()).copied() } else { None };
let bb = if b.is_dir() { sizes.get(b.url()).copied() } else { None };
self.cmp(aa.unwrap_or(a.length), bb.unwrap_or(b.length), self.promote(a, b))
}),
}
true
@ -73,7 +76,7 @@ impl FilesSorter {
let dummy = File {
url: Default::default(),
meta: items[0].meta.clone(),
length: None,
length: 0,
link_to: None,
is_link: false,
is_hidden: false,

View File

@ -211,8 +211,11 @@ impl Tasks {
return false;
}
let targets: Vec<_> =
targets.iter().filter(|f| f.is_dir() && f.length().is_none()).map(|f| f.url()).collect();
let targets: Vec<_> = targets
.iter()
.filter(|f| f.is_dir() && targets.size(f.url()).is_none())
.map(|f| f.url())
.collect();
if !targets.is_empty() {
self.scheduler.precache_size(targets);