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> { impl<'a> Widget for Left<'a> {
fn render(self, area: Rect, buf: &mut Buffer) { 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(); let mode = self.cx.manager.active().mode();
// Colors // Colors
@ -33,10 +33,14 @@ impl<'a> Widget for Left<'a> {
primary.bg().fg(**secondary).add_modifier(Modifier::BOLD), primary.bg().fg(**secondary).add_modifier(Modifier::BOLD),
)); ));
if let Some(h) = &manager.hovered { if let Some(h) = &folder.hovered {
// Length // 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())); spans.push(Span::styled(&separator.closing, body.fg()));
} }

View File

@ -8,7 +8,7 @@ use tokio::fs;
pub struct File { pub struct File {
pub(super) url: Url, pub(super) url: Url,
pub(super) meta: Metadata, pub(super) meta: Metadata,
pub(super) length: Option<u64>, pub(super) length: u64,
pub(super) link_to: Option<Url>, pub(super) link_to: Option<Url>,
pub(super) is_link: bool, pub(super) is_link: bool,
pub(super) is_hidden: bool, pub(super) is_hidden: bool,
@ -30,7 +30,7 @@ impl File {
link_to = fs::read_link(&url).await.map(Url::from).ok(); 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); 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 } Self { url, meta, length, link_to, is_link, is_hidden }
} }
@ -76,7 +76,7 @@ impl File {
// --- Length // --- Length
#[inline] #[inline]
pub fn length(&self) -> Option<u64> { self.length } pub fn length(&self) -> u64 { self.length }
// --- Link to // --- Link to
#[inline] #[inline]

View File

@ -126,7 +126,7 @@ impl Files {
if !self.show_hidden { if !self.show_hidden {
(self.hidden, items) = items.into_iter().partition(|f| f.is_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.items = items;
self.version = FILES_VERSION.fetch_add(1, Ordering::Relaxed); self.version = FILES_VERSION.fetch_add(1, Ordering::Relaxed);
true true
@ -146,7 +146,7 @@ impl Files {
self.hidden.extend(hidden); self.hidden.extend(hidden);
} }
self.sorter.sort(&mut self.items); self.sorter.sort(&mut self.items, &self.sizes);
return true; return true;
} }
@ -162,7 +162,7 @@ impl Files {
pub fn update_size(&mut self, items: BTreeMap<Url, u64>) -> bool { pub fn update_size(&mut self, items: BTreeMap<Url, u64>) -> bool {
self.sizes.extend(items); self.sizes.extend(items);
if self.sorter.by == SortBy::Size { if self.sorter.by == SortBy::Size {
self.sorter.sort(&mut self.items); self.sorter.sort(&mut self.items, &self.sizes);
} }
true true
} }
@ -186,6 +186,10 @@ impl Files {
#[inline] #[inline]
pub fn duplicate(&self, idx: usize) -> Option<File> { self.items.get(idx).cloned() } 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 // --- Selected
pub fn selected(&self, pending: &BTreeSet<usize>, unset: bool) -> Vec<&File> { pub fn selected(&self, pending: &BTreeSet<usize>, unset: bool) -> Vec<&File> {
if self.selected.is_empty() && (unset || pending.is_empty()) { if self.selected.is_empty() && (unset || pending.is_empty()) {
@ -234,7 +238,7 @@ impl Files {
return false; return false;
} }
self.sorter = sorter; self.sorter = sorter;
self.sorter.sort(&mut self.items) self.sorter.sort(&mut self.items, &self.sizes)
} }
// --- Show hidden // --- Show hidden
@ -248,7 +252,7 @@ impl Files {
if state { if state {
self.items.append(&mut self.hidden); self.items.append(&mut self.hidden);
self.sorter.sort(&mut self.items); self.sorter.sort(&mut self.items, &self.sizes);
} else { } else {
let items = mem::take(&mut self.items); let items = mem::take(&mut self.items);
(self.hidden, self.items) = items.into_iter().partition(|f| f.is_hidden); (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 config::{manager::SortBy, MANAGER};
use shared::Url;
use super::File; use super::File;
@ -22,7 +23,7 @@ impl Default for FilesSorter {
} }
impl 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() { if items.is_empty() {
return false; return false;
} }
@ -45,7 +46,9 @@ impl FilesSorter {
}), }),
SortBy::Natural => self.sort_naturally(items), SortBy::Natural => self.sort_naturally(items),
SortBy::Size => items.sort_unstable_by(|a, b| { 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 true
@ -73,7 +76,7 @@ impl FilesSorter {
let dummy = File { let dummy = File {
url: Default::default(), url: Default::default(),
meta: items[0].meta.clone(), meta: items[0].meta.clone(),
length: None, length: 0,
link_to: None, link_to: None,
is_link: false, is_link: false,
is_hidden: false, is_hidden: false,

View File

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